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

如何按名称前缀合并Shapefile要素类并聚合几何?

要素类合并与几何聚合实现方案

我已成功读取包含多种要素类的Shapefile,感谢@Pieter的建议,优化后的代码如下:

import geopandas as gpd
from shapely import box
from shapely.geometry.polygon import Polygon
from shapely.geometry.multipolygon import MultiPolygon

shapefile = "LAFIS.shp"
vect_data = gpd.read_file(shapefile)

vec_data.head()
vec_data['DESCR_ENG'].unique()
geometry_arr = (vec_data['geometry'])
descr_name_arr = (vec_data['DESCR_ENG'])
d = {
    "BW_name": descr_name_arr,
    "geometry": geometry_arr,
}
gdf = gpd.GeoDataFrame(d, crs="EPSG:25832")
gdf

test_vector_data = gpd.GeoDataFrame(
    data={"DESCR_ENG": [
        "Cultivated Grassland,Alpe (without tare)",
        "Cultivated Grassland,Biennial cut meadow (tare 20%)/S28-1 Dry meadows and low bog meadows",
        "Cultivated Grassland,Biennial cut meadow (tare 20%)/S28-2 Species-rich mountain meadows",
        "Cultivated Grassland,Biennial cut meadow/S28-2 Species-rich mountain meadows",
        "Cultivated Grassland,Lawn special area (tare 20%)",
        "Cultivated Grassland,Lawn special area (tare 50%)",
        "Cultivated Grassland,Meadow (Half Sheared Tara 20%)",
        "Cultivated Grassland,Meadow (half-sheared)",
        "Cultivated Grassland,Meadow (half-sheared)/S28-1 poor meadows and fen meadows",
        "Cultivated Grassland,Mixed Alternate Meadow",
        "Cultivated Grassland,Pasture",
        "Cultivated Grassland,Pasture (rock 20%)",
        "Cultivated Grassland,Potential pasture (tare 20%)",
        "Fallow,Arable land fallow - EFA",
        "Forest Trees / SRF,Alpe (stocked 20%)",
        "Forest Trees / SRF,Alpe (stocked 50%)",
        "Forest Trees / SRF,Alpeggio (without tares)/S28-6 Wooded pastures",
        "Forest Trees / SRF,Biennial cut meadow (tare 20%)/S28-4 Meadows rich in tree species",
        "Forest Trees / SRF,Biennial cut meadow/S28-4 Species-rich meadows with trees",
        "Forest Trees / SRF,Biennial cut meadow/S28-5 Lush meadows with trees",
        "Forest Trees / SRF,Meadow special area (tare 20%)/S28-4 Meadows rich in wooded species",
        "Forest Trees / SRF,Meadow special area (tare 20%)/S28-5 Lush meadows with trees",
        "Forest Trees / SRF,Meadow special area (tare 50%)/S28-4 Meadows rich in wooded species",
        "Forest Trees / SRF,Meadow special area (tare 50%)/S28-5 Lush meadows with trees",
        "Forest Trees / SRF,Meadow special area/S28-4 Species-rich meadows with trees",
        "Forest Trees / SRF,Meadow special area/S28-5 Lush meadows with trees",
        "Forest Trees / SRF,Pasture (rock 20%)/S28-6 Wooded pastures",
        "Forest Trees / SRF,Pasture (rock 50%)/S28-6 Wooded pastures",
        "Forest Trees / SRF,Pasture (tare 20%)/S28-6 Wooded pastures",
        "Forest Trees / SRF,Pasture (tare 50%)/S28-6 Wooded pastures",
        "Forest Trees / SRF,Pasture (trees 20%)/S28-6 Wooded pastures",
        "Forest Trees / SRF,Pasture/S28-6 Wooded pastures",
        "Forest Trees / SRF,Stable meadow (tare 20%)/S28-4 Meadows rich in wooded species",
        "Forest Trees / SRF,Stable meadow (tare 20%)/S28-5 Lush meadows with trees",
        "Forest Trees / SRF,Stable meadow/S28-4 Species-rich meadows with trees",
        "Forest Trees / SRF,Stable meadow/S28-5 Lush meadows with trees",
        "Forest Trees / SRF,Willow (Tara 50%)",
        "Forest Trees / SRF,Willow (Tare 20%)",
        "Legumes,Alfalfa",
        "Legumes,Clover",
        "Maize,Corn",
        "Miscellaneous,Industrial Medicinal Plants",
        "Miscellaneous,Plant cultivation",
        "No Agriculture,Bosco/S28-8 Peat bogs and alders",
        "No Agriculture,Forest",
        "No Agriculture,Greenhouses",
        "No Agriculture,Hedges",
        "No Agriculture,Hedges/S28-9 Hedges",
        "No Agriculture,Infrastructures",
        "No Agriculture,Other Areas",
        "No Agriculture,Other crops/S28-3 Reedbeds",
        "No Agriculture,Other crops/S28-8 Peat and alder bogs",
        "No Agriculture,Water",
        "Orchards and Berries,Apple",
        "Orchards and Berries,Apricot",
        "Orchards and Berries,Astoni plants fruit",
        "Orchards and Berries,Berry fruit (without strawberry)",
        "Orchards and Berries,Biennial cut meadow (tare 20%)/S28-7 Chestnut groves and meadows with sparse fruit trees",
        "Orchards and Berries,Castagneto/S28-7 Chestnut groves and meadows with sparse fruit trees",
        "Orchards and Berries,Cherry",
        "Orchards and Berries,Chestnut",
        "Orchards and Berries,Currants",
        "Orchards and Berries,Meadow special area (tare 20%)/S28-7 Chestnut groves and meadows with sparse fruit trees",
        "Orchards and Berries,Meadow special area/S28-7 Chestnut groves and meadows with sparse fruit trees",
        "Orchards and Berries,Olive",
        "Orchards and Berries,Orchard being planted",
        "Orchards and Berries,Other fruit",
        "Orchards and Berries,Pear",
        "Orchards and Berries,Plums",
        "Orchards and Berries,Stable meadow (tare 20%)/S28-7 Chestnut groves and meadows with sparse fruit trees",
        "Orchards and Berries,Stable meadow/S28-7 Chestnut groves and meadows with sparse fruit trees",
        "Orchards and Berries,Strawberry",
        "Orchards and Berries,Table grapes",
        "Orchards and Berries,Vineyard under planting",
        "Orchards and Berries,Viticulture",
        "Other Cereals,Grain",
        "Permanent Grassland,Alpe (tare 70%)",
        "Permanent Grassland,Meadow (Permanent Meadow Tara 20%)",
        "Permanent Grassland,Meadow (permanent meadow)",
        "Permanent Grassland,Meadow (permanent meadow)/S28-1 poor meadows and fen meadows",
        "Permanent Grassland,Meadow (permanent meadow)/S28-2 species-rich mountain meadows",
        "Permanent Grassland,Meadow special area",
        "Permanent Grassland,Meadow special area (tare 20%)/S28-1 Dry meadows and low bog meadows",
        "Permanent Grassland,Meadow special area (tare 20%)/S28-2 Species-rich mountain meadows",
        "Permanent Grassland,Meadow special area (tare 50%)/S28-1 Dry meadows and low bog meadows",
        "Permanent Grassland,Meadow special area (tare 50%)/S28-2 Species-rich mountain meadows",
        "Permanent Grassland,Meadow special area/S28-1 poor meadows and fen meadows",
        "Permanent Grassland,Meadow special area/S28-2 species-rich mountain meadows",
        "Permanent Grassland,Potential pasture (50% tare)",
        "Permanent Grassland,Stable meadow (tare 20%)/S28-1 Dry meadows and meadows with low bog",
        "Permanent Grassland,Stable meadow (tare 20%)/S28-2 Species-rich mountain meadows",
        "Vegetables,Asparagus",
        "Vegetables,Cabbage",
        "Vegetables,Cauliflower",
        "Vegetables,Field vegetable cultivation",
        "Vegetables,Radish",
        "Vegetables,Salads",
    ]},
    geometry = [box(0, 0, 5, 5), box(5, 0, 10, 5), box(10, 0, 15, 5), box(15, 0, 20, 5)],
    crs=25832,
)
# 添加新的"Classes"列
test_vector_data["Classes"] = None
test_vector_data.loc[test_vector_data["DESCR_ENG"].str.startswith("Cultivated"), "Classes"] = "Cultivated Grassland"
test_vector_data.loc[test_vector_data["DESCR_ENG"].str.startswith("Fallow"), "Classes"] = "Fallow"
test_vector_data.loc[test_vector_data["DESCR_ENG"].str.startswith("Forest"), "Classes"] = "Forest Trees"
test_vector_data.loc[test_vector_data["DESCR_ENG"].str.startswith("Legumes"), "Classes"] = "Legumes"
test_vector_data.loc[test_vector_data["DESCR_ENG"].str.startswith("Maize"), "Classes"] = "Maize"
test_vector_data.loc[test_vector_data["DESCR_ENG"].str.startswith("Miscellaneous"), "Classes"] = "Miscellaneous"
test_vector_data.loc[test_vector_data["DESCR_ENG"].str.startswith("No Agriculture"), "Classes"] = "No Agriculture"
test_vector_data.loc[test_vector_data["DESCR_ENG"].str.startswith("Orchards and Berries"), "Classes"] = "Orchards and Berries"
test_vector_data.loc[test_vector_data["DESCR_ENG"].str.startswith("Other Cereals"), "Classes"] = "Other Cereals"
test_vector_data.loc[test_vector_data["DESCR_ENG"].str.startswith("Permanent Grassland"), "Classes"] = "Permanent Grassland"
test_vector_data.loc[test_vector_data["DESCR_ENG"].str.startswith("Vegetables"), "Classes"] = "Vegetables"

