Skip to content

Commit

Permalink
adding py files to create public transit
Browse files Browse the repository at this point in the history
  • Loading branch information
mkreuschner committed Oct 31, 2024
1 parent 0ab5353 commit dff3f4e
Show file tree
Hide file tree
Showing 2 changed files with 168 additions and 0 deletions.
94 changes: 94 additions & 0 deletions src/main/python/create_transitVehicles.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import xml.etree.ElementTree as ET
import xml.dom.minidom as minidom
import csv

# Define the namespaces
namespaces = {
None: "http://www.matsim.org/files/dtd", # Default namespace
"xsi": "http://www.w3.org/2001/XMLSchema-instance"
}

# Create the root element with namespaces
root = ET.Element('vehicleDefinitions', {
"xmlns": namespaces[None],
"xmlns:xsi": namespaces["xsi"],
"xsi:schemaLocation": "http://www.matsim.org/files/dtd http://www.matsim.org/files/dtd/vehicleDefinitions_v2.0.xsd"
})

# Function to add a new vehicle type based on data from the CSV file
def add_vehicle_type_from_csv(csv_file):
with open(csv_file, newline='') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
# Read parameters from the CSV row
vehicle_id = row['vehicle_id']
access_time = float(row['access_time'])
door_operation = row['door_operation']
egress_time = float(row['egress_time'])
seats = int(row['seats'])
standing_room = int(row['standing_room'])
length = float(row['length'])
width = float(row['width'])
engine_info = row['engine_info'].lower() == 'true' # Convert to boolean

# Create vehicle type element
vehicle_type = ET.Element('vehicleType', id=vehicle_id)

# Attributes for vehicle type
attributes = ET.SubElement(vehicle_type, 'attributes')
ET.SubElement(attributes, 'attribute', attrib={"name": "accessTimeInSecondsPerPerson", "class": "java.lang.Double"}).text = str(access_time)
ET.SubElement(attributes, 'attribute', attrib={"name": "doorOperationMode", "class": "org.matsim.vehicles.VehicleType$DoorOperationMode"}).text = door_operation
ET.SubElement(attributes, 'attribute', attrib={"name": "egressTimeInSecondsPerPerson", "class": "java.lang.Double"}).text = str(egress_time)

# Capacity, length, width, and other elements
ET.SubElement(vehicle_type, 'capacity', seats=str(seats), standingRoomInPersons=str(standing_room))
ET.SubElement(vehicle_type, 'length', meter=str(length))
ET.SubElement(vehicle_type, 'width', meter=str(width))

# Engine Information (optional)
if engine_info:
engine_information = ET.SubElement(vehicle_type, 'engineInformation')
engine_attributes = ET.SubElement(engine_information, 'attributes')
ET.SubElement(engine_attributes, 'attribute', attrib={"name": "HbefaEmissionsConcept", "class": "java.lang.String"}).text = "average"
ET.SubElement(engine_attributes, 'attribute', attrib={"name": "HbefaSizeClass", "class": "java.lang.String"}).text = "average"
ET.SubElement(engine_attributes, 'attribute', attrib={"name": "HbefaTechnology", "class": "java.lang.String"}).text = "average"
ET.SubElement(engine_attributes, 'attribute', attrib={"name": "HbefaVehicleCategory", "class": "java.lang.String"}).text = "NON_HBEFA_VEHICLE"

# Remaining elements
ET.SubElement(vehicle_type, 'costInformation')
ET.SubElement(vehicle_type, 'passengerCarEquivalents', pce="1.0")
ET.SubElement(vehicle_type, 'networkMode', networkMode="car")
ET.SubElement(vehicle_type, 'flowEfficiencyFactor', factor="1.0")

# Append the completed vehicleType to root
root.append(vehicle_type)

# Function to add vehicles from CSV data
def add_vehicles_from_csv(csv_file):
with open(csv_file, newline='') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
operator = row['operator']
line_number = row['line_number']
vehicle_count = int(row['vehicle_count'])
vehicle_type = row['vehicle_type']

for i in range(vehicle_count):
vehicle_id = f"pt_{operator}-{line_number}-{i}"
vehicle = ET.Element('vehicle', id=vehicle_id, type=vehicle_type)
root.append(vehicle)

# Example usage:
# Load vehicle types and vehicles from CSV
add_vehicle_type_from_csv('/Users/mkreuschnervsp/Desktop/kyoto_vehicle_types.csv')
add_vehicles_from_csv('/Users/mkreuschnervsp/Desktop/kyoto_vehicles.csv')

# Function to prettify and save the XML
def save_pretty_xml(element, filename):
xml_string = ET.tostring(element, encoding='utf-8')
pretty_xml = minidom.parseString(xml_string).toprettyxml(indent=" ")
with open(filename, "w", encoding="utf-8") as file:
file.write(pretty_xml)

# Save the prettified XML to a file
save_pretty_xml(root, '/Users/mkreuschnervsp/Desktop/matsim-kyoto_transitVehicles_pretty.xml')
74 changes: 74 additions & 0 deletions src/main/python/merge_transitSchedule.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import xml.etree.ElementTree as ET

def merge_transit_schedules(file1, file2, output_file):
# Parse the XML files
tree1 = ET.parse(file1)
root1 = tree1.getroot()

tree2 = ET.parse(file2)
root2 = tree2.getroot()

# Create a new root for the merged document
merged_root = ET.Element("transitSchedule")

# Copy <attributes> from the first file
attributes1 = root1.find("attributes")
if attributes1 is not None:
merged_root.append(attributes1)

# Merge <transitStops>
transitStops = ET.Element("transitStops")
merged_root.append(transitStops)
stop_ids = set()

def merge_stops(root, stop_ids, transitStops):
for stop in root.findall(".//stopFacility"):
stop_id = stop.get("id")
if stop_id not in stop_ids:
stop_ids.add(stop_id)
transitStops.append(stop)

# Apply merging of stops from both files
merge_stops(root1, stop_ids, transitStops)
merge_stops(root2, stop_ids, transitStops)

# Merge <transitLines>
transitLines = ET.Element("transitLines")
merged_root.append(transitLines)
line_ids = set()

def merge_lines(root, line_ids, transitLines):
for line in root.findall(".//transitLine"):
line_id = line.get("id")
if line_id not in line_ids:
line_ids.add(line_id)
transitLines.append(line)
else:
# If the line already exists, merge its routes
existing_line = [l for l in transitLines if l.get("id") == line_id][0]
route_ids = {r.get("id") for r in existing_line.findall(".//transitRoute")}

for route in line.findall("transitRoute"):
route_id = route.get("id")
if route_id not in route_ids:
route_ids.add(route_id)
existing_line.append(route)

# Apply merging of lines and routes from both files
merge_lines(root1, line_ids, transitLines)
merge_lines(root2, line_ids, transitLines)

# Save the merged XML to the output file
merged_tree = ET.ElementTree(merged_root)
merged_tree.write(output_file, encoding="utf-8", xml_declaration=True)
print(f"Merge complete. Output saved to {output_file}")

# Paths to your input files and output file
file1 = "/Users/mkreuschnervsp/git/matsim-kyoto/input/kyotobus-transitSchedule.xml"
file2 = "/Users/mkreuschnervsp/git/matsim-kyoto/input/kyotocitybus-transitSchedule.xml"
output_file = "/Users/mkreuschnervsp/git/matsim-kyoto/input/mergedKyoto-transitSchedule.xml"

merge_transit_schedules(file1, file2, output_file)



0 comments on commit dff3f4e

Please sign in to comment.