Search code examples
gisopenstreetmapgeopandasosmnx

How to download buildings data from OSM with a polygon (shapefile) as the bounding box?


I am struggling to complete this task. I am trying OSMnx which can be used to download data from OSM above however I am getting an error when using its from_polygon feature when trying to download data. Also I am not sure if this data will include Buildings data.

I load my shapefile into geopandas and can then view and interact with it

This is the code

Building_data = ox.graph_from_polygon(my_shapefile, network_type='all')
ox.plot_graph(Building_data)

However I am getting this error

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

EDIT: So I tried to use the OSMnx library instead:

import osmnx as ox
import shapefile
import geopandas
from shapely.geometry import shape

shp = shapefile.Reader('shapefile.shp')
feature = shp.shapeRecords()[0]
first = feature.shape.__geo_interface__

#convert to shapely shape
shp_geom = shape(first)

fprints = ox.geometries.geometries_from_polygon(shp_geom, {'buildings':True})

fprints.to_file('footprints.shp', driver='ESRI Shapefile')

However even though I am using a shapefile with OSMnx I am still getting the error:

CRSError: Invalid projection: +proj=utm +zone=80957 +ellps=WGS84 +datum=WGS84 +units=m +no_defs +type=crs: (Internal Proj Error: proj_create: Error -35 (invalid UTM zone number))

Any ideas?


Solution

  • I wasn't able to download buildings data from OSM with a polygon (shapefile) as the bounding box however I was able to using distance from a point with the following code:

    import osmnx as ox 
    import ast
    
    point = 'point coordinates'
    dist = 'distance in m'
    buildings = ox.geometries.geometries_from_point(point, {'building': True}, dist=dist)
    

    And convert to a geodataframe:

    buildings_save = buildings.applymap(lambda x: str(x) if isinstance(x, list) else x)
    

    Then I clip the buildings data to a boundary using geopandas:

    import geopandas as gpd
    
    boundary = gpd.read_file('C:/boundary.shp')
    buildings_final = gpd.clip(buildings_save, boundary)
    

    Plot the data to check:

    import matplotlib.pyplot as plt
    
    fig, ax = plt.subplots(figsize = (15,12))
    buildings_final.plot(ax = ax, color = 'red', edgecolor = 'black',)
    plt.title('Buildings Data')
    plt.show()