-
Notifications
You must be signed in to change notification settings - Fork 10
Usage: 2.5. Reading Data: JSON & GeoJSON
Available as a jupyter notebook or wiki page.
GeNet lets you read JSON data into a Networn graph and PT Schedule, or GeoJSON into Network Graph.
For JSON inputs the network JSON file should follow this format:
{
"nodes": {
"unique_node_ID": {
"id": "unique_node_ID",
"y": y_spatial_coordinate,
"x": x_spatial_coordinate
}
},
"links": {
"unique_link_ID": {
"id": "unique_link_ID",
"from": "unique_source_node_ID",
"to": "unique_target_node_ID",
"freespeed": 4.166666666666667,
"permlanes": 1,
"modes": "car,bus,walk",
"geometry": "kevj`maB_`la`}`@{ooxA`k~rH", (encoded polyline, otherwise assumed to be straight line between source and target node)
"length": 52.765151087870265,
"capacity": 600.0
"attributes": { # (optional MATSim link attributes)
"osm:way:access": {
"name": "osm:way:access",
"class": "java.lang.String",
"text": "permissive"
},
"osm:way:id": { # simple form that assumes the java type
"OSM_ID"
},
},
}
}
}
from genet import read_json_network, read_json_schedule, read_json
n = read_json_network('../example_data/example_json/network.json', 'epsg:27700')
2022-07-14 15:31:04,968 - Reading Network from ../example_data/example_json/network.json
2022-07-14 15:31:05,058 - Added 4 nodes
2022-07-14 15:31:05,067 - Added 2 links
The JSON Schedule should follow this format:
{
"schedule": {
"stops": {
"unique_stop_ID": {
"id": "unique_stop_ID",
"name": "Stop Name", (optional but useful)
"x": y_spatial_coordinate,
"y": x_spatial_coordinate,
"linkRefId": "netowrk_link_ID", (reference to a link in the network graph)
}
},
"services": {
"unique_service_ID": {
"id": "unique_service_ID",
"name": "N55", (optional but useful)
"routes": {
"unique_route_ID": {
"id": "unique_route_ID",
"route_short_name": "N55", (optional but useful)
"mode": "bus", (PT mode)
"trips": {
"trip_id": [
"unique_trip_ID"
],
"trip_departure_time": [
"HH:MM:SS" (departure time for the trip)
],
"vehicle_id": [
"unique_vehicle_ID"
]
},
"arrival_offsets": [ (arrival offsets from trip departure time for each stop in route)
"00:00:00",
"00:02:20"
],
"departure_offsets": [ (departure offsets from trip departure time for each stop in route)
"00:00:00",
"00:02:20"
],
"route_long_name": "", (optional but useful)
"route": [ (network route for the route)
"1",
"10"
],
"ordered_stops": [
"unique_stop_ID_1",
"unique_stop_ID_2"
]
}
}
}
},
"minimal_transfer_times": {
"unique_stop_ID_1": {
"stop": "unique_stop_ID_2",
"transferTime": 100.0
},
"unique_stop_ID_2": {
"stop": "unique_stop_ID_1",
"transferTime": 100.0
}
}
},
"vehicles": {
"vehicle_types": {
"bus": {
"capacity": {
"seats": {
"persons": "70"
},
"standingRoom": {
"persons": "0"
}
},
"length": {
"meter": "18.0"
},
"width": {
"meter": "2.5"
},
"accessTime": {
"secondsPerPerson": "0.5"
},
"egressTime": {
"secondsPerPerson": "0.5"
},
"doorOperation": {
"mode": "serial"
},
"passengerCarEquivalents": {
"pce": "2.8"
}
}
},
"vehicles": {
"veh_0_bus": {
"type": "bus"
}
}
}
}
the references to the network: linkRefId
and route
can be left out. That network will not work with MATSim. GeNet can snap and route PT services and fill in those blanks, though not at scale.
s = read_json_schedule('../example_data/example_json/schedule.json', 'epsg:27700')
2022-07-14 15:31:05,075 - Reading Schedule from ../example_data/example_json/schedule.json
If you have both json inputs for a network you can also read both the network json and schedule json at the same time.
n = read_json(
network_path='../example_data/example_json/network.json',
schedule_path='../example_data/example_json/schedule.json',
epsg='epsg:27700'
)
2022-07-14 15:31:05,119 - Reading Network from ../example_data/example_json/network.json
2022-07-14 15:31:05,281 - Added 4 nodes
2022-07-14 15:31:05,354 - Added 2 links
2022-07-14 15:31:05,360 - Reading Schedule from ../example_data/example_json/schedule.json
Given GeoJson, you can create a Network graph. Two files are expected, one for nodes and one for links.
The nodes should follow this format:
{
"type": "FeatureCollection",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::27700" } },
"features": [
{ "type": "Feature", "properties": {"id": "25508485", "x": 528489.467895946, "y": 182206.20303669578, "lon": -0.14930198709481451, "lat": 51.524162533239284, "s2_id": 5221390301001263407 }, "geometry": { "type": "Point", "coordinates": [ 528489.467895945999771, 182206.203036695776973 ] } }
]
}
And the links should follow this format:
{
"type": "FeatureCollection",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::27700" } },
"features": [
{ "type": "Feature", "properties": {"id": "1", "from": "25508485", "to": "21667818", "freespeed": 4.166666666666667, "capacity": 600.0, "permlanes": 1.0, "oneway": "1", "modes": "car", "s2_from": 5221390301001263407, "s2_to": 5221390302696205321, "attributes": { "osm:way:access": { "name": "osm:way:access", "class": "java.lang.String", "text": "permissive" }, "osm:way:highway": { "name": "osm:way:highway", "class": "java.lang.String", "text": "unclassified" }, "osm:way:id": "26997928" },
"osm:way:name": { "name": "osm:way:name", "class": "java.lang.String", "text": "Brunswick Place" } }, "length": 52.765151087870265 }, "geometry": { "type": "LineString", "coordinates": [ [ 528489.467895945999771, 182206.203036695776973 ], [ 528504.134284314350225, 182155.743513659806922 ] ] } }
]
}
Note that additional, nested attributes can take a long form:
"osm:way:name": { "name": "osm:way:name", "class": "java.lang.String", "text": "Brunswick Place" }
or a simple form that assumed data types:
"osm:way:name": "Brunswick Place"
from genet import read_geojson_network
n = read_geojson_network(
'../example_data/example_geojson/network_nodes.geojson',
'../example_data/example_geojson/network_links.geojson',
'epsg:27700')
2022-07-14 15:31:05,419 - Reading Network nodes from ../example_data/example_geojson/network_nodes.geojson
2022-07-14 15:31:05,520 - Reading Network links from ../example_data/example_geojson/network_links.geojson
2022-07-14 15:31:05,613 - Added 4 nodes
2022-07-14 15:31:05,622 - Added 2 links
The GeoJSONs carry a projection for their geometry. The epsg passed in the method above is for the Network, the links will inherit the geometry stored in the geojson but project it (if not already in the correct projection) to match the Network's projection