You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带面积属性的GIS点等面积分组技术实现咨询

实现GIS点按总面积均等分组的方案

Python 实现

这是处理大规模数据最灵活的方案,核心采用贪心近似算法(数据量较大时能快速得到接近均等的分组结果,精度足以满足需求):

  1. 准备数据:将GIS点的属性表导出为CSV格式(需包含唯一ID和面积字段)
  2. 编写Python脚本:
import pandas as pd

# 读取数据
df = pd.read_csv("points_area.csv")
# 计算每组目标总面积
total_area = df["area"].sum()
target_per_group = total_area / 20

# 按面积从大到小排序,优先分配大值提升分组均等性
df_sorted = df.sort_values(by="area", ascending=False)

# 初始化20个分组
groups = [{"total": 0, "ids": []} for _ in range(20)]

for idx, row in df_sorted.iterrows():
    # 找到当前总面积最小的分组
    min_group = min(groups, key=lambda x: x["total"])
    # 将当前点加入该分组
    min_group["total"] += row["area"]
    min_group["ids"].append(row["id"])

# 整理分组结果并关联原数据
group_mapping = []
for group_id, group in enumerate(groups):
    for point_id in group["ids"]:
        group_mapping.append({"id": point_id, "group_id": group_id + 1})

group_df = pd.DataFrame(group_mapping)
result_df = pd.merge(df, group_df, on="id")
# 保存结果
result_df.to_csv("points_grouped.csv", index=False)
  1. 将分组结果CSV通过唯一ID字段关联回原GIS点要素类,添加group_id字段即可完成分组。

ArcGIS Desktop 实现

可结合ArcGIS的Python脚本工具完成:

  • 步骤1:打开ArcMap/ArcGIS Pro,右键点要素类 -> 导出 -> 表转CSV,导出属性表
  • 步骤2:运行上述Python脚本得到分组后的CSV文件
  • 步骤3:右键地理数据库 -> 导入 -> 表,将分组CSV导入ArcGIS
  • 步骤4:使用连接和关联工具,通过唯一ID字段将分组表与原要素类连接,右键连接后的图层 -> 属性 -> 连接和关联 -> 右键分组表 -> 复制字段,将group_id字段复制到原要素类
  • 步骤5:通过group_id字段进行分组选择、导出或符号化。

也可直接在ArcGIS中运行适配ArcPy的脚本:

import arcpy

fc = "your_point_feature_class"
area_field = "area"
id_field = "OBJECTID"
group_field = "group_id"

# 添加分组字段
arcpy.AddField_management(fc, group_field, "SHORT")

# 读取所有点的ID和面积
points = []
with arcpy.da.SearchCursor(fc, [id_field, area_field]) as cursor:
    for row in cursor:
        points.append({"id": row[0], "area": row[1]})

# 计算目标面积并排序
total_area = sum(p["area"] for p in points)
target_per_group = total_area / 20
points_sorted = sorted(points, key=lambda x: x["area"], reverse=True)

# 初始化分组并分配点
groups = [{"total": 0, "ids": []} for _ in range(20)]
for p in points_sorted:
    min_group = min(groups, key=lambda x: x["total"])
    min_group["total"] += p["area"]
    min_group["ids"].append(p["id"])

# 更新要素类的分组字段
group_dict = {}
for group_id, group in enumerate(groups):
    for pid in group["ids"]:
        group_dict[pid] = group_id + 1

with arcpy.da.UpdateCursor(fc, [id_field, group_field]) as cursor:
    for row in cursor:
        row[1] = group_dict[row[0]]
        cursor.updateRow(row)

QGIS 实现

结合Python脚本或图形化工具操作:

  1. 右键点图层 -> 导出 -> 导出属性表,将属性表导出为CSV
  2. 运行基础Python脚本得到分组CSV
  3. 图层 -> 添加图层 -> 添加矢量图层,选择分组CSV导入QGIS
  4. 打开Processing工具箱 -> 矢量通用 -> 连接属性,通过唯一ID字段将分组表与原点图层连接
  5. 右键原点图层 -> 属性表 -> 字段计算器,新建字段并赋值为group_id,将分组字段永久保存到原图层
  6. 通过group_id字段进行分组操作。

也可直接在QGIS Python控制台运行适配脚本:

from qgis.core import QgsVectorLayer, QgsField, QgsFeature
from PyQt5.QtCore import QVariant

layer = iface.activeLayer()
area_field = "area"
id_field = "fid"
group_field = "group_id"

# 添加分组字段
layer.startEditing()
layer.dataProvider().addAttributes([QgsField(group_field, QVariant.Int)])
layer.updateFields()

# 读取点数据
points = []
for feat in layer.getFeatures():
    points.append({"id": feat[id_field], "area": feat[area_field]})

# 计算目标面积并排序
total_area = sum(p["area"] for p in points)
target_per_group = total_area / 20
points_sorted = sorted(points, key=lambda x: x["area"], reverse=True)

# 分组逻辑
groups = [{"total": 0, "ids": []} for _ in range(20)]
for p in points_sorted:
    min_group = min(groups, key=lambda x: x["total"])
    min_group["total"] += p["area"]
    min_group["ids"].append(p["id"])

# 更新图层分组字段
group_dict = {}
for group_id, group in enumerate(groups):
    for pid in group["ids"]:
        group_dict[pid] = group_id + 1

for feat in layer.getFeatures():
    feat[group_field] = group_dict[feat[id_field]]
    layer.updateFeature(feat)

layer.commitChanges()

内容的提问来源于stack exchange,提问作者Spatialised

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 02:33:29