Skip to content

Commit a48f9f6

Browse files
committed
Added the ability to set transit zone labels using a geojson with the data
1 parent 9006231 commit a48f9f6

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import json
2+
import os
3+
4+
import inro.modeller as _m
5+
from shapely.geometry import shape, Point
6+
7+
class TransitZones(_m.Tool()):
8+
transit_zones = _m.Attribute(str)
9+
10+
def __init__(self):
11+
"""Tool with click-button that can be imported in the Modeller GUI.
12+
"""
13+
self.tool_run_msg = ""
14+
15+
def page(self):
16+
pb = _m.ToolPageBuilder(self)
17+
pb.title = "Reassign transit zones"
18+
pb.add_select_file(
19+
"transit_zones", "directory", file_filter="*.json;*.geojson*", start_path="",
20+
title="Transit zone area file:"
21+
)
22+
if self.tool_run_msg:
23+
pb.add_html(self.tool_run_msg)
24+
return pb.render()
25+
26+
def run(self):
27+
self()
28+
29+
def __call__(self):
30+
"""Reassign transit zones for current scenario.
31+
"""
32+
scen = _m.Modeller().scenario
33+
network = scen.get_network()
34+
if not os.path.exists(self.transit_zones):
35+
self.write(f"Error: File '{self.transit_zones}' does not exist.")
36+
return
37+
try:
38+
with open(self.transit_zones, "r", encoding="utf-8") as file:
39+
geojson_data = json.load(file)
40+
except json.JSONDecodeError:
41+
self.write(f"Error: File '{self.transit_zones}' is not a valid JSON file.")
42+
return
43+
num_features = len(geojson_data["features"])
44+
increment = 100/num_features
45+
self.percent = 0
46+
47+
transit_zone_labels = set()
48+
processed_nodes = 0
49+
# Access features
50+
try:
51+
for feature in geojson_data["features"]:
52+
zone = feature["properties"]["zone"] # Access attributes
53+
transit_zone_labels.add(zone)
54+
geometry = shape(feature["geometry"]) # Convert geometry to Shapely object
55+
for node in network.nodes():
56+
if Point(node.x, node.y).within(geometry):
57+
node.label = zone
58+
processed_zones += 1
59+
self.percent += increment
60+
except KeyError:
61+
self.write("The provided GeoJSON has an invalid format.")
62+
return
63+
_m.Modeller().scenario.publish_network(network)
64+
msg = f"Transit zones for scenario {scen.id} created successfully. Processed {len(transit_zone_labels)} zones and {processed_nodes} nodes."
65+
self.write(msg)
66+
self.tool_run_msg = _m.PageBuilder.format_info(msg)
67+
68+
def percent_completed(self):
69+
return (0, 100, self.percent)
70+
71+
72+
def write(self, message):
73+
_m.logbook_write(message)
74+
75+
def flush(self):
76+
"""Flush the logbook (i.e., do nothing)."""
77+
pass

0 commit comments

Comments
 (0)