在QGIS中,判断质心(点图层)是否在多边形外部,本文提供以下两种方法。
1. 使用“按位置选择”工具
这是最直接的方法,用于交互式选择。
位置:菜单栏 → 矢量 → 研究工具 → 按位置选择。
操作:
- 选择要素于设置为质心图层(点图层)。
- 与以下要素进行比较设置为多边形图层。
- 要素位置设置为内含于。
- 点击运行。位于多边形内部的点将被选中。

2. 代码实现
使用如下代码,判断质心是否位于多边形内部。代码已给出文字总结。
from qgis.core import QgsProject, QgsGeometry, QgsSpatialIndex
def check_points_in_polygons():
"""检查每个点是否都包含于一个多边形中(不添加字段)"""
# 获取当前项目
project = QgsProject.instance()
# 获取点图层和多边形图层
point_layer = project.mapLayersByName("点图层")[0]
polygon_layer = project.mapLayersByName("面图层")[0]
if not point_layer or not polygon_layer:
print("未找到指定的图层")
return False
# 获取所有要素
point_features = list(point_layer.getFeatures())
polygon_features = list(polygon_layer.getFeatures())
if not point_features:
print("点图层为空")
return False
if not polygon_features:
print("多边形图层为空")
return False
print("=== 检查点与多边形的包含关系 ===")
# 创建多边形空间索引以提高性能
polygon_index = QgsSpatialIndex(polygon_layer.getFeatures())
# 初始化统计变量
total_points = len(point_features)
total_polygons = len(polygon_features)
points_in_polygons = 0
points_not_in_polygons = 0
# 存储详细结果
point_results = {} # 点ID -> 是否在多边形内
polygon_point_counts = {} # 多边形ID -> 包含的点数
# 初始化多边形计数
for polygon_feature in polygon_features:
polygon_point_counts[polygon_feature.id()] = 0
# 检查每个点
for point_feature in point_features:
point_geom = point_feature.geometry()
point_id = point_feature.id()
# 查找可能包含该点的多边形
candidate_poly_ids = polygon_index.intersects(point_geom.boundingBox())
point_inside = False
containing_polygon_id = None
for poly_id in candidate_poly_ids:
polygon_feature = polygon_layer.getFeature(poly_id)
polygon_geom = polygon_feature.geometry()
# 精确检查点是否在多边形内部
if point_geom.within(polygon_geom):
point_inside = True
containing_polygon_id = poly_id
polygon_point_counts[poly_id] += 1
break
# 记录结果
point_results[point_id] = {
'inside': point_inside,
'polygon_id': containing_polygon_id
}
if point_inside:
points_in_polygons += 1
else:
points_not_in_polygons += 1
# 输出详细结果
print(f"\n=== 统计结果 ===")
print(f"点图层要素总数: {total_points}")
print(f"多边形图层要素总数: {total_polygons}")
print(f"被多边形包含的点数: {points_in_polygons}")
print(f"未被多边形包含的点数: {points_not_in_polygons}")
# 输出每个点的状态
print(f"\n=== 每个点的包含状态 ===")
for point_id, result in point_results.items():
if result['inside']:
print(f"点ID {point_id}: 被多边形ID {result['polygon_id']} 包含")
else:
print(f"点ID {point_id}: 未被任何多边形包含")
# 输出每个多边形包含的点数
print(f"\n=== 每个多边形包含的点数 ===")
for poly_id, count in polygon_point_counts.items():
if count > 0:
print(f"多边形ID {poly_id}: 包含 {count} 个点")
else:
print(f"多边形ID {poly_id}: 未包含任何点")
# 检查是否有多个点被同一个多边形包含
print(f"\n=== 多边形包含多个点的情况 ===")
multiple_points_polygons = []
for poly_id, count in polygon_point_counts.items():
if count > 1:
multiple_points_polygons.append((poly_id, count))
print(f"多边形ID {poly_id}: 包含 {count} 个点(多个点)")
# 最终判断
print(f"\n=== 最终判断 ===")
if points_not_in_polygons == 0:
print("✓ 所有点都包含于多边形内部")
# 检查是否每个多边形最多包含一个点
if len(multiple_points_polygons) == 0:
print("✓ 每个多边形最多包含一个点")
return True
else:
print(f"⚠ 有 {len(multiple_points_polygons)} 个多边形包含多个点")
return False
else:
print(f"✗ 有 {points_not_in_polygons} 个点未被任何多边形包含")
return False
# 运行函数
result = check_points_in_polygons()
print(f"\n函数返回结果: {result}")
代码解读:
采用空间索引检查方法。
原理:先创建多边形图层的空间索引,快速筛选可能包含点的候选多边形,再进行精确判断
优势:性能最优,适合处理大量数据
关键代码:
polygon_index = QgsSpatialIndex(polygon_layer.getFeatures())
candidate_ids = polygon_index.intersects(point_geom.boundingBox())
注意事项:
坐标系一致:确保点图层和多边形图层使用相同的坐标系
几何有效性:确保多边形几何有效(无自相交等错误)
边界情况:点在多边形边界上时,认定为不包含。
更多问题,欢迎留言或联系我们。转载须注明出处。