Python检测点是否在多边形中:contains方法返回空结果求助
问题:可视化中点在多边形内,但
contains()无匹配结果 操作流程与异常现象
- 成功导入Shapefile:
import geopandas as gpd shapefile_path = "data/TRI_75_SIG_DI/TRI_PARI_SIG_DI/n_tri_pari_carte_inond_s_075.shp" gdf = gpd.read_file(shapefile_path)
- 通过Folium正常展示多边形图层:
import folium m = folium.Map(location=[48.8566, 2.3522], zoom_start=12) folium.GeoJson(gdf).add_to(m) m
- 创建视觉上处于多边形内的点并展示:
import geopandas as gpd from shapely.geometry import Point point_coordinates = (2.3546, 48.8517) point = Point(point_coordinates) m = folium.Map(location=[point_coordinates[1], point_coordinates[0]], zoom_start=13) folium.Marker( location=[point_coordinates[1], point_coordinates[0]], icon=folium.Icon(color='blue'), popup="Point d'intérêt" ).add_to(m) m
- 执行
gdf.geometry.contains(point)后,未得到预期的包含该点的多边形结果。
排查与解决方法
1. 检查并统一坐标系(最常见原因)
Shapefile的坐标系(CRS)大概率和你创建的点不一致:
- 先查看GeoDataFrame的CRS:
print(gdf.crs)
- 你创建的Shapely Point默认无CRS,而Folium使用的是WGS84(经纬度,EPSG:4326),但Shapefile可能采用投影坐标系(如UTM)。
解决代码:
# 将点转为带WGS84坐标系的GeoSeries,再转换为GeoDataFrame的CRS point_gs = gpd.GeoSeries([point], crs="EPSG:4326") point_transformed = point_gs.to_crs(gdf.crs).iloc[0] # 重新执行包含判断 match_result = gdf.geometry.contains(point_transformed) # 输出匹配的多边形 print(gdf[match_result])
2. 修复多边形拓扑错误
部分Shapefile的多边形存在自相交、无效几何等问题,会导致contains()判断失效:
# 修复GeoDataFrame中的无效几何 gdf['geometry'] = gdf.geometry.make_valid() # 再次执行判断 match_result = gdf.geometry.contains(point_transformed) print(gdf[match_result])
3. 尝试反向判断(within())
有时候用点的within()方法判断是否在多边形内,结果更稳定:
match_result = gdf.geometry.apply(lambda geom: point_transformed.within(geom)) print(gdf[match_result])
4. 验证坐标顺序
虽然你当前坐标顺序(经度,纬度)在Folium中显示正常,但少数投影坐标系可能要求相反顺序,可尝试验证:
# 交换坐标创建点并转换CRS point_swapped = Point(48.8517, 2.3546) point_swapped_gs = gpd.GeoSeries([point_swapped], crs="EPSG:4326").to_crs(gdf.crs).iloc[0] match_result = gdf.geometry.contains(point_swapped_gs) print(gdf[match_result])
内容的提问来源于stack exchange,提问作者John Smith
相关产品推荐
相关产品推荐

