Python中如何排除落在建筑物形状范围内的地理坐标点
问题原因
你代码里存在三个核心错误,导致判断结果不符合预期:
- 坐标顺序错误:OSMNX返回的地理要素、shapely的
Point构造函数,均遵循先经度、后纬度的参数顺序,你当前构造点时写为Point(df.lat[point],df.lng[point]),顺序完全颠倒,相当于把所有点放到了和实际位置完全不相关的坐标上,自然无法匹配到建筑物范围。 - 赋值逻辑错误:循环中每次判断都直接给整个
df['within_building']列赋值,而非给当前行单独赋值,最终整列的值只会和最后一次循环的判断结果一致,完全不符合逐行判断的需求。 - 判断逻辑错误:你使用了
.all()进行判断,逻辑变为「只有所有建筑物都包含该点,才标记为在建筑内」,这显然不符合业务逻辑,我们只要点落在任意一栋建筑范围内就需要标记,应该用.any()判断。
验证建筑物多边形的方法
你可以直接用folium的GeoJson组件将OSMNX拿到的建筑物面叠加到地图上,和你的点直接可视化对比:
# 叠加建筑物到现有地图 folium.GeoJson(gdf.geometry, name="buildings").add_to(wash_map) # 增加图层控制方便切换查看 folium.LayerControl().add_to(wash_map)
修正后的完整代码
import pandas as pd import osmnx as ox import folium from shapely.geometry import Point # 示例数据 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] }) def filter_building_points(df, center_point, dist): ox.config(log_console=True) tags = {"building": True} # 获取范围内建筑物 gdf = ox.geometries.geometries_from_point(center_point, tags, dist=dist) # 逐行判断点是否在建筑内 within_building = [] for _, row in df.iterrows(): # 注意Point参数顺序是 经度、纬度 point = Point(row['lng'], row['lat']) # 只要落在任意一个建筑内就标记为True is_in = gdf.geometry.contains(point).any() within_building.append(is_in) df['within_building'] = within_building return gdf # 执行判断 gdf_buildings = filter_building_points(df, [38.8977, -77.0365], 1000) # 绘制验证地图 wash_map = folium.Map(location=[38.8977, -77.0365], zoom_start=15) # 加建筑物图层 folium.GeoJson(gdf_buildings.geometry, name="建筑物").add_to(wash_map) # 加点,建筑内的点标红,建筑外的点标绿 for _, row in df.iterrows(): color = 'red' if row['within_building'] else 'green' folium.CircleMarker( location=[row["lat"], row["lng"]], radius=5, fill=True, fill_color=color, color=color ).add_to(wash_map) folium.LayerControl().add_to(wash_map) wash_map.save('check_buildings.html')
内容的提问来源于stack exchange,提问作者Luis
相关产品推荐
相关产品推荐

