"""
This script converts a flow file in csv-format to XML
(generalized meandata format : http://sumo.dlr.de/xsd/meandata_file.xsd)
"""
from __future__ import absolute_import
from __future__ import print_function
import sys
import os
from collections import defaultdict
import detector
SUMO_HOME = os.environ.get('SUMO_HOME',
os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..'))
sys.path.append(os.path.join(SUMO_HOME, 'tools'))
import sumolib
from sumolib.xml import parse
from sumolib.options import ArgumentParser
DEBUG = False
def get_options(args=None):
parser = ArgumentParser(description="Convert detector flow file to edgeData format")
parser.add_argument("-d", "--detector-file", dest="detfile", category="input", type=ArgumentParser.additional_file,
help="read detectors from FILE", metavar="FILE")
parser.add_argument("-f", "--detector-flow-file", dest="flowfile", category="input", type=ArgumentParser.file,
help="read detector flows to compare to from FILE (mandatory)", metavar="FILE")
parser.add_argument("-o", "--output-file", dest="output", category="output", type=ArgumentParser.edgedata_file,
help="output edgeData FILE (mandatory)", metavar="FILE")
parser.add_argument("--id-column", default="Detector", dest="detcol",
help="Read detector ids from the given column")
parser.add_argument("--time-column", default="Time", dest="timecol",
help="Read detector time from the given column")
parser.add_argument("--time-scale", type=int, default=60, dest="timescale",
help="Interpretation of time units in seconds (default 60)")
parser.add_argument("-q", "--flow-columns", dest="flowcols", default="qPKW,qLKW", type=str,
help="which columns contains flows (specified via column header)", metavar="STRING")
parser.add_argument("-b", "--begin", default=0, type=ArgumentParser.time,
help="custom begin time (minutes or H:M:S)")
parser.add_argument("-e", "--end", default=1440, type=ArgumentParser.time,
help="custom end time (minutes or H:M:S)")
parser.add_argument("-i", "--interval", default=1440, type=ArgumentParser.time,
help="custom aggregation interval (minutes or H:M:S)")
parser.add_argument("--cadyts", action="store_true",
default=False, help="generate output in cadyts format")
parser.add_argument("-v", "--verbose", action="store_true", dest="verbose",
default=False, help="tell me what you are doing")
options = parser.parse_args(args=args)
if not options.flowfile or not options.output:
parser.print_help()
sys.exit()
return options
class LaneMap:
def get(self, key, default):
return key[0:-2]
def main(options):
readers = {}
flowcols = options.flowcols.split(',')
tMin = None
tMax = None
for flowcol in flowcols:
detReader = detector.DetectorReader(options.detfile, LaneMap())
tMin, tMax = detReader.findTimes(options.flowfile, tMin, tMax, options.detcol, options.timecol)
hasData = detReader.readFlows(options.flowfile, flow=flowcol, det=options.detcol,
time=options.timecol, timeVal=0, timeMax=1440)
if options.verbose:
print("flowColumn: %s hasData: %s" % (flowcol, hasData))
readers[flowcol] = detReader
if options.verbose:
print("found data from minute %s to %s" % (int(tMin), int(tMax)))
ts = options.timescale
beginM = int(sumolib.miscutils.parseTime(options.begin, ts) / ts)
intervalM = int(sumolib.miscutils.parseTime(options.interval, ts) / ts)
endM = min(int(sumolib.miscutils.parseTime(options.end, ts) / ts), tMax)
with open(options.output, "w") as outf:
root = "measurements" if options.cadyts else "data"
sumolib.xml.writeHeader(outf)
outf.write('<%s>\n' % root)
while beginM <= endM:
iEndM = beginM + intervalM
edges = defaultdict(dict)
maxGroups = defaultdict(lambda: 0)
for flowcol in flowcols:
detReader = detector.DetectorReader(options.detfile, LaneMap())
detReader.readFlows(options.flowfile, flow=flowcol, det=options.detcol, time=options.timecol,
timeVal=beginM, timeMax=iEndM, addDetectors=(options.detfile is None))
for edge, detData in detReader._edge2DetData.items():
maxFlow = 0
nGroups = 0
for group in detData:
if group.isValid:
maxFlow = max(maxFlow, group.totalFlow)
nGroups += 1
edges[edge][flowcol] = maxFlow
maxGroups[edge] = max(maxGroups[edge], nGroups)
if options.cadyts:
for edge in sorted(edges.keys()):
print(' <singlelink link="%s" start="%s" end="%s" value="%s" stddev="8" type="COUNT_VEH"/>' %
(edge, beginM * ts, iEndM * ts, sum(edges[edge].values())), file=outf)
else:
outf.write(' <interval id="flowdata" begin="%s" end="%s">\n' % (beginM * ts, iEndM * ts))
for edge in sorted(edges.keys()):
attrs = ' '.join(['%s="%s"' % (k, v) for k, v in sorted(edges[edge].items())])
outf.write(' <edge id="%s" %s groups="%s"/>\n' % (edge, attrs, nGroups))
outf.write(' </interval>\n')
beginM += intervalM
outf.write('</%s>\n' % root)
if __name__ == "__main__":
main(get_options())