sumolib
1# -*- coding: utf-8 -*- 2# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo 3# Copyright (C) 2011-2026 German Aerospace Center (DLR) and others. 4# This program and the accompanying materials are made available under the 5# terms of the Eclipse Public License 2.0 which is available at 6# https://www.eclipse.org/legal/epl-2.0/ 7# This Source Code may also be made available under the following Secondary 8# Licenses when the conditions for such availability set forth in the Eclipse 9# Public License 2.0 are satisfied: GNU General Public License, version 2 10# or later which is available at 11# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html 12# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later 13 14# @file __init__.py 15# @author Daniel Krajzewicz 16# @author Jakob Erdmann 17# @author Michael Behrisch 18# @date 2011-06-23 19 20from __future__ import absolute_import 21import os 22import sys 23import subprocess 24import warnings 25 26from . import files, net, output, sensors, shapes, statistics, fpdiff # noqa 27from . import color, geomhelper, miscutils, options, route, vehicletype, version # noqa 28# the visualization submodule is not imported to avoid an explicit matplotlib dependency 29from .miscutils import openz 30from .options import pullOptions, ArgumentParser 31from .version import _version as __version__ # noqa 32from .xml import writeHeader as writeXMLHeader # noqa 33 34 35def saveConfiguration(executable, configoptions, filename): 36 configoptions.save_configuration = filename 37 call(executable, configoptions) 38 39 40def call(executable, args): 41 ap = ArgumentParser() 42 pullOptions(executable, ap) 43 cmd = [executable] 44 for option, value in args.__dict__.items(): 45 o = "--" + option.replace("_", "-") 46 if value is not None: 47 a = ap.get_option(option) 48 if a is not None and a.default != value: 49 cmd.append(o) 50 cmd.append(str(value)) 51 return subprocess.call(cmd) 52 53 54def checkBinary(name, bindir=None): 55 """ 56 Checks for the given binary in the places, defined by the environment 57 variables SUMO_HOME and <NAME>_BINARY. 58 """ 59 60 def exe(binary): 61 return binary + ".exe" if os.name == "nt" and binary[-4:] != ".exe" else binary 62 63 envName = "GUISIM_BINARY" if name == "sumo-gui" else name.upper() + "_BINARY" 64 env = os.environ 65 if envName in env and os.path.exists(exe(env[envName])): 66 return exe(env[envName]) 67 if bindir is not None: 68 binary = exe(os.path.join(bindir, name)) 69 if os.path.exists(binary): 70 return binary 71 if "SUMO_HOME" in env: 72 binary = exe(os.path.join(env.get("SUMO_HOME"), "bin", name)) 73 if os.path.exists(binary): 74 return binary 75 try: 76 import sumo 77 # If there is a directory "sumo" in the current path, the import will succeed, so we need to double check. 78 if hasattr(sumo, "SUMO_HOME"): 79 binary = exe(os.path.join(sumo.SUMO_HOME, "bin", name)) 80 if os.path.exists(binary): 81 return binary 82 except ImportError: 83 pass 84 if bindir is None: 85 binary = exe(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', 'bin', name))) 86 if os.path.exists(binary): 87 return binary 88 if name[-1] != "D" and name[-5:] != "D.exe": 89 binaryD = (name[:-4] if name[-4:] == ".exe" else name) + "D" 90 found = checkBinary(binaryD, bindir) 91 if found != binaryD: 92 return found 93 return name 94 95 96class _Running: 97 98 """ 99 A generator of running, numerical IDs 100 Should be enhanced by: 101 - a member method for returning the size 102 - a member iterator over the stored ids 103 """ 104 105 def __init__(self, orig_ids=False, warn=False): 106 """Contructor""" 107 # whether original IDs shall be used instead of an index 108 self.orig_ids = orig_ids 109 # whether a warning for non-integer IDs shall be given 110 self.warn = warn 111 # running index of assigned numerical IDs 112 self.index = 0 113 # map from known IDs to assigned numerical IDs 114 self._m = {} 115 116 def g(self, id): 117 """ 118 If the given id is known, the numerical representation is returned, 119 otherwise a new running number is assigned to the id and returned""" 120 if id not in self._m: 121 if self.orig_ids: 122 self._m[id] = id 123 if self.warn: 124 try: 125 int(id) 126 except ValueError: 127 sys.stderr.write( 128 'Warning: ID "%s" is not an integer.\n' % id) 129 self.warn = False 130 else: 131 self._m[id] = self.index 132 self.index += 1 133 return self._m[id] 134 135 def k(self, id): 136 """ 137 Returns whether the given id is known.""" 138 return id in self._m 139 140 def d(self, id): 141 """ 142 Removed the element.""" 143 del self._m[id] 144 145 146class TeeFile: 147 148 """A helper class which allows simultaneous writes to several files""" 149 150 def __init__(self, *outputfiles): 151 self.files = outputfiles 152 153 def write(self, txt): 154 """Writes the text to all files""" 155 for fp in self.files: 156 fp.write(txt) 157 158 def flush(self): 159 """flushes all file contents to disc""" 160 for fp in self.files: 161 fp.flush() 162 if isinstance(fp, int) or hasattr(fp, "fileno"): 163 try: 164 os.fsync(fp) 165 except OSError: 166 pass 167 168 def close(self): 169 """closes all closable outputs""" 170 for fp in self.files: 171 if fp not in (sys.__stdout__, sys.__stderr__) and hasattr(fp, "close"): 172 fp.close() 173 174 175def _intTime(tStr): 176 """ 177 Converts a time given as a string containing a float into an integer representation. 178 """ 179 return int(float(tStr)) 180 181 182def _laneID2edgeID(laneID): 183 return laneID[:laneID.rfind("_")] 184 185 186def open(fileOrURL, tryGZip=True, mode="rb"): 187 warnings.warn("sumolib.open is deprecated, due to the name clash and strange signature! " 188 "Use sumolib.miscutils.openz instead.") 189 return openz(fileOrURL, mode, tryGZip=tryGZip)
def
saveConfiguration(executable, configoptions, filename):
def
call(executable, args):
41def call(executable, args): 42 ap = ArgumentParser() 43 pullOptions(executable, ap) 44 cmd = [executable] 45 for option, value in args.__dict__.items(): 46 o = "--" + option.replace("_", "-") 47 if value is not None: 48 a = ap.get_option(option) 49 if a is not None and a.default != value: 50 cmd.append(o) 51 cmd.append(str(value)) 52 return subprocess.call(cmd)
def
checkBinary(name, bindir=None):
55def checkBinary(name, bindir=None): 56 """ 57 Checks for the given binary in the places, defined by the environment 58 variables SUMO_HOME and <NAME>_BINARY. 59 """ 60 61 def exe(binary): 62 return binary + ".exe" if os.name == "nt" and binary[-4:] != ".exe" else binary 63 64 envName = "GUISIM_BINARY" if name == "sumo-gui" else name.upper() + "_BINARY" 65 env = os.environ 66 if envName in env and os.path.exists(exe(env[envName])): 67 return exe(env[envName]) 68 if bindir is not None: 69 binary = exe(os.path.join(bindir, name)) 70 if os.path.exists(binary): 71 return binary 72 if "SUMO_HOME" in env: 73 binary = exe(os.path.join(env.get("SUMO_HOME"), "bin", name)) 74 if os.path.exists(binary): 75 return binary 76 try: 77 import sumo 78 # If there is a directory "sumo" in the current path, the import will succeed, so we need to double check. 79 if hasattr(sumo, "SUMO_HOME"): 80 binary = exe(os.path.join(sumo.SUMO_HOME, "bin", name)) 81 if os.path.exists(binary): 82 return binary 83 except ImportError: 84 pass 85 if bindir is None: 86 binary = exe(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', 'bin', name))) 87 if os.path.exists(binary): 88 return binary 89 if name[-1] != "D" and name[-5:] != "D.exe": 90 binaryD = (name[:-4] if name[-4:] == ".exe" else name) + "D" 91 found = checkBinary(binaryD, bindir) 92 if found != binaryD: 93 return found 94 return name
Checks for the given binary in the places, defined by the environment
variables SUMO_HOME and
class
TeeFile:
147class TeeFile: 148 149 """A helper class which allows simultaneous writes to several files""" 150 151 def __init__(self, *outputfiles): 152 self.files = outputfiles 153 154 def write(self, txt): 155 """Writes the text to all files""" 156 for fp in self.files: 157 fp.write(txt) 158 159 def flush(self): 160 """flushes all file contents to disc""" 161 for fp in self.files: 162 fp.flush() 163 if isinstance(fp, int) or hasattr(fp, "fileno"): 164 try: 165 os.fsync(fp) 166 except OSError: 167 pass 168 169 def close(self): 170 """closes all closable outputs""" 171 for fp in self.files: 172 if fp not in (sys.__stdout__, sys.__stderr__) and hasattr(fp, "close"): 173 fp.close()
A helper class which allows simultaneous writes to several files
def
write(self, txt):
154 def write(self, txt): 155 """Writes the text to all files""" 156 for fp in self.files: 157 fp.write(txt)
Writes the text to all files
def
open(fileOrURL, tryGZip=True, mode='rb'):