Finish base code and keep input building file and network file
This commit is contained in:
parent
f691449d42
commit
7c15ee4399
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -3,6 +3,9 @@
|
|||
# Ignore files that start with 'building' in the 'input_files' directory
|
||||
input_files/*
|
||||
|
||||
!input_files/merged-network.osm.pbf
|
||||
!input_files/summerschool_all_buildings.geojson
|
||||
|
||||
# Ignore all files inside the 'output_files' directory
|
||||
output_files/*
|
||||
output/*
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,78 +0,0 @@
|
|||
import hub.helpers.constants as cte
|
||||
|
||||
class HubFunctionToMatsimActivity:
|
||||
"""
|
||||
Hub function to matsim activity construction function class
|
||||
"""
|
||||
def __init__(self):
|
||||
self._dictionary = {
|
||||
cte.RESIDENTIAL: 'home',
|
||||
cte.SINGLE_FAMILY_HOUSE: 'home',
|
||||
cte.MULTI_FAMILY_HOUSE: 'home',
|
||||
cte.ROW_HOUSE: 'home',
|
||||
cte.MID_RISE_APARTMENT: 'home',
|
||||
cte.HIGH_RISE_APARTMENT: 'home',
|
||||
cte.OFFICE_AND_ADMINISTRATION: 'work',
|
||||
cte.SMALL_OFFICE: 'work',
|
||||
cte.MEDIUM_OFFICE: 'work',
|
||||
cte.LARGE_OFFICE: 'work',
|
||||
cte.COURTHOUSE: 'work',
|
||||
cte.FIRE_STATION: 'work',
|
||||
cte.PENITENTIARY: 'work',
|
||||
cte.POLICE_STATION: 'work',
|
||||
cte.POST_OFFICE: 'work',
|
||||
cte.LIBRARY: 'edu',
|
||||
cte.EDUCATION: 'edu',
|
||||
cte.PRIMARY_SCHOOL: 'edu',
|
||||
cte.PRIMARY_SCHOOL_WITH_SHOWER: 'edu',
|
||||
cte.SECONDARY_SCHOOL: 'edu',
|
||||
cte.UNIVERSITY: 'edu',
|
||||
cte.LABORATORY_AND_RESEARCH_CENTER: 'edu',
|
||||
cte.STAND_ALONE_RETAIL: 'work,secondary',
|
||||
cte.HOSPITAL: 'work',
|
||||
cte.OUT_PATIENT_HEALTH_CARE: 'work',
|
||||
cte.HEALTH_CARE: 'work',
|
||||
cte.RETIREMENT_HOME_OR_ORPHANAGE: 'home,secondary',
|
||||
cte.COMMERCIAL: 'work,secondary',
|
||||
cte.STRIP_MALL: 'work,secondary',
|
||||
cte.SUPERMARKET: 'work,secondary',
|
||||
cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD: 'work,secondary',
|
||||
cte.RETAIL_SHOP_WITH_REFRIGERATED_FOOD: 'work,secondary',
|
||||
cte.RESTAURANT: 'work,secondary',
|
||||
cte.QUICK_SERVICE_RESTAURANT: 'work,secondary',
|
||||
cte.FULL_SERVICE_RESTAURANT: 'work,secondary',
|
||||
cte.HOTEL: 'work,secondary',
|
||||
cte.HOTEL_MEDIUM_CLASS: 'work,secondary',
|
||||
cte.SMALL_HOTEL: 'work,secondary',
|
||||
cte.LARGE_HOTEL: 'work,secondary',
|
||||
cte.DORMITORY: 'work',
|
||||
cte.EVENT_LOCATION: 'work,secondary',
|
||||
cte.CONVENTION_CENTER: 'work,secondary',
|
||||
cte.HALL: 'work',
|
||||
cte.GREEN_HOUSE: 'work',
|
||||
cte.INDUSTRY: 'work',
|
||||
cte.WORKSHOP: 'work',
|
||||
cte.WAREHOUSE: 'work',
|
||||
cte.WAREHOUSE_REFRIGERATED: 'work',
|
||||
cte.SPORTS_LOCATION: 'work,secondary',
|
||||
cte.SPORTS_ARENA: 'work,secondary',
|
||||
cte.GYMNASIUM: 'work,secondary',
|
||||
cte.MOTION_PICTURE_THEATRE: 'work,secondary',
|
||||
cte.MUSEUM: 'work,secondary',
|
||||
cte.PERFORMING_ARTS_THEATRE: 'work,secondary',
|
||||
cte.TRANSPORTATION: 'work',
|
||||
cte.AUTOMOTIVE_FACILITY: 'work',
|
||||
cte.PARKING_GARAGE: 'work',
|
||||
cte.RELIGIOUS: 'work,secondary',
|
||||
cte.NON_HEATED: 'work',
|
||||
cte.DATACENTER: 'work',
|
||||
cte.FARM: 'work'
|
||||
}
|
||||
|
||||
@property
|
||||
def dictionary(self) -> dict:
|
||||
"""
|
||||
Get the dictionary
|
||||
:return: {}
|
||||
"""
|
||||
return self._dictionary
|
BIN
input_files/merged-network.osm.pbf
Normal file
BIN
input_files/merged-network.osm.pbf
Normal file
Binary file not shown.
2473
input_files/summerschool_all_buildings.geojson
Normal file
2473
input_files/summerschool_all_buildings.geojson
Normal file
File diff suppressed because it is too large
Load Diff
7
main.py
7
main.py
|
@ -7,6 +7,7 @@ from hub.helpers.dictionaries import Dictionaries
|
|||
|
||||
from matsim_engine import MatSimEngine
|
||||
from matsim import Matsim
|
||||
from matsim_visualizer import MatsimVisualizer
|
||||
|
||||
try:
|
||||
file_path = (Path(__file__).parent / 'input_files' / 'summerschool_all_buildings.geojson')
|
||||
|
@ -24,11 +25,11 @@ try:
|
|||
ConstructionFactory(construction_format, city).enrich()
|
||||
UsageFactory(usage_format, city).enrich()
|
||||
|
||||
# Matsim(city, 'output_files')._export()
|
||||
Matsim(city, 'output_files')._export()
|
||||
MatSimEngine('output_files/Montreal_config.xml').run()
|
||||
|
||||
# visualizer = MatSimVisualizer('output_files/network.xml.gz', 'output_files/output_events.xml.gz')
|
||||
# visualizer.visualize()
|
||||
visualizer = MatsimVisualizer('output_files/Montreal/output_network.xml.gz', 'output_files/Montreal/output_events.xml.gz')
|
||||
visualizer.visualize()
|
||||
|
||||
except Exception as ex:
|
||||
print('error: ', ex)
|
||||
|
|
290
matsim.py
290
matsim.py
|
@ -13,7 +13,6 @@ FACILITIES_DTD = "http://www.matsim.org/files/dtd/facilities_v1.dtd"
|
|||
POPULATION_DTD = "http://www.matsim.org/files/dtd/population_v5.dtd"
|
||||
|
||||
|
||||
# TODO: remove xmltodict completely and replace with lxml as it doesnt allow for repeated mixed ordered tags
|
||||
class Matsim:
|
||||
def __init__(self, city, output_file_path):
|
||||
self._city = city
|
||||
|
@ -69,23 +68,23 @@ class Matsim:
|
|||
}
|
||||
|
||||
facility_xml = etree.SubElement(facilities_xml, 'facility', {
|
||||
'id': facility['id'],
|
||||
'x': facility['x'],
|
||||
'y': facility['y'],
|
||||
'id': f"{facility['id']}",
|
||||
'x': f"{facility['x']}",
|
||||
'y': f"{facility['y']}",
|
||||
})
|
||||
|
||||
activity_xml = etree.SubElement(facility_xml, 'activity', {
|
||||
'type': activity_info['type']
|
||||
'type': f"{activity_info['type']}"
|
||||
})
|
||||
|
||||
etree.SubElement(activity_xml, 'capacity', {
|
||||
'value': activity_info['capacity']
|
||||
'value': f"{activity_info['capacity']}"
|
||||
})
|
||||
|
||||
etree.SubElement(activity_xml, 'opentime', {
|
||||
'day': activity_info['opentime'][0]['day'],
|
||||
'start_time': activity_info['opentime'][0]['start_time'],
|
||||
'end_time': activity_info['opentime'][0]['end_time']
|
||||
'day': f"{activity_info['opentime'][0]['day']}",
|
||||
'start_time': f"{activity_info['opentime'][0]['start_time']}",
|
||||
'end_time': f"{activity_info['opentime'][0]['end_time']}"
|
||||
})
|
||||
|
||||
facility['activity'].append(activity_info)
|
||||
|
@ -98,13 +97,13 @@ class Matsim:
|
|||
gdf.to_file("input_files/buildings_shapefile.shp")
|
||||
|
||||
# Convert the Python dictionary to an XML string
|
||||
xml_content = etree.tostring(facilities_xml, pretty_print=True, encoding='UTF-8', xml_declaration=True).decode('utf-8')
|
||||
xml_content = etree.tostring(facilities_xml, pretty_print=True, encoding='UTF-8').decode('utf-8')
|
||||
|
||||
# Write the XML to the file
|
||||
output_file = f"{self._output_file_path}/{self._city.name}_facilities.xml"
|
||||
with open(output_file, 'w') as file:
|
||||
file.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>")
|
||||
file.write(f"<!DOCTYPE facilities SYSTEM \"{FACILITIES_DTD}\">")
|
||||
file.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
|
||||
file.write(f"<!DOCTYPE facilities SYSTEM \"{FACILITIES_DTD}\">\n")
|
||||
file.write(xml_content)
|
||||
|
||||
with open(output_file, 'rb') as f_in:
|
||||
|
@ -145,8 +144,8 @@ class Matsim:
|
|||
current_work = 0
|
||||
for facility in self._facilities['facility']:
|
||||
if facility['activity'][0]['type'] == cte.RESIDENTIAL:
|
||||
max_capacity = int(facility['activity'][0]['capacity']['value'])
|
||||
for _ in range(max_capacity):
|
||||
max_capacity = int(facility['activity'][0]['capacity'])
|
||||
for i in range(max_capacity):
|
||||
person = etree.SubElement(population, 'person', {
|
||||
'id': str(id),
|
||||
'sex': 'm',
|
||||
|
@ -158,10 +157,10 @@ class Matsim:
|
|||
|
||||
# Residential activity
|
||||
etree.SubElement(plan, 'act', {
|
||||
'type': facility['activity'][0]['type'],
|
||||
'facility': facility['id'],
|
||||
'x': facility['x'],
|
||||
'y': facility['y'],
|
||||
'type': f"{facility['activity'][0]['type']}",
|
||||
'facility': f"{facility['id']}",
|
||||
'x': f"{facility['x']}",
|
||||
'y': f"{facility['y']}",
|
||||
'end_time': '7:30:00'
|
||||
})
|
||||
|
||||
|
@ -170,12 +169,12 @@ class Matsim:
|
|||
|
||||
# Work activity
|
||||
etree.SubElement(plan, 'act', {
|
||||
'type': work[current_work]['type'],
|
||||
'facility': work[current_work]['facility'],
|
||||
'x': work[current_work]['x'],
|
||||
'y': work[current_work]['y'],
|
||||
'start_time': work[current_work]['start_time'],
|
||||
'end_time': work[current_work]['end_time'],
|
||||
'type': f"{work[current_work]['type']}",
|
||||
'facility': f"{work[current_work]['facility']}",
|
||||
'x': f"{work[current_work]['x']}",
|
||||
'y': f"{work[current_work]['y']}",
|
||||
'start_time': f"{work[current_work]['start_time']}",
|
||||
'end_time': f"{work[current_work]['end_time']}",
|
||||
})
|
||||
|
||||
# Leg to home
|
||||
|
@ -183,10 +182,10 @@ class Matsim:
|
|||
|
||||
# Residential activity (return)
|
||||
etree.SubElement(plan, 'act', {
|
||||
'type': facility['activity'][0]['type'],
|
||||
'facility': facility['id'],
|
||||
'x': facility['x'],
|
||||
'y': facility['y'],
|
||||
'type': f"{facility['activity'][0]['type']}",
|
||||
'facility': f"{facility['id']}",
|
||||
'x': f"{facility['x']}",
|
||||
'y': f"{facility['y']}",
|
||||
})
|
||||
|
||||
work[current_work]['capacity'] -= 1
|
||||
|
@ -196,42 +195,235 @@ class Matsim:
|
|||
id += 1
|
||||
|
||||
# Convert the Python dictionary to an XML string
|
||||
xml_content = etree.tostring(population, pretty_print=True, encoding='UTF-8', xml_declaration=True).decode('utf-8')
|
||||
xml_content = etree.tostring(population, pretty_print=True, encoding='UTF-8').decode('utf-8')
|
||||
|
||||
# Write the XML to the file
|
||||
output_file = f"{self._output_file_path}/{self._city.name}_population.xml"
|
||||
with open(output_file, 'w') as file:
|
||||
file.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
|
||||
file.write(f"<!DOCTYPE population SYSTEM \"{POPULATION_DTD}\">\n")
|
||||
file.write(xml_content)
|
||||
|
||||
with open(output_file, 'rb') as f_in:
|
||||
with gzip.open(output_file + '.gz', 'wb') as f_out:
|
||||
shutil.copyfileobj(f_in, f_out)
|
||||
|
||||
# TODO: Reimplement this after figuring out what's wrong with other files
|
||||
def _export_config(self):
|
||||
pass
|
||||
root = etree.Element('config')
|
||||
|
||||
# ======== NETWORK ========= #
|
||||
network_path_module = etree.SubElement(root, 'module', {
|
||||
'name': 'network'
|
||||
})
|
||||
_add_param(network_path_module, 'inputNetworkFile', f"{self._city.name}_network.xml.gz")
|
||||
|
||||
# ======== POPULATION ========= #
|
||||
population_path_module = etree.SubElement(root, 'module', {
|
||||
'name': 'plans'
|
||||
})
|
||||
_add_param(population_path_module, 'inputPlansFile', f"{self._city.name}_population.xml.gz")
|
||||
|
||||
# ======== FACILITIES ========= #
|
||||
facilities_path_module = etree.SubElement(root, 'module', {
|
||||
'name': 'facilities'
|
||||
})
|
||||
_add_param(facilities_path_module, 'inputFacilitiesFile', f"{self._city.name}_facilities.xml.gz")
|
||||
_add_param(facilities_path_module, 'facilitiesSource', 'fromFile')
|
||||
|
||||
# ======== CONTROLER ========= #
|
||||
controler_module = etree.SubElement(root, 'module', {
|
||||
'name': 'controler'
|
||||
})
|
||||
controler_params = [
|
||||
('writeEventsInterval', '1000'),
|
||||
('writePlansInterval', '1000'),
|
||||
('eventsFileFormat', 'xml'),
|
||||
('outputDirectory', f"{self._output_file_path}/Montreal"),
|
||||
('firstIteration', '0'),
|
||||
('lastIteration', '10'),
|
||||
('mobsim', 'qsim'),
|
||||
]
|
||||
for param in controler_params:
|
||||
_add_param(controler_module, param[0], param[1])
|
||||
|
||||
# ======== QSIM ========= #
|
||||
qsim_module = etree.SubElement(root, 'module', {
|
||||
'name': 'qsim'
|
||||
})
|
||||
qsim_params = [
|
||||
('startTime', '00:00:00'),
|
||||
('endTime', '30:00:00'),
|
||||
('flowCapacityFactor', '1.00'),
|
||||
('storageCapacityFactor', '1.00'),
|
||||
('numberOfThreads', '1'),
|
||||
('snapshotperiod', '00:00:01'),
|
||||
('removeStuckVehicles', 'false'),
|
||||
('stuckTime', '3600.0'),
|
||||
('timeStepSize', '00:00:01'),
|
||||
('trafficDynamics', 'queue'),
|
||||
]
|
||||
for param in qsim_params:
|
||||
_add_param(qsim_module, param[0], param[1])
|
||||
|
||||
# ======== SCORING ========= #
|
||||
score_module = etree.SubElement(root, 'module', {
|
||||
'name': 'planCalcScore'
|
||||
})
|
||||
_add_param(score_module, 'BrainExpBeta', '1.0')
|
||||
_add_param(score_module, 'learningRate', '1.0')
|
||||
|
||||
scoring_paramset = etree.SubElement(score_module, 'parameterset', {
|
||||
'type': 'scoringParameters'
|
||||
})
|
||||
scoring_paramset_params = [
|
||||
('earlyDeparture', '0.0'),
|
||||
('lateArrival', '0.0'),
|
||||
('marginalUtilityOfMoney', '0.062'),
|
||||
('performing', '0.96'),
|
||||
('utilityOfLineSwitch', '0.0'),
|
||||
('waitingPt', '-0.18'),
|
||||
]
|
||||
for param in scoring_paramset_params:
|
||||
_add_param(scoring_paramset, param[0], param[1])
|
||||
|
||||
mode_paramsets = [
|
||||
("car",
|
||||
[
|
||||
("marginalUtilityOfTraveling_util_hr", "0.0"),
|
||||
("constant", "-0.562"),
|
||||
("monetaryDistanceRate", "-0.0004")
|
||||
]),
|
||||
("walk",
|
||||
[
|
||||
("marginalUtilityOfTraveling_util_hr", "-1.14"),
|
||||
("constant", "0.0"),
|
||||
("marginalUtilityOfDistance_util_m", "0.0")
|
||||
])
|
||||
]
|
||||
for mode, parameters in mode_paramsets:
|
||||
_add_parameterset(scoring_paramset, "modeParams", [("mode", mode)] + parameters)
|
||||
|
||||
activity_paramsets = [
|
||||
('residential',[
|
||||
('priority', '1'),
|
||||
('typicalDuration', '13:00:00'),
|
||||
('minimalDuration', '01:00:00'),
|
||||
]),
|
||||
('medium office',[
|
||||
('priority', '1'),
|
||||
('typicalDuration', '09:00:00'),
|
||||
('minimalDuration', '08:00:00'),
|
||||
('openingTime', '08:00:00'),
|
||||
('earliestEndTime', '17:00:00'),
|
||||
('latestStartTime', '09:00:00'),
|
||||
('closingTime', '18:00:00'),
|
||||
]),
|
||||
('warehouse',[
|
||||
('priority', '1'),
|
||||
('typicalDuration', '09:00:00'),
|
||||
('minimalDuration', '08:00:00'),
|
||||
('openingTime', '08:00:00'),
|
||||
('earliestEndTime', '17:00:00'),
|
||||
('latestStartTime', '09:00:00'),
|
||||
('closingTime', '18:00:00'),
|
||||
]),
|
||||
('stand alone retail',[
|
||||
('priority', '1'),
|
||||
('typicalDuration', '09:00:00'),
|
||||
('minimalDuration', '08:00:00'),
|
||||
('openingTime', '08:00:00'),
|
||||
('earliestEndTime', '17:00:00'),
|
||||
('latestStartTime', '09:00:00'),
|
||||
('closingTime', '18:00:00'),
|
||||
]),
|
||||
]
|
||||
for activity_type, parameters in activity_paramsets:
|
||||
_add_parameterset(scoring_paramset, "activityParams", [("activityType", activity_type)] + parameters)
|
||||
|
||||
# ======== STRATEGY ========= #
|
||||
strategy_module = etree.SubElement(root, 'module', {
|
||||
'name': 'strategy'
|
||||
})
|
||||
_add_param(strategy_module, 'maxAgentPlanMemorySize', '6')
|
||||
|
||||
strategy_paramsets = [
|
||||
("ChangeExpBeta",[
|
||||
("weight", "0.7"),
|
||||
]),
|
||||
("ReRoute",[
|
||||
("disableAfterIteration", "2900"),
|
||||
("weight", "0.01"),
|
||||
]),
|
||||
("SubtourModeChoice", [
|
||||
("disableAfterIteration", "2900"),
|
||||
("weight", "0.01"),
|
||||
]),
|
||||
("TimeAllocationMutator", [
|
||||
("disableAfterIteration", "2900"),
|
||||
("weight", "0.01"),
|
||||
]),
|
||||
]
|
||||
for name, parameters in strategy_paramsets:
|
||||
_add_parameterset(strategy_module, "strategysettings", [("strategyName", name)] + parameters)
|
||||
|
||||
# ======== SUBTOUR MODE CHOICE ========= #
|
||||
subtour_module = etree.SubElement(root, 'module', {
|
||||
'name': 'subtourModeChoice'
|
||||
})
|
||||
# Defines the chain-based modes, seperated by commas
|
||||
_add_param(subtour_module, 'chainBasedModes', 'car')
|
||||
# Defines whether car availability must be considered or not. An agent has no car only if it has no license, or never access to a car
|
||||
_add_param(subtour_module, 'considerCarAvailability', 'true')
|
||||
# Defines all the modes available, including chain-based modes, seperated by commas
|
||||
_add_param(subtour_module, 'modes', 'car,walk')
|
||||
|
||||
xml_content = etree.tostring(root, pretty_print=True, encoding='UTF-8').decode('utf-8')
|
||||
|
||||
# Write the XML to the file
|
||||
output_file = f"{self._output_file_path}/{self._city.name}_config.xml"
|
||||
with open(output_file, 'w') as file:
|
||||
file.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
|
||||
file.write(f"<!DOCTYPE config SYSTEM \"{CONFIG_DTD}\">\n")
|
||||
file.write(xml_content)
|
||||
|
||||
|
||||
def _add_param(parent, name, value):
|
||||
etree.SubElement(parent, "param", {
|
||||
'name': name,
|
||||
'value': value
|
||||
})
|
||||
|
||||
|
||||
def _add_parameterset(parent, type, parameters):
|
||||
parameterset = etree.SubElement(parent, "parameterset", {
|
||||
'type': type
|
||||
})
|
||||
for name, value in parameters:
|
||||
_add_param(parameterset, name, value)
|
||||
|
||||
|
||||
def _convert_schedules(building_schedules):
|
||||
converted_schedules = []
|
||||
for schedule in building_schedules:
|
||||
opening_hour = 0
|
||||
closing_hour = 0
|
||||
opening_hour = 0
|
||||
closing_hour = 0
|
||||
schedule = building_schedules[0]
|
||||
|
||||
for i, value in enumerate(schedule.values):
|
||||
if value > 0:
|
||||
opening_hour = i
|
||||
break
|
||||
for i, value in enumerate(schedule.values):
|
||||
if value > 0:
|
||||
opening_hour = i
|
||||
break
|
||||
|
||||
for i, value in reversed(list(enumerate(schedule.values))):
|
||||
if value > 0:
|
||||
closing_hour = i
|
||||
break
|
||||
for i, value in reversed(list(enumerate(schedule.values))):
|
||||
if value > 0:
|
||||
closing_hour = i
|
||||
break
|
||||
|
||||
for day in schedule.day_types:
|
||||
if day[0:3] != 'hol':
|
||||
converted_schedules.append({
|
||||
'day': day[0:3],
|
||||
'start_time': f"{opening_hour:02}:00:00",
|
||||
'end_time': f"{closing_hour:02}:00:00"
|
||||
})
|
||||
|
||||
for day in schedule.day_types:
|
||||
if day[0:3] != 'hol':
|
||||
converted_schedules.append({
|
||||
'day': day[0:3],
|
||||
'start_time': opening_hour,
|
||||
'end_time': closing_hour
|
||||
})
|
||||
return converted_schedules
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
class MatsimActivityToMatsimSchedule:
|
||||
"""
|
||||
Hub function to nrcan construction function class
|
||||
"""
|
||||
def __init__(self):
|
||||
self._dictionary = {
|
||||
'work': '08:00:00-18:00:00',
|
||||
'home': '00:00:00-30:00:00',
|
||||
'edu': '08:00:00-18:00:00',
|
||||
'secondary': '08:00:00-20:00:00'
|
||||
}
|
||||
|
||||
@property
|
||||
def dictionary(self) -> dict:
|
||||
"""
|
||||
Get the dictionary
|
||||
:return: {}
|
||||
"""
|
||||
return self._dictionary
|
|
@ -1,12 +1,4 @@
|
|||
import math
|
||||
import subprocess
|
||||
import xmltodict
|
||||
|
||||
import geopandas as gpd
|
||||
from shapely.geometry import Point
|
||||
|
||||
from matsim_activity_to_matsim_schedule import MatsimActivityToMatsimSchedule
|
||||
from hub_function_to_matsim_activity import HubFunctionToMatsimActivity
|
||||
|
||||
class MatSimEngine:
|
||||
def __init__(self, config_file_path):
|
||||
|
@ -20,4 +12,4 @@ class MatSimEngine:
|
|||
# Must generate this config file first.
|
||||
command.append(self._config_file_path)
|
||||
|
||||
subprocess.run(command)
|
||||
subprocess.run(command, check=True)
|
||||
|
|
|
@ -8,7 +8,7 @@ from collections import defaultdict
|
|||
import matplotlib.cm as cm
|
||||
import matplotlib.colors as colors
|
||||
|
||||
class MatSimVisualizer():
|
||||
class MatsimVisualizer():
|
||||
def __init__(self, network_file_path, events_file_path):
|
||||
self.network_file_path = network_file_path
|
||||
self.events_file_path = events_file_path
|
||||
|
@ -92,7 +92,7 @@ class MatSimVisualizer():
|
|||
edge_widths = [2 + self.norm(traffic_data.get(link['id'], 0)) * 3 for link in self.links]
|
||||
|
||||
plt.cla()
|
||||
nx.draw(self.G, self.pos, node_size=10, node_color='blue', width=edge_widths, edge_color=edge_colors, with_labels=False,
|
||||
nx.draw(self.G, self.pos, node_size=0, node_color='blue', width=edge_widths, edge_color=edge_colors, with_labels=False,
|
||||
edge_cmap=self.cmap)
|
||||
|
||||
plt.title(f"Time: {tick}")
|
||||
|
|
BIN
traffic_animation.gif
Normal file
BIN
traffic_animation.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 MiB |
Loading…
Reference in New Issue
Block a user