OSMnx: Python for street networks. Retrieve, model, analyze, and visualize street networks and other spatial data from OpenStreetMap.


PyPI Version PyPI Downloads Anaconda Downloads Documentation Status Build Status Coverage Status


OSMnx is a Python package that lets you download geospatial data from OpenStreetMap and model, project, visualize, and analyze real-world street networks and any other geospatial geometries. You can download and model walkable, drivable, or bikeable urban networks with a single line of Python code then easily analyze and visualize them. You can just as easily download and work with other infrastructure types, amenities/points of interest, building footprints, elevation data, street bearings/orientations, and speed/travel time.

If you use OSMnx in your work, please cite the journal article.

Citation info: Boeing, G. 2017. "OSMnx: New Methods for Acquiring, Constructing, Analyzing, and Visualizing Complex Street Networks." Computers, Environment and Urban Systems 65, 126-139. doi:10.1016/j.compenvurbsys.2017.05.004

Getting Started

How do I install OSMnx? See the installation instructions.

How do I use OSMnx? See the usage examples and tutorials in the examples repo.

How does this function work? Check out the documentation.

What can I do with OSMnx? Check out recent projects and blog posts that used OSMnx.

I have a usage question. Please ask it on StackOverflow.


OSMnx is built on top of GeoPandas, NetworkX, and matplotlib and interacts with OpenStreetMap's APIs to:

  • Download and model street networks or other networked infrastructure anywhere in the world with a single line of code
  • Download any other spatial geometries, place boundaries, building footprints, or points of interest as a GeoDataFrame
  • Download by city name, polygon, bounding box, or point/address + network distance
  • Download drivable, walkable, bikeable, or all street networks
  • Download node elevations and calculate edge grades (inclines)
  • Impute missing speeds and calculate graph edge travel times
  • Simplify and correct the network's topology to clean-up nodes and consolidate intersections
  • Fast map-matching of points, routes, or trajectories to nearest graph edges or nodes
  • Save networks to disk as shapefiles, GeoPackages, and GraphML
  • Save/load street network to/from a local .osm XML file
  • Conduct topological and spatial analyses to automatically calculate dozens of indicators
  • Calculate and visualize street bearings and orientations
  • Calculate and visualize shortest-path routes that minimize distance, travel time, elevation, etc
  • Visualize street networks as a static map or interactive Leaflet web map
  • Visualize travel distance and travel time with isoline and isochrone maps
  • Plot figure-ground diagrams of street networks and building footprints

