def build(self): # output name for the osm file, will be used by osmBuild, can be # deleted after the process self.filename("osm", "_bbox.osm.xml") # output name for the net file, will be used by osmBuild, randomTrips and # sumo-gui self.filename("net", ".net.xml") if 'osm' in self.data: # testing mode shutil.copy(data['osm'], self.files["osm"]) else: self.report("Downloading map data") osmGet.get( ["-b", ",".join(map(str, self.data["coords"])), "-p", self.prefix, "-d", self.tmp]) options = ["-f", self.files["osm"], "-p", self.prefix, "-d", self.tmp] self.additionalFiles = [] self.routenames = [] if self.data["poly"]: # output name for the poly file, will be used by osmBuild and # sumo-gui self.filename("poly", ".poly.xml") options += ["-m", typemaps["poly"]] self.additionalFiles.append(self.files["poly"]) typefiles = [typemaps["net"]] netconvertOptions = osmBuild.DEFAULT_NETCONVERT_OPTS netconvertOptions += ",--tls.default-type,actuated" if "pedestrian" in self.data["vehicles"]: # sidewalks are already included via typefile netconvertOptions += ",--crossings.guess" typefiles.append(typemaps["urban"]) typefiles.append(typemaps["pedestrians"]) if "ship" in self.data["vehicles"]: typefiles.append(typemaps["ships"]) if "bicycle" in self.data["vehicles"]: typefiles.append(typemaps["bicycles"]) # special treatment for public transport if self.data["publicTransport"]: self.filename("stops", "_stops.add.xml") netconvertOptions += ",--ptstop-output,%s" % self.files["stops"] self.filename("ptlines", "_ptlines.xml") self.filename("ptroutes", "_pt.rou.xml") netconvertOptions += ",--ptline-output,%s" % self.files["ptlines"] self.additionalFiles.append(self.files["stops"]) self.routenames.append(self.files["ptroutes"]) netconvertOptions += ",--railway.topology.repair" if self.data["leftHand"]: netconvertOptions += ",--lefthand" if self.data["carOnlyNetwork"]: if self.data["publicTransport"]: options += ["--vehicle-classes", "publicTransport"] else: options += ["--vehicle-classes", "passenger"] options += ["--netconvert-typemap", ','.join(typefiles)] options += ["--netconvert-options", netconvertOptions] self.report("Converting map data") osmBuild.build(options) ptOptions = None if self.data["publicTransport"]: self.report("Generating public transport schedule") self.filename("pt_stopinfos", "stopinfos.xml", False) self.filename("pt_vehroutes", "vehroutes.xml", False) self.filename("pt_trips", "trips.trips.xml", False) ptOptions = [ "-n", self.files["net"], "-e", self.data["duration"], "-p", "600", "--random-begin", "--seed", "42", "--ptstops", self.files["stops"], "--ptlines", self.files["ptlines"], "-o", self.files["ptroutes"], "--ignore-errors", # "--no-vtypes", "--vtype-prefix", "pt_", "--stopinfos-file", self.files["pt_stopinfos"], "--routes-file", self.files["pt_vehroutes"], "--trips-file", self.files["pt_trips"], "--min-stops", "0", "--extend-to-fringe", "--verbose", ] ptlines2flows.main(ptlines2flows.get_options(ptOptions)) if self.data["decal"]: self.report("Downloading background images") tileOptions = [ "-n", self.files["net"], "-t", "100", "-d", "background_images", "-l", "-300", ] try: os.chdir(self.tmp) os.mkdir("background_images") tileGet.get(tileOptions) self.report("Success.") self.decalError = False except Exception: os.chdir(self.tmp) shutil.rmtree("background_images", ignore_errors=True) self.report("Error while downloading background images") self.decalError = True if self.data["vehicles"] or ptOptions: # routenames stores all routefiles and will join the items later, will # be used by sumo-gui randomTripsCalls = [] self.edges = sumolib.net.readNet(os.path.join(self.tmp, self.files["net"])).getEdges() for vehicle, options in self.data["vehicles"].items(): self.report("Processing %s" % vehicleNames[vehicle]) self.filename("route", ".%s.rou.xml" % vehicle) self.filename("trips", ".%s.trips.xml" % vehicle) try: options = self.parseTripOpts(vehicle, options, self.data["publicTransport"]) except ZeroDivisionError: continue if vehicle == "pedestrian" and self.data["publicTransport"]: options += ["--additional-files", ",".join([self.files["stops"], self.files["ptroutes"]])] randomTrips.main(randomTrips.get_options(options)) randomTripsCalls.append(options) # --validate is not called for pedestrians if vehicle == "pedestrian": self.routenames.append(self.files["route"]) else: self.routenames.append(self.files["trips"]) # create a batch file for reproducing calls to randomTrips.py if os.name == "posix": SUMO_HOME_VAR = "$SUMO_HOME" else: SUMO_HOME_VAR = "%SUMO_HOME%" randomTripsPath = os.path.join( SUMO_HOME_VAR, "tools", "randomTrips.py") ptlines2flowsPath = os.path.join( SUMO_HOME_VAR, "tools", "ptlines2flows.py") self.filename("build.bat", "build.bat", False) batchFile = self.files["build.bat"] with open(batchFile, 'w') as f: if os.name == "posix": f.write("#!/bin/bash\n") if ptOptions is not None: f.write("python \"%s\" %s\n" % (ptlines2flowsPath, " ".join(map(quoted_str, self.getRelative(ptOptions))))) for opts in sorted(randomTripsCalls): f.write("python \"%s\" %s\n" % (randomTripsPath, " ".join(map(quoted_str, self.getRelative(opts)))))
def build(self): # output name for the osm file, will be used by osmBuild, can be # deleted after the process self.filename("osm", "_bbox.osm.xml.gz") # output name for the net file, will be used by osmBuild, randomTrips and # sumo-gui self.filename("net", ".net.xml") if 'osm' in self.data: # testing mode self.files["osm"] = data['osm'] else: self.report("Downloading map data") osmArgs = ["-b=" + (",".join(map(str, self.data["coords"]))), "-p", self.prefix, "-d", self.tmp, "-z"] if self.data["poly"]: osmArgs.append("--shapes") if 'osmMirror' in self.data: osmArgs += ["-u", self.data["osmMirror"]] if 'roadTypes' in self.data: osmArgs += ["-r", json.dumps(self.data["roadTypes"])] osmGet.get(osmArgs) options = ["-f", self.files["osm"], "-p", self.prefix, "-d", self.tmp] self.additionalFiles = [] self.routenames = [] if self.data["poly"]: # output name for the poly file, will be used by osmBuild and sumo-gui self.filename("poly", ".poly.xml") options += ["-m", typemaps["poly"]] self.additionalFiles.append(self.files["poly"]) typefiles = [typemaps["net"]] # leading space ensures that arguments starting with -- are not # misinterpreted as options netconvertOptions = " " + osmBuild.DEFAULT_NETCONVERT_OPTS netconvertOptions += ",--tls.default-type,actuated" # netconvertOptions += ",--default.spreadtype,roadCenter" if "pedestrian" in self.data["vehicles"]: # sidewalks are already included via typefile netconvertOptions += ",--crossings.guess" netconvertOptions += ",--osm.sidewalks" typefiles.append(typemaps["urban"]) typefiles.append(typemaps["pedestrians"]) if "ship" in self.data["vehicles"]: typefiles.append(typemaps["ships"]) if "bicycle" in self.data["vehicles"]: typefiles.append(typemaps["bicycles"]) netconvertOptions += ",--osm.bike-access" # special treatment for public transport if self.data["publicTransport"]: self.filename("stops", "_stops.add.xml") netconvertOptions += ",--ptstop-output,%s" % self.files["stops"] self.filename("ptlines", "_ptlines.xml") self.filename("ptroutes", "_pt.rou.xml") netconvertOptions += ",--ptline-output,%s" % self.files["ptlines"] self.additionalFiles.append(self.files["stops"]) self.routenames.append(self.files["ptroutes"]) netconvertOptions += ",--railway.topology.repair" if self.data["leftHand"]: netconvertOptions += ",--lefthand" if self.data["decal"]: # change projection to web-mercator to match the background image projection netconvertOptions += ",--proj,+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs" # noqa if self.data["carOnlyNetwork"]: if self.data["publicTransport"]: options += ["--vehicle-classes", "publicTransport"] else: options += ["--vehicle-classes", "passenger"] options += ["--netconvert-typemap", ','.join(typefiles)] options += ["--netconvert-options", netconvertOptions] self.report("Converting map data") osmBuild.build(options) ptOptions = None if self.data["publicTransport"]: self.report("Generating public transport schedule") self.filename("pt_stopinfos", "stopinfos.xml", False) self.filename("pt_vehroutes", "vehroutes.xml", False) self.filename("pt_trips", "trips.trips.xml", False) ptOptions = [ "-n", self.files["net"], "-e", self.data["duration"], "-p", "600", "--random-begin", "--seed", "42", "--ptstops", self.files["stops"], "--ptlines", self.files["ptlines"], "-o", self.files["ptroutes"], "--ignore-errors", # "--no-vtypes", "--vtype-prefix", "pt_", "--stopinfos-file", self.files["pt_stopinfos"], "--routes-file", self.files["pt_vehroutes"], "--trips-file", self.files["pt_trips"], "--min-stops", "0", "--extend-to-fringe", "--verbose", ] ptlines2flows.main(ptlines2flows.get_options(ptOptions)) if self.data["decal"]: self.report("Downloading background images") tileOptions = [ "-n", self.files["net"], "-t", "100", "-d", "background_images", "-l", "-300", ] try: os.chdir(self.tmp) os.mkdir("background_images") tileGet.get(tileOptions) self.report("Success.") self.decalError = False except Exception: os.chdir(self.tmp) shutil.rmtree("background_images", ignore_errors=True) self.report("Error while downloading background images") self.decalError = True if self.data["vehicles"] or ptOptions: # routenames stores all routefiles and will join the items later, will # be used by sumo-gui randomTripsCalls = [] self.edges = sumolib.net.readNet(os.path.join(self.tmp, self.files["net"])).getEdges() for vehicle, options in self.data["vehicles"].items(): self.report("Processing %s" % vehicleNames[vehicle]) self.filename("route", ".%s.rou.xml" % vehicle) self.filename("trips", ".%s.trips.xml" % vehicle) try: options = self.parseTripOpts(vehicle, options, self.data["publicTransport"]) except ZeroDivisionError: continue if vehicle == "pedestrian" and self.data["publicTransport"]: options += ["--additional-files", ",".join([self.files["stops"], self.files["ptroutes"]])] options += ["--persontrip.walk-opposite-factor", "0.8"] randomTrips.main(randomTrips.get_options(options)) randomTripsCalls.append(options) # --validate is not called for pedestrians if vehicle == "pedestrian": self.routenames.append(self.files["route"]) else: self.routenames.append(self.files["trips"]) # clean up unused route file (was only used for validation) os.remove(self.files["route"]) # create a batch file for reproducing calls to randomTrips.py if os.name == "posix": SUMO_HOME_VAR = "$SUMO_HOME" else: SUMO_HOME_VAR = "%SUMO_HOME%" randomTripsPath = os.path.join(SUMO_HOME_VAR, "tools", "randomTrips.py") ptlines2flowsPath = os.path.join(SUMO_HOME_VAR, "tools", "ptlines2flows.py") self.filename("build.bat", "build.bat", False) batchFile = self.files["build.bat"] with open(batchFile, 'w') as f: if os.name == "posix": f.write("#!/bin/bash\n") if ptOptions is not None: f.write('python "%s" %s\n' % (ptlines2flowsPath, " ".join(map(quoted_str, self.getRelative(ptOptions))))) for opts in sorted(randomTripsCalls): f.write('python "%s" %s\n' % (randomTripsPath, " ".join(map(quoted_str, self.getRelative(opts))))) os.chmod(batchFile, BATCH_MODE)