Browse Source

first commit

Florian 4 years ago
commit
f4b6e4ab1d
4 changed files with 41942 additions and 0 deletions
  1. 30 0
      README.md
  2. 41751 0
      input/network.xml
  3. 73 0
      input/signals.xml
  4. 88 0
      signals_gen.py

+ 30 - 0
README.md

@@ -0,0 +1,30 @@
+# signals_gen
+
+Python generator for MATSim signals xml files
+
+## setup
+
+- use `venv` (https://github.com/juliendehos/venv)
+
+## prerequisites
+
+MATSim network files (`.xml`)
+OpenStreetMap traffic signal files (`.xml`):
+*(test files are available in `input/` folder)*
+
+## install
+
+    venv i signals_gen
+    venv a signals_gen
+    pip install lxml
+
+## usage
+
+### run
+
+    ./signals_gen.py
+
+### examples
+
+## todo
+this readme

File diff suppressed because it is too large
+ 41751 - 0
input/network.xml


+ 73 - 0
input/signals.xml

@@ -0,0 +1,73 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<osm version="0.6" generator="Osmosis 0.46">
+  <bounds minlon="1.80470" minlat="50.92250" maxlon="1.92400" maxlat="50.97730" origin=""/>
+  <node id="29059804" version="7" timestamp="2011-03-04T10:14:18Z" uid="221860" user="Rems" changeset="7453100" lat="50.9546896" lon="1.8597579">
+    <tag k="highway" v="traffic_signals"/>
+  </node>
+  <node id="257818843" version="6" timestamp="2013-04-24T12:07:31Z" uid="37548" user="Marcussacapuces91" changeset="15847619" lat="50.9497102" lon="1.8541238">
+    <tag k="bicycle" v="yes"/>
+    <tag k="highway" v="traffic_signals"/>
+    <tag k="crossing" v="traffic_signals"/>
+  </node>
+  <node id="273190765" version="5" timestamp="2012-10-25T21:13:28Z" uid="949628" user="Sidhannowe" changeset="13632274" lat="50.9473896" lon="1.8512426">
+    <tag k="horse" v="no"/>
+    <tag k="highway" v="traffic_signals"/>
+    <tag k="crossing" v="traffic_signals"/>
+  </node>
+  <node id="304798432" version="6" timestamp="2010-05-01T17:05:26Z" uid="135078" user="Frédéric Lesiuk" changeset="4577225" lat="50.9398471" lon="1.857853">
+    <tag k="highway" v="traffic_signals"/>
+  </node>
+  <node id="314039265" version="7" timestamp="2012-12-27T20:15:06Z" uid="949628" user="Sidhannowe" changeset="14430488" lat="50.9379313" lon="1.857691">
+    <tag k="highway" v="traffic_signals"/>
+  </node>
+  <node id="314057831" version="5" timestamp="2013-04-24T12:08:53Z" uid="37548" user="Marcussacapuces91" changeset="15847619" lat="50.9517651" lon="1.8534771">
+    <tag k="highway" v="traffic_signals"/>
+  </node>
+  <node id="326138714" version="6" timestamp="2015-08-03T18:02:42Z" uid="27454" user="Popolon" changeset="33077100" lat="50.9486545" lon="1.8540524">
+    <tag k="highway" v="traffic_signals"/>
+    <tag k="crossing" v="traffic_signals"/>
+  </node>
+  <node id="374183267" version="5" timestamp="2015-08-03T18:02:42Z" uid="27454" user="Popolon" changeset="33077100" lat="50.9468271" lon="1.8457469">
+    <tag k="highway" v="traffic_signals"/>
+  </node>
+  <node id="374319826" version="3" timestamp="2015-08-03T19:43:38Z" uid="27454" user="Popolon" changeset="33080180" lat="50.9451294" lon="1.8653971">
+    <tag k="highway" v="traffic_signals"/>
+  </node>
+  <node id="634807122" version="3" timestamp="2010-05-02T19:02:51Z" uid="135078" user="Frédéric Lesiuk" changeset="4588784" lat="50.9579517" lon="1.8748267">
+    <tag k="highway" v="traffic_signals"/>
+  </node>
+  <node id="634807127" version="5" timestamp="2015-10-07T22:18:40Z" uid="1559158" user="vakulya" changeset="34500699" lat="50.9517875" lon="1.8766142">
+    <tag k="highway" v="traffic_signals"/>
+  </node>
+  <node id="634807128" version="4" timestamp="2011-01-22T12:10:05Z" uid="88448" user="Ted Pottage" changeset="7049550" lat="50.9580136" lon="1.8755896">
+    <tag k="highway" v="traffic_signals"/>
+  </node>
+  <node id="672959735" version="2" timestamp="2014-04-14T19:30:52Z" uid="949628" user="Sidhannowe" changeset="21693583" lat="50.9444021" lon="1.8227524">
+    <tag k="highway" v="traffic_signals"/>
+    <tag k="crossing" v="traffic_signals"/>
+    <tag k="supervised" v="no"/>
+  </node>
+  <node id="709053441" version="3" timestamp="2015-10-07T22:18:40Z" uid="1559158" user="vakulya" changeset="34500699" lat="50.9515988" lon="1.8766601">
+    <tag k="source" v="cadastre-dgi-fr source : Direction Générale des Impôts - Cadastre. Mise à jour : 2010"/>
+    <tag k="highway" v="traffic_signals"/>
+  </node>
+  <node id="1678793057" version="4" timestamp="2016-07-05T19:58:14Z" uid="414659" user="kritic" changeset="40508693" lat="50.9595429" lon="1.8489334">
+    <tag k="highway" v="traffic_signals"/>
+  </node>
+  <node id="2791259687" version="1" timestamp="2014-04-14T19:30:43Z" uid="949628" user="Sidhannowe" changeset="21693583" lat="50.9444977" lon="1.8236957">
+    <tag k="highway" v="traffic_signals"/>
+    <tag k="crossing" v="traffic_signals"/>
+  </node>
+  <node id="3679278632" version="2" timestamp="2017-06-10T07:44:38Z" uid="161619" user="FvGordon" changeset="49414532" lat="50.9477228" lon="1.8539666">
+    <tag k="highway" v="traffic_signals"/>
+  </node>
+  <node id="3679278636" version="2" timestamp="2016-05-17T14:04:06Z" uid="3942402" user="elisapruvotgeovelo" changeset="39377532" lat="50.9476773" lon="1.8541152">
+    <tag k="highway" v="traffic_signals"/>
+  </node>
+  <node id="3905952932" version="2" timestamp="2017-06-10T07:44:38Z" uid="161619" user="FvGordon" changeset="49414532" lat="50.9475942" lon="1.8539909">
+    <tag k="highway" v="traffic_signals"/>
+  </node>
+  <node id="3905952939" version="2" timestamp="2017-06-10T07:44:38Z" uid="161619" user="FvGordon" changeset="49414532" lat="50.9476056" lon="1.8540883">
+    <tag k="highway" v="traffic_signals"/>
+  </node>
+</osm>

+ 88 - 0
signals_gen.py

@@ -0,0 +1,88 @@
+#!/usr/bin/env python3
+''' generates signals xml files for MATSim from OSM data '''
+
+import lxml.etree as etree
+
+INPUT_NETWORK = 'input/network.xml'
+INPUT_SIGNALS = 'input/signals.xml'
+OUT_SIGNAL_SYSTEMS = 'out_signals_systems.xml'
+OUT_SIGNAL_GROUPS = 'out_signals_groups.xml'
+OUT_SIGNAL_CONTROL = 'out_signals_control.xml'
+CYCLE_TIME = 120
+
+def make_subelement(parent_node, sub_name, sub_attrs=None):
+    ''' creates an xml sub element and set its attributes '''
+    sub = etree.SubElement(parent_node, sub_name)
+    if sub_attrs is None:
+        return sub
+    for attr, value in sub_attrs.items():
+        sub.set(attr, value)
+    return sub
+
+def make_signal_systems(network_root, signals):
+    ''' make signal systems xml root '''
+    signal_systems = etree.Element('signalSystems')
+    for n_sig, sig in enumerate(signals):
+        sig_node_id = sig.get('id')
+        links = network_root.xpath("/network/links/link[@to='{}']".format(sig_node_id))
+        if links:
+            signal_system = make_subelement(signal_systems, 'signalSystem', {'id': str(n_sig+1)})
+            signals = make_subelement(signal_system, 'signals')
+            for n_link, link in enumerate(links):
+                make_subelement(signals, 'signal', {'linkIdRef': link.get('id'), 'id': str(n_link+1)})
+    return signal_systems
+
+def make_signal_groups(signal_systems):
+    ''' make signal groups xml root '''
+    signal_groups = etree.Element('signalGroups')
+    for n_sig_sys, sig_sys in enumerate(signal_systems.xpath('/signalSystems/signalSystem')):
+        signal_system = make_subelement(signal_groups, 'signalSystem', {'refId': sig_sys.get('id')})
+        for n_sig, sig in enumerate(sig_sys.xpath('signals/signal')):
+            signal_group = make_subelement(signal_system, 'signalGroup', {'id': str(n_sig+1)})
+            make_subelement(signal_group, 'signal', {'refId': sig.get('id')})
+    return signal_groups
+
+def make_signal_control(signal_systems, signal_groups):
+    ''' make signal control xml root '''
+    signal_control = etree.Element('signalControl')
+    for sig_sys in signal_systems.xpath('/signalSystems/signalSystem'):
+        sig_sys_id = sig_sys.get('id')
+        signal_system = make_subelement(signal_control, 'signalSystem', {'refId': sig_sys_id})
+        sig_sys_controller = make_subelement(signal_system, 'signalSystemController')
+        controller_identifier = make_subelement(sig_sys_controller, 'controllerIdentifier')
+        controller_identifier.text = 'DefaultPlanbasedSignalSystemController'
+        signal_plan = make_subelement(sig_sys_controller, 'signalPlan', {'id': '1'})
+        make_subelement(signal_plan, 'start', {'daytime': '06:00:00'})
+        make_subelement(signal_plan, 'stop', {'daytime': '18:00:00'})
+        make_subelement(signal_plan, 'cycleTime', {'sec': str(CYCLE_TIME)})
+        make_subelement(signal_plan, 'offset', {'sec': '0'})
+        sig_groups = signal_groups.xpath("/signalGroups/signalSystem[@refId='{}']/signalGroup".format(sig_sys_id))
+        for n_sig_grp, sig_grp in enumerate(sig_groups):
+            sig_group_settings = make_subelement(signal_plan, 'signalGroupSettings', {'refId': sig_grp.get('id')})
+            delta_sec = int(CYCLE_TIME / len(sig_groups))
+            onset_sec = delta_sec * n_sig_grp
+            dropping_sec = onset_sec + delta_sec - 5
+            make_subelement(sig_group_settings, 'onset', {'sec': str(onset_sec)})
+            make_subelement(sig_group_settings, 'dropping', {'sec': str(dropping_sec)})
+    return signal_control
+
+if __name__ == '__main__':
+    # network nodes
+    NETWORK_ROOT = etree.parse(INPUT_NETWORK)
+
+    # signals nodes
+    SIGNALS_ROOT = etree.parse(INPUT_SIGNALS)
+    SIGNALS = SIGNALS_ROOT.xpath('/osm/node')
+
+    # xml trees
+    SIGNAL_SYSTEMS = make_signal_systems(NETWORK_ROOT, SIGNALS)
+    SIGNAL_GROUPS = make_signal_groups(SIGNAL_SYSTEMS)
+    SIGNAL_CONTROL = make_signal_control(SIGNAL_SYSTEMS, SIGNAL_GROUPS)
+
+    # output
+    TREE_SIGNAL_SYSTEMS = etree.ElementTree(SIGNAL_SYSTEMS)
+    TREE_SIGNAL_GROUPS = etree.ElementTree(SIGNAL_GROUPS)
+    TREE_SIGNAL_CONTROL = etree.ElementTree(SIGNAL_CONTROL)
+    TREE_SIGNAL_SYSTEMS.write(OUT_SIGNAL_SYSTEMS, pretty_print=True, xml_declaration=True, encoding="utf-8")
+    TREE_SIGNAL_GROUPS.write(OUT_SIGNAL_GROUPS, pretty_print=True, xml_declaration=True, encoding="utf-8")
+    TREE_SIGNAL_CONTROL.write(OUT_SIGNAL_CONTROL, pretty_print=True, xml_declaration=True, encoding="utf-8")