当前位置: 首页 > news >正文

如何硬解析 .shp 文件中的几何体,拯救 .dbf、.shx 等文件缺失的 ESRI Shapefile 格式文件

最近遇到一个问题就是 ESRI Shapefile 格式文件中 .dbf 文件损坏,导致 .shp 无法打开,又不能放弃这个数据,所以只能做修复,网上搜了很多方法,结果都失败了,所以用 deepseek 查询应解析的方法,亲测可行(简单多边形),现将方法分享:

ESRI Shapefile 文件组成

1 核心文件

扩展名必选用途
.shp存储几何图形(点、线、面等)
.shx存储几何索引(加速查询)
.dbf存储属性数据(类似表格)
.prj坐标系统定义(如 WGS84)
.cpg字符编码声明(如 UTF-8)
  • 必须同时存在 .shp.shx.dbf 文件才能正常使用。
  • 缺失 .prj 可能导致坐标系统未知。

2 .shp 文件结构(二进制格式)

文件头(Header)

偏移量长度类型描述
04Bint32文件标识码(固定 9994
244Bint32版本号(1000
284Bint32几何类型(见下表)
36-6832Bdouble边界框(xmin, ymin, xmax, ymax)

几何记录(Record)

  • 记录头(8B):
    • int32 记录编号(从 1 开始)
    • int32 记录长度(以 16-bit 字为单位)
  • 记录内容
    • int32 几何类型
    • 几何数据(坐标点等)

Shapefile 几何类型

类型值名称描述
0Null Shape空几何
1Point二维点 [x, y]
3PolyLine多段线
5Polygon多边形(首尾闭合)
8MultiPoint多点集合
11PointZ三维点 [x, y, z, m]

多边形规则

  • 外环:顶点按 逆时针 排列
  • 内环(孔洞):顶点按 顺时针 排列

Python 硬解析只有 .shp 文件的已损坏的 ESRI Shapefile 格式数据(Polygon)

环境和数据准备

安装 gma:pip install gma

本文基于:gma 2.1.7,Python 3.12

本文用到数据:
链接: https://pan.baidu.com/s/1kMlji9xqSsYIVn1cygIewA?pwd=9nc1
提取码: 9nc1

代码

import structdef parse_polygon_shp(shp_path):polygons = []iii = 0with open(shp_path, "rb") as f:# 跳过文件头(100字节)f.read(100)while True:# 读取记录头(8字节:记录号+长度)record_header = f.read(8)if not record_header:break# 解析记录头(大端序)record_num = struct.unpack(">i", record_header[:4])[0]record_len = struct.unpack(">i", record_header[4:8])[0]  # 单位:16-bit words# 读取记录内容(长度:record_len * 2 字节)try:record_data = f.read(record_len * 2)except:breakif len(record_data) < 44:  # 多边形至少需要44字节continue# 解析几何类型(小端序,从记录内容开始)shape_type = struct.unpack("<i", record_data[0:4])[0]if shape_type != 5:  # 仅处理多边形continue# 解析边界框(4个double)bbox = struct.unpack("<4d", record_data[4:36])# 解析环数和点数num_parts = struct.unpack("<i", record_data[36:40])[0]num_points = struct.unpack("<i", record_data[40:44])[0]# 解析环的起始索引(num_parts个int32)parts = []offset = 44parts_data = record_data[offset : offset + 4 * num_parts]parts = list(struct.unpack(f"<{num_parts}i", parts_data))offset += 4 * num_parts# 解析所有点(num_points个xy对)points = []points_data = record_data[offset : offset + 16 * num_points]for i in range(num_points):x = struct.unpack("<d", points_data[16*i : 16*i + 8])[0]y = struct.unpack("<d", points_data[16*i + 8 : 16*i + 16])[0]points.append((x, y))# 保存多边形数据polygons.append({"shape_type": shape_type,"bbox": bbox,"num_parts": num_parts,"num_points": num_points,"parts": parts,"points": points})return polygonsshp_path = "青海省.shp"
res = parse_polygon_shp(shp_path)import pandas as pd
from gma import iofts = []
for data in res:pt = data['points']ft = io.CreateFeature(pt, GeomType = 'Polygon', Projection = 'WGS84')fts.append(ft)ly = io.CreateLayer(fts)
ly.SaveAs("青海省_New.shp")

注意:此方法暂不适合复杂的多边形。如果是复杂多边形需要进一步优化。

http://www.xdnf.cn/news/1174447.html

相关文章:

  • .Net core 部署到IIS出现500.19Internal Server Error 解决方法
  • 变频器实习DAY12
  • VRRP技术-设备备份技术
  • Vue3 面试题及详细答案120道(61-75 )
  • Mermaid流程图
  • 思路探索:当大型语言模型遇见数据分析的现实挑战
  • vue3与ue5通信-工具类
  • 【音视频学习】四、深入解析视频技术中的YUV数据存储方式:从原理到实践
  • Kubernetes 服务发布进阶
  • Web后端实战:登录认证(JWT令牌生成和Filter过滤器Interceptor拦截器)
  • 使用 MobaXterm 登录你的阿里云 ECS 实例
  • springboot 3.0 和 2.0 校验用的包不一样
  • 压测软件JMeter安装配置以及创建桌面快捷方式(详细图解)
  • 18.设备虚拟化
  • Java按模板导出Excel
  • YOLOv5模型剪枝实战教程
  • Java项目中定时任务三方工具和技术的深度应用指南
  • Android埋点实现方案深度分析
  • Docker 应用数据备份、迁移方案
  • 设计模式代码总结
  • 【2025】使用vue构建一个漂亮的天气卡片
  • ChatGPT桌面版深度解析
  • vue3笔记(2)自用
  • RCE随笔-奇技淫巧(2)
  • Android toybox常用工具介绍
  • ES6 标签模板:前端框架的灵活利器
  • mongodb的备份和还原(精简)
  • 微算法科技(NASDAQ: MLGO)研究量子机器学习算法 (Quantum Machine Learning Algorithms),加速机器学习任务
  • opencv学习(视频读取)
  • HF86611_VB1/HF86611Q_VB1:多通道USB HiFi音频解码器固件技术解析