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

如何使用Python将Shapefile文件拆分为两个独立文件

如何用Python拆分Shapefile为两个文件

问题描述

我有一个Shapefile文件,希望将其拆分为两个不同的Shapefile文件(拆分出指定经纬度范围的区域和剩余区域)。我尝试的代码输出的是由多个点组成的连线,无法得到预期的面/线要素,代码如下:

import geopandas as gpd ; import shapefile ; import numpy as np ; import pandas as pd
from shapely.geometry import Polygon, Point
import matplotlib.pyplot as plt ;  

lat_1=6 ; lat_2=20 ; lon_1=70 ; lon_2=90
A=gpd.read_file(shp_file)
points=[]
for shape_rec in A.shapeRecords():
    #print(shape_rec)
     pts = pd.DataFrame(np.array(shape_rec.shape.points))
     pts.columns=['lon','lat']
     points.append(pts) 
points_1=pd.concat(points)

points_2=points_1[(points_1.lon >=lon_1)&(points_1.lon <=lon_2) & (points_1.lat >=lat_1)&(points_1.lat <=lat_2)] 


gdf = gpd.GeoDataFrame( points_2, geometry=gpd.points_from_xy(points_2.lon , points_2.lat ), crs='EPSG:4326')
gdf.drop(['lat', 'lon'], axis=1, inplace=True)  # optional
gdf.to_file(main+'shp_files/test.shp') 

问题原因

你这段代码错误地把Shapefile中的几何要素拆解成了单个点,筛选后保存的是点要素,自然只会得到点连线,而不是保留原有的多边形/线几何类型。

解决方案

下面提供两种符合需求的实现方式,根据你的实际场景选择:

方式1:筛选完全落在指定范围的整要素

如果目标是保留完全处于指定经纬度范围内的完整要素,直接基于GeoDataFrame的几何属性筛选即可:

import geopandas as gpd

# 配置参数
lat_min, lat_max = 6, 20
lon_min, lon_max = 70, 90
shp_path = "你的原始Shapefile路径"
output_path = "输出文件夹路径/"

# 读取原始数据
gdf = gpd.read_file(shp_path)

# 筛选质心在指定范围内的要素(也可改用geometry.bounds判断完全包含)
filtered = gdf[
    (gdf.geometry.centroid.x >= lon_min) &
    (gdf.geometry.centroid.x <= lon_max) &
    (gdf.geometry.centroid.y >= lat_min) &
    (gdf.geometry.centroid.y <= lat_max)
]

# 筛选剩余要素
remaining = gdf[~gdf.index.isin(filtered.index)]

# 保存结果
filtered.to_file(f"{output_path}filtered_area.shp")
remaining.to_file(f"{output_path}remaining_area.shp")

方式2:裁剪出与范围相交的要素部分

如果目标是提取要素与指定范围重叠的部分(比如一个多边形只有局部在范围内,需要切割出这部分),用geopandas.clip工具:

import geopandas as gpd
from shapely.geometry import Polygon

# 配置参数
lat_min, lat_max = 6, 20
lon_min, lon_max = 70, 90
shp_path = "你的原始Shapefile路径"
output_path = "输出文件夹路径/"

# 创建裁剪范围的多边形
clip_poly = Polygon([
    (lon_min, lat_min), (lon_max, lat_min),
    (lon_max, lat_max), (lon_min, lat_max), (lon_min, lat_min)
])
clip_gdf = gpd.GeoDataFrame({"geometry": [clip_poly]}, crs="EPSG:4326")

# 读取原始数据,确保CRS匹配
gdf = gpd.read_file(shp_path).to_crs("EPSG:4326")

# 裁剪相交区域
clipped = gpd.clip(gdf, clip_gdf)

# 提取剩余区域
remaining = gdf.difference(clip_poly)
remaining = gpd.GeoDataFrame(geometry=remaining, crs=gdf.crs)
remaining = remaining[~remaining.geometry.is_empty]  # 移除空几何

# 保存结果
clipped.to_file(f"{output_path}clipped_area.shp")
remaining.to_file(f"{output_path}remaining_area.shp")

注意事项

  • 确保原始Shapefile的坐标参考系(CRS)是EPSG:4326(经纬度),如果不是,先通过gdf.to_crs("EPSG:4326")转换。
  • 方式1适合筛选完整要素,方式2适合切割要素局部区域,按需选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 05:03:26