十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

shp转geojson实战:结构差异、编码处理与批量转换验证

shp转geojson实战:结构差异、编码处理与批量转换验证 简介这是一款面向GIS开发者和数据处理人员的Python小工具用于在GeoJSON与Shapefile两种常见地理数据格式之间进行批量互转解决手工转换效率低、批量处理难的问题适用于地图可视化、空间分析及WebGIS开发前的数据准备场景。压缩包共2000个文件包含pyc/pyd等Python编译模块、exe/dll运行组件、h头文件、tcl脚本、xml/json配置与数据文件等整体约74.75MB结构较为完整。使用方法已由作者在关联博文中公布测试环境覆盖Win10 64位与Win7 SP1 64位兼容性较广。目前已有1145人学习下载适合需要快速处理大量地理数据文件的开发者参考使用可直接套用或改造作者给出的调用方式降低格式转换的配置成本。1. 见到 shp-geojson-v0.2.rar 时先想清楚它在解决什么拿到一个叫shp-geojson-v0.2.rar的压缩包最常见背景是对方要把一批矢量数据从 ArcGIS 生态交付到 Web 端或者你在接手一套反复迭代的 shp→geojson 转换流程。shp 是桌面 GIS 时代的老霸主geojson 是 Leaflet、MapLibre、D3 以及开源后端事实上的通用交换格式这两者之间的转换几乎每周都会碰到。v0.2 这个版本号说明工具或数据已经修订过一次你拿到的不是首版草稿但依然要先验证再使用。这类压缩包内部一般是两种形态整理好的转换代码加说明或者某次任务批量产出的 geojson 结果附 shp 原文件做对照。不管哪种处理路径都绕不开三件事读懂 shp 的结构差异、跑通转换命令、处理 rar 解压后的编码和路径问题。这篇就按这个顺序把整套方案讲清楚适合正在做数据清洗、格式迁移或准备定时同步任务的人。先给一个反直觉的结论shp→geojson 的麻烦通常不在几何本身而在属性编码和坐标系。2. shp 与 geojson 的结构差异从文件组成看到编码和坐标系2.1 shp 不是一个文件shp/shx/dbf/prj/cpg 的最小配套ESRI Shapefile 名字里带 file落到磁盘上却是一组文件的集合。最常见的五个成员各自负责几何、索引、属性和坐标系描述缺任何一个都会影响转换结果。后缀作用缺失后果.shp几何坐标本体无法读取.shx几何空间索引多数读取器警告后仍可读.dbf属性表dBASE 格式属性全部丢失.prj坐标系描述WKT / ESRI WKT坐标系未知常被默认当作 WGS84.cpg属性编码声明中文属性大概率乱码解压后用ls -l看一眼文件族再读一下 .cpg 内容比直接跑转换命令更能提前发现问题$ ls -l road_2020.* -rw-r--r--. 1 gis gis 5242880 1月 3 10:00 road_2020.shp -rw-r--r--. 1 gis gis 10244 1月 3 10:00 road_2020.shx -rw-r--r--. 1 gis gis 24576000 1月 3 10:00 road_2020.dbf -rw-r--r--. 1 gis gis 891 1月 3 10:00 road_2020.prj -rw-r--r--. 1 gis gis 5 1月 3 10:00 road_2020.cpg $ cat road_2020.cpg UTF-8这段输出里最值得看的是 .dbf 体积2.4 万 KB 的属性表说明字段多或记录数大转换成 geojson 后文件膨胀会很明显。.prj 存在且可读说明坐标系信息完整.cpg 写的是 UTF-8那么读取时别按 GBK 猜。缺少 .cpg 的 shp建议先试试file road_2020.dbf或者用strings抽几段属性看看是 UTF-8 中文字节还是 GBK 双字节判断成本很低。2.2 geojson 的组织方式与 WGS84 经纬度约定geojson 本质是一个文本 JSON最外层通常是FeatureCollection内部是 feature 数组每个 feature 含geometry和properties两块。几何里坐标是嵌套数组多边形是外环 内洞的多层结构和 shp 内部存储的 Point/LineString/Polygon 一一对应。坐标顺序是[经度, 纬度]也就是[lon, lat]这跟很多桌面软件显示时的 (x, y) 一致但和某些数据库存储的 (lat, lon) 相反混用会得到跑到海里的点。geojson 规范要求坐标系是 WGS84EPSG:4326所以 shp 如果是投影坐标系高斯克吕格、UTM 这类转换必须做重投影而不是直接改数字。打开工具方面geojson.io拖进去就能看QGIS 直接拖放VS Code 装个 GeoJSON 插件也能预览这些适合转换后快速目测严谨验证还得靠命令行第 5 章展开。2.3 编码与坐标精度两个高频坑属性编码是 shp→geojson 踩得最多的坑。.dbf 里中文字段以 GBK 或 UTF-8 字节存在geojson 规范固定 UTF-8所以转换必然涉及编码迁移。常见做法是ogr2ogr加-lco ENCODINGUTF-8geopandas 则用encodingGBK参数直接读。这里有个细节改的是读取时按什么编码解码不是把文件另存成什么编码方向搞反了乱码依旧。坐标精度方面shp 内部用 double 存坐标geojson 用文本十进制存。写多了文件膨胀写短了精度不够。经验值是COORDINATE_PRECISION7约 1 厘米平面精度道路、行政区这类数据 6 位约 0.1 米也够用。栅格或遥感配套的矢量边界建议 7 位因为叠加分析时零点几米的偏差会影响相交判定。提示判断一个包是不是能用先看 .prj 和 .cpg再看 .dbf 体积最后才跑转换。顺序反了问题会藏在输出文件里不好定位。3. 用 ogr2ogr 和 geopandas 实现 shp 与 geojson 互转3.1 ogr2ogr 最小命令坐标系参数与精度控制GDAL 套件里的 ogr2ogr 是转换主工具Linux 和 Windows 下都能用命令结构是输出格式、输出文件、输入文件、一组选项。最常用的一套参数这样写# shp → geojson统一到 WGS84坐标保留 7 位小数 ogr2ogr -f GeoJSON output.geojson input.shp \ -s_srs EPSG:4547 -t_srs EPSG:4326 \ -lco COORDINATE_PRECISION7解释一下每个参数-f GeoJSON声明输出格式-s_srs EPSG:4547声明输入坐标系当输入缺 .prj 或者 .prj 内容错误时必须显式指定否则 ogr2ogr 默认当 WGS84 读-t_srs EPSG:4326是目标坐标系这里的重投影是必要的不是可选项-lco COORDINATE_PRECISION7控制坐标小数位数这是 GeoJSON 输出的 layer creation option省掉的话 ogr2ogr 会输出一长串浮点数。反向转换geojson → shp时有一个容易忽略的点shp 输出目标必须是一个目录而不是单文件# geojson → shp输出到目录 shp_out ogr2ogr -f ESRI Shapefile shp_out output.geojson \ -lco ENCODINGUTF-8这条命令里shp_out会被当目录处理生成的 .shp/.shx/.dbf/.prj 都在里面。-lco ENCODINGUTF-8让 .dbf 以 UTF-8 存储并生成对应的 .cpg这样 ArcMap 或 QGIS 打开时中文属性不会乱码。加了-nlt PROMOTE_TO_MULTI可以把点、线、面统一提升为 Multi 类型适合后续要入库的场合。3.2 geopandas 路径encoding 和 to_crs 一起处理不想记命令参数时geopandas 是更直观的替代读出来是 DataFrame 风格过滤、裁剪、字段重命名都能顺手做import geopandas as gpd gdf gpd.read_file(road_2020.shp, encodingGBK) if gdf.crs is None: gdf.crs EPSG:4547 # 缺 .prj 时手动补坐标系 gdf gdf.to_crs(epsg4326) # 重投影到 WGS84 gdf.to_file(road_2020.geojson, driverGeoJSON)encodingGBK解决属性乱码gdf.crs is None判断缺 .prj 的情况手动赋值后再to_crs最后的driverGeoJSON显式指定输出。注意一点to_crs要求先有合法 crsGeoDataFrame 的 crs 是 pyproj 的 CRS 对象直接赋字符串在 geospatial 库里是允许的但老版本可能要包一层from pyproj import CRS。过滤字段也一样自然gdf gdf[gdf[roads_type] highway]再导出即可。唯一要注意的是读入时字段名已经经过一次处理shp 里 10 字符截断的字段名在 GeoDataFrame 里是截断后的样子写过滤条件前先gdf.columns.tolist()看一眼。3.3 字段映射与 shp 转 txt 的顺手方案属性字段从 dbf 走到 JSON类型是一一对应的但宽度、小数位这些约束会丢失。反过来 geojson→shp 时字段名超过 10 个字符会被静默截断两个源文件字段名前 10 位相同时还会冲突。dbf 字段类型geojson 里的表现形式反向转换注意点Integernumber 整数注意大整数可能被当浮点Realnumber 浮点小数位按字面值保留Characterstring长度限制重新生效Logicalboolean部分读取器转成 0/1很多人搜shp转txt实际是把属性表导出成文本或 CSV避免碰几何。ogr2ogr 一条命令就能做# 属性导出为 CSV并在每行附加坐标 ogr2ogr -f CSV attr_table.csv road_2020.shp -lco GEOMETRYAS_XYGEOMETRYAS_XY只适合点数据会生成 POINT_X、POINT_Y 两列。线和面用GEOMETRYAS_WKT把几何转成 WKT 文本写进一个字段这样 txt 里既能看属性也能看形状后续awk、Excel 都能处理。这里是导出属性到文本不是把 shp 二进制直接改后缀概念上别混。4. 处理 rar 包解压检查、批量转换与按版本回包4.1 解压前先列包unrar l 与配套文件检查Linux 下处理 rar 包主要靠 unrar 或 7zWindows 上 WinRAR/7-Zip 都行。建议先列包内清单再解压尤其当包名带版本号时先确认内容是不是当前要的 v0.2。unrar l shp-geojson-v0.2.rar unrar x shp-geojson-v0.2.rar ./work/unrar l只列出文件名、原始大小和解压后大小不落盘unrar x按包内目录结构完整解压./work/是目标目录。看清单时重点查两点一是同一份 shp 的五个配套文件是否都在二是 geojson 结果和源 shp 是否同名同目录这决定后面批量转换时会不会互相覆盖。unrar 常用参数作用l列出包内文件清单不解压x按目录结构完整解压e忽略目录结构全部平铺到当前目录o强制覆盖已存在文件-k保留已存在文件不覆盖unrar e平铺解压容易把不同目录下的同名 shp 盖掉我一般不推荐。包内如果出现中文文件名乱码多半是 rar 创建端的文件名编码和当前系统不一致unrar在 Linux 下默认按 UTF-8 处理Windows 压制的中文名偶尔会出问题先ls -lb看字节再决定要不要用 convmv 转码。4.2 批量转换目录下所有 shp 的 bash 脚本数据量大时逐条跑命令不现实我习惯写一个精简脚本放进包内随数据一起交付后续任何人在任何机器上都能复现 v0.2 的产物#!/usr/bin/env bash set -euo pipefail find . -maxdepth 2 -name *.shp | while IFS read -r shp; do base${shp%.shp} ogr2ogr -f GeoJSON ${base}.geojson $shp \ -t_srs EPSG:4326 -lco COORDINATE_PRECISION6 echo done: ${base}.geojson doneset -euo pipefail让脚本在 ogr2ogr 报错时立即退出避免留下半截失败文件还继续跑find -maxdepth 2控制扫描深度防止误入子模块目录${shp%.shp}是参数扩展去掉后缀生成输出文件名。这里IFS是为了处理文件名带空格的情况道路数据经常有空格漏掉这个细节 find 结果会被拆成多段。4.3 geopandas 批处理统一编码、字段与坐标系如果包内 shp 来源不一有的 GBK 有的 UTF-8bash 脚本就忙不过来了。我一般给这种情况配一个 Python 批处理把编码探测、字段截断和重投影一起做掉from pathlib import Path import geopandas as gpd out_dir Path(geojson_out) out_dir.mkdir(exist_okTrue) for shp in Path(.).glob(**/*.shp): try: gdf gpd.read_file(shp, encodingGBK) except UnicodeDecodeError: gdf gpd.read_file(shp, encodingUTF-8) # 兜底重试 gdf gdf.to_crs(epsg4326) if gdf.crs else gdf gdf.to_file(out_dir / f{shp.stem}.geojson, driverGeoJSON)Path.glob(**/*.shp)递归找所有 shp先按 GBK 读抛UnicodeDecodeError再换 UTF-8 重试是处理混合编码包最省事的办法to_crs前面加条件判断是为了跳过那些没写 .prj 的文件它们 crs 为 None直接to_crs会报错。这个脚本跑完建议再打印一份清单把每个输出文件的要素数记录下来后面验证用得上。4.4 回包命名与压缩策略批量转换完成后把结果按版本回包命名规范直接沿用输入包名加产物标识rar a -r -m5 shp-geojson-v0.2-result.rar geojson_out/rar a添加文件-r递归目录-m5最大压缩比。geojson 是纯文本坐标字符串重复度高rar/zip 压缩收益明显体积通常能压到三分之一左右。如果目标环境没有 rar 命令zip -r shp-geojson-v0.2-result.zip geojson_out/效果接近压缩率略低但通用性更好。提示压缩前先用ogr2ogr -simplify 0.0001对几何做一次简化能进一步缩小体量但简化是有损操作会改变边界形状交付前要确认业务方是否接受。5. 转换结果的验证与三个高频边界问题5.1 ogrinfo 与 jq 快速验证要素数与属性转换完成后别急着交付先用 ogrinfo 看统计信息再用 jq 抽查具体记录。两步加起来不超过一分钟能挡住绝大多数低级问题ogrinfo -so -al output.geojson jq .features | length output.geojson jq .features[0].properties output.geojsonogrinfo -so -al输出要素总数、几何类型、图层范围和字段列表-so是只输出摘要文件大时不至于刷屏。jq 的两条命令分别统计要素数量、打印第一条记录的属性对照源 shp 的记录数一眼就能看出有没有丢要素。如果有嵌套坐标越界嫌疑可以再跑一条def walk(coords, max_x180, max_y90): if isinstance(coords, list): if all(isinstance(c, (int, float)) for c in coords) and len(coords) 2: if abs(coords[0]) max_x or abs(coords[1]) max_y: return coords return None for item in coords: hit walk(item, max_x, max_y) if hit: return hit return None这段递归遍历嵌套坐标数组找到第一个越界经纬度就返回并定位到具体坐标能快速识别坐标顺序写反或漏了重投影的问题比肉眼翻 JSON 可靠得多。5.2 混合几何、环方向、多余精度三个边界问题第一个是混合几何类型。shp 一个文件只能存一种几何类型但 geojson 没有这个限制来源混乱的包在转出后可能出现部分 feature 是Polygon、部分是MultiPolygon下游入库或切片时类型不一致会报错。处理方式是在转换时统一ogr2ogr ... -nlt PROMOTE_TO_MULTI把单几何提升为 Multi 类型。第二个是环方向。geojson 规范RFC 7946要求外环逆时针、内环顺时针部分严格解析器会按这个约定剔除错误方向的环。shp 内部不强制这个约定所以转换后最好用 shapely 的orient统一方向from shapely.geometry import shape, mapping from shapely.geometry.polygon import orient # 以某个 feature 的 geometry 为例 geom shape(feature[geometry]) if geom.geom_type in (Polygon, MultiPolygon): feature[geometry] mapping(orient(geom, sign1.0))第三个是坐标精度浪费。源数据 GCJ-02、BD-09 这类坐标系混入时精度位数再多也没有意义先用-t_srs归一。另外 geojson 里出现[-0.000000, 0.000000]这种坐标多半是源数据本身有问题属于能转换但与真实位置无关的脏数据验证时才更容易暴露。5.3 下游衔接txt 导出与 3dtiles 前置转换产物在交付目录里通常只作中间态。要快速出文本属性清单直接复用第 3 章的 CSV 导出命令要做 3dtiles 切片给 Cesium 用则先把 geojson 统一到 WGS84 并确认几何类型单一再走切片工具生成 b3dmgeojson 本身只是前置输入。验证到这里shp-geojson-v0.2.rar 里的数据经过解压、转换、校验和回包才算真正具备交付条件。本文还有配套的精品资源点击获取
返回列表