from __future__ import print_function
from __future__ import absolute_import
import os
import sys
import subprocess
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
import sumolib
from sumolib.xml import parse
from sumolib.net import lane2edge, lane2index
def get_options(args=None):
ap = sumolib.options.ArgumentParser(description="Remap edge attributes from one network to another")
ap.add_argument("--orig-net", dest="origNet", required=True, category="input", type=ap.net_file,
help="SUMO network for reading attributes", metavar="FILE")
ap.add_argument("--target-net", dest="targetNet", required=True, category="input", type=ap.net_file,
help="SUMO network for receiving attributes", metavar="FILE")
ap.add_argument("-o", "--output-file", dest="output", required=True, category="output", type=ap.net_file,
help="File for writing the patched network", metavar="FILE")
ap.add_argument("-p", "--patch-file-prefix", dest="patchPrefix", category="output", default="patch",
help="prefix for patch files")
ap.add_argument("-a", "--attributes", required=True,
help="the list of edge attributes that shall be transferred")
gp = ap.add_mutually_exclusive_group(required=False)
gp.add_argument("--osm.origid", action="store_true", dest="osmOrigId", default=False,
help="match objects based on OSM ids (stored in params from --output.original-names)")
gp.add_argument("--origid", action="store_true", dest="origId", default=False,
help="match objects based on origIDs after renaming")
ap.add_argument("-v", "--verbose", action="store_true", dest="verbose",
default=False, help="tell me what you are doing")
options = ap.parse_args()
options.attributes = options.attributes.split(',')
options.edgfile = options.patchPrefix + ".edg.xml"
return options
class Ambiguous:
pass
RETRIEVERS = {}
def getAttr(edge, a):
method = RETRIEVERS.get(a, 'get' + a[0].upper() + a[1:])
return getattr(edge, method)()
def getAttrs(options, edge):
return [getAttr(edge, a) for a in options.attributes]
def main(options):
if options.verbose:
print("Reading orig-net '%s'" % options.origNet)
net = sumolib.net.readNet(options.origNet)
if options.verbose:
print("Reading target-net '%s'" % options.targetNet)
net2 = sumolib.net.readNet(options.targetNet)
lookup = {}
if options.osmOrigId:
for edge in net.getEdges():
lane = edge.getLanes()[0]
origIds = lane.getParam("origId").split()
attrs = getAttrs(options, edge)
for origId in origIds:
attrs2 = lookup.get(origId)
if attrs2 is None:
lookup[origId] = attrs
else:
attrs3 = []
for a, v, v2 in zip(options.attributes, attrs, attrs2):
if v == v2 or v2 is None:
attrs3.append(v)
elif v is None:
attrs3.append(v2)
else:
print("Ambiguous attribute '%s' for origId '%s' (%s != %s)" % (
a, origId, v, v2), file=sys.stderr)
attrs3.append(Ambiguous)
lookup[origId] = attrs3
elif options.origId:
for edge in net.getEdges():
attrs = getAttrs(options, edge)
lookup[edge.getID()] = attrs
else:
print("Geometrical matching not yet implemented", file=sys.stderr)
sys.exit(1)
patchedValues = {}
if options.osmOrigId or options.origId:
for edge in net2.getEdges():
lane = edge.getLanes()[0]
origIds = lane.getParam("origId")
if origIds is None:
continue
origIds = origIds.split()
attrs = getAttrs(options, edge)
attrs2 = []
for i, a in enumerate(options.attributes):
v = None
for origId in origIds:
if origId in lookup:
v2 = lookup[origId][i]
if v2 == Ambiguous:
v = None
break
if v is None:
v = v2
elif v2 is not None and v != v2:
print("Ambiguous attribute '%s' for edge '%s' with origIds '%s' (%s != %s)" % (
a, edge.getID(), origIds, v, v2), file=sys.stderr)
v = None
break
if v == attrs[i]:
v = None
attrs2.append(v)
if any([v is not None for v in attrs2]):
patchedValues[edge.getID()] = attrs2
with sumolib.openz(options.edgfile, 'w') as fout:
sumolib.writeXMLHeader(fout, "$Id$", "edges", schemaPath="edgediff_file.xsd", options=options)
for edgeID in sorted(patchedValues.keys()):
validAttrs = [(a, v) for a, v in zip(options.attributes, patchedValues[edgeID]) if v is not None]
fout.write(' <edge id="%s" %s/>\n' % (
edgeID, ' '.join(['%s="%s"' % av for av in validAttrs])))
fout.write('</edges>\n')
NETCONVERT = sumolib.checkBinary('netconvert')
subprocess.call([NETCONVERT,
'-s', options.targetNet,
'-e', options.edgfile,
'-o', options.output])
if __name__ == "__main__":
main(get_options())