排除 Python 中建筑物形状列表中的点

Excluding points within list of buildings' shapes in Python

我有一个数据框,其中包含华盛顿 D.C 的数千个具有地理位置(经度、纬度)的点。以下是它的一个片段:

import pandas as pd
df = pd.DataFrame({'lat': [ 38.897221,38.888100,38.915390,38.895100,38.895100,38.901005,38.960491,38.996342,38.915310,38.936820], 'lng': [-77.031048,-76.898480,-77.021380,-77.036700,-77.036700   ,-76.990784,-76.862907,-77.028131,-77.010403,-77.184930]})

如果您在地图上绘制点,您可以看到其中一些点明显位于某些建筑物内:

import folium
wash_map = folium.Map(location=[38.8977, -77.0365], zoom_start=10)
for  index,location_info in df.iterrows():
      folium.CircleMarker(
          location=[location_info["lat"], location_info["lng"]], radius=5,
          fill=True, fill_color='red',).add_to(wash_map)
wash_map.save('example_stack.html')
import webbrowser
import os
webbrowser.open('file://'+os.path.realpath('example_stack.html'), new=2)

我的目标是排除建筑物内的所有点。为此,我首先下载城市建筑的边界框,然后尝试排除这些多边形内的点,如下所示:

import osmnx as ox
#brew install spatialindex this solves problems in mac
%matplotlib inline
ox.config(log_console=True)
ox.__version__
tags = {"building": True}
gdf = ox.geometries.geometries_from_point([38.8977, -77.0365], tags, dist=1000)
gdf.shape

为了计算简单,我请求了白宫周围半径为 1 公里的所有建筑物的形状。在我自己的代码中,我尝试使用更大的半径来确保包括所有建筑物。

为了排除多边形内的点,我开发了以下函数(包括形状获取):

def buildings(df,center_point,dist):
    import osmnx as ox
    #brew install spatialindex this solves problems in mac
    %matplotlib inline
    ox.config(log_console=True)
    ox.__version__
    tags = {"building": True}
    gdf = ox.geometries.geometries_from_point(center_point, tags,dist)
    from shapely.geometry import Point,Polygon
    # Next step is to put our coordinates in the correct shapely format: remember to run the map funciton before
    #df['within_building']=[]
    for point in range(len(df)):
        if gdf.geometry.contains(Point(df.lat[point],df.lng[point])).all()==False:
            df['within_building']=False
        else :
            df['within_building']=True



buildings(df,[38.8977, -77.0365],1000)
df['within_building'].all()==False

函数总是 returns 点在建筑物形状之外,尽管您可以在地图上清楚地看到其中一些点在建筑物形状之内。我不知道如何在我的地图上绘制形状,所以我不确定我的多边形是否正确,但对于坐标来说它们似乎是正确的。有什么想法吗?

您提供的示例点似乎不在这些建筑物的占地面积内。我不知道你的点的坐标参考系统是什么,所以我猜是 EPSG4326。但要回答您的问题,您可以按照以下方式排除它们,从而导致 gdf_points_not_in_bldgs:

import geopandas as gpd
import matplotlib.pyplot as plt
import osmnx as ox
import pandas as pd

# the coordinates you provided
df = pd.DataFrame({'lat': [38.897221,38.888100,38.915390,38.895100,38.895100,38.901005,38.960491,38.996342,38.915310,38.936820],
                   'lng': [-77.031048,-76.898480,-77.021380,-77.036700,-77.036700   ,-76.990784,-76.862907,-77.028131,-77.010403,-77.184930]})

# create GeoDataFrame of point geometries
geom = gpd.points_from_xy(df['lng'], df['lat'])
gdf_points = gpd.GeoDataFrame(geometry=geom, crs='epsg:4326')

# get building footprints
tags = {"building": True}
gdf_bldgs = ox.geometries_from_point([38.8977, -77.0365], tags, dist=1000)
gdf_bldgs.shape

# get all points that are not within a building footprint
mask = gdf_points.within(gdf_bldgs.unary_union)
gdf_points_not_in_bldgs = gdf_points[~mask]
print(gdf_points_not_in_bldgs.shape)  # (10, 1)

# plot buildings and points
ax = gdf_bldgs.plot()
ax = gdf_points.plot(ax=ax, c='r')
plt.show()

# zoom in to see better
ax = gdf_bldgs.plot()
ax = gdf_points.plot(ax=ax, c='r')
ax.set_xlim(-77.04, -77.03)
ax.set_ylim(38.89, 38.90)
plt.show()