# 打印结果
print(test_vector_data.head())


test_vector_data["geometry"] = [MultiPolygon([feature]) if isinstance(feature, Polygon) \
    else feature for feature in test_vector_data["geometry"]]

核心需求

每个要素的geometry列存储对应Polygon,需将所有DESCR_ENG字段中逗号前部分相同的要素合并为单一类别(例如所有以"Cultivated Grassland,"开头的要素合并为"Cultivated Grassland",以"Forest Trees / SRF,"开头的合并为"Forest Trees / SRF"),同时聚合对应几何,使每个分组拥有唯一的多边形。


实现步骤

1. 提取类别字段

无需逐个判断前缀,直接通过字符串分割提取逗号前的内容作为类别:

# 处理真实数据gdf(若用测试数据则替换为test_vector_data)
gdf["Classes"] = gdf["BW_name"].str.split(",").str[0].str.strip()
  • str.split(","):按逗号分割字符串
  • str[0]:取分割后的第一部分(即逗号前的类别名称)
  • str.strip():去除可能存在的首尾空格

2. 聚合几何并合并同类要素

使用GeoPandas的dissolve方法,按Classes分组,自动合并几何:

# 按Classes分组,聚合几何(默认用unary_union合并多Polygon为MultiPolygon)
merged_gdf = gdf.dissolve(by="Classes", aggfunc="first").reset_index()
  • dissolve是GeoPandas专门用于矢量数据聚合的方法,会自动处理几何合并
  • aggfunc="first":对非几何字段取每组第一个值(无需保留其他字段可省略)
  • reset_index():将分组字段Classes从索引转为普通列

3. 验证与保存结果

查看聚合后的结果并导出为新Shapefile:

print(merged_gdf[["Classes", "geometry"]])
merged_gdf.to_file("merged_LAFIS.shp")

补充说明

  • 若合并后出现无效几何体,可通过buffer(0)修复:
merged_gdf["geometry"] = merged_gdf["geometry"].buffer(0)
  • 测试数据只需将上述代码中的gdf替换为test_vector_data即可验证效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 15:22:02