def startElement(self, name, attrs): if name == 'vehicle': self._vehicleAttrs = dict(attrs) self._vID = attrs['id'] if 'route' in attrs: self._routeString = self._routes[attrs['route']] del self._vehicleAttrs['route'] elif name == 'route': if not self._vID: self._routeID = attrs['id'] self._routeString = '' if 'edges' in attrs: self._routeString = attrs['edges'] elif name == 'vType': # XXX does not handle child elements (for carFollowing, the next case copies the input) print(' <vType %s>' % (' '.join(['%s="%s"' % ( key, value) for key, value in sorted(dict(attrs).items())])), file=self.outfile) elif name[0:12] == 'carFollowing': print(' <%s %s />' % (name, ' '.join(['%s="%s"' % ( key, value) for key, value in sorted(dict(attrs).items())])), file=self.outfile) elif name == 'routes': sumolib.writeXMLHeader( self.outfile, "$Id$%s" % self.calledBy, "routes")
def main(netFile, outFile, radius, useTravelDist, symmetrical): net = sumolib.net.readNet(netFile, withConnections=False, withFoes=False) with open(outFile, 'w') as outf: sumolib.writeXMLHeader( outf, "$Id: generateBidiDistricts.py 20482 2016-04-18 20:49:42Z behrisch $") outf.write('<tazs>\n') for taz, edges in computeAllBidiTaz(net, radius, useTravelDist, symmetrical): outf.write(' <taz id="%s" edges="%s"/>\n' % ( taz.getID(), ' '.join(sorted([e.getID() for e in edges])))) outf.write('</tazs>\n') return net
def main(): options = get_options() with open(options.output, 'w') as f: sumolib.writeXMLHeader(f, "$Id$", "routes") # noqa index = options.index for depart in range(options.begin, options.end): if random.random() < options.prob: write_ped( f, index, options, depart) index += 1 f.write('</routes>')
def main(netFile, outFile, radius, travelDist, symmetrical): net = sumolib.net.readNet(netFile, withConnections=False, withFoes=False) with open(outFile, 'w') as outf: sumolib.writeXMLHeader( outf, "$Id$") outf.write('<tazs>\n') for taz, edges in computeAllBidiTaz(net, radius, travelDist, symmetrical): outf.write(' <taz id="%s" edges="%s"/>\n' % ( taz.getID(), ' '.join(sorted([e.getID() for e in edges])))) outf.write('</tazs>\n') return net
def main(options): net = sumolib.net.readNet(options.netfile, withConnections=False, withFoes=False) l2 = options.length / 2 with open(options.outfile + ".edg.xml", 'w') as out_e: with open(options.outfile + ".nod.xml", 'w') as out_n: sumolib.writeXMLHeader(out_e, "$Id$") # noqa sumolib.writeXMLHeader(out_n, "$Id$") # noqa out_e.write('<edges>\n') out_n.write('<nodes>\n') for stop in sumolib.xml.parse(options.stopfile, 'busStop', heterogeneous=True): edge_id = stop.id + "_access" x, y = sumolib.geomhelper.positionAtShapeOffset( net.getLane(stop.lane).getShape(), (float(stop.startPos) + float(stop.endPos)) / 2) from_id = edge_id + '_from' to_id = edge_id + '_to' out_n.write(' <node id="%s" x="%s" y="%s"/>\n' % (from_id, x - l2, y)) out_n.write(' <node id="%s" x="%s" y="%s"/>\n' % (to_id, x + l2, y)) out_e.write(' <edge id="%s" from="%s" to="%s" allow="pedestrian" width="%s"/>\n' % ( edge_id, from_id, to_id, options.width)) out_e.write('</edges>\n') out_n.write('</nodes>\n')
def createRoutes(options, trpMap, stopNames): print("creating routes...") stopsUntil = collections.defaultdict(list) for stop in sumolib.output.parse_fast(options.stopinfos, 'stopinfo', ['id', 'ended', 'busStop']): stopsUntil[(stop.id, stop.busStop)].append(float(stop.ended)) ft = formatTime if options.hrtime else lambda x: x with codecs.open(options.outfile, 'w', encoding="UTF8") as foutflows: flows = [] actualDepart = {} # departure may be delayed when the edge is not yet empty sumolib.writeXMLHeader( foutflows, "$Id$", "routes") if not options.novtypes: writeTypes(foutflows, options.vtypeprefix) collections.defaultdict(int) for vehicle in sumolib.output.parse(options.routes, 'vehicle'): id = vehicle.id lineRef, name, completeness, period = trpMap[id] flowID = "%s_%s" % (vehicle.type, lineRef) try: if vehicle.route is not None: edges = vehicle.route[0].edges else: edges = vehicle.routeDistribution[0].route[1].edges except BaseException: if options.ignoreErrors: sys.stderr.write("Warning: Could not parse edges for vehicle '%s'\n" % id) continue else: sys.exit("Could not parse edges for vehicle '%s'\n" % id) flows.append((id, flowID, lineRef, vehicle.type, float(vehicle.depart))) actualDepart[id] = float(vehicle.depart) parking = ' parking="true"' if vehicle.type == "bus" and options.busparking else '' stops = vehicle.stop foutflows.write(' <route id="%s" edges="%s" >\n' % (flowID, edges)) if vehicle.stop is not None: for stop in stops: if (id, stop.busStop) in stopsUntil: until = stopsUntil[(id, stop.busStop)] stopname = ' <!-- %s -->' % stopNames[stop.busStop] if stop.busStop in stopNames else '' untilZeroBased = until[0] - actualDepart[id] if len(until) > 1: stopsUntil[(id, stop.busStop)] = until[1:] foutflows.write( ' <stop busStop="%s" duration="%s" until="%s"%s/>%s\n' % ( stop.busStop, stop.duration, ft(untilZeroBased), parking, stopname)) else: sys.stderr.write("Warning: Missing stop '%s' for flow '%s'\n" % (stop.busStop, id)) else: sys.stderr.write("Warning: No stops for flow '%s'\n" % id) foutflows.write(' </route>\n') flow_duration = options.end - options.begin for vehID, flowID, lineRef, type, begin in flows: line, name, completeness, period = trpMap[vehID] foutflows.write(' <flow id="%s" type="%s" route="%s" begin="%s" end="%s" period="%s" line="%s" %s>\n' % ( flowID, type, flowID, ft(begin), ft(begin + flow_duration), int(float(period)), lineRef, options.flowattrs)) if name is not None: foutflows.write(' <param key="name" value=%s/>\n' % quoteattr(name)) if completeness is not None: foutflows.write(' <param key="completeness" value=%s/>\n' % quoteattr(completeness)) foutflows.write(' </flow>\n') foutflows.write('</routes>\n') print("done.")
def main(options): gtfsZip = zipfile.ZipFile(sumolib.open(options.gtfs, False)) routes, trips_on_day, shapes, stops, stop_times = gtfs2osm.import_gtfs( options, gtfsZip) stop_times['arrival_time'] = stop_times['arrival_time'].map(time2sec) stop_times['departure_time'] = stop_times['departure_time'].map(time2sec) if 'fare_stops.txt' in gtfsZip.namelist(): zones = pd.read_csv(gtfsZip.open('fare_stops.txt'), dtype=str) stops_merged = pd.merge(pd.merge(stops, stop_times, on='stop_id'), zones, on='stop_id') else: stops_merged = pd.merge(stops, stop_times, on='stop_id') stops_merged['fare_zone'] = '' stops_merged['fare_token'] = '' stops_merged['start_char'] = '' trips_routes_merged = pd.merge(trips_on_day, routes, on='route_id') full_data_merged = pd.merge(stops_merged, trips_routes_merged, on='trip_id')[[ 'trip_id', 'route_id', 'route_short_name', 'route_type', 'stop_id', 'stop_name', 'stop_lat', 'stop_lon', 'stop_sequence', 'fare_zone', 'fare_token', 'start_char', 'arrival_time', 'departure_time' ]].drop_duplicates() fcdFile = {} tripFile = {} if not os.path.exists(options.fcd): os.makedirs(options.fcd) seenModes = set() modes = set( options.modes.split(",") if options.modes else gtfs2osm.GTFS2OSM_MODES. values()) for mode in modes: filePrefix = os.path.join(options.fcd, mode) fcdFile[mode] = io.open(filePrefix + '.fcd.xml', 'w', encoding="utf8") sumolib.writeXMLHeader(fcdFile[mode], "gtfs2fcd.py") fcdFile[mode].write(u'<fcd-export>\n') if options.verbose: print('Writing fcd file "%s"' % fcdFile[mode].name) tripFile[mode] = io.open(filePrefix + '.rou.xml', 'w') tripFile[mode].write(u"<routes>\n") timeIndex = 0 for _, trip_data in full_data_merged.groupby(['route_id']): seqs = {} for trip_id, data in trip_data.groupby(['trip_id']): stopSeq = [] buf = u"" offset = 0 firstDep = None for __, d in data.sort_values(by=['stop_sequence']).iterrows(): arrivalSec = d.arrival_time + timeIndex stopSeq.append(d.stop_id) departureSec = d.departure_time + timeIndex until = 0 if firstDep is None else departureSec - timeIndex - firstDep buf += (( u' <timestep time="%s"><vehicle id="%s" x="%s" y="%s" until="%s" ' + u'name=%s fareZone="%s" fareSymbol="%s" startFare="%s" speed="20"/></timestep>\n' ) % (arrivalSec - offset, trip_id, d.stop_lon, d.stop_lat, until, sumolib.xml.quoteattr(d.stop_name), d.fare_zone, d.fare_token, d.start_char)) if firstDep is None: firstDep = departureSec - timeIndex offset += departureSec - arrivalSec mode = gtfs2osm.GTFS2OSM_MODES[d.route_type] if mode in modes: s = tuple(stopSeq) if s not in seqs: seqs[s] = trip_id fcdFile[mode].write(buf) timeIndex = arrivalSec tripFile[mode].write( u' <vehicle id="%s" route="%s" type="%s" depart="%s" line="%s_%s"/>\n' % (trip_id, seqs[s], mode, firstDep, d.route_short_name, seqs[s])) seenModes.add(mode) if options.gpsdat: if not os.path.exists(options.gpsdat): os.makedirs(options.gpsdat) for mode in modes: fcdFile[mode].write(u'</fcd-export>\n') fcdFile[mode].close() tripFile[mode].write(u"</routes>\n") tripFile[mode].close() if mode in seenModes: traceExporter.main([ '', '--base-date', '0', '-i', fcdFile[mode].name, '--gpsdat-output', os.path.join(options.gpsdat, "gpsdat_%s.csv" % mode) ]) else: os.remove(fcdFile[mode].name) os.remove(tripFile[mode].name) if options.vtype_output: with io.open(options.vtype_output, 'w', encoding="utf8") as vout: sumolib.xml.writeHeader(vout, root="additional") for mode in sorted(seenModes): vout.write(u' <vType id="%s" vClass="%s"/>\n' % (mode, gtfs2osm.OSM2SUMO_MODES[mode])) vout.write(u'</additional>\n')
def main(options): if options.seed: random.seed(options.seed) net = sumolib.net.readNet(options.netfile) if options.min_distance > net.getBBoxDiameter() * (options.intermediate + 1): options.intermediate = int( math.ceil(options.min_distance / net.getBBoxDiameter())) - 1 print(("Warning: setting number of intermediate waypoints to %s to achieve a minimum trip length of " + "%s in a network with diameter %.2f.") % ( options.intermediate, options.min_distance, net.getBBoxDiameter())) trip_generator = buildTripGenerator(net, options) idx = 0 vtypeattrs, options.tripattrs, personattrs, otherattrs = split_trip_attributes( options.tripattrs, options.pedestrians, options.vehicle_class) vias = {} def generate_one(idx): label = "%s%s" % (options.tripprefix, idx) try: source_edge, sink_edge, intermediate = trip_generator.get_trip( options.min_distance, options.max_distance, options.maxtries) combined_attrs = options.tripattrs if options.fringeattrs and source_edge.is_fringe(source_edge._incoming): combined_attrs += " " + options.fringeattrs via = "" if len(intermediate) > 0: via = ' via="%s" ' % ' '.join( [e.getID() for e in intermediate]) if options.validate: vias[label] = via if options.pedestrians: fouttrips.write( ' <person id="%s" depart="%.2f"%s>\n' % (label, depart, personattrs)) if options.persontrips: fouttrips.write( ' <personTrip from="%s" to="%s"%s/>\n' % ( source_edge.getID(), sink_edge.getID(), otherattrs)) else: fouttrips.write( ' <walk from="%s" to="%s"%s/>\n' % (source_edge.getID(), sink_edge.getID(), otherattrs)) fouttrips.write(' </person>\n') elif options.flows > 0: to = '' if options.jtrrouter else ' to="%s"' % sink_edge.getID() if options.binomial: for j in range(options.binomial): fouttrips.write((' <flow id="%s#%s" begin="%s" end="%s" probability="%s" ' + 'from="%s"%s%s%s/>\n') % ( label, j, options.begin, options.end, 1.0 / options.period / options.binomial, source_edge.getID(), to, via, combined_attrs)) else: fouttrips.write((' <flow id="%s" begin="%s" end="%s" period="%s" from="%s"%s%s%s/>\n') % ( label, options.begin, options.end, options.period * options.flows, source_edge.getID(), to, via, combined_attrs)) else: fouttrips.write(' <trip id="%s" depart="%.2f" from="%s" to="%s"%s%s/>\n' % ( label, depart, source_edge.getID(), sink_edge.getID(), via, combined_attrs)) except Exception as exc: print(exc, file=sys.stderr) return idx + 1 with open(options.tripfile, 'w') as fouttrips: sumolib.writeXMLHeader(fouttrips, "$Id$", "routes") # noqa if options.vehicle_class: fouttrips.write(' <vType id="%s" vClass="%s"%s/>\n' % (options.vtypeID, options.vehicle_class, vtypeattrs)) options.tripattrs += ' type="%s"' % options.vtypeID personattrs += ' type="%s"' % options.vtypeID depart = options.begin if trip_generator: if options.flows == 0: while depart < options.end: if options.binomial is None: # generate with constant spacing idx = generate_one(idx) depart += options.period else: # draw n times from a Bernoulli distribution # for an average arrival rate of 1 / period prob = 1.0 / options.period / options.binomial for i in range(options.binomial): if random.random() < prob: idx = generate_one(idx) depart += 1 else: for i in range(options.flows): idx = generate_one(idx) fouttrips.write("</routes>\n") # call duarouter for routes or validated trips args = [DUAROUTER, '-n', options.netfile, '-r', options.tripfile, '--ignore-errors', '--begin', str(options.begin), '--end', str(options.end), '--no-step-log', '--no-warnings'] if options.additional is not None: args += ['--additional-files', options.additional] if options.carWalkMode is not None: args += ['--persontrip.transfer.car-walk', options.carWalkMode] if options.walkfactor is not None: args += ['--persontrip.walkfactor', options.walkfactor] if options.routefile: args2 = args + ['-o', options.routefile] print("calling ", " ".join(args2)) subprocess.call(args2) if options.validate: # write to temporary file because the input is read incrementally tmpTrips = options.tripfile + ".tmp" args2 = args + ['-o', tmpTrips, '--write-trips'] print("calling ", " ".join(args2)) subprocess.call(args2) os.remove(options.tripfile) # on windows, rename does not overwrite os.rename(tmpTrips, options.tripfile) if options.weights_outprefix: trip_generator.source_generator.write_weights( options.weights_outprefix + SOURCE_SUFFIX) trip_generator.sink_generator.write_weights( options.weights_outprefix + SINK_SUFFIX) if trip_generator.via_generator: trip_generator.via_generator.write_weights( options.weights_outprefix + VIA_SUFFIX) # return wether trips could be generated as requested return trip_generator is not None
def main(): options = get_options() vals = defaultdict(list) stats = Statistics("%s %ss" % (options.element, options.attribute), histogram=options.binwidth > 0, scale=options.binwidth) missingAttr = set() invalidType = set() if options.fast: def elements(): for element in parse_fast(options.datafile, options.element, [options.idAttr, options.attribute]): yield getattr(element, options.idAttr), getattr(element, options.attribute) else: def elements(): for element in parse(options.datafile, options.element, heterogeneous=True): elementID = None if element.hasAttribute(options.idAttr): elementID = element.getAttribute(options.idAttr) stringVal = None if element.hasAttribute(options.attribute): stringVal = element.getAttribute(options.attribute) yield elementID, stringVal for elementID, stringVal in elements(): if stringVal is not None: try: val = sumolib.miscutils.parseTime(stringVal) vals[elementID].append(val) stats.add(val, elementID) except Exception: invalidType.add(stringVal) else: missingAttr.add(elementID) print(stats.toString(options.precision)) if missingAttr: print("%s elements did not provide attribute '%s' Example ids: '%s'" % (len(missingAttr), options.attribute, "', '".join( sorted(missingAttr)[:10]))) if invalidType: print( ("%s distinct values of attribute '%s' could not be interpreted " + "as numerical value or time. Example values: '%s'") % (len(invalidType), options.attribute, "', '".join( sorted(invalidType)[:10]))) if options.hist_output is not None: with open(options.hist_output, 'w') as f: for bin, count in stats.histogram(): f.write("%s %s\n" % (bin, count)) if options.full_output is not None: with open(options.full_output, 'w') as f: for id, data in sorted(vals.items()): for x in data: f.write( setPrecision("%.2f %s\n", options.precision) % (x, id)) if options.xml_output is not None: with open(options.xml_output, 'w') as f: sumolib.writeXMLHeader(f, "$Id$", "attributeStats") # noqa f.write(stats.toXML(options.precision)) f.write('</attributeStats>\n')
def main(options): if options.seed: random.seed(options.seed) net = sumolib.net.readNet(options.netfile) if options.min_distance > net.getBBoxDiameter() * (options.intermediate + 1): options.intermediate = int( math.ceil(options.min_distance / net.getBBoxDiameter())) - 1 print("Warning: setting number of intermediate waypoints to %s to achieve a minimum trip length of %s in a network with diameter %.2f." % ( options.intermediate, options.min_distance, net.getBBoxDiameter())) trip_generator = buildTripGenerator(net, options) idx = 0 if options.pedestrians: # figure out which of the tripattrs belong to the <person> and which # belong to the <walk> walkattrs = ' '.join( [a for a in options.tripattrs.split() if is_walk_attribute(a)]) personattrs = ' '.join( [a for a in options.tripattrs.split() if not is_walk_attribute(a)]) def generate_one(idx): label = "%s%s" % (options.tripprefix, idx) try: source_edge, sink_edge, intermediate = trip_generator.get_trip( options.min_distance, options.max_distance, options.maxtries) via = "" if len(intermediate) > 0: via = 'via="%s" ' % ' '.join( [e.getID() for e in intermediate]) if options.pedestrians: fouttrips.write( ' <person id="%s" depart="%.2f" %s>\n' % (label, depart, personattrs)) fouttrips.write( ' <walk from="%s" to="%s" %s/>\n' % (source_edge.getID(), sink_edge.getID(), walkattrs)) fouttrips.write(' </person>\n') else: fouttrips.write(' <trip id="%s" depart="%.2f" from="%s" to="%s" %s%s/>\n' % ( label, depart, source_edge.getID(), sink_edge.getID(), via, options.tripattrs)) except Exception as exc: print(exc, file=sys.stderr) return idx + 1 with open(options.tripfile, 'w') as fouttrips: sumolib.writeXMLHeader( fouttrips, "$Id: randomTrips.py 21557 2016-09-28 10:43:52Z luecken $") fouttrips.write("<trips>\n") if options.vehicle_class: fouttrips.write(' <vType id="%s" vClass="%s" />\n' % (options.vehicle_class, options.vehicle_class)) options.tripattrs += ' type="%s"' % options.vehicle_class depart = options.begin if trip_generator: while depart < options.end: if options.binomial is None: # generate with constant spacing idx = generate_one(idx) depart += options.period else: # draw n times from a bernouli distribution # for an average arrival rate of 1 / period prob = 1.0 / options.period / options.binomial for i in range(options.binomial): if random.random() < prob: idx = generate_one(idx) depart += 1 fouttrips.write("</trips>\n") if options.routefile: args = [DUAROUTER, '-n', options.netfile, '-t', options.tripfile, '-o', options.routefile, '--ignore-errors', '--begin', str(options.begin), '--end', str(options.end), '--no-step-log', '--no-warnings'] if options.additional is not None: args += ['--additional-files', options.additional] print("calling ", " ".join(args)) subprocess.call(args) if options.validate: print("calling route2trips") route2trips.main([options.routefile], outfile=options.tripfile) if options.weights_outprefix: trip_generator.source_generator.write_weights( options.weights_outprefix + SOURCE_SUFFIX) trip_generator.sink_generator.write_weights( options.weights_outprefix + SINK_SUFFIX) trip_generator.via_generator.write_weights( options.weights_outprefix + VIA_SUFFIX) # return wether trips could be genreated as requested return trip_generator is not None
def createRoutes(options, trpMap, stopNames): print("creating routes...") stopsUntil = {} for stop in sumolib.output.parse_fast(options.stopinfos, 'stopinfo', ['id', 'ended', 'busStop']): stopsUntil[(stop.id, stop.busStop)] = float(stop.ended) ft = formatTime if options.hrtime else lambda x: x with codecs.open(options.outfile, 'w', encoding="UTF8") as foutflows: flows = [] actualDepart = { } # departure may be delayed when the edge is not yet empty sumolib.writeXMLHeader(foutflows, "$Id$", "routes") if not options.novtypes: writeTypes(foutflows, options.vtypeprefix) collections.defaultdict(int) for vehicle in sumolib.output.parse(options.routes, 'vehicle'): id = vehicle.id lineRef, name, completeness, period = trpMap[id] flowID = "%s_%s" % (vehicle.type, lineRef) try: if vehicle.route is not None: edges = vehicle.route[0].edges else: edges = vehicle.routeDistribution[0].route[1].edges except BaseException: if options.ignoreErrors: sys.stderr.write( "Warning: Could not parse edges for vehicle '%s'\n" % id) continue else: sys.exit("Could not parse edges for vehicle '%s'\n" % id) flows.append( (id, flowID, lineRef, vehicle.type, float(vehicle.depart))) actualDepart[id] = float(vehicle.depart) parking = ' parking="true"' if vehicle.type == "bus" and options.busparking else '' stops = vehicle.stop foutflows.write(' <route id="%s" edges="%s" >\n' % (flowID, edges)) if vehicle.stop is not None: for stop in stops: if (id, stop.busStop) in stopsUntil: stopname = ' <!-- %s -->' % stopNames[ stop.busStop] if stop.busStop in stopNames else '' untilZeroBased = stopsUntil[ (id, stop.busStop)] - actualDepart[id] foutflows.write( ' <stop busStop="%s" duration="%s" until="%s"%s/>%s\n' % (stop.busStop, stop.duration, ft(untilZeroBased), parking, stopname)) else: sys.stderr.write( "Warning: Missing stop '%s' for flow '%s'\n" % (stop.busStop, id)) else: sys.stderr.write("Warning: No stops for flow '%s'\n" % id) foutflows.write(' </route>\n') flow_duration = options.end - options.begin for vehID, flowID, lineRef, type, begin in flows: line, name, completeness, period = trpMap[vehID] foutflows.write( ' <flow id="%s" type="%s" route="%s" begin="%s" end="%s" period="%s" line="%s" %s>\n' % (flowID, type, flowID, ft(begin), ft(begin + flow_duration), int(float(period)), lineRef, options.flowattrs)) foutflows.write(( ' <param key="name" value=%s/>\n <param key="completeness" ' + 'value="%s"/>\n </flow>\n') % (quoteattr(name), completeness)) foutflows.write('</routes>\n') print("done.")
def main(options): net = sumolib.net.readNet(options.netfile) incomingRoutes = defaultdict(set) # edge : set(route0, route1, ...) if options.longRoutes: # build dictionary of routes leading from an intersection to each edge for junction in net.getNodes(): isEntry = len(junction.getIncoming()) == 0 if len(junction.getOutgoing()) > 1 or isEntry: for edge in junction.getOutgoing(): if isEntry or getNumSiblings(edge) > 1: edges = getEdgesToIntersection(edge) edgeIDs = tuple([e.getID() for e in edges]) incomingRoutes[edges[-1]].add(edgeIDs) with open(options.outfile, 'w') as outf: sumolib.writeXMLHeader(outf, "$Id$", "additional") # noqa for junction in net.getNodes(): if len(junction.getOutgoing()) > 1: routes = [] for edge in junction.getOutgoing(): routes.append(getEdgesToIntersection(edge)) for edge in junction.getIncoming(): if options.longRoutes: # overlapping routes: start behind an intersection and # route across the next intersection to the entry of the # 2nd intersetion (more rerouters and overlapping routes) if getNumAlterantives(edge, routes) > 1: for incomingRoute in incomingRoutes[edge]: assert (incomingRoute[-1] == edge.getID()) firstEdgeID = incomingRoute[0] routeIDs = [] for edges in routes: if edges[0] in edge.getOutgoing().keys(): routeID = "%s_%s_%s" % ( firstEdgeID, edge.getID(), edges[0].getID()) prob = options.turnDefaults[ getTurnIndex(edge, edges[0])] edgeIDs = list(incomingRoute) + [ e.getID() for e in edges ] outf.write( ' <route id="%s" edges="%s"/>\n' % (routeID, ' '.join(edgeIDs))) routeIDs.append((routeID, prob)) outf.write( ' <rerouter id="rr_%s_%s" edges="%s">\n' % (firstEdgeID, edge.getID(), firstEdgeID)) outf.write( ' <interval begin="%s" end="%s">\n' % (options.begin, options.end)) for routeID, prob in routeIDs: outf.write( ' <routeProbReroute id="%s" probability="%s"/>\n' % (routeID, prob)) outf.write(' </interval>\n') outf.write(' </rerouter>\n') else: # minimal routes: start ahead of an intersection and # continue up to the entry of the next intersection routeIDs = [] for edges in routes: if edges[0] in edge.getOutgoing().keys(): routeID = "%s_%s" % (edge.getID(), edges[0].getID()) prob = options.turnDefaults[getTurnIndex( edge, edges[0])] edgeIDs = [e.getID() for e in [edge] + edges] outf.write( ' <route id="%s" edges="%s"/>\n' % (routeID, ' '.join(edgeIDs))) routeIDs.append((routeID, prob)) if len(routeIDs) > 1: outf.write( ' <rerouter id="rr_%s" edges="%s">\n' % (edge.getID(), edge.getID())) outf.write( ' <interval begin="%s" end="%s">\n' % (options.begin, options.end)) for routeID, prob in routeIDs: outf.write( ' <routeProbReroute id="%s" probability="%s"/>\n' % (routeID, prob)) outf.write(' </interval>\n') outf.write(' </rerouter>\n') outf.write('</additional>\n')
def main(options): if options.turnFile is None: # read data from connection params net = sumolib.net.readNet(options.net) with open(options.turnOutput, 'w') as tf, open(options.flowOuput, 'w') as ff: sumolib.writeXMLHeader(tf, "$Id$", "turns") # noqa sumolib.writeXMLHeader(ff, "$Id$", "routes") # noqa tf.write(' <interval begin="%s" end="%s">\n' % (options.begin, options.end)) for edge in net.getEdges(): counts = getCounts(edge, options.countParam) if counts: tf.write(' <fromEdge id="%s">\n' % (edge.getID())) for toEdge, count in counts.items(): tf.write( ' <toEdge id="%s" probability="%s"/>\n' % (toEdge, count)) tf.write(' </fromEdge>\n') totalCount = int(sum(counts.values())) fromEdge = edge if options.fringe_flows: fromEdge = findFringe(edge, options.countParam) if fromEdge: ff.write( ' <flow id="%s%s" from="%s" begin="%s" end="%s" number="%s"%s/>\n' % (options.prefix, edge.getID(), fromEdge.getID(), options.begin, options.end, totalCount, options.flowattrs)) tf.write(' </interval>\n') tf.write('</turns>\n') ff.write('</routes>\n') else: # read turn-count file options.turnOutput = options.turnFile with open(options.flowOuput, 'w') as ff: ff.write('<routes>\n') for i, interval in enumerate( sumolib.xml.parse(options.turnFile, 'interval')): for edge in interval.fromEdge: count = 0 for toEdge in edge.toEdge: count += float(getattr(toEdge, options.turnAttr)) if count > 0: flowID = edge.id if i > 0: flowID += "#%s" % i ff.write( ' <flow id="%s%s" from="%s" begin="%s" end="%s" number="%s"%s/>\n' % (options.prefix, flowID, edge.id, interval.begin, interval.end, int(count), options.flowattrs)) ff.write('</routes>\n') JTRROUTER = sumolib.checkBinary('jtrrouter') args = [ JTRROUTER, '-n', options.net, '--turn-ratio-files', options.turnOutput, '--route-files', options.flowOuput, '--accept-all-destinations', '-o', options.out ] if not options.fringe_flows: args += ['-S'] if options.discountSources: args += ['-D'] subprocess.call(args)
def main(): options = get_options() if options.verbose: print("parsing network from", options.network) net = readNet(options.network, withInternal=True) read = 0 routeInfos = {} # id-> RouteInfo skipped = set() for routeFile in options.routeFiles: if options.verbose: print("parsing routes from", routeFile) idx = 0 if options.standalone: for idx, route in enumerate(parse(routeFile, 'route')): if options.verbose and idx > 0 and idx % 100000 == 0: print(idx, "routes read") addOrSkip(routeInfos, skipped, route.id, route, options.min_edges) else: if options.heterogeneous: for idx, vehicle in enumerate(parse(routeFile, 'vehicle')): if options.verbose and idx > 0 and idx % 100000 == 0: print(idx, "vehicles read") addOrSkip(routeInfos, skipped, vehicle.id, vehicle.route[0], options.min_edges) else: prev = (None, None) for vehicle, route in parse_fast_nested( routeFile, 'vehicle', 'id', 'route', 'edges'): if prev[0] != vehicle.id: if options.verbose and idx > 0 and idx % 500000 == 0: print(idx, "vehicles read") if prev[0] is not None: addOrSkip(routeInfos, skipped, prev[0], prev[1], options.min_edges) prev = (vehicle.id, route) idx += 1 if prev[0] is not None: addOrSkip(routeInfos, skipped, prev[0], prev[1], options.min_edges) read += idx if options.verbose: print(read, "routes read", len(skipped), "short routes skipped") if options.verbose: print("calculating air distance and checking loops") for idx, ri in enumerate(routeInfos.values()): if options.verbose and idx > 0 and idx % 100000 == 0: print(idx, "routes checked") calcDistAndLoops(ri, net, options) prefix = os.path.commonprefix(options.routeFiles) duarouterOutput = prefix + '.rerouted.rou.xml' duarouterAltOutput = prefix + '.rerouted.rou.alt.xml' if os.path.exists(duarouterAltOutput) and options.reuse_routing: if options.verbose: print("reusing old duarouter file", duarouterAltOutput) else: if options.standalone: duarouterInput = prefix # generate suitable input file for duarouter duarouterInput += ".vehRoutes.xml" with open(duarouterInput, 'w') as outf: outf.write('<routes>\n') for rID, rInfo in routeInfos.items(): outf.write(' <vehicle id="%s" depart="0">\n' % rID) outf.write(' <route edges="%s"/>\n' % ' '.join(rInfo.edges)) outf.write(' </vehicle>\n') outf.write('</routes>\n') else: duarouterInput = ",".join(options.routeFiles) command = [ sumolib.checkBinary('duarouter'), '-n', options.network, '-r', duarouterInput, '-o', duarouterOutput, '--no-step-log', '--routing-threads', str(options.threads), '--routing-algorithm', 'astar', '--aggregate-warnings', '1' ] if options.verbose: command += ["-v"] if options.verbose: print("calling duarouter:", " ".join(command)) subprocess.call(command) for vehicle in parse(duarouterAltOutput, 'vehicle'): if vehicle.id in skipped: continue routeAlts = vehicle.routeDistribution[0].route if len(routeAlts) == 1: routeInfos[vehicle.id].detour = 0 routeInfos[vehicle.id].detourRatio = 1 routeInfos[vehicle.id].shortest_path_distance = routeInfos[ vehicle.id].length else: oldCosts = float(routeAlts[0].cost) newCosts = float(routeAlts[1].cost) assert (routeAlts[0].edges.split() == routeInfos[vehicle.id].edges) routeInfos[ vehicle.id].shortest_path_distance = sumolib.route.getLength( net, routeAlts[1].edges.split()) if oldCosts <= newCosts: routeInfos[vehicle.id].detour = 0 routeInfos[vehicle.id].detourRatio = 1 if oldCosts < newCosts: sys.stderr.write(( "Warning: fastest route for '%s' is slower than original route " + "(old=%s, new=%s). Check vehicle types\n") % (vehicle.id, oldCosts, newCosts)) else: routeInfos[vehicle.id].detour = oldCosts - newCosts routeInfos[vehicle.id].detourRatio = oldCosts / newCosts implausible = [] allRoutesStats = Statistics("overall implausibility") implausibleRoutesStats = Statistics("implausibility above threshold") for rID in sorted(routeInfos.keys()): ri = routeInfos[rID] ri.implausibility = ( options.airdist_ratio_factor * ri.airDistRatio + options.detour_factor * ri.detour + options.detour_ratio_factor * ri.detourRatio + max(0, options.min_dist / ri.shortest_path_distance - 1) + max(0, options.min_air_dist / ri.airDist - 1)) allRoutesStats.add(ri.implausibility, rID) if ri.implausibility > options.threshold or ri.edgeLoop or ri.nodeLoop: implausible.append((ri.implausibility, rID, ri)) implausibleRoutesStats.add(ri.implausibility, rID) # generate restrictions if options.restrictions_output is not None: with open(options.restrictions_output, 'w') as outf: for score, rID, ri in sorted(implausible): edges = ri.edges if options.odrestrictions and len(edges) > 2: edges = [edges[0], edges[-1]] outf.write("0 %s\n" % " ".join(edges)) # write xml output if options.xmlOutput is not None: with open(options.xmlOutput, 'w') as outf: sumolib.writeXMLHeader(outf, "$Id$", options=options) # noqa outf.write('<implausibleRoutes>\n') for score, rID, ri in sorted(implausible): edges = " ".join(ri.edges) outf.write(' <route id="%s" edges="%s" score="%s"/>\n' % (rID, edges, score)) outf.write('</implausibleRoutes>\n') if options.ignore_routes is not None: numImplausible = len(implausible) ignored = set([r.strip() for r in open(options.ignore_routes)]) implausible = [r for r in implausible if r not in ignored] print( "Loaded %s routes to ignore. Reducing implausible from %s to %s" % (len(ignored), numImplausible, len(implausible))) # generate polygons polyOutput = prefix + '.implausible.add.xml' colorgen = Colorgen(("random", 1, 1)) with open(polyOutput, 'w') as outf: outf.write('<additional>\n') for score, rID, ri in sorted(implausible): generate_poly(options, net, rID, colorgen(), ri.edges, outf, score) outf.write('</additional>\n') sys.stdout.write( 'score\troute\t(airDistRatio, detourRatio, detour, shortestDist, airDist, edgeLoop, nodeLoop)\n' ) for score, rID, ri in sorted(implausible): # , ' '.join(ri.edges))) sys.stdout.write('%.7f\t%s\t%s\n' % (score, rID, (ri.airDistRatio, ri.detourRatio, ri.detour, ri.shortest_path_distance, ri.airDist, ri.edgeLoop, ri.nodeLoop))) print(allRoutesStats) print(implausibleRoutesStats)
def createRoutes(options, trpMap): print("creating routes...") stopsUntil = {} for stop in sumolib.output.parse_fast(options.stopinfos, 'stopinfo', ['id', 'ended', 'busStop']): stopsUntil[(stop.id, stop.busStop)] = float(stop.ended) with codecs.open(options.outfile, 'w', encoding="UTF8") as foutflows: flows = [] actualDepart = { } # departure may be delayed when the edge is not yet empty sumolib.writeXMLHeader(foutflows, "$Id$", "routes") if not options.novtypes: writeTypes(foutflows, options.vtypeprefix) for vehicle in sumolib.output.parse(options.routes, 'vehicle'): id = vehicle.id try: if vehicle.route is not None: edges = vehicle.route[0].edges else: edges = vehicle.routeDistribution[0].route[1].edges except StandardError: if options.ignoreErrors: sys.stderr.write( "Warning: Could not parse edges for vehicle '%s'\n" % id) continue else: sys.exit("Could not parse edges for vehicle '%s'\n" % id) flows.append((id, vehicle.type, float(vehicle.depart))) actualDepart[id] = float(vehicle.depart) parking = ' parking="true"' if vehicle.type == "bus" and options.busparking else '' stops = vehicle.stop foutflows.write(' <route id="%s" edges="%s" >\n' % (id, edges)) if vehicle.stop is not None: for stop in stops: if (id, stop.busStop) in stopsUntil: untilZeroBased = stopsUntil[ (id, stop.busStop)] - actualDepart[id] foutflows.write( ' <stop busStop="%s" duration="%s" until="%s"%s/>\n' % (stop.busStop, stop.duration, untilZeroBased, parking)) else: sys.stderr.write( "Warning: Missing stop '%s' for flow '%s'\n" % (stop.busStop, id)) else: sys.stderr.write("Warning: No stops for flow '%s'\n" % id) foutflows.write(' </route>\n') lineCount = collections.defaultdict(int) flow_duration = options.end - options.begin for flow, type, begin in flows: line, name, completeness = trpMap[flow] lineRef = "%s:%s" % (line, lineCount[line]) lineCount[line] += 1 foutflows.write( ' <flow id="%s_%s" type="%s" route="%s" begin="%s" end="%s" period="%s" line="%s" %s>\n' % (type, lineRef, type, flow, begin, begin + flow_duration, options.period, lineRef, options.flowattrs)) foutflows.write( ' <param key="name" value="%s"/>\n <param key="completeness" value="%s"/>\n </flow>\n' % (escape(name), completeness)) foutflows.write('</routes>\n') print("done.")
def createTrips(options): print("generating trips...") net = sumolib.net.readNet(options.netfile) stopsLanes = {} for stop in sumolib.output.parse_fast(options.ptstops, 'busStop', ['id', 'lane']): stopsLanes[stop.id] = stop.lane trpMap = {} with open(options.trips, 'w') as fouttrips: sumolib.writeXMLHeader( fouttrips, "$Id$", "routes") writeTypes(fouttrips, options.vtypeprefix) trp_nr = 0 for line in sumolib.output.parse(options.ptlines, 'ptLine'): fr = None to = None stop_ids = [] for stop in line.busStop: if not stop.id in stopsLanes: sys.stderr.write("Warning: skipping unknown stop '%s'\n" % stop.id) continue laneId = stopsLanes[stop.id] try: edge_id, lane_index = laneId.rsplit("_", 1) except ValueError: if options.ignoreErrors: sys.stderr.write("Warning: ignoring stop '%s' on invalid lane '%s'\n" % (stop.id, laneId)) continue else: sys.exit("Invalid lane '%s' for stop '%s'" % (laneId, stop.id)) if fr == None: fr = edge_id dep_lane = laneId to = edge_id edge = net.getEdge(edge_id) stop_ids.append(stop.id) if fr is None or len(stop_ids) < options.min_stops: sys.stderr.write("Warning: skipping line '%s' because it has too few stops\n" % line.id) trp_nr += 1 continue if options.osmRoutes and line.route is not None: edges = line.route[0].edges.split(' ') lenE = len(edges) if (lenE > 3): vias = ' '.join(edges[0:lenE]) fouttrips.write( ' <trip id="%s" type="%s%s" depart="0" departLane="%s" from="%s" to="%s" via="%s">\n' % ( trp_nr, options.vtypeprefix, line.type, 'best', fr, to, vias)) else: fouttrips.write( ' <trip id="%s" type="%s%s" depart="0" departLane="%s" from="%s" to="%s" >\n' % ( trp_nr, options.vtypeprefix, line.type, 'best', fr, to)) else: fouttrips.write( ' <trip id="%s" type="%s%s" depart="0" departLane="%s" from="%s" to="%s" >\n' % ( trp_nr, options.vtypeprefix, line.type, 'best', fr, to)) trpMap[str(trp_nr)] = (line.line, line.attr_name, line.completeness) trp_nr += 1 for stop in stop_ids: fouttrips.write(' <stop busStop="%s" duration="30" />\n' % (stop)) fouttrips.write(' </trip>\n') fouttrips.write("</routes>\n") print("done.") return trpMap
def main(options): nan = float("nan") columns = [ 'vehID', 'tripId', # tripId of current stop or set by earlier stop 'stopID', # busStop id or lane,pos 'priorStop', # busStop id or lane,pos 'arrival', # route-input 'until', # route-input ] columns2 = columns[:3] + [ 'started', # stop-output 'ended', # stop-input ] stops = [] tripIds = dict() # vehID -> lastTripId priorStops = dict() # vehID -> lastStopID for vehicle in parse(options.routeFile, ['vehicle', 'trip'], heterogeneous=True, attr_conversions=ATTR_CONVERSIONS): if vehicle.stop is not None: for stop in vehicle.stop: vehID = vehicle.id tripId = stop.getAttributeSecure("tripId", tripIds.get(vehID)) tripIds[vehID] = tripId stopID = getStopID(stop) priorStop = priorStops.get(vehID) priorStops[vehID] = stopID stops.append((vehID, tripId, stopID, priorStop, stop.getAttributeSecure("arrival", nan), stop.getAttributeSecure("until", nan))) print("Parsed %s stops" % len(stops)) simStops = [] tripIds = dict() # vehID -> lastTripId priorStops = dict() # vehID -> lastStopID for stop in parse(options.stopFile, "stopinfo", heterogeneous=True, attr_conversions=ATTR_CONVERSIONS): vehID = stop.id tripId = stop.getAttributeSecure("tripId", tripIds.get(vehID)) tripIds[vehID] = tripId stopID = getStopID(stop) priorStop = priorStops.get(vehID) priorStops[vehID] = stopID simStops.append(( vehID, tripId, stopID, # priorStop, stop.getAttributeSecure("started", nan), stop.getAttributeSecure("ended", nan))) print("Parsed %s stopinfos" % len(simStops)) dfSchedule = pd.DataFrame.from_records(stops, columns=columns) dfSim = pd.DataFrame.from_records(simStops, columns=columns2) # merge on common columns vehID, tripId, stopID df = pd.merge( dfSchedule, dfSim, on=columns[:3], #how="outer", how="inner", ) print("Found %s matches" % len(df)) if options.verbose: #print(dfSchedule) #print(dfSim) print(df) if options.output: outf = open(options.output, 'w') sumolib.writeXMLHeader(outf, "$Id$", "scheduleStats") # noqa description, fun = STATS[options.sType] useHist = options.histogram is not None useGHist = options.gHistogram is not None if options.groupBy: numGroups = 0 stats = [] gs = Statistics( "%s %s grouped by [%s]" % (options.gType, description, ','.join(options.groupBy)), abs=True, histogram=useGHist, scale=options.gHistogram) for name, group in df.groupby(options.groupBy): numGroups += 1 s = Statistics("%s:%s" % (description, name), abs=True, histogram=useHist, scale=options.histogram) group.apply(fun, axis=1, args=(s, )) gVal = GROUPSTATS[options.gType](s) gs.add(gVal, name) stats.append((gVal, s)) stats.sort() for gVal, s in stats: print(s.toString(precision=options.precision, histStyle=2)) if options.output: outf.write(s.toXML(precision=options.precision)) print() print(gs.toString(precision=options.precision, histStyle=2)) if options.output: outf.write(gs.toXML(precision=options.precision)) else: s = Statistics(description, abs=True, histogram=useHist, scale=options.histogram) df.apply(fun, axis=1, args=(s, )) print(s.toString(precision=options.precision, histStyle=2)) if options.output: outf.write(s.toXML(precision=options.precision)) if options.output: outf.write("</scheduleStats>\n") outf.close()
def main(options): if options.verbose: print('Loading GTFS data "%s"' % options.gtfs) gtfsZip = zipfile.ZipFile(options.gtfs) routes = pd.read_csv(gtfsZip.open('routes.txt')) stops = pd.read_csv(gtfsZip.open('stops.txt')) stop_times = pd.read_csv(gtfsZip.open('stop_times.txt')) trips = pd.read_csv(gtfsZip.open('trips.txt')) calendar_dates = pd.read_csv(gtfsZip.open('calendar_dates.txt')) # currently not used: # agency = pd.read_csv(gtfsZip.open('agency.txt')) # calendar = pd.read_csv(gtfsZip.open('calendar.txt')) # transfers = pd.read_csv(gtfsZip.open('transfers.txt')) # Merging the tables tmp = pd.merge(trips, calendar_dates, on='service_id') trips_on_day = tmp[tmp['date'] == options.date] if options.region == "moin": zones = pd.read_csv(gtfsZip.open('fare_stops.txt')) stops_merged = pd.merge(pd.merge(stops, stop_times, on='stop_id'), zones, on='stop_id') else: stops_merged = pd.merge(stops, stop_times, on='stop_id') stops_merged['fare_zone'] = '' stops_merged['fare_token'] = '' stops_merged['start_char'] = '' trips_routes_merged = pd.merge(trips_on_day, routes, on='route_id') full_data_merged = pd.merge(stops_merged, trips_routes_merged, on='trip_id')[[ 'trip_id', 'route_id', 'route_short_name', 'route_type', 'stop_id', 'stop_name', 'stop_lat', 'stop_lon', 'stop_sequence', 'fare_zone', 'fare_token', 'start_char', 'arrival_time', 'departure_time' ]].drop_duplicates() gtfs_modes = { # modes according to https://developers.google.com/transit/gtfs/reference/#routestxt 0: 'tram', 1: 'subway', 2: 'rail', 3: 'bus', 4: 'ship', #5: 'cableTram', #6: 'aerialLift', #7: 'funicular', # modes used in Berlin and MDV see https://developers.google.com/transit/gtfs/reference/extended-route-types 100: 'rail', # DB 109: 'light_rail', # S-Bahn 400: 'subway', # U-Bahn 700: 'bus', # Bus 714: 'bus', # SEV 715: 'bus', # Rufbus 900: 'tram', # Tram 1000: 'ship', # Faehre # modes used by hafas 's': 'light_rail', 'RE': 'rail', 'RB': 'rail', 'IXB': 'rail', # tbd 'ICE': 'rail_electric', 'IC': 'rail_electric', 'IRX': 'rail', # tbd 'EC': 'rail', 'NJ': 'rail', # tbd 'RHI': 'rail', # tbd 'DPN': 'rail', # tbd 'SCH': 'rail', # tbd 'Bsv': 'rail', # tbd 'KAT': 'rail', # tbd 'AIR': 'rail', # tbd 'DPS': 'rail', # tbd 'lt': 'light_rail', #tbd 'BUS': 'bus', # tbd 'Str': 'tram', # tbd 'DPF': 'rail', # tbd '3': 'bus', # tbd } fcdFile = {} tripFile = {} if not os.path.exists(options.fcd): os.makedirs(options.fcd) for mode in set(gtfs_modes.values()): filePrefix = os.path.join(options.fcd, mode) fcdFile[mode] = open(filePrefix + '.fcd.xml', 'w', encoding="utf8") sumolib.writeXMLHeader(fcdFile[mode], "gtfs2fcd.py") fcdFile[mode].write('<fcd-export>\n') print('Writing fcd file "%s"' % fcdFile[mode].name) tripFile[mode] = open(filePrefix + '.rou.xml', 'w') tripFile[mode].write("<routes>\n") timeIndex = 0 for _, trip_data in full_data_merged.groupby(['route_id']): seqs = {} for trip_id, data in trip_data.groupby(['trip_id']): stopSeq = [] buf = "" offset = 0 firstDep = None for __, d in data.sort_values(by=['stop_sequence']).iterrows(): arrival = list(map(int, d.arrival_time.split(":"))) arrivalSec = arrival[0] * 3600 + arrival[1] * 60 + arrival[ 2] + timeIndex stopSeq.append(d.stop_id) departure = list(map(int, d.departure_time.split(":"))) departureSec = departure[0] * 3600 + departure[ 1] * 60 + departure[2] + timeIndex until = 0 if firstDep is None else departureSec - timeIndex - firstDep buf += ( ' <timestep time="%s"><vehicle id="%s_%s" x="%s" y="%s" until="%s" name=%s fareZone="%s" fareSymbol="%s" startFare="%s" speed="20"/></timestep>\n' % (arrivalSec - offset, d.route_short_name, trip_id, d.stop_lon, d.stop_lat, until, sumolib.xml.quoteattr(d.stop_name), d.fare_zone, d.fare_token, d.start_char)) if firstDep is None: firstDep = departureSec - timeIndex offset += departureSec - arrivalSec mode = gtfs_modes[d.route_type] s = tuple(stopSeq) if s not in seqs: seqs[s] = trip_id fcdFile[mode].write(buf) timeIndex = arrivalSec tripFile[mode].write( ' <vehicle id="%s" route="%s" type="%s" depart="%s" line="%s_%s"/>\n' % (trip_id, seqs[s], mode, firstDep, d.route_short_name, seqs[s])) if options.gpsdat: if not os.path.exists(options.gpsdat): os.makedirs(options.gpsdat) for mode in set(gtfs_modes.values()): fcdFile[mode].write('</fcd-export>\n') fcdFile[mode].close() tripFile[mode].write("</routes>\n") tripFile[mode].close() f = "gpsdat_%s.csv" % mode traceExporter.main([ '', '--base-date', '0', '-i', fcdFile[mode].name, '--gpsdat-output', f ]) with open(f) as inp, open(os.path.join(options.gpsdat, f), "w") as outp: for l in inp: outp.write(l[l.index("_") + 1:]) os.remove(f)
def createTrips(options): print("generating trips...") stopsLanes = {} stopNames = {} for stop in sumolib.output.parse(options.ptstops, 'busStop'): stopsLanes[stop.id] = stop.lane if stop.name: stopNames[stop.id] = stop.attr_name trpMap = {} with codecs.open(options.trips, 'w', encoding="UTF8") as fouttrips: sumolib.writeXMLHeader(fouttrips, "$Id$", "routes") writeTypes(fouttrips, options.vtypeprefix) departTimes = [ options.begin for line in sumolib.output.parse_fast( options.ptlines, 'ptLine', ['id']) ] if options.randomBegin: departTimes = sorted([ options.begin + int(random.random() * options.period) for t in departTimes ]) lineCount = collections.defaultdict(int) typeCount = collections.defaultdict(int) numLines = 0 numStops = 0 numSkipped = 0 for trp_nr, line in enumerate( sumolib.output.parse(options.ptlines, 'ptLine', heterogeneous=True)): stop_ids = [] if not line.hasAttribute("period"): line.setAttribute("period", options.period) for stop in line.busStop: if stop.id not in stopsLanes: sys.stderr.write("Warning: skipping unknown stop '%s'\n" % stop.id) continue laneId = stopsLanes[stop.id] try: edge_id, lane_index = laneId.rsplit("_", 1) except ValueError: if options.ignoreErrors: sys.stderr.write( "Warning: ignoring stop '%s' on invalid lane '%s'\n" % (stop.id, laneId)) continue else: sys.exit("Invalid lane '%s' for stop '%s'" % (laneId, stop.id)) stop_ids.append(stop.id) if options.types is not None and line.type not in options.types: if options.verbose: print("Skipping line '%s' because it has type '%s'\n" % (line.id, line.type)) numSkipped += 1 continue if len(stop_ids) < options.min_stops: sys.stderr.write( "Warning: skipping line '%s' because it has too few stops\n" % line.id) numSkipped += 1 continue lineRefOrig = line.line.replace(" ", "_") lineRef = "%s:%s" % (lineRefOrig, lineCount[lineRefOrig]) lineCount[lineRefOrig] += 1 tripID = "%s_%s_%s" % (trp_nr, line.type, lineRef) begin = departTimes[trp_nr] if options.osmRoutes and line.route is not None: edges = line.route[0].edges.split() vias = '' if len(edges) > 2: vias = ' via="%s"' % (' '.join(edges[1:-1])) fouttrips.write(( ' <trip id="%s" type="%s%s" depart="%s" departLane="best" from="%s" ' + 'to="%s"%s>\n') % (tripID, options.vtypeprefix, line.type, begin, edges[0], edges[-1], vias)) else: if len(stop_ids) == 0: sys.stderr.write( "Warning: skipping line '%s' because it has no stops\n" % line.id) numSkipped += 1 continue fr, _ = stopsLanes[stop_ids[0]].rsplit("_", 1) to, _ = stopsLanes[stop_ids[-1]].rsplit("_", 1) fouttrips.write(( ' <trip id="%s" type="%s%s" depart="%s" departLane="best" from="%s" ' + 'to="%s">\n') % (tripID, options.vtypeprefix, line.type, begin, fr, to)) trpMap[tripID] = (lineRef, line.attr_name, line.completeness, line.period) for stop in stop_ids: fouttrips.write( ' <stop busStop="%s" duration="%s"/>\n' % (stop, options.stopduration)) fouttrips.write(' </trip>\n') typeCount[line.type] += 1 numLines += 1 numStops += len(stop_ids) fouttrips.write("</routes>\n") if options.verbose: print("Imported %s lines with %s stops and skipped %s lines" % (numLines, numStops, numSkipped)) for lineType, count in typeCount.items(): print(" %s: %s" % (lineType, count)) print("done.") return trpMap, stopNames
def main(options): if options.seed: random.seed(options.seed) net = sumolib.net.readNet(options.netfile) if options.min_distance > net.getBBoxDiameter() * (options.intermediate + 1): options.intermediate = int( math.ceil(options.min_distance / net.getBBoxDiameter())) - 1 print("Warning: setting number of intermediate waypoints to %s to achieve a minimum trip length of %s in a network with diameter %.2f." % ( options.intermediate, options.min_distance, net.getBBoxDiameter())) trip_generator = buildTripGenerator(net, options) idx = 0 if options.pedestrians: personattrs, otherattrs = split_trip_attributes(options.tripattrs) options.tripattrs = prependSpace(options.tripattrs) vias = {} def generate_one(idx): label = "%s%s" % (options.tripprefix, idx) try: source_edge, sink_edge, intermediate = trip_generator.get_trip( options.min_distance, options.max_distance, options.maxtries) via = "" if len(intermediate) > 0: via = ' via="%s" ' % ' '.join( [e.getID() for e in intermediate]) if options.validate: vias[label] = via if options.pedestrians: fouttrips.write( ' <person id="%s" depart="%.2f"%s>\n' % (label, depart, personattrs)) if options.persontrips: fouttrips.write( ' <personTrip from="%s" to="%s"%s/>\n' % (source_edge.getID(), sink_edge.getID(), otherattrs)) else: fouttrips.write( ' <walk from="%s" to="%s"%s/>\n' % (source_edge.getID(), sink_edge.getID(), otherattrs)) fouttrips.write(' </person>\n') elif options.flows > 0: if options.binomial: for j in range(options.binomial): fouttrips.write(' <flow id="%s#%s" begin="%s" end="%s" probability="%s" from="%s" to="%s"%s%s/>\n' % ( label, j, options.begin, options.end, 1.0 / options.period / options.binomial, source_edge.getID(), sink_edge.getID(), via, options.tripattrs)) else: fouttrips.write(' <flow id="%s" begin="%s" end="%s" period="%s" from="%s" to="%s"%s%s/>\n' % ( label, options.begin, options.end, options.period * options.flows, source_edge.getID(), sink_edge.getID(), via, options.tripattrs)) else: fouttrips.write(' <trip id="%s" depart="%.2f" from="%s" to="%s"%s%s/>\n' % ( label, depart, source_edge.getID(), sink_edge.getID(), via, options.tripattrs)) except Exception as exc: print(exc, file=sys.stderr) return idx + 1 with open(options.tripfile, 'w') as fouttrips: sumolib.writeXMLHeader( fouttrips, "$Id: randomTrips.py 23999 2017-04-21 09:04:47Z behrisch $", "routes") if options.vehicle_class: fouttrips.write(' <vType id="%s" vClass="%s" />\n' % (options.vehicle_class, options.vehicle_class)) options.tripattrs += ' type="%s"' % options.vehicle_class depart = options.begin if trip_generator: if options.flows == 0: while depart < options.end: if options.binomial is None: # generate with constant spacing idx = generate_one(idx) depart += options.period else: # draw n times from a bernouli distribution # for an average arrival rate of 1 / period prob = 1.0 / options.period / options.binomial for i in range(options.binomial): if random.random() < prob: idx = generate_one(idx) depart += 1 else: for i in range(options.flows): idx = generate_one(idx) fouttrips.write("</routes>\n") if options.routefile: args = [DUAROUTER, '-n', options.netfile, '-t', options.tripfile, '-o', options.routefile, '--ignore-errors', '--begin', str(options.begin), '--end', str(options.end), '--no-step-log', '--no-warnings'] if options.additional is not None: args += ['--additional-files', options.additional] print("calling ", " ".join(args)) subprocess.call(args) if options.validate: print("calling route2trips") route2trips.main([options.routefile], outfile=options.tripfile, vias=vias, calledBy=" via randomTrips.py") if options.weights_outprefix: trip_generator.source_generator.write_weights( options.weights_outprefix + SOURCE_SUFFIX) trip_generator.sink_generator.write_weights( options.weights_outprefix + SINK_SUFFIX) trip_generator.via_generator.write_weights( options.weights_outprefix + VIA_SUFFIX) # return wether trips could be genreated as requested return trip_generator is not None
def main(options): #print(options.vehicle_class[1]) #print(len(options.vehicle_class)) #print(options.vehicle_percentage) if options.seed: random.seed(options.seed) net = sumolib.net.readNet(options.netfile) if options.min_distance > net.getBBoxDiameter() * (options.intermediate + 1): options.intermediate = int( math.ceil(options.min_distance / net.getBBoxDiameter())) - 1 print("Warning: setting number of intermediate waypoints to %s to achieve a minimum trip length of %s in a network with diameter %.2f." % ( options.intermediate, options.min_distance, net.getBBoxDiameter())) trip_generator = buildTripGenerator(net, options) idx = 0 vtypeattrs, options.tripattrs, personattrs, otherattrs = split_trip_attributes( options.tripattrs, options.pedestrians, options.vehicle_class) vias = {} def generate_one(idx, vehicle_idx): label = "%s%s" % (options.tripprefix, idx) try: source_edge, sink_edge, intermediate = trip_generator.get_trip( options.min_distance, options.max_distance, options.maxtries) via = "" if len(intermediate) > 0: via = ' via="%s" ' % ' '.join( [e.getID() for e in intermediate]) if options.validate: vias[label] = via if options.pedestrians: fouttrips.write( ' <person id="%s" depart="%.2f"%s>\n' % (label, depart, personattrs)) if options.persontrips: fouttrips.write( ' <personTrip from="%s" to="%s"%s/>\n' % (source_edge.getID(), sink_edge.getID(), otherattrs)) else: fouttrips.write( ' <walk from="%s" to="%s"%s/>\n' % (source_edge.getID(), sink_edge.getID(), otherattrs)) fouttrips.write(' </person>\n') elif options.flows > 0: if options.binomial: for j in range(options.binomial): fouttrips.write(' <flow id="%s#%s" begin="%s" end="%s" probability="%s" from="%s" to="%s"%s%s/>\n' % ( label, j, options.begin, options.end, 1.0 / options.period / options.binomial, source_edge.getID(), sink_edge.getID(), via, options.tripattrs)) else: fouttrips.write(' <flow id="%s" begin="%s" end="%s" period="%s" from="%s" to="%s"%s%s/>\n' % ( label, options.begin, options.end, options.period * options.flows, source_edge.getID(), sink_edge.getID(), via, options.tripattrs)) else: fouttrips.write(' <trip id="%s" depart="%.2f" from="%s" to="%s"%s%s type="%s">\n' % ( label, depart, source_edge.getID(), sink_edge.getID(), via, options.tripattrs, options.vehicle_class[vehicle_idx])) if options.device: #add device parameters try: if options.device[vehicle_idx]: fouttrips.write(' <param key="has.%s.device" value="true"/>\n' % options.device[vehicle_idx]) except IndexError: pass fouttrips.write(' </trip>\n') except Exception as exc: print(exc, file=sys.stderr) return idx + 1 with open(options.tripfile, 'w') as fouttrips: sumolib.writeXMLHeader( fouttrips, "$Id$", "routes") if options.vehicle_class: for i in range(len(options.vehicle_class)): fouttrips.write(' <vType id="%s" vClass="%s"%s/>\n' % (options.vehicle_class[i], options.vehicle_class[i], vtypeattrs)) #options.tripattrs += ' type="%s"' % options.vehicle_class[i] depart = options.begin if trip_generator: if options.flows == 0: #initialize percentage indexer and accumulator vehicle_idx = 0 accumulator = options.vehicle_percentage[vehicle_idx] while depart < options.end: if options.binomial is None: # generate with constant spacing if options.vehicle_percentage is None: # make all cars single, initial vehicle class idx = generate_one(idx, 0) else: idx = generate_one(idx, vehicle_idx) if idx == accumulator: #percentage reached vehicle_idx += 1 accumulator += options.vehicle_percentage[vehicle_idx] #print('here %d' % accumulator) depart += options.period else: # draw n times from a Bernoulli distribution # for an average arrival rate of 1 / period prob = 1.0 / options.period / options.binomial for i in range(options.binomial): if random.random() < prob: idx = generate_one(idx) depart += 1 else: for i in range(options.flows): idx = generate_one(idx) fouttrips.write("</routes>\n") if options.routefile: args = [DUAROUTER, '-n', options.netfile, '-r', options.tripfile, '-o', options.routefile, '--ignore-errors', '--begin', str(options.begin), '--end', str(options.end), '--no-step-log', '--no-warnings'] if options.additional is not None: args += ['--additional-files', options.additional] if options.carWalkMode is not None: args += ['--persontrip.transfer.car-walk', options.carWalkMode] if options.walkfactor is not None: args += ['--persontrip.walkfactor', options.walkfactor] print("calling ", " ".join(args)) subprocess.call(args) if options.validate: print("calling route2trips") route2trips.main([options.routefile], outfile=options.tripfile, vias=vias, calledBy=" via randomTrips.py") if options.weights_outprefix: trip_generator.source_generator.write_weights( options.weights_outprefix + SOURCE_SUFFIX) trip_generator.sink_generator.write_weights( options.weights_outprefix + SINK_SUFFIX) trip_generator.via_generator.write_weights( options.weights_outprefix + VIA_SUFFIX) # return wether trips could be generated as requested return trip_generator is not None
def main(options): if options.seed: random.seed(options.seed) np.random.seed(options.seed) routes = Routes(options.routeFiles) intervals = getIntervals(options) # preliminary integrity check for the whole time range b = intervals[0][0] e = intervals[-1][-1] countData = (parseDataIntervals(parseTurnCounts, options.turnFiles, b, e, routes, options.turnAttr, options=options, warn=True) + parseDataIntervals(parseEdgeCounts, options.edgeDataFiles, b, e, routes, options.edgeDataAttr, options=options, warn=True) + parseDataIntervals(parseTurnCounts, options.odFiles, b, e, routes, options.turnAttr, options=options, isOD=True, warn=True)) routeUsage = getRouteUsage(routes, countData) for cd in countData: if cd.count > 0 and not cd.routeSet: print("Warning: no routes pass edge '%s' (count %s)" % ( ' '.join(cd.edgeTuple), cd.count), file=sys.stderr) if options.verbose: print("Loaded %s routes (%s distinct)" % (len(routes.all), routes.number)) if options.weighted: print("Loaded probability for %s routes" % routes.withProb) if options.verboseHistogram: edgeCount = sumolib.miscutils.Statistics("route edge count", histogram=True) detectorCount = sumolib.miscutils.Statistics("route detector count", histogram=True) for i, edges in enumerate(routes.unique): edgeCount.add(len(edges), i) detectorCount.add(len(routeUsage[i]), i) print("input %s" % edgeCount) print("input %s" % detectorCount) mismatchf = None if options.mismatchOut: mismatchf = open(options.mismatchOut, 'w') sumolib.writeXMLHeader(mismatchf, "$Id$") # noqa mismatchf.write('<data>\n') underflowSummary = sumolib.miscutils.Statistics("all interval underflow") overflowSummary = sumolib.miscutils.Statistics("all interval overflow") gehSummary = sumolib.miscutils.Statistics("all interval GEH%") with open(options.out, 'w') as outf: sumolib.writeXMLHeader(outf, "$Id$", "routes") # noqa if options.threads > 1: # call the multiprocessing function results = multi_process(options.threads, options.seed, intervals, _solveIntervalMP, outf, mismatchf, options=options, routes=routes) # handle the uFlow, oFlow and GEH for _, result in results: for i, begin in enumerate(result[0]): underflowSummary.add(result[1][i], begin) overflowSummary.add(result[2][i], begin) gehSummary.add(result[3][i], begin) else: for begin, end in intervals: intervalPrefix = "" if len(intervals) == 1 else "%s_" % int(begin) uFlow, oFlow, gehOK, _ = solveInterval(options, routes, begin, end, intervalPrefix, outf, mismatchf) underflowSummary.add(uFlow, begin) overflowSummary.add(oFlow, begin) gehSummary.add(gehOK, begin) outf.write('</routes>\n') if options.mismatchOut: mismatchf.write('</data>\n') mismatchf.close() if len(intervals) > 1: print(underflowSummary) print(overflowSummary) print(gehSummary)
def main(options): if options.verbose: print('Loading GTFS data "%s"' % options.gtfs) gtfsZip = zipfile.ZipFile(options.gtfs) routes = pd.read_csv(gtfsZip.open('routes.txt'), dtype=str) stops = pd.read_csv(gtfsZip.open('stops.txt'), dtype=str) stop_times = pd.read_csv(gtfsZip.open('stop_times.txt'), converters={'trip_id': str, 'arrival_time': time2sec, 'departure_time': time2sec, 'stop_id': str, 'stop_sequence': int}) trips = pd.read_csv(gtfsZip.open('trips.txt'), dtype=str) calendar_dates = pd.read_csv(gtfsZip.open('calendar_dates.txt'), dtype=str) # currently not used: # agency = pd.read_csv(gtfsZip.open('agency.txt'), dtype=str) # calendar = pd.read_csv(gtfsZip.open('calendar.txt'), dtype=str) # transfers = pd.read_csv(gtfsZip.open('transfers.txt'), dtype=str) # Merging the tables tmp = pd.merge(trips, calendar_dates, on='service_id') trips_on_day = tmp[tmp['date'] == options.date] if 'fare_stops.txt' in gtfsZip.namelist(): zones = pd.read_csv(gtfsZip.open('fare_stops.txt'), dtype=str) stops_merged = pd.merge(pd.merge(stops, stop_times, on='stop_id'), zones, on='stop_id') else: stops_merged = pd.merge(stops, stop_times, on='stop_id') stops_merged['fare_zone'] = '' stops_merged['fare_token'] = '' stops_merged['start_char'] = '' trips_routes_merged = pd.merge(trips_on_day, routes, on='route_id') full_data_merged = pd.merge(stops_merged, trips_routes_merged, on='trip_id')[['trip_id', 'route_id', 'route_short_name', 'route_type', 'stop_id', 'stop_name', 'stop_lat', 'stop_lon', 'stop_sequence', 'fare_zone', 'fare_token', 'start_char', 'arrival_time', 'departure_time']].drop_duplicates() gtfs_modes = { # modes according to https://developers.google.com/transit/gtfs/reference/#routestxt '0': 'tram', '1': 'subway', '2': 'rail', '3': 'bus', '4': 'ship', # '5': 'cableTram', # '6': 'aerialLift', # '7': 'funicular', # modes used in Berlin and MDV see https://developers.google.com/transit/gtfs/reference/extended-route-types '100': 'rail', # DB '109': 'light_rail', # S-Bahn '400': 'subway', # U-Bahn '700': 'bus', # Bus '714': 'bus', # SEV '715': 'bus', # Rufbus '900': 'tram', # Tram '1000': 'ship', # Faehre # modes used by hafas 's': 'light_rail', 'RE': 'rail', 'RB': 'rail', 'IXB': 'rail', # tbd 'ICE': 'rail_electric', 'IC': 'rail_electric', 'IRX': 'rail', # tbd 'EC': 'rail', 'NJ': 'rail', # tbd 'RHI': 'rail', # tbd 'DPN': 'rail', # tbd 'SCH': 'rail', # tbd 'Bsv': 'rail', # tbd 'KAT': 'rail', # tbd 'AIR': 'rail', # tbd 'DPS': 'rail', # tbd 'lt': 'light_rail', # tbd 'BUS': 'bus', # tbd 'Str': 'tram', # tbd 'DPF': 'rail', # tbd } fcdFile = {} tripFile = {} if not os.path.exists(options.fcd): os.makedirs(options.fcd) seenModes = set() for mode in set(gtfs_modes.values()): filePrefix = os.path.join(options.fcd, mode) fcdFile[mode] = open(filePrefix + '.fcd.xml', 'w', encoding="utf8") sumolib.writeXMLHeader(fcdFile[mode], "gtfs2fcd.py") fcdFile[mode].write('<fcd-export>\n') if options.verbose: print('Writing fcd file "%s"' % fcdFile[mode].name) tripFile[mode] = open(filePrefix + '.rou.xml', 'w') tripFile[mode].write("<routes>\n") timeIndex = 0 for _, trip_data in full_data_merged.groupby(['route_id']): seqs = {} for trip_id, data in trip_data.groupby(['trip_id']): stopSeq = [] buf = "" offset = 0 firstDep = None for __, d in data.sort_values(by=['stop_sequence']).iterrows(): arrivalSec = d.arrival_time + timeIndex stopSeq.append(d.stop_id) departureSec = d.departure_time + timeIndex until = 0 if firstDep is None else departureSec - timeIndex - firstDep buf += ((' <timestep time="%s"><vehicle id="%s" x="%s" y="%s" until="%s" ' + 'name=%s fareZone="%s" fareSymbol="%s" startFare="%s" speed="20"/></timestep>\n') % (arrivalSec - offset, trip_id, d.stop_lon, d.stop_lat, until, sumolib.xml.quoteattr(d.stop_name), d.fare_zone, d.fare_token, d.start_char)) if firstDep is None: firstDep = departureSec - timeIndex offset += departureSec - arrivalSec mode = gtfs_modes[d.route_type] s = tuple(stopSeq) if s not in seqs: seqs[s] = trip_id fcdFile[mode].write(buf) timeIndex = arrivalSec tripFile[mode].write(' <vehicle id="%s" route="%s" type="%s" depart="%s" line="%s_%s"/>\n' % (trip_id, seqs[s], mode, firstDep, d.route_short_name, seqs[s])) seenModes.add(mode) if options.gpsdat: if not os.path.exists(options.gpsdat): os.makedirs(options.gpsdat) for mode in set(gtfs_modes.values()): fcdFile[mode].write('</fcd-export>\n') fcdFile[mode].close() tripFile[mode].write("</routes>\n") tripFile[mode].close() if mode in seenModes: traceExporter.main(['', '--base-date', '0', '-i', fcdFile[mode].name, '--gpsdat-output', os.path.join(options.gpsdat, "gpsdat_%s.csv" % mode)]) else: os.remove(fcdFile[mode].name) os.remove(tripFile[mode].name) if options.vtype_output: with open(options.vtype_output, 'w', encoding="utf8") as vout: sumolib.xml.writeHeader(vout, os.path.basename(__file__), "additional") for mode in sorted(seenModes): vout.write(' <vType id="%s" vClass="%s"/>\n' % (mode, "rail_urban" if mode in ("light_rail", "subway") else mode)) vout.write('</additional>\n')
def createTrips(options): print("generating trips...") stopsLanes = {} stopNames = {} for stop in sumolib.output.parse(options.ptstops, 'busStop'): stopsLanes[stop.id] = stop.lane if stop.name: stopNames[stop.id] = stop.attr_name trpMap = {} with codecs.open(options.trips, 'w', encoding="UTF8") as fouttrips: sumolib.writeXMLHeader( fouttrips, "$Id: ptlines2flows.py v1_3_1+0313-ccb31df3eb [email protected] 2019-09-02 13:26:32 +0200 $", "routes") writeTypes(fouttrips, options.vtypeprefix, options) departTimes = [ options.begin for line in sumolib.output.parse_fast( options.ptlines, 'ptLine', ['id']) ] if options.randomBegin: departTimes = sorted([ options.begin + int(random.random() * options.period) for t in departTimes ]) lineCount = collections.defaultdict(int) typeCount = collections.defaultdict(int) numLines = 0 numStops = 0 numSkipped = 0 for trp_nr, line in enumerate( sumolib.output.parse(options.ptlines, 'ptLine', heterogeneous=True)): stop_ids = [] if not line.hasAttribute("period"): line.setAttribute("period", options.period) if line.busStop is not None: for stop in line.busStop: if stop.id not in stopsLanes: sys.stderr.write( "Warning: skipping unknown stop '%s'\n" % stop.id) continue laneId = stopsLanes[stop.id] try: edge_id, lane_index = laneId.rsplit("_", 1) except ValueError: if options.ignoreErrors: sys.stderr.write( "Warning: ignoring stop '%s' on invalid lane '%s'\n" % (stop.id, laneId)) continue else: sys.exit("Invalid lane '%s' for stop '%s'" % (laneId, stop.id)) stop_ids.append(stop.id) if options.types is not None and line.type not in options.types: if options.verbose: print("Skipping line '%s' because it has type '%s'" % (line.id, line.type)) numSkipped += 1 continue if line.hasAttribute("nightService"): if line.nightService == "only" and not options.night: if options.verbose: print( "Skipping line '%s' because it only drives at night" % (line.id)) numSkipped += 1 continue if line.nightService == "no" and options.night: if options.verbose: print( "Skipping line '%s' because it only drives during the day" % (line.id)) numSkipped += 1 continue lineRefOrig = line.line.replace(" ", "_") lineRefOrig = lineRefOrig.replace(";", "+") lineRefOrig = lineRefOrig.replace(">", "") lineRefOrig = lineRefOrig.replace("<", "") if len(stop_ids) < options.min_stops: sys.stderr.write( "Warning: skipping line '%s' (%s_%s) because it has too few stops\n" % (line.id, line.type, lineRefOrig)) numSkipped += 1 continue lineRef = "%s:%s" % (lineRefOrig, lineCount[lineRefOrig]) lineCount[lineRefOrig] += 1 tripID = "%s_%s_%s" % (trp_nr, line.type, lineRef) begin = departTimes[trp_nr] edges = [] if line.route is not None: edges = line.route[0].edges.split() if options.osmRoutes and len(edges) == 0 and options.verbose: print("Cannot use OSM route for line '%s' (no edges given)" % line.id) elif options.osmRoutes and len(edges) > 0: edges = line.route[0].edges.split() vias = '' if len(edges) > 2: vias = ' via="%s"' % (' '.join(edges[1:-1])) fouttrips.write(( ' <trip id="%s" type="%s%s" depart="%s" departLane="best" from="%s" ' + 'to="%s"%s>\n') % (tripID, options.vtypeprefix, line.type, begin, edges[0], edges[-1], vias)) else: if options.extendFringe and len(edges) > len(stop_ids): fr = edges[0] to = edges[-1] # ensure that route actually covers the terminal stops # (otherwise rail network may be invalid beyond stops) if len(stop_ids) > 0: firstStop = getStopEdge(stopsLanes, stop_ids[0]) lastStop = getStopEdge(stopsLanes, stop_ids[-1]) if firstStop not in edges: fr = firstStop if options.verbose: print(( "Cannot extend route before first stop for line '%s' " + "(stop edge %s not in route)") % (line.id, firstStop)) if lastStop not in edges: to = lastStop if options.verbose: print(( "Cannot extend route after last stop for line '%s' " + "(stop edge %s not in route)") % (line.id, lastStop)) else: if options.extendFringe and options.verbose: print( "Cannot extend route to fringe for line '%s' (not enough edges given)" % line.id) if len(stop_ids) == 0: sys.stderr.write( "Warning: skipping line '%s' because it has no stops\n" % line.id) numSkipped += 1 continue fr = getStopEdge(stopsLanes, stop_ids[0]) to = getStopEdge(stopsLanes, stop_ids[-1]) fouttrips.write(( ' <trip id="%s" type="%s%s" depart="%s" departLane="best" from="%s" ' + 'to="%s">\n') % (tripID, options.vtypeprefix, line.type, begin, fr, to)) trpMap[tripID] = PTLine(lineRef, line.attr_name, line.completeness, line.period, line.getAttributeSecure("color", None)) for stop in stop_ids: dur = options.stopduration + options.stopdurationSlack fouttrips.write( ' <stop busStop="%s" duration="%s"/>\n' % (stop, dur)) fouttrips.write(' </trip>\n') typeCount[line.type] += 1 numLines += 1 numStops += len(stop_ids) fouttrips.write("</routes>\n") if options.verbose: print("Imported %s lines with %s stops and skipped %s lines" % (numLines, numStops, numSkipped)) for lineType, count in typeCount.items(): print(" %s: %s" % (lineType, count)) print("done.") return trpMap, stopNames
def main(options): persons = [] # (depart, xmlsnippet) for person in sumolib.output.parse(options.planfile, 'person'): outf = StringIO() vehIndex = 0 plan = person.plan[0] firstAct = plan.getChildList()[0] depart = firstAct.start_time if depart is None: depart = options.defaultStart attributes = person.attributes[0] if person.attributes else None # write vehicles vehicleslist = [] untillist = [] lastAct = None lastLeg = None for item in plan.getChildList(): leg = None idveh = "%s_%s" % (person.id, vehIndex) if "act" in item.name: # act or activity if lastLeg is not None: leg = lastLeg leg.dep_time = lastAct.end_time writeLeg(outf, options, idveh, leg, lastAct.link, item.link) lastLeg = None lastAct = item if item.name == "leg": if item.route is None: lastLeg = item else: leg = item writeLeg(outf, options, idveh, leg, leg.route[0].start_link, leg.route[0].end_link) if leg: untillist.append(leg.dep_time) vehicleslist.append(idveh) vehIndex = vehIndex+1 untillist.append(lastAct.end_time if lastAct.end_time else options.defaultEnd) # write person if not options.carsOnly: vehIndex = 0 outf.write(' <person id="%s" depart="%s">\n' % (person.id, depart)) if attributes is not None: for attr in attributes.attribute: outf.write(' <param key="%s" value="%s"/>\n' % (attr.attr_name, attr.getText())) lastLeg = None for item in plan.getChildList(): if "act" in item.name: # act or activity if lastLeg is not None: outf.write(' <ride lines="%s" to="%s" />\n' % (vehicleslist[vehIndex], item.link)) vehIndex = vehIndex+1 outf.write(' <stop lane="%s_0" until="%s" actType="%s" />\n' % (item.link, untillist[vehIndex], item.type)) if item.name == "leg": lastLeg = item outf.write(' </person>\n') persons.append((sumolib.miscutils.parseTime(depart), outf.getvalue())) persons.sort() with open(options.outfile, 'w') as outf: sumolib.writeXMLHeader(outf, "$Id: matsim_importPlans.py v1_3_1+0713-63b241ac79 [email protected] 2019-10-20 15:41:56 +0200 $", "routes") # noqa for depart, xml in persons: outf.write(xml) outf.write('</routes>\n') outf.close()
def createTrips(options): print("generating trips...") stopsLanes = {} for stop in sumolib.output.parse_fast(options.ptstops, 'busStop', ['id', 'lane']): stopsLanes[stop.id] = stop.lane trpMap = {} with open(options.trips, 'w') as fouttrips: sumolib.writeXMLHeader( fouttrips, "$Id$", "routes") writeTypes(fouttrips, options.vtypeprefix) departTimes = [0 for line in sumolib.output.parse_fast(options.ptlines, 'ptLine', ['id'])] if options.randomBegin: departTimes = sorted([int(random.random() * options.period) for t in departTimes]) for trp_nr, line in enumerate(sumolib.output.parse(options.ptlines, 'ptLine')): stop_ids = [] for stop in line.busStop: if not stop.id in stopsLanes: sys.stderr.write("Warning: skipping unknown stop '%s'\n" % stop.id) continue laneId = stopsLanes[stop.id] try: edge_id, lane_index = laneId.rsplit("_", 1) except ValueError: if options.ignoreErrors: sys.stderr.write("Warning: ignoring stop '%s' on invalid lane '%s'\n" % (stop.id, laneId)) continue else: sys.exit("Invalid lane '%s' for stop '%s'" % (laneId, stop.id)) stop_ids.append(stop.id) if options.types is not None and not line.type in options.types: if options.verbose: print("Skipping line '%s' because it has type '%s'\n" % (line.id, line.type)) continue if len(stop_ids) < options.min_stops: sys.stderr.write("Warning: skipping line '%s' because it has too few stops\n" % line.id) continue begin = departTimes[trp_nr] if options.osmRoutes and line.route is not None: edges = line.route[0].edges.split() vias = '' if len(edges) > 2: vias = ' via="%s"' % (' '.join(edges[1:-1])) fouttrips.write( ' <trip id="%s" type="%s%s" depart="%s" departLane="%s" from="%s" to="%s"%s>\n' % ( line.id, options.vtypeprefix, line.type, begin, 'best', edges[0], edges[-1], vias)) else: if len(stop_ids) == 0: sys.stderr.write("Warning: skipping line '%s' because it has no stops\n" % line.id) continue fr, _ = stopsLanes[stop_ids[0]].rsplit("_", 1) to, _ = stopsLanes[stop_ids[-1]].rsplit("_", 1) fouttrips.write( ' <trip id="%s" type="%s%s" depart="%s" departLane="%s" from="%s" to="%s">\n' % ( line.id, options.vtypeprefix, line.type, begin, 'best', fr, to)) trpMap[line.id] = (line.line.replace(" ", "_"), line.attr_name, line.completeness) for stop in stop_ids: fouttrips.write(' <stop busStop="%s" duration="%s"/>\n' % (stop, options.stopduration)) fouttrips.write(' </trip>\n') fouttrips.write("</routes>\n") print("done.") return trpMap
def main(options): if options.seed: random.seed(options.seed) net = sumolib.net.readNet(options.netfile) if options.min_distance > net.getBBoxDiameter() * (options.intermediate + 1): options.intermediate = int( math.ceil(options.min_distance / net.getBBoxDiameter())) - 1 print(( "Warning: setting number of intermediate waypoints to %s to achieve a minimum trip length of " + "%s in a network with diameter %.2f.") % (options.intermediate, options.min_distance, net.getBBoxDiameter())) if options.angle_weight != 1: xmin, ymin, xmax, ymax = net.getBoundary() options.angle_center = (xmin + xmax) / 2, (ymin + ymax) / 2 trip_generator = buildTripGenerator(net, options) idx = 0 vtypeattrs, options.tripattrs, personattrs, otherattrs = split_trip_attributes( options.tripattrs, options.pedestrians, options.vehicle_class) vias = {} def generate_one(idx): label = "%s%s" % (options.tripprefix, idx) try: source_edge, sink_edge, intermediate = trip_generator.get_trip( options.min_distance, options.max_distance, options.maxtries) combined_attrs = options.tripattrs if options.fringeattrs and source_edge.is_fringe( source_edge._incoming): combined_attrs += " " + options.fringeattrs via = "" if len(intermediate) > 0: via = ' via="%s" ' % ' '.join( [e.getID() for e in intermediate]) if options.validate: vias[label] = via if options.pedestrians: fouttrips.write(' <person id="%s" depart="%.2f"%s>\n' % (label, depart, personattrs)) if options.persontrips: fouttrips.write( ' <personTrip from="%s" to="%s"%s/>\n' % (source_edge.getID(), sink_edge.getID(), otherattrs)) elif options.personrides: fouttrips.write( ' <ride from="%s" to="%s" lines="%s"%s/>\n' % (source_edge.getID(), sink_edge.getID(), options.personrides, otherattrs)) else: fouttrips.write( ' <walk from="%s" to="%s"%s/>\n' % (source_edge.getID(), sink_edge.getID(), otherattrs)) fouttrips.write(' </person>\n') else: if options.junctionTaz: attrFrom = ' fromJunction="%s"' % source_edge.getFromNode( ).getID() attrTo = ' toJunction="%s"' % sink_edge.getToNode().getID() else: attrFrom = ' from="%s"' % source_edge.getID() attrTo = ' to="%s"' % sink_edge.getID() if options.jtrrouter: attrTo = '' if options.flows > 0: if options.binomial: for j in range(options.binomial): fouttrips.write(( ' <flow id="%s#%s" begin="%s" end="%s" probability="%s"%s%s%s%s/>\n' ) % (label, j, options.begin, options.end, 1.0 / options.period / options.binomial, attrFrom, attrTo, via, combined_attrs)) else: fouttrips.write(( ' <flow id="%s" begin="%s" end="%s" period="%s"%s%s%s%s/>\n' ) % (label, options.begin, options.end, options.period * options.flows, attrFrom, attrTo, via, combined_attrs)) else: fouttrips.write( ' <trip id="%s" depart="%.2f"%s%s%s%s/>\n' % (label, depart, attrFrom, attrTo, via, combined_attrs)) except Exception as exc: print(exc, file=sys.stderr) return idx + 1 with open(options.tripfile, 'w') as fouttrips: sumolib.writeXMLHeader(fouttrips, "$Id$", "routes") # noqa if options.vehicle_class: fouttrips.write( ' <vType id="%s" vClass="%s"%s/>\n' % (options.vtypeID, options.vehicle_class, vtypeattrs)) options.tripattrs += ' type="%s"' % options.vtypeID personattrs += ' type="%s"' % options.vtypeID depart = options.begin if trip_generator: if options.flows == 0: while depart < options.end: if options.binomial is None: # generate with constant spacing idx = generate_one(idx) depart += options.period else: # draw n times from a Bernoulli distribution # for an average arrival rate of 1 / period prob = 1.0 / options.period / options.binomial for i in range(options.binomial): if random.random() < prob: idx = generate_one(idx) depart += 1 else: for i in range(options.flows): idx = generate_one(idx) fouttrips.write("</routes>\n") # call duarouter for routes or validated trips args = [ DUAROUTER, '-n', options.netfile, '-r', options.tripfile, '--ignore-errors', '--begin', str(options.begin), '--end', str(options.end), '--no-step-log' ] if options.additional is not None: args += ['--additional-files', options.additional] if options.carWalkMode is not None: args += ['--persontrip.transfer.car-walk', options.carWalkMode] if options.walkfactor is not None: args += ['--persontrip.walkfactor', options.walkfactor] if options.remove_loops: args += ['--remove-loops'] if options.vtypeout is not None: args += ['--vtype-output', options.vtypeout] if options.junctionTaz: args += ['--junction-taz'] if not options.verbose: args += ['--no-warnings'] else: args += ['-v'] if options.routefile: args2 = args + ['-o', options.routefile] print("calling ", " ".join(args2)) subprocess.call(args2) if options.validate: # write to temporary file because the input is read incrementally tmpTrips = options.tripfile + ".tmp" args2 = args + ['-o', tmpTrips, '--write-trips'] print("calling ", " ".join(args2)) subprocess.call(args2) os.remove(options.tripfile) # on windows, rename does not overwrite os.rename(tmpTrips, options.tripfile) if options.weights_outprefix: trip_generator.source_generator.write_weights( options.weights_outprefix + SOURCE_SUFFIX) trip_generator.sink_generator.write_weights(options.weights_outprefix + SINK_SUFFIX) if trip_generator.via_generator: trip_generator.via_generator.write_weights( options.weights_outprefix + VIA_SUFFIX) # return wether trips could be generated as requested return trip_generator is not None
def main(options): if options.seed: random.seed(options.seed) routes = Routes(options.routeFiles) # store which routes are passing each counting location (using route index) countData = ( parseTurnCounts(options.turnFiles, routes, options.turnAttr) + parseEdgeCounts(options.edgeDataFiles, routes, options.edgeDataAttr)) # store which counting locations are used by each route (using countData index) routeUsage = [set() for r in routes.unique] for i, cd in enumerate(countData): for routeIndex in cd.routeSet: routeUsage[routeIndex].add(i) if options.verbose: print("Loaded %s routes (%s distinct)" % (len(routes.all), routes.number)) edgeCount = sumolib.miscutils.Statistics("route edge count", histogram=True) detectorCount = sumolib.miscutils.Statistics("route detector count", histogram=True) for i, edges in enumerate(routes.unique): edgeCount.add(len(edges), i) detectorCount.add(len(routeUsage[i]), i) print("input %s" % edgeCount) print("input %s" % detectorCount) # pick a random couting location and select a new route that passes it until # all counts are satisfied or no routes can be used anymore openRoutes = set(range(0, routes.number)) openCounts = set(range(0, len(countData))) openRoutes = updateOpenRoutes(openRoutes, routeUsage, countData) openCounts = updateOpenCounts(openCounts, countData, openRoutes) usedRoutes = [] if options.optimizeInput: usedRoutes = [routes.edges2index[e] for e in routes.all] resetCounts(usedRoutes, routeUsage, countData) else: while openCounts: cd = countData[random.sample(openCounts, 1)[0]] routeIndex = random.sample(cd.routeSet.intersection(openRoutes), 1)[0] usedRoutes.append(routeIndex) for dataIndex in routeUsage[routeIndex]: countData[dataIndex].count -= 1 openRoutes = updateOpenRoutes(openRoutes, routeUsage, countData) openCounts = updateOpenCounts(openCounts, countData, openRoutes) hasMismatch = sum([cd.count for cd in countData]) > 0 if hasMismatch and options.optimize is not None: optimize(options, countData, routes, usedRoutes, routeUsage) resetCounts(usedRoutes, routeUsage, countData) begin, end = parseTimeRange(options.turnFiles + options.edgeDataFiles) if usedRoutes: with open(options.out, 'w') as outf: sumolib.writeXMLHeader(outf, "$Id$", "routes") # noqa period = (end - begin) / len(usedRoutes) depart = begin routeCounts = getRouteCounts(routes, usedRoutes) if options.writeRouteIDs: for routeIndex in sorted(set(usedRoutes)): outf.write( ' <route id="%s" edges="%s"/> <!-- %s -->\n' % (routeIndex, ' '.join(routes.unique[routeIndex]), routeCounts[routeIndex])) outf.write('\n') elif options.writeRouteDist: outf.write(' <routeDistribution id="%s"/>\n' % options.writeRouteDist) for routeIndex in sorted(set(usedRoutes)): outf.write( ' <route id="%s" edges="%s" probability="%s"/>\n' % (routeIndex, ' '.join(routes.unique[routeIndex]), routeCounts[routeIndex])) outf.write(' </routeDistribution>\n\n') routeID = options.writeRouteDist if options.writeFlows is None: for i, routeIndex in enumerate(usedRoutes): if options.writeRouteIDs: routeID = routeIndex if routeID is not None: outf.write( ' <vehicle id="%s%s" depart="%.2f" route="%s"%s/>\n' % (options.prefix, i, depart, routeID, options.vehattrs)) else: outf.write( ' <vehicle id="%s%s" depart="%.2f"%s>\n' % (options.prefix, i, depart, options.vehattrs)) outf.write(' <route edges="%s"/>\n' % ' '.join(routes.unique[routeIndex])) outf.write(' </vehicle>\n') depart += period else: routeDeparts = defaultdict(list) for routeIndex in usedRoutes: routeDeparts[routeIndex].append(depart) depart += period if options.writeRouteDist: totalCount = sum(routeCounts) probability = totalCount / (end - begin) flowID = options.prefix + options.writeRouteDist if options.writeFlows == "number" or probability > 1.001: repeat = 'number="%s"' % totalCount if options.writeFlows == "probability": sys.stderr.write( "Warning: could not write flow %s with probability %.2f\n" % (flowID, probability)) else: repeat = 'probability="%s"' % probability outf.write( ' <flow id="%s" begin="%.2f" end="%.2f" %s route="%s"%s/>\n' % (flowID, begin, end, repeat, options.writeRouteDist, options.vehattrs)) else: for routeIndex in sorted(set(usedRoutes)): fBegin = min(routeDeparts[routeIndex]) fEnd = max(routeDeparts[routeIndex] + [fBegin + 1.0]) probability = routeCounts[routeIndex] / (fEnd - fBegin) flowID = "%s%s" % (options.prefix, routeIndex) if options.writeFlows == "number" or probability > 1.001: repeat = 'number="%s"' % routeCounts[routeIndex] if options.writeFlows == "probability": sys.stderr.write( "Warning: could not write flow %s with probability %.2f\n" % (flowID, probability)) else: repeat = 'probability="%s"' % probability if options.writeRouteIDs: outf.write( ' <flow id="%s" begin="%.2f" end="%.2f" %s route="%s"%s/>\n' % (flowID, fBegin, fEnd, repeat, routeIndex, options.vehattrs)) else: outf.write( ' <flow id="%s%s" begin="%.2f" end="%.2f" %s%s>\n' % (options.prefix, routeIndex, fBegin, fEnd, repeat, options.vehattrs)) outf.write(' <route edges="%s"/>\n' % ' '.join(routes.unique[routeIndex])) outf.write(' </flow>\n') outf.write('</routes>\n') underflow = sumolib.miscutils.Statistics("underflow locations") overflow = sumolib.miscutils.Statistics("overflow locations") gehStats = sumolib.miscutils.Statistics("GEH") numGehOK = 0.0 hourFraction = (end - begin) / 3600.0 totalCount = 0 for cd in countData: localCount = cd.origCount - cd.count totalCount += localCount if cd.count > 0: underflow.add(cd.count, cd.edgeTuple) elif cd.count < 0: overflow.add(cd.count, cd.edgeTuple) origHourly = cd.origCount / hourFraction localHourly = localCount / hourFraction geh = sumolib.miscutils.geh(origHourly, localHourly) if geh < options.gehOk: numGehOK += 1 gehStats.add( geh, "[%s] %s %s" % (' '.join(cd.edgeTuple), int(origHourly), int(localHourly))) print( "Wrote %s routes (%s distinct) achieving total count %s at %s locations. GEH<%s for %.2f%%" % (len(usedRoutes), len(set(usedRoutes)), totalCount, len(countData), options.gehOk, 100 * numGehOK / len(countData))) if options.verbose: edgeCount = sumolib.miscutils.Statistics("route edge count", histogram=True) detectorCount = sumolib.miscutils.Statistics("route detector count", histogram=True) for i, r in enumerate(usedRoutes): edgeCount.add(len(routes.unique[r]), i) detectorCount.add(len(routeUsage[r]), i) print("result %s" % edgeCount) print("result %s" % detectorCount) print(gehStats) if underflow.count() > 0: print("Warning: %s (total %s)" % (underflow, sum(underflow.values))) if overflow.count() > 0: print("Warning: %s (total %s)" % (overflow, sum(overflow.values))) if options.mismatchOut: with open(options.mismatchOut, 'w') as outf: sumolib.writeXMLHeader(outf, "$Id$") # noqa outf.write('<data>\n') outf.write(' <interval id="deficit" begin="0" end="3600">\n') for cd in countData: if len(cd.edgeTuple) == 1: outf.write( ' <edge id="%s" measuredCount="%s" deficit="%s"/>\n' % (cd.edgeTuple[0], cd.origCount, cd.count)) elif len(cd.edgeTuple) == 2: outf.write( ' <edgeRelation from="%s" to="%s" measuredCount="%s" deficit="%s"/>\n' % (cd.edgeTuple[0], cd.edgeTuple[1], cd.origCount, cd.count)) else: print( "Warning: output for edge relations with more than 2 edges not supported (%s)" % cd.edgeTuple, file=sys.stderr) outf.write(' </interval>\n') outf.write('</data>\n')
def main(options): persons = [] # (depart, xmlsnippet) for person in sumolib.xml.parse(options.plan_file, 'person'): outf = StringIO() vehIndex = 0 plan = person.plan[0] if len(plan.getChildList()) == 0: continue firstAct = plan.getChildList()[0] depart = firstAct.start_time if depart is None: depart = options.default_start attributes = person.attributes[0] if person.attributes else None # write vehicles vehicleslist = [] untillist = [] lastAct = None lastLeg = None for item in plan.getChildList(): leg = None idveh = "%s_%s" % (person.id, vehIndex) if "act" in item.name: # act or activity if lastLeg is not None: leg = lastLeg leg.dep_time = lastAct.end_time writeLeg(outf, options, idveh, leg, lastAct.link, item.link) lastLeg = None lastAct = item if item.name == "leg": if item.route is None: lastLeg = item else: leg = item writeLeg(outf, options, idveh, leg, leg.route[0].start_link, leg.route[0].end_link) if leg: untillist.append(leg.dep_time) vehicleslist.append(idveh) vehIndex = vehIndex + 1 untillist.append( lastAct.end_time if lastAct.end_time else options.default_end) # write person if not options.vehicles_only: vehIndex = 0 outf.write(' <person id="%s" depart="%s">\n' % (person.id, depart)) if attributes is not None: for attr in attributes.attribute: outf.write(' <param key="%s" value="%s"/>\n' % (attr.attr_name, attr.getText())) lastLeg = None for item in plan.getChildList(): if "act" in item.name: # act or activity if lastLeg is not None: if lastLeg.mode == "non_network_walk": pass # outf.write(' <transship to="%s"/>\n' % item.link) elif lastLeg.mode in ("walk", "transit_walk"): outf.write(' <walk to="%s"/>\n' % item.link) else: outf.write(' <ride lines="%s" to="%s"/>\n' % (vehicleslist[vehIndex], item.link)) vehIndex = vehIndex + 1 outf.write( ' <stop lane="%s_0" until="%s" actType="%s"/>\n' % (item.link, untillist[vehIndex], item.type)) if item.name == "leg": lastLeg = item outf.write(' </person>\n') persons.append((sumolib.miscutils.parseTime(depart), outf.getvalue())) persons.sort() with open(options.output_file, 'w') as outf: sumolib.writeXMLHeader(outf, root="routes") outf.write( ' <vType id="car" vClass="passenger"/>\n <vType id="bicycle" vClass="bicycle"/>\n\n' ) for depart, xml in persons: outf.write(xml) outf.write('</routes>\n') outf.close() if options.repair or options.remove_loops: args = [ "-n", options.net_file, "-r", options.output_file, "-o", options.output_file + ".repaired" ] args += ["--repair"] if options.repair else [] args += ["--remove-loops"] if options.remove_loops else [] subprocess.call([sumolib.checkBinary("duarouter")] + args)
def main(options): if options.seed: random.seed(options.seed) net = sumolib.net.readNet(options.netfile) if options.min_distance > net.getBBoxDiameter() * (options.intermediate + 1): options.intermediate = int( math.ceil(options.min_distance / net.getBBoxDiameter())) - 1 print("Warning: setting number of intermediate waypoints to %s to achieve a minimum trip length of %s in a network with diameter %.2f." % ( options.intermediate, options.min_distance, net.getBBoxDiameter())) trip_generator = buildTripGenerator(net, options) idx = 0 if options.pedestrians: # figure out which of the tripattrs belong to the <person> and which # belong to the <walk> walkattrs = ' '.join( [a for a in options.tripattrs.split() if is_walk_attribute(a)]) personattrs = ' '.join( [a for a in options.tripattrs.split() if not is_walk_attribute(a)]) def generate_one(idx): label = "%s%s" % (options.tripprefix, idx) try: source_edge, sink_edge, intermediate = trip_generator.get_trip( options.min_distance, options.max_distance, options.maxtries) via = "" if len(intermediate) > 0: via = 'via="%s" ' % ' '.join( [e.getID() for e in intermediate]) if options.pedestrians: fouttrips.write( ' <person id="%s" depart="%.2f" %s>\n' % (label, depart, personattrs)) fouttrips.write( ' <walk from="%s" to="%s" %s/>\n' % (source_edge.getID(), sink_edge.getID(), walkattrs)) fouttrips.write(' </person>\n') else: fouttrips.write(' <trip id="%s" depart="%.2f" from="%s" to="%s" %s%s/>\n' % ( label, depart, source_edge.getID(), sink_edge.getID(), via, options.tripattrs)) except Exception as exc: print(exc, file=sys.stderr) return idx + 1 with open(options.tripfile, 'w') as fouttrips: sumolib.writeXMLHeader( fouttrips, "$Id: randomTrips.py 20482 2016-04-18 20:49:42Z behrisch $") fouttrips.write("<trips>\n") if options.vehicle_class: fouttrips.write(' <vType id="%s" vClass="%s" />\n' % (options.vehicle_class, options.vehicle_class)) options.tripattrs += ' type="%s"' % options.vehicle_class depart = options.begin if trip_generator: while depart < options.end: if options.binomial is None: # generate with constant spacing idx = generate_one(idx) depart += options.period else: # draw n times from a bernouli distribution # for an average arrival rate of 1 / period prob = 1.0 / options.period / options.binomial for i in range(options.binomial): if random.random() < prob: idx = generate_one(idx) depart += 1 fouttrips.write("</trips>\n") if options.routefile: args = [DUAROUTER, '-n', options.netfile, '-t', options.tripfile, '-o', options.routefile, '--ignore-errors', '--begin', str(options.begin), '--end', str(options.end), '--no-step-log', '--no-warnings'] if options.additional is not None: args += ['--additional-files', options.additional] print("calling ", " ".join(args)) subprocess.call(args) if options.validate: print("calling route2trips") route2trips.main([options.routefile], outfile=options.tripfile) if options.weights_outprefix: trip_generator.source_generator.write_weights( options.weights_outprefix + SOURCE_SUFFIX) trip_generator.sink_generator.write_weights( options.weights_outprefix + SINK_SUFFIX) trip_generator.via_generator.write_weights( options.weights_outprefix + VIA_SUFFIX) # return wether trips could be genreated as requested return trip_generator is not None
def createTrips(options): print("generating trips...") stopsLanes = {} stopNames = {} for stop in sumolib.output.parse(options.ptstops, 'busStop'): stopsLanes[stop.id] = stop.lane if stop.name: stopNames[stop.id] = stop.attr_name trpMap = {} with codecs.open(options.trips, 'w', encoding="UTF8") as fouttrips: sumolib.writeXMLHeader( fouttrips, "$Id$", "routes") writeTypes(fouttrips, options.vtypeprefix) departTimes = [options.begin for line in sumolib.output.parse_fast(options.ptlines, 'ptLine', ['id'])] if options.randomBegin: departTimes = sorted([options.begin + int(random.random() * options.period) for t in departTimes]) lineCount = collections.defaultdict(int) typeCount = collections.defaultdict(int) numLines = 0 numStops = 0 numSkipped = 0 for trp_nr, line in enumerate(sumolib.output.parse(options.ptlines, 'ptLine', heterogeneous=True)): stop_ids = [] if not line.hasAttribute("period"): line.setAttribute("period", options.period) for stop in line.busStop: if stop.id not in stopsLanes: sys.stderr.write("Warning: skipping unknown stop '%s'\n" % stop.id) continue laneId = stopsLanes[stop.id] try: edge_id, lane_index = laneId.rsplit("_", 1) except ValueError: if options.ignoreErrors: sys.stderr.write("Warning: ignoring stop '%s' on invalid lane '%s'\n" % (stop.id, laneId)) continue else: sys.exit("Invalid lane '%s' for stop '%s'" % (laneId, stop.id)) stop_ids.append(stop.id) if options.types is not None and line.type not in options.types: if options.verbose: print("Skipping line '%s' because it has type '%s'" % (line.id, line.type)) numSkipped += 1 continue if line.hasAttribute("nightService"): if line.nightService == "only" and not options.night: if options.verbose: print("Skipping line '%s' because because it only drives at night" % (line.id)) numSkipped += 1 continue if line.nightService == "no" and options.night: if options.verbose: print("Skipping line '%s' because because it only drives during the day" % (line.id)) numSkipped += 1 continue lineRefOrig = line.line.replace(" ", "_") lineRefOrig = lineRefOrig.replace(";", "+") lineRefOrig = lineRefOrig.replace(">", "") if len(stop_ids) < options.min_stops: sys.stderr.write("Warning: skipping line '%s' (%s_%s) because it has too few stops\n" % ( line.id, line.type, lineRefOrig)) numSkipped += 1 continue lineRef = "%s:%s" % (lineRefOrig, lineCount[lineRefOrig]) lineCount[lineRefOrig] += 1 tripID = "%s_%s_%s" % (trp_nr, line.type, lineRef) begin = departTimes[trp_nr] if options.osmRoutes and line.route is not None: edges = line.route[0].edges.split() vias = '' if len(edges) > 2: vias = ' via="%s"' % (' '.join(edges[1:-1])) fouttrips.write( (' <trip id="%s" type="%s%s" depart="%s" departLane="best" from="%s" ' + 'to="%s"%s>\n') % ( tripID, options.vtypeprefix, line.type, begin, edges[0], edges[-1], vias)) else: if len(stop_ids) == 0: sys.stderr.write("Warning: skipping line '%s' because it has no stops\n" % line.id) numSkipped += 1 continue fr, _ = stopsLanes[stop_ids[0]].rsplit("_", 1) to, _ = stopsLanes[stop_ids[-1]].rsplit("_", 1) fouttrips.write( (' <trip id="%s" type="%s%s" depart="%s" departLane="best" from="%s" ' + 'to="%s">\n') % ( tripID, options.vtypeprefix, line.type, begin, fr, to)) trpMap[tripID] = (lineRef, line.attr_name, line.completeness, line.period) for stop in stop_ids: fouttrips.write(' <stop busStop="%s" duration="%s"/>\n' % (stop, options.stopduration)) fouttrips.write(' </trip>\n') typeCount[line.type] += 1 numLines += 1 numStops += len(stop_ids) fouttrips.write("</routes>\n") if options.verbose: print("Imported %s lines with %s stops and skipped %s lines" % (numLines, numStops, numSkipped)) for lineType, count in typeCount.items(): print(" %s: %s" % (lineType, count)) print("done.") return trpMap, stopNames
def main(options): nodefile = options.prefix + ".nod.xml" edgefile = options.prefix + ".edg.xml" edg = open(edgefile, "w") sumolib.writeXMLHeader(edg, "$Id$", "edges") # noqa numNodes = 0 numEdges = 0 lastEdge = 0 edgeLine = 0 edgeID1 = "" edgeID2 = "" nodes = [] nodeEdges = defaultdict(lambda: 0) connections = {} # edge -> laneDirections for i, line in enumerate(open(options.netfile)): if i == 0: numNodes = int(line) elif i <= numNodes: nodes.append(line) elif i == numNodes + 1: numEdges = int(line) lastEdge = numNodes + 2 + numEdges * 3 edgeLine = 0 elif i < lastEdge: if edgeLine == 0: fromID, toID, length, speed, nLanes1, nLanes2, edgeID1, edgeID2 = line.split( ) nodeEdges[toID] += 1 nodeEdges[fromID] += 1 edg.write( ' <edge id="%s" from="%s" to="%s" speed="%s" numLanes="%s" length="%s"/>\n' % (edgeID1, fromID, toID, speed, nLanes1, length)) edg.write( ' <edge id="%s" from="%s" to="%s" speed="%s" numLanes="%s" length="%s"/>\n' % (edgeID2, toID, fromID, speed, nLanes2, length)) elif edgeLine == 1: connections[edgeID1] = list(map(int, line.split())) elif edgeLine == 2: connections[edgeID2] = list(map(int, line.split())) edgeLine = (edgeLine + 1) % 3 elif i == lastEdge: # extract traffic signal approach ids break edg.write('</edges>\n') edg.close() with open(nodefile, "w") as nod: sumolib.writeXMLHeader(nod, "$Id$", "nodes") # noqa for line in nodes: lat, lon, nodeID, signalized = line.split() nodeType = options.junctionType if signalized == "1": nodeType = "traffic_light" elif nodeEdges[nodeID] < 4: nodeType = "priority" nod.write(' <node id="%s" x="%s" y="%s" type="%s"/>\n' % (nodeID, lon, lat, nodeType)) nod.write('</nodes>\n') NETCONVERT = sumolib.checkBinary('netconvert') # the sample route data didn't include a single turn-around so let's not build any args = [ NETCONVERT, '-e', edgefile, '-n', nodefile, '--proj.utm', '--junctions.corner-detail', '0', '--no-turnarounds', '--no-internal-links', ] if options.ignoreCons: subprocess.call(args + ['-o', options.output]) else: # connections are encoded relative to driving direction. # We build the network once to obtain directions and then build again with the connections subprocess.call(args + [ '-o', options.tmp, '--no-warnings', ]) net = sumolib.net.readNet(options.tmp) connfile = options.prefix + ".con.xml" con = open(connfile, "w") sumolib.writeXMLHeader(con, "$Id$", "connections") # noqa for edgeID in sorted(connections.keys()): edge = net.getEdge(edgeID) directionTargets = 3 * [None] directionTargetLanes = [[], [], []] targetIndex = [] for target, cons in edge.getOutgoing().items(): targetLanes = [] for c in cons: targetLanes.append(c.getToLane().getIndex()) targetIndex.append([ cons[0].getJunctionIndex(), target.getID(), targetLanes, cons[0].getDirection() ]) targetIndex.sort() numTargets = len(targetIndex) if numTargets == 1: # interpret the single target as "straight" targetIndex = [[None] * 4] + targetIndex elif numTargets == 2: if targetIndex[0][-1] == 's': targetIndex.insert(0, [None] * 4) elif targetIndex[1][-1] != 's': targetIndex.insert(1, [None] * 4) # check which direction is missing for i, [linkIndex, target, targetLanes, targetDir] in enumerate(targetIndex): if i == 3: break directionTargets[i] = target directionTargetLanes[i] = targetLanes code = connections[edgeID] lanes = edge.getLanes() assert (len(code) == len(lanes) * 3) for laneIndex, lane in enumerate(lanes): for index in [0, 1, 2]: if code[3 * laneIndex + index] == 1: if directionTargets[index] is not None: # target lane is not specified, we resuse the target lanes from sumo targetLanes = directionTargetLanes[index] toLane = targetLanes[0] if len(targetLanes) > 1: directionTargetLanes[index] = targetLanes[1:] con.write( ' <connection from="%s" to="%s" fromLane="%s" toLane="%s"/>\n' % (edgeID, directionTargets[index], laneIndex, toLane)) # else: # sys.stderr.write("Warning: Could not find target from edge %s laneIndex %s for direction index %s\n" % (edgeID, laneIndex, index)) # noqa con.write('</connections>\n') con.close() subprocess.call(args + ['-o', options.output, '-x', connfile]) print("Built network with %s nodes and %s edges" % (numNodes, numEdges * 2))
def main(): options = get_options() print("generating trips...") net = sumolib.net.readNet(options.netfile) stopsLanes = {} for stop in sumolib.output.parse_fast(options.ptstops, 'busStop', ['id', 'lane']): stopsLanes[stop.id] = stop.lane trpIDLineMap = {} with open(options.trips, 'w') as fouttrips: sumolib.writeXMLHeader( fouttrips, "$Id: ptlines2flows.py 26004 2017-09-13 12:18:02Z namdre $", "routes") trp_nr = 0 for line in sumolib.output.parse(options.ptlines, 'ptLine'): stops = line._child_dict['busStop'] fr = '' stop_ids = [] for stop in stops: laneId = stopsLanes[stop.id] edge_id, lane_index = laneId.rsplit("_", 1) if fr == '': fr = edge_id dep_lane = laneId to = edge_id edge = net.getEdge(edge_id) stop_ids.append(stop.id) if options.osmRoutes and 'route' in line._child_dict: route = line._child_dict['route'] edges = route[0].edges.split(' ') lenE = len(edges) if (lenE > 3): vias = ' '.join(edges[0:lenE]) fouttrips.write( '\t<trip id="%s" depart="0" departLane="%s" from="%s" to="%s" via="%s">\n' % (trp_nr, 'best', fr, to, vias)) else: fouttrips.write( '\t<trip id="%s" depart="0" departLane="%s" from="%s" to="%s" >\n' % (trp_nr, 'best', fr, to)) else: fouttrips.write( '\t<trip id="%s" depart="0" departLane="%s" from="%s" to="%s" >\n' % (trp_nr, 'best', fr, to)) trpIDLineMap[str(trp_nr)] = line.line trp_nr += 1 for stop in stop_ids: fouttrips.write('\t\t<stop busStop="%s" duration="30" />\n' % (stop)) fouttrips.write('\t</trip>\n') fouttrips.write("</routes>\n") print("done.") print("running SUMO to dertermine actual departure times...") subprocess.call([ sumolib.checkBinary("sumo"), "-r", options.trips, "-n", options.netfile, "--no-step-log", "-a", options.ptstops, "--vehroute-output", options.routes, "--stop-output", options.stopinfos, ]) print("done.") print("creating routes...") stopsUntil = {} for stop in sumolib.output.parse_fast(options.stopinfos, 'stopinfo', ['id', 'ended', 'busStop']): stopsUntil[stop.busStop] = stop.ended with open(options.outfile, 'w') as foutflows: flows = [] sumolib.writeXMLHeader( foutflows, "$Id: ptlines2flows.py 26004 2017-09-13 12:18:02Z namdre $", "routes") foutflows.write('\t<vType id="bus" vClass="bus" />\n') for vehicle in sumolib.output.parse(options.routes, 'vehicle'): id = vehicle.id flows.append(id) edges = vehicle.routeDistribution[0]._child_dict['route'][1].edges stops = vehicle.stop foutflows.write('\t<route id="%s" edges="%s" >\n' % (id, edges)) for stop in stops: foutflows.write( '\t\t<stop busStop="%s" duration="%s" until="%s" />\n' % (stop.busStop, stop.duration, stopsUntil[stop.busStop])) foutflows.write('\t</route>\n') for flow in flows: lineRef = trpIDLineMap[flow] foutflows.write( '\t<flow id="%s" route="%s" begin="%s" end="%s" period="%s" type="bus" line="%s"/>\n' % (flow, flow, options.begin, options.end, options.period, lineRef)) foutflows.write('</routes>\n') print("done.")
def main(options): if options.seed: random.seed(options.seed) # store which routes are passing each counting location (using route index) routes = [ r.edges.split() for r in sumolib.xml.parse(options.routeFile, 'route') ] countData = ( parseTurnCounts(options.turnFile, routes, options.turnAttr) + parseEdgeCounts(options.edgeDataFile, routes, options.edgeDataAttr)) # store which counting locations are used by each route (using countData index) routeUsage = [set() for r in routes] for i, cd in enumerate(countData): for routeIndex in cd.routeSet: routeUsage[routeIndex].add(i) if options.verbose: edgeCount = sumolib.miscutils.Statistics("route edge count", histogram=True) detectorCount = sumolib.miscutils.Statistics("route detector count", histogram=True) for i, edges in enumerate(routes): edgeCount.add(len(edges), i) detectorCount.add(len(routeUsage[i]), i) print("input %s" % edgeCount) print("input %s" % detectorCount) # pick a random couting location and select a new route that passes it until # all counts are satisfied or no routes can be used anymore openRoutes = set(range(0, len(routes))) openCounts = set(range(0, len(countData))) openRoutes = updateOpenRoutes(openRoutes, routeUsage, countData) openCounts = updateOpenCounts(openCounts, countData, openRoutes) usedRoutes = [] if options.optimizeInput: for routeIndex in range(len(routes)): usedRoutes.append(routeIndex) for dataIndex in routeUsage[routeIndex]: countData[dataIndex].count -= 1 else: while openCounts: cd = countData[random.sample(openCounts, 1)[0]] routeIndex = random.sample(cd.routeSet.intersection(openRoutes), 1)[0] usedRoutes.append(routeIndex) for dataIndex in routeUsage[routeIndex]: countData[dataIndex].count -= 1 openRoutes = updateOpenRoutes(openRoutes, routeUsage, countData) openCounts = updateOpenCounts(openCounts, countData, openRoutes) hasMismatch = sum([cd.count for cd in countData]) > 0 if hasMismatch and options.optimize is not None: optimize(options.optimize, countData, routes, usedRoutes, routeUsage) begin, end = parseTimeRange(options.turnFile + options.edgeDataFile) with open(options.out, 'w') as outf: sumolib.writeXMLHeader(outf, "$Id$", "routes") # noqa period = (end - begin) / len(usedRoutes) depart = begin for i, routeIndex in enumerate(usedRoutes): outf.write(' <vehicle id="%s%s" depart="%s"%s>\n' % (options.prefix, i, depart, options.vehattrs)) outf.write(' <route edges="%s"/>\n' % ' '.join(routes[routeIndex])) outf.write(' </vehicle>\n') depart += period outf.write('</routes>\n') underflow = sumolib.miscutils.Statistics("underflow locations") overflow = sumolib.miscutils.Statistics("overflow locations") totalCount = 0 for cd in countData: totalCount += cd.origCount - cd.count if cd.count > 0: underflow.add(cd.count, cd.edgeTuple) elif cd.count < 0: overflow.add(cd.count, cd.edgeTuple) print( "Wrote %s routes (%s distinct) achieving total count %s at %s locations" % (len(usedRoutes), len(set(usedRoutes)), totalCount, len(countData))) if options.verbose: edgeCount = sumolib.miscutils.Statistics("route edge count", histogram=True) detectorCount = sumolib.miscutils.Statistics("route detector count", histogram=True) for i, r in enumerate(usedRoutes): edgeCount.add(len(routes[r]), i) detectorCount.add(len(routeUsage[r]), i) print("result %s" % edgeCount) print("result %s" % detectorCount) if underflow.count() > 0: print("Warning: %s (total %s)" % (underflow, sum(underflow.values))) if overflow.count() > 0: print("Warning: %s (total %s)" % (overflow, sum(overflow.values))) if options.mismatchOut: with open(options.mismatchOut, 'w') as outf: sumolib.writeXMLHeader(outf, "$Id$") # noqa outf.write('<data>\n') outf.write(' <interval id="deficit" begin="0" end="3600">\n') for cd in countData: if len(cd.edgeTuple) == 1: outf.write( ' <edge id="%s" measuredCount="%s" deficit="%s"/>\n' % (cd.edgeTuple[0], cd.origCount, cd.count)) elif len(cd.edgeTuple) == 2: outf.write( ' <edgeRelation from="%s" to="%s" measuredCount="%s" deficit="%s"/>\n' % (cd.edgeTuple[0], cd.edgeTuple[1], cd.origCount, cd.count)) else: print( "Warning: output for edge relations with more than 2 edges not supported (%s)" % cd.edgeTuple, file=sys.stderr) outf.write(' </interval>\n') outf.write('</data>\n')