Skip to content

OsmGT Wiki

amauryval edited this page Sep 3, 2020 · 49 revisions

What is it ?

OsmGt is a geospatial python library to help you to play with OpenStreetMap (OSM) roads data and to do network analysis with Graph-tool.

This library offers some main features :

  • get roads data into a Geodataframe (GeoPandas) : vehicle or pedestrian paths [more coming soon]
  • generate a graph-tool graph linked to the roads GeoDataframe (topolygy checking and fixing)
  • add new nodes on the network to extend you network analysis

Additional features about OpenStreetMap data are available

  • get OSM points of interest

Also, OsmGt can be a tool to do some common network analysis:

  • (a lot of ) shortest paths
  • isochrones based on time and distance

Of course you can use the geodataframe and the graph without this functions according to your specific requirements.

Don"t forge to check these examples on this Jupyter Notebook


How to install it ?

conda install -c amauryval osmgt

How to use it ?

Before to present code lines, we have to present you some prerequisites informations about functions arguments.

You can load/compute data from:

  1. a location name (ex: Lyon) ; a Nominatim api call is done to catch the boundaries of the input location name area
  2. a bounding box (min_x=-74.018433, min_y=40.718087, max_x=-73.982749, max_y=40.733356)

You can load a specific network based on the transport mode (from Overpass Turbo query):

  1. vehicle mode: will create a directed graph, because direction are important
  2. pedestrian mode (freeway are not load here for example): will create an undirected graph
  3. more will comming soon...

How to load data ?

Roads and graph

2 methods are available.

  • Get roads network from a location name :
from osmgt import OsmGt

roads_osmgt_initialized = OsmGt.roads_from_location(
    location_name="Lyon",
    mode="vehicle",  # or "pedestrian"
    additional_nodes=my_additional_nodes_gdf  # eat a GeoDataframe [optional]
)

# You can get the GeoDataframe
roads_gdf = roads_osmgt_initialized.get_gdf()

# You can get the graph-tool graph based on the roads gdf built
roads_graph = roads_osmgt_initialized.get_graph()

As you can see add additionals nodes on your next network:

  1. with a nodes Geodataframe (attributes are preserved)
  • Get roads network from a bounding box:
from osmgt import OsmGt

roads_osmgt_initialized = OsmGt.roads_from_bbox(
    bbox_values=(min_x=-74.018433, min_y=40.718087, max_x=-73.982749, max_y=40.733356),
    mode="vehicle",  # or "pedestrian"
    additional_nodes=my_additional_nodes_gdf  # eat a GeoDataframe [optional]
)

# You can get a roads GeoDataframe
roads_gdf = roads_osmgt_initialized.get_gdf()
# the topology processing generate a column named "topo_uuid" used as unique id for each features, because the network has been fixing (intersection, connection...)
# OSM attributes are present, especially the OSM ID named "id" (not unique after processing)

# You can get the graph-tool graph based on the roads GeoDataframe built above
roads_graph = roads_osmgt_initialized.get_graph()

Of course you are free to use the graph-tool library !

Point of interests

2 methods are available.

  • Get POIs from a location name:
from osmgt import OsmGt

pois_gdf = OsmGt.pois_from_location(
    location_name="Lyon"
)
  • Get POIs from a bounding box:
from osmgt import OsmGt

pois_gdf = OsmGt.pois_from_bbox(
    bbox_values=(min_x=-74.018433, min_y=40.718087, max_x=-73.982749, max_y=40.733356),
)

Now we can use the GeoDataframe output as argument on the OsmGt.roads_from_bbox() method to add all the POIs found on the roads network !

Let's go to play

Now you have load some data. So we can play with the graph-tool library, compute some network analysis.

We are starting with this:

from osmgt import OsmGt

bbox_area = (74.018433, 40.718087, -73.982749, 40.733356)

pois_gdf = OsmGt.pois_from_bbox(
    bbox_values=bbox_area
)

roads_osmgt_initialized = OsmGt.roads_from_bbox(
    bbox_values=bbox_area,
    mode="vehicle",
    additional_nodes=pois_gdf
)

# You have a roads GeoDataframe
roads_gdf = roads_osmgt_initialized.get_gdf()

# You have a graph-tool graph based on the roads GeoDataframe built above
roads_graph = roads_osmgt_initialized.get_graph()

Be careful: if you do some geometry changes on the output roads Geodataframe, the roads graph generated won't match anymore, because the link between them is based on the node wkt geometry value :

  • graph is build with the start and end geom wkt nodes of each road lines
  • graph edge are based on the "topo_uuid" linestring value
  • graph edge wiegth based on the line length

That's why the graph-tool graph have some specified methods to link the roads GeoDataframe:

roads_graph = roads_osmgt_initialized.get_graph()

# find a specific vertex based on the name (means geom wkt)
a_vertex = roads_graph.find_vertex_from_name("POINT (1 0)")  # vertex (or node)
an_edge = roads_graph.find_edge_from_name("10_0")  # edge (meaning linestring on the GeoDataframe)

# find a specific edge/vertex based on a graph-tool edge/vertex
an_edge = roads_graph.edge_names[a_graph_tool_edge]
a_vertex = roads_graphaph.vertex_names[a_graph_tool_vertex]

So if you are doing a shortest path computing, you can link the shortest path graph-tool output with your GeoDataframe with these methods. You can see an example HERE at "By using the hard way" ; hard way because OsmGt can help you to do some network analysis...

How can OsmGt help you ?

OsmGt have other method to help you to compute:

  • shortest paths
  • isochrones

Shortest paths

2 methods are available:

  • Find some shortest paths from a location name
from osmgt import OsmGt

shortest_paths_gdf = OsmGt.shortest_path_from_location(
    location_name="Lyon",
    source_target_points=source_targets_pairs,  # a list of tuples containing a source and target shapely Point,
    mode="pedestrian",  # or "vehicle"
)
  • Find some shortest paths from a bounding box
from osmgt import OsmGt

shortest_paths_gdf = OsmGt.shortest_path_from_bbox(
    bbox_values=(74.018433, 40.718087, -73.982749, 40.733356),
    source_target_points=source_targets_pairs,  # a list of tuples containing a source and target shapely Point,
    mode="pedestrian",  # or "vehicle"
)

Each function returns 1 GeoDataframe containing all the shortest paths computed [TODO describe column generated by OsmGT]

Isochrones

2 methods are available:

  • create isochrone based on times
from osmgt import OsmGt

isochrones_polygons_gdf, isochrones_lines_gdf = OsmGt.isochrone_from_coordinates(
    source_node=source_point,  # a shapely Point
    isochrones_times=[2, 5, 10],  # in minutes, so we'll create 3 isochrones based on time
    trip_speed=3,  # km/h
    mode="pedestrian",  # or "vehicle"
)
  • create isochrone based on distances
from osmgt import OsmGt

isochrones_polygons_gdf, isochrones_lines_gdf = isochrone_distance_from_coordinates(
    source_node=source_point,  # a shapely Point
    distances=[100, 1000],  # in meters, so we'll create 2 isochrones based on distance
    trip_speed=3,  # km/h
    mode="pedestrian",  # or "vehicle"
)

Each function returns 2 GeoDataframe containing:

  1. isochrones polygons
  2. roads network concerned and tagged by each isochrone [TODO describe column generated by OsmGT]
Clone this wiki locally