All of these features are demonstrated in the examples repo and documented in the documentation. Feature development details are in the change log. Read the journal article for further technical details.

  • Extend clean_intersections to return a new graph, topologically equal to the input graph, but with clusters of nodes merged into a single centroid node.

    Extend clean_intersections to return a new graph, topologically equal to the input graph, but with clusters of nodes merged into a single centroid node.

    Hi @gboeing. I'm happy to put forward the first version of the new clean_intersections() method. The method now returns the simplified graph instead of just the intersection centroids.

    I've added comments to the code, which hopefully will be easy to follow, but I'm happy to write down the main steps of the algorithm. The method doesn't appear to be (too) slow, but there is probably room for improvement.

    There are a few nuances to look out for, e.g. when choosing between multiple geometries, but I think that the final decision was sensible.

    Finally, the simplified graph can end up having a lot of nodes of degree 2 (in its undirected version). Therefore, further simplification can be achieved by removing these nodes. I'm working on this, but maybe this should be a separate method.

    I'm looking forward to your input. Cheers, Pedro.

    opened by ppintosilva 41
  • New feature: Retrieving OSM POIs with osmnx?

    New feature: Retrieving OSM POIs with osmnx?


    first of all, awesome work with the package! Highly useful and needed.

    I was wondering if there would be interest to include separate functionalities to retrieve OpenStreetMap POIs with osmnx? I am currently starting to write such functionalities for my own project, and I think I will be using osmnx as a basis for fetching Points of interest from OpenStreetMap (such as restaurants etc.). I know that it is possible to work with other infrastructures than roads, but if I have understood correctly that function works only with graphs, not with point data such as POIs.

    If you think this would be interesting, I would be happy to help implementing these functions.

    Cheers, Henrikki

    P.S. FYI: I introduce osmnx also with the fully open GIS course (Lesson 7) that can be found here http://autogis.github.io.

    opened by HTenkanen 37
  • ValueError: Geometry must be a shapely Polygon or MultiPolygon

    ValueError: Geometry must be a shapely Polygon or MultiPolygon

    If we run this code:

    import osmnx as ox
    G = ox.graph_from_place('Baltimore, Maryland, USA', network_type='drive')

    We get this error:

    ValueError                                Traceback (most recent call last)
    <ipython-input-1-afb511cf7347> in <module>()
          1 import osmnx as ox
          2 ox.config(log_console=True)
    ----> 3 G = ox.graph_from_place('Baltimore, Maryland, USA', network_type='drive')
    C:\Anaconda\lib\site-packages\osmnx\osmnx.py in graph_from_place(query, network_type, simplify, retain_all, truncate_by_edge, name, which_result, buffer_dist, timeout, memory, max_query_area_size, clean_periphery)
       1815     # create graph using this polygon(s) geometry
       1816     G = graph_from_polygon(polygon, network_type=network_type, simplify=simplify, retain_all=retain_all, 
    -> 1817                            truncate_by_edge=truncate_by_edge, name=name, timeout=timeout, memory=memory, max_query_area_size=max_query_area_size, clean_periphery=clean_periphery)
       1819     log('graph_from_place() returning graph with {:,} nodes and {:,} edges'.format(len(G.nodes()), len(G.edges())))
    C:\Anaconda\lib\site-packages\osmnx\osmnx.py in graph_from_polygon(polygon, network_type, simplify, retain_all, truncate_by_edge, name, timeout, memory, max_query_area_size, clean_periphery)
       1730         raise ValueError('Shape does not have a valid geometry')
       1731     if not isinstance(polygon, (Polygon, MultiPolygon)):
    -> 1732         raise ValueError('Geometry must be a shapely Polygon or MultiPolygon')
       1734     if clean_periphery and simplify:
    ValueError: Geometry must be a shapely Polygon or MultiPolygon
    opened by gboeing 28
  • graph_from_place giving networkx NetworkXPointlessConcept Exception

    graph_from_place giving networkx NetworkXPointlessConcept Exception

    I am trying to follow the article on the link here (awesome blog btw).

    However, every time I try to get a graph from a place using graph_from_place I get the following error:

      File "/home/manuel/miniconda3/envs/test/lib/python3.5/site-packages/osmnx/osmnx.py", line 1815, in graph_from_place
        truncate_by_edge=truncate_by_edge, name=name, timeout=timeout, memory=memory, max_query_area_size=max_query_area_size, clean_periphery=clean_periphery)
      File "/home/manuel/miniconda3/envs/test/lib/python3.5/site-packages/osmnx/osmnx.py", line 1749, in graph_from_polygon
        G = truncate_graph_polygon(G_buffered, polygon, retain_all=retain_all, truncate_by_edge=truncate_by_edge)
      File "/home/manuel/miniconda3/envs/test/lib/python3.5/site-packages/osmnx/osmnx.py", line 1320, in truncate_graph_polygon
        G = get_largest_component(G)
      File "/home/manuel/miniconda3/envs/test/lib/python3.5/site-packages/osmnx/osmnx.py", line 1099, in get_largest_component
        if not nx.is_weakly_connected(G):
      File "<decorator-gen-62>", line 2, in is_weakly_connected
      File "/home/manuel/miniconda3/envs/test/lib/python3.5/site-packages/networkx/utils/decorators.py", line 68, in _not_implemented_for
        return f(*args,**kwargs)
      File "/home/manuel/miniconda3/envs/test/lib/python3.5/site-packages/networkx/algorithms/components/weakly_connected.py", line 178, in is_weakly_connected
        """Connectivity is undefined for the null graph.""")
    networkx.exception.NetworkXPointlessConcept: Connectivity i

    gdf_from_place works, as well as graph_from_point .

    I am using spatialindex=1.8.5

    The environment's packages:


    My machine's watermark:

    CPython 3.5.1
    IPython 4.2.0
    compiler   : GCC 4.4.7 20120313 (Red Hat 4.4.7-1)
    system     : Linux
    release    : 4.4.0-47-generic
    machine    : x86_64
    processor  : x86_64
    CPU cores  : 8
    interpreter: 64bit
    opened by manugarri 25
  • New geometries module - Work In Progress

    New geometries module - Work In Progress

    Resolves #478

    Work in progress on a new geometries module that combines the capabilities of the existing pois and footprints modules and introduces conversion of ways to LineStrings or Polygons as appropriate.


    # New geometries module
    MK = ox.gdf_from_point((52.0430,-0.7590), dist=1000, tags={'highway':True, 'landuse':True, 'building':True})
    # Presentation code
    MK.to_crs(epsg=27700, inplace=True)
    fig,ax = plt.subplots(figsize=(16,16))
    MK[MK['landuse'].notna()].plot(ax=ax, column='landuse', cmap='tab20b', legend=True)
    MK[MK['highway'].notna()].plot(ax=ax, color='white')
    MK[MK['building'].notna()].plot(ax=ax, color='dimgrey', zorder=3)


    opened by AtelierLibre 24
  • Add scheduled Overpass and Nominatim API tests

    Add scheduled Overpass and Nominatim API tests

    Adds tests for OpenStreetMap APIs designed to run on a schedule under AWS Lambda.

    This is a stub and I’m looking for feedback on the approach. osm_api_tests.py is outside the normal project hierarchy, and gets deployed to Lambda as a standalone Python 3 script. It’s possible but slightly annoying to include 3rd party packages on Lambda, so I’m using only standard library functionality. If merged, the AWS deployment details will need to be updated.

    Will close https://github.com/gboeing/osmnx/issues/107.

    opened by migurski 24
  • add geometries module

    add geometries module

    This PR consolidates testing and revisions to the work done by @AtelierLibre in #542. Closes #478.

    It also incorporates the changes in #552 including:

    • renames all the geometries.gdf_from_x functions -> geometries.geometries_from_x
    • makes polygon_features module private
    • deprecates the footprints module/functions with a user warning
    • deprecates the pois module/functions with a user warning
    • cleans up comments and docstrings
    • autodocs the geometries module

    Plus some refactoring/generalizing of code in the truncate and utils_geo modules to make pre-existing code more general for use in both graph construction as well as geometries GeoDataFrame construction.

    opened by gboeing 23
  • Feature: Closest Road to a certain location's coordinates

    Feature: Closest Road to a certain location's coordinates

    I'm using osmnx and networkx for calculating shortest routes in Dubai and I'm having an issue when finding the closest road to a tracking location's coordinates. Even if I use coordinates that are right on a specific highway, sometimes it is matched to a close road due to the fact that I use the osmnx.get_nearest_node to find the closest road. This function will search for the closest graph node in the OSM map to that specific location. Due to the fact that for certain highways you have very large distances between consective node, the closest node might not be on the same road on which the tracking location was recorded. It would be nice if there was a method osmnx.get_nearest_edge that mapped each location to the closest road.

    Here is an example with 2 orig_coordinates that were recorded on the same highway but the second one is matched to a node on a different road. I recommend using jupyter notebooks to visualize the problem on the map

    import networkx as nx
    import osmnx as ox
    import requests
    from matplotlib import pyplot as plt
    import matplotlib.cm as cm
    import matplotlib.colors as colors
    ox.config(use_cache=True, log_console=True)
    # get a graph for some city
    SMALL_MARINA = [25.09, 25.06, 55.16, 55.11]
    G2 = ox.graph_from_bbox(
    fig2, ax2 = ox.plot_graph(G2, fig_height=20, fig_width=20)
    # get the nearest network node to each point
    good_orig_node = ox.get_nearest_node(G2, (25.070661, 55.137911), method='euclidean')
    bad_orig_node = ox.get_nearest_node(G2, (25.071764, 55.138978), method='euclidean')
    dest_node = ox.get_nearest_node(G2, (25.079223, 55.146241), method='euclidean')
    # find the route between these nodes then plot it
    route = nx.shortest_path(G2, good_orig_node, dest_node, weight='length')
    fig, ax = ox.plot_graph_route(G2, route, fig_height=20, fig_width=20)
    # find the route between these nodes then plot it
    route = nx.shortest_path(G2, bad_orig_node, dest_node, weight='length')
    fig, ax = ox.plot_graph_route(G2, route, fig_height=20, fig_width=20)

    Coordinate(South-West) is matched to the right road

    screen shot 2018-08-24 at 17 07 42

    Coordinate(South-West) is matched to the wrong road

    screen shot 2018-08-24 at 17 07 59 enhancement 
    opened by miskolc 22
  • Are the pois module and footprints module redundant?

    Are the pois module and footprints module redundant?

    Over time, the pois and footprints modules have expanded their functionality and grown more similar to each other. I believe they are approximately redundant now and should be merged together to simplify the codebase.

    The following methods are approximately equivalent:

    import osmnx as ox
    ox.config(use_cache=True, log_console=True)
    place = 'Emeryville, CA, USA'
    # use pois module
    po = ox.pois_from_place(place, tags={'building':True})
    po.shape #(1117, 73)
    # use footprints module
    fp = ox.footprints_from_place(place)
    fp.shape #(1127, 55)

    Minor differences would have to be reconciled between these modules (especially the detailed handling of relations in footprints) to account for the differences between the resulting GeoDataFrames.

    enhancement help wanted 
    opened by gboeing 21
  • Certificate verify failed

    Certificate verify failed

    Hello all,

    I am new here thus excuse me if I am asking something simple.

    I have been trying to get osmnx going with that: import osmnx as ox city = ox.gdf_from_place('Berkeley, CA') ox.plot_shape(ox.project_gdf(city))

    But I am getting this output error all the time: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)

    Please could you suggest any solutions cause the ones I have seen so far are not working.

    Thanks a lot.

    opened by tetekos 20
  • Add node elevations from DEM files

    Add node elevations from DEM files

    Refactor of #343 to use demquery.


    • I split my code into a new Python package on PyPI.
    • Since learning about Virtual Rasters, the code to find elevations is an order of magnitude simpler. I don't do any joining of nearby rasters; GDAL does all of that.
    • I discovered that interp2d gives those warnings only when the grid is not the expected size for the type of interpolation: 3x3 for linear interpolation, 5x5 for cubic interpolation, and 7x7 for quintic interpolation. So I removed the option to manually choose the size of the interpolation region. If interp_kind is linear, it creates a 3x3 grid.
    • Checks for nodata values; the virtual raster can have regions with no data that are inside the file's bounds, if the provided files didn't create an exact rectangle. My package raises an error if it sees those values in the interpolation region.
    • I'm working on writing tests in the demquery package. ~~I'm having issues with rasterio working on Travis CI~~ the osmnx .travis.yml was quite helpful.
    • Do you have plans to deprecate Python 2.7 and 3.4? Python 3.4 is already end of life, and 2.7 is in a month. I made demquery 3.5+ compatible, but haven't tested Python 2.7.
    • Right now, demquery is only on PyPI, and I think that's why the current Travis build is failing.


    Download both the files USGS_NED_13_n33w117_IMG USGS_NED_13_n34w117_IMG 450MB extracted each

    import osmnx as ox
    west = -116.66587829589844
    south = 32.90120475753773
    north = 33.094201303793194
    east = -116.46263122558594
    G = ox.graph_from_bbox(north=north, south=south, west=west, east=east)
    dem_paths = ['USGS_NED_13_n33w117_IMG.img', 'USGS_NED_13_n34w117_IMG.img']
    # interp_kind can be None, linear, cubic, or quintic
    G = add_node_elevations_from_dem(G, dem_paths, interp_kind=None)
    G = add_edge_grades(G)
    opened by kylebarron 19
  • Improvements to save_as_xml function

    Improvements to save_as_xml function

    Somewhat related to issue #915.

    Commits are quite self-explanatory, but this fixes a few things:

    1. A bug where non-existent tags would get written to the XML file when they shouldn't.
    2. Adds a way to specify the OSM version to write in the header
    3. Adds a way to specify how many decimals to keep when writing lat-long coordinates
    4. Sets the encoding to UTF-8. This is useful for areas that have non-ascii characters in the name (for example, in Québec)


    opened by davidmurray 2
  • drop GDAL dependency

    drop GDAL dependency

    OSMnx currently depends on GDAL directly in the elevation module to build VRTs, because rasterio doesn't expose equivalent functionality directly. However, it's not a good idea to import both rasterio and GDAL into the same working environment (see https://github.com/rasterio/rasterio/issues/2573#issuecomment-1368135052).

    Rasterio devs are currently proposing new functionality that would allow us to build VRTs directly with rasterio. If so, we could drop the GDAL dependency. See this issue and this PR.

    opened by gboeing 0
  • Simplify save_graph_xml output

    Simplify save_graph_xml output

    Do not delete the following template. Fill it out completely.

    Is your feature proposal related to a problem?

    The save_graph_xml function adds a lot of (unnecessary?) data to the resulting XML file: https://github.com/gboeing/osmnx/blob/586cf2651af80c2cdb1c6e30b94d8176beea7c4a/osmnx/osm_xml.py#L207-L212

    The resulting XML file has a lot of extra fields compared to regular OSM XML files :

    <?xml version="1.0"?>
    <osm version="0.6" generator="OSMnx">
      <node id="0" timestamp="2017-01-01T00:00:00Z" uid="1" user="osmnx" version="1" changeset="1" lat="45.5571316" lon="-73.5963673">
        <tag k="highway" v="nan"/>
      <node id="1" timestamp="2017-01-01T00:00:00Z" uid="1" user="osmnx" version="1" changeset="1" lat="nan" lon="nan">
        <tag k="highway" v="nan"/>
      <node id="2" timestamp="2017-01-01T00:00:00Z" uid="1" user="osmnx" version="1" changeset="1" lat="nan" lon="nan">
        <tag k="highway" v="nan"/>
      <node id="3" timestamp="2017-01-01T00:00:00Z" uid="1" user="osmnx" version="1" changeset="1" lat="45.5575365" lon="-73.5889391">
        <tag k="highway" v="nan"/>

    In addition, what's the point of the timestamp if it's always the same date in 2017?

    Describe the solution you'd like to propose


    1. Adding a parameter to save_graph_xml to decide whether or not these extra fields should be added to the xml file, or:
    2. Removing this code altogether.


    opened by davidmurray 5
  • Include Point geometries in folium module to plot nodes interactively

    Include Point geometries in folium module to plot nodes interactively

    Hi @gboeing! I'm working on a streamlit project where users can get bbox coordinates by clicking on a web map. The main goal is to let them create their own street networks and get some relevant stats to study the mobility in the target area.

    The folium module looks great to add some interactivity to the analysis but I faced that it only supports LineStrings geometries. And since I do not want to only describe the graph with edges but also with nodes, I was looking for some extra methods to allow plotting them based on their connectivity attributes.

    Specifically, I needed to render Point geometries on a Leaflet web map and get them colored by some attribute (betweenness centrality, degree centrality, node degree, etc) with the cmap bar legend/reference. Something like this:


    Below I share you the code and some examples:

    1. build a Point geoms gdf and add node colors based on some attribute
    2. create a circle marker map based on color attributes
    3. some examples can be found here

    If you find this could be an interesting feature to add in the folium.py module we can have some further discussions about the CircleMarker map implementation.


    opened by PyMap 2
Geoff Boeing
Urban planning professor at USC: urban analytics, street networks, rental markets, data science.
Geoff Boeing
Spatial Interpolation Toolbox is a Python-based GUI that is able to interpolate spatial data in vector format.

Spatial Interpolation Toolbox This is the home to Spatial Interpolation Toolbox, a graphical user interface (GUI) for interpolating geographic vector

Michael Ward 2 Nov 1, 2021
prettymaps - A minimal Python library to draw customized maps from OpenStreetMap data.

A small set of Python functions to draw pretty maps from OpenStreetMap data. Based on osmnx, matplotlib and shapely libraries.

Marcelo de Oliveira Rosa Prates 9k Jan 8, 2023
Python renderer for OpenStreetMap with custom icons intended to display as many map features as possible

Map Machine project consists of Python OpenStreetMap renderer: SVG map generation, SVG and PNG tile generation, Röntgen icon set: unique CC-BY 4.0 map

Sergey Vartanov 0 Dec 18, 2022
Location field and widget for Django. It supports Google Maps, OpenStreetMap and Mapbox

django-location-field Let users pick locations using a map widget and store its latitude and longitude. Stable version: django-location-field==2.1.0 D

Caio Ariede 481 Dec 29, 2022
A bot that tweets info and location map for new bicycle parking added to OpenStreetMap within a GeoJSON boundary.

Bike parking tweepy bot app A twitter bot app that searches for bicycle parking added to OpenStreetMap. Relies on AWS Lambda/S3, Python3, Tweepy, Flas

Angelo Trivisonno 1 Dec 19, 2021
A library to access OpenStreetMap related services

OSMPythonTools The python package OSMPythonTools provides easy access to OpenStreetMap (OSM) related services, among them an Overpass endpoint, Nomina

Franz-Benjamin Mocnik 342 Dec 31, 2022
Use Mapbox GL JS to visualize data in a Python Jupyter notebook

Location Data Visualization library for Jupyter Notebooks Library documentation at https://mapbox-mapboxgl-jupyter.readthedocs-hosted.com/en/latest/.

Mapbox 620 Dec 15, 2022
A package built to support working with spatial data using open source python

EarthPy EarthPy makes it easier to plot and manipulate spatial data in Python. Why EarthPy? Python is a generic programming language designed to suppo

Earth Lab 414 Dec 23, 2022
Processing and interpolating spatial data with a twist of machine learning

Documentation | Documentation (dev version) | Contact | Part of the Fatiando a Terra project About Verde is a Python library for processing spatial da

Fatiando a Terra 468 Dec 20, 2022
Python library to visualize circular plasmid maps

Plasmidviewer Plasmidviewer is a Python library to visualize plasmid maps from GenBank. This library provides only the function to visualize circular

Mori Hideto 9 Dec 4, 2022
PySAL: Python Spatial Analysis Library Meta-Package

Python Spatial Analysis Library PySAL, the Python spatial analysis library, is an open source cross-platform library for geospatial data science with

Python Spatial Analysis Library 1.1k Dec 18, 2022
Raster-based Spatial Analysis for Python

?? xarray-spatial: Raster-Based Spatial Analysis in Python ?? Fast, Accurate Python library for Raster Operations ⚡ Extensible with Numba ⏩ Scalable w

makepath 649 Jan 1, 2023
Using SQLAlchemy with spatial databases

GeoAlchemy GIS Support for SQLAlchemy. Introduction GeoAlchemy is an extension of SQLAlchemy. It provides support for Geospatial data types at the ORM

null 109 Dec 1, 2022
Software for Advanced Spatial Econometrics

GeoDaSpace Software for Advanced Spatial Econometrics GeoDaSpace current version 1.0 (32-bit) Development environment: Mac OSX 10.5.x (32-bit) wxPytho

GeoDa Center 38 Jan 3, 2023
Using Global fishing watch's data to build a machine learning model that can identify illegal fishing and poaching activities through satellite and geo-location data.

Using Global fishing watch's data to build a machine learning model that can identify illegal fishing and poaching activities through satellite and geo-location data.

Ayush Mishra 3 May 6, 2022
Hapi is a Python library for building Conceptual Distributed Model using HBV96 lumped model & Muskingum routing method

Current build status All platforms: Current release info Name Downloads Version Platforms Hapi - Hydrological library for Python Hapi is an open-sourc

Mostafa Farrag 15 Dec 26, 2022
Open Data Cube analyses continental scale Earth Observation data through time

Open Data Cube Core Overview The Open Data Cube Core provides an integrated gridded data analysis environment for decades of analysis ready earth obse

Open Data Cube 410 Dec 13, 2022
A public data repository for datasets created from TransLink GTFS data.

TransLink Spatial Data What: TransLink is the statutory public transit authority for the Metro Vancouver region. This GitHub repository is a collectio

Henry Tang 3 Jan 14, 2022
A short term landscape evolution using a path sampling method to solve water and sediment flow continuity equations and model mass flows over complex topographies.

r.sim.terrain A short-term landscape evolution model that simulates topographic change for both steady state and dynamic flow regimes across a range o

Brendan Harmon 7 Oct 21, 2022