Skip to content

Instantly share code, notes, and snippets.

@nside
Created December 12, 2022 04:39
Show Gist options
  • Save nside/9f29d7cdadbf22d5a539350fc6da0724 to your computer and use it in GitHub Desktop.
Save nside/9f29d7cdadbf22d5a539350fc6da0724 to your computer and use it in GitHub Desktop.
# This code reads a set of latitude and longitude coordinates from a csv file, creates a dictionary of Point objects using the shapely library, and then creates a MultiLineString object using the Point objects. It then takes the union of the MultiLineString object to create a single shape representing a road network. The road network is then buffered by a small amount and written to a geojson file.
# The latitude and longitude coordinates in the input csv file likely represent the nodes (intersections or endpoints) of a road network, and the edges (roads) connecting the nodes are inferred from the input file. The Point objects are created using these coordinates, and the LineString objects representing the edges are created by connecting the Point objects. The union of the LineString objects is then taken to create the final road network shape.
import csv, json
from shapely.geometry import LineString, MultiLineString, Point, MultiPoint, mapping
from shapely.ops import unary_union
from shapely.geometry import CAP_STYLE, JOIN_STYLE
# Load the nodes from the CSV file and create a dictionary of shapely Points
nodes = {}
with open("csvs/nodes.csv", "r") as f:
reader = csv.reader(f)
# Skip the header row
next(reader)
for row in reader:
node_id, lat, lon = row
nodes[node_id] = Point(float(lon), float(lat))
print('read nodes')
# Load the edges from the CSV file and create a shapely MultiLineString object
edges = []
with open("csvs/edges.csv", "r") as f:
reader = csv.reader(f)
# Skip the header row
for row in reader:
from_node_id, to_node_id = row
# Get the coordinates of the "from" and "to" nodes
if not from_node_id in nodes: continue
if not to_node_id in nodes: continue
from_node = nodes[from_node_id].coords[0]
to_node = nodes[to_node_id].coords[0]
edges.append(LineString([from_node, to_node]))
print('read edges')
edges = MultiLineString(edges)
# Union the edges together to create a single shape representing the road network
road_network = unary_union(edges)
print('union done')
# Buffer the road network by 0.00001 instead of 2 meters
road_network = road_network.buffer(0.00001, cap_style=CAP_STYLE.flat)
geojson = mapping(road_network)
with open("road_network.geojson", "w") as f:
json.dump(geojson, f)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment