Eclipse SUMO is an open source, highly portable, microscopic and continuous traffic simulation package designed to handle large networks. It allows for intermodal simulation including pedestrians and comes with a large set of tools for scenario creation.
I've developed a Python script to convert polylines in XML format to routes with edges using a SUMO network definition. I'd like to request a review of this code to ensure it's correct and follows best practices for working with SUMO.
Code Overview:
The script does the following:
Parses command-line arguments for input files (network and polyline XML) and output file.
Loads a SUMO network file.
Parses an XML file containing polylines.
For each polyline, finds the nearest edges in the network to create a route.
Writes the resulting routes to an output XML file.
Key ### Objects and Functions:
sumolib.net.Net: The SUMO network object, loaded from the network file.
sumolib.net.Edge: Represents edges in the SUMO network.
find_closest_edge(net, point, threshold): Finds the nearest edge to a given point.
polyline_to_route(net, shape, threshold): Converts a polyline shape to a sequence of edges.
parse_polylines(polyfile): Parses the input XML file to extract polyline shapes.
Questions:
Is the approach of finding the closest edge for each point in the polyline correct? Are there potential issues with this method?
Are there any SUMO-specific considerations or functions I should be using that I've overlooked?
Is the use of sumolib appropriate and efficient?
Are there any edge cases or scenarios where this script might fail or produce incorrect results?
Is the XML parsing and writing implemented correctly?
Additional Context:
This script is intended to be a reverse operation of the route2poly.py script provided in the SUMO tools. Any insights on how to make it more consistent with SUMO's approach would be greatly appreciated.
Here the code :
`#!/usr/bin/env python
import sys
import os
from optparse import OptionParser
from xml.etree import ElementTree as ET
if 'SUMO_HOME' in os.environ:
sys.path.append(os.path.join(os.environ['SUMO_HOME'], 'tools'))
else:
sys.exit("Please declare environment variable 'SUMO_HOME'")
import sumolib
def parse_args():
parser = OptionParser()
parser.add_option("-n", "--net-file", dest="netfile",
help="SUMO network file", metavar="FILE")
parser.add_option("-p", "--poly-file", dest="polyfile",
help="Input polyline XML file", metavar="FILE")
parser.add_option("-o", "--output-file", dest="outfile",
help="Output route file", metavar="FILE")
parser.add_option("-t", "--threshold", dest="threshold", type="float", default=10,
help="Distance threshold for edge matching (default: 10 meters)")
(options, args) = parser.parse_args()
if not options.netfile or not options.polyfile or not options.outfile:
parser.error("All three files (net, poly, and output) are required.")
return options
def load_net(netfile):
return sumolib.net.readNet(netfile)
def find_closest_edge(net, point, threshold):
x, y = point
edges = net.getNeighboringEdges(x, y, threshold)
if not edges:
return None
return min(edges, key=lambda x: x[1])[0]
def polyline_to_route(net, shape, threshold):
route = []
for point in shape:
edge = find_closest_edge(net, point, threshold)
if edge and (not route or edge != route[-1]):
route.append(edge)
return route
def parse_polylines(polyfile):
tree = ET.parse(polyfile)
root = tree.getroot()
polylines = {}
for poly in root.findall('poly'):
id = poly.get('id')
shape = poly.get('shape')
points = [tuple(map(float, p.split(','))) for p in shape.split()]
polylines[id] = points
return polylines
def main():
options = parse_args()
net = load_net(options.netfile)
polylines = parse_polylines(options.polyfile)
with open(options.outfile, 'w') as outf:
outf.write('<routes>\n')
for poly_id, shape in polylines.items():
route = polyline_to_route(net, shape, options.threshold)
if route:
edge_ids = ' '.join(edge.getID() for edge in route)
outf.write(f' <route id="{poly_id}" edges="{edge_ids}"/>\n')
else:
print(f"Warning: Could not create route for polyline {poly_id}")
outf.write('</routes>\n')
print(f"Routes have been written to {options.outfile}")
if __name__ == "__main__":
main()`
Hi everyone, @bcoueraud87 @namdre 😃
Description:
I've developed a Python script to convert polylines in XML format to routes with edges using a SUMO network definition. I'd like to request a review of this code to ensure it's correct and follows best practices for working with SUMO.
Code Overview:
The script does the following:
Key ### Objects and Functions:
Questions:
Additional Context:
This script is intended to be a reverse operation of the route2poly.py script provided in the SUMO tools. Any insights on how to make it more consistent with SUMO's approach would be greatly appreciated.
Here the code :