eclipse-sumo / sumo

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.
https://eclipse.dev/sumo
Eclipse Public License 2.0
2.58k stars 1.44k forks source link

🚍 Bus Stop Insertion in SUMO Trips with Python 🐍 #15475

Open dominique-AR opened 2 months ago

dominique-AR commented 2 months ago

🚍 Bus Stop Insertion in SUMO Trips with Python 🐍 @namdre, @bcoueraud87

This Python script automates the insertion of bus stops into SUMO trips 🚏. It reads bus trip data and efficiently integrates stops into the routes, saving time and effort in transit simulations. While it works, there's room for improvement! Contributions to enhance performance, stop logic, or any other features are welcome 🚀.

import os
import xml.etree.ElementTree as ET
from config import ROUTE_FOLDER, STOPS_FILE, DURATION, OUTPUT_FOLDER
import tkinter as tk
from tkinter import messagebox

def show_messagebox(success=True):
    """ Affiche une boîte de message pour indiquer le succès ou l'échec. """
    root = tk.Tk()
    root.withdraw()  # Masquer la fenêtre principale
    if success:
        messagebox.showinfo("Succès", "L'intégration des arrêts de bus a été effectuée avec succès.")
    else:
        messagebox.showerror("Erreur", "Une erreur est survenue lors de l'intégration des arrêts de bus.")
    root.destroy()

def integrate_stops_to_all_files(route_folder, stops_file, duration, output_folder):
    try:
        stops_tree = ET.parse(stops_file)
        stops_root = stops_tree.getroot()

        # Parcourir chaque fichier dans le dossier des itinéraires
        for filename in os.listdir(route_folder):
            if filename.endswith(".xml"):
                route_file = os.path.join(route_folder, filename)
                tree = ET.parse(route_file)
                root = tree.getroot()

                # Traiter chaque route dans l'ordre
                for route in root.findall('.//route'):
                    edge_list = route.get('edges').split()  # Liste ordonnée des arêtes
                    last_stop = None

                    # Parcourir les arêtes dans l'ordre et ajouter les arrêts correspondants
                    for edge in edge_list:
                        # Parcourir les arrêts de bus et comparer avec les arêtes
                        for stop in stops_root.findall('.//busStop'):
                            lane_id = stop.get('lane').split('_')[0]
                            if lane_id == edge:
                                # Créer un nouvel élément stop avec l'ID récupéré du busStop
                                new_stop = ET.Element('stop', busStop=stop.get('id'), duration=str(duration))
                                route.append(new_stop)
                                new_stop.tail = '\n'
                                last_stop = new_stop

                    # Ajouter un retour à la ligne après le dernier arrêt
                    if last_stop is not None:
                        last_stop.tail = '\n\t'

                # Sauvegarder les modifications dans un nouveau fichier XML dans le dossier de sortie
                output_file = os.path.join(output_folder, f"modified_{filename}")
                tree.write(output_file)

        # Afficher une boîte de dialogue de confirmation de succès
        show_messagebox(success=True)

    except Exception as e:
        print(f"Erreur : {e}")
        show_messagebox(success=False)

# Appeler la fonction avec les paramètres importés
integrate_stops_to_all_files(ROUTE_FOLDER, STOPS_FILE, DURATION, OUTPUT_FOLDER)
behrisch commented 2 months ago

Thanks for this one! @dominique-AR Can you maybe submit it as a pull request so that we can make sure, that the paperwork (https://sumo.dlr.de/docs/FAQ.html#how_do_code_contributions_work) has been done? Thank you in advance!