2. 数据源格式问题:Shapefile编码错误、GeoJSON不规范、坐标系缺失

做地图数据导入,说白了就是跟各种格式的数据源打交道。我这些年踩过的坑,十有八九都出在数据源本身。今天咱们就聊聊最常见的三类问题:Shapefile的编码乱码、GeoJSON格式不规范、还有坐标系定义缺失。

核心观点:数据源格式问题占导入失败的60%以上。其中编码问题最容易排查,坐标系问题后果最严重。

2.1 Shapefile编码错误——.dbf文件乱码的根源

Shapefile其实是个“三件套”:.shp存几何、.shx存索引、.dbf存属性。乱码就出在.dbf这个属性文件上。为什么?因为.dbf文件的编码方式五花八门。

我个人习惯,拿到Shapefile第一件事就是检查.dbf的编码。Windows环境下生成的Shapefile,默认编码通常是GBK或GB2312。而Linux或macOS下生成的,往往是UTF-8或Latin-1。你想想看,用UTF-8的解析器去读GBK编码的.dbf,不出乱码才怪。

我的经验:有一次客户给了一个全国POI数据,属性表里全是“鍖椾含”“涓婃捣”这种乱码。我一看就知道是GBK编码被当成了UTF-8读。用Notepad++打开.dbf文件,转成UTF-8再保存,问题就解决了。

怎么判断.dbf的编码?我一般用两种方法:

  • 工具法:用QGIS打开Shapefile,右键图层→属性→数据源,看“编码”字段。如果是“System”或空着,大概率是GBK。
  • 命令行法:用ogrinfo命令查看:ogrinfo -al -so yourfile.shp,输出里会显示编码信息。

修复编码问题,我推荐用GDAL的ogr2ogr工具:

# 将GBK编码的Shapefile转为UTF-8
ogr2ogr -f "ESRI Shapefile" output.shp input.shp -lco ENCODING=UTF-8

# 如果不知道原编码,可以尝试强制指定
ogr2ogr -f "ESRI Shapefile" output.shp input.shp -lco ENCODING=GBK

注意:强制转换编码前,最好先确认原文件的编码。我曾经有一次把UTF-8的文件当成GBK转,结果属性全变成了问号。嗯,那叫一个惨。

2.2 GeoJSON格式不规范——看似简单实则坑多

GeoJSON这几年越来越流行,轻量、易读、Web友好。但正因为太灵活,很多人写出来的GeoJSON根本不规范。我见过最离谱的,是把属性字段名写成中文还带空格。

规范的GeoJSON必须满足以下几点:

  • 顶层结构:必须是{"type": "FeatureCollection", "features": [...]},不能直接是数组。
  • 每个Feature:必须有type、geometry、properties三个字段,缺一不可。
  • Geometry类型:必须是GeoJSON标准定义的7种类型之一(Point、MultiPoint、LineString、MultiLineString、Polygon、MultiPolygon、GeometryCollection)。
  • 坐标数组:经纬度顺序必须是[经度, 纬度],不能反过来。这是最常见的错误。

为什么会有人搞错经纬度顺序?说白了,很多人在Excel里手动编辑坐标,习惯写“纬度,经度”。但GeoJSON标准要求“经度,纬度”。我建议用在线GeoJSON验证器检查一下,或者用Python的geojson库做校验:

import geojson

with open('data.geojson', 'r') as f:
    data = geojson.load(f)

# 验证是否为合法的GeoJSON
if geojson.is_valid(data):
    print("格式正确")
else:
    print("格式错误:", geojson.validation.errors(data))

避坑指南:我曾经处理过一个全国路网数据,导入后所有道路都跑到了非洲。排查了半天,发现是经纬度写反了。从那以后,我写了个脚本自动检查坐标范围——经度应该在-180到180之间,纬度在-90到90之间。超出这个范围,直接报错。

2.3 坐标系定义缺失或错误——最隐蔽的杀手

坐标系问题,是地图数据导入中最隐蔽、后果最严重的坑。没有之一。

我见过太多人,拿到数据直接导入,结果点跑到海里、线对不上、面变形。为什么?因为数据本身有坐标系,但导入时没告诉系统它是什么坐标系。

常见的坐标系问题分三种:

问题类型 表现 原因
坐标系缺失 数据能显示,但位置不对 .prj文件丢失或为空
坐标系错误 数据偏移几百到几千米 WGS84被当成CGCS2000,或反之
投影坐标系混淆 数据变形严重 把投影坐标当成地理坐标

怎么判断数据有没有坐标系?我一般用ogrinfo:

ogrinfo -al -so yourfile.shp | grep "Coordinate System"

如果输出是空的,说明没有坐标系定义。这时候需要手动指定。怎么知道该指定什么坐标系?看数据来源:

  • 国内公开数据:通常是CGCS2000(EPSG:4490)或WGS84(EPSG:4326)
  • GPS采集数据:一般是WGS84
  • 地方坐标系:需要向数据提供方确认

修复坐标系问题,我推荐用GDAL的ogr2ogr配合-s_srs和-t_srs参数:

# 先指定源坐标系,再转换到目标坐标系
ogr2ogr -f "ESRI Shapefile" output.shp input.shp \
  -s_srs EPSG:4490 -t_srs EPSG:4326

重要提醒:坐标系转换不是万能的。如果源数据本身精度就不高,转换后误差会放大。我建议在转换前先做数据质量检查,特别是控制点精度。

知识体系总览

下面这张图,是我自己总结的数据源格式问题排查思路。每次遇到导入失败,我就按这个流程走一遍,基本能定位问题。

数据源格式问题排查流程 数据导入失败 是Shapefile? 检查.dbf编码 GBK/UTF-8/Latin-1 检查GeoJSON格式 结构/坐标顺序 有坐标系定义? 手动指定坐标系 WGS84/CGCS2000 验证坐标系正确性 检查偏移/变形 修复后重新导入

这张图的逻辑很简单:先判断数据格式,再检查编码或结构,最后确认坐标系。每一步都有对应的修复方法。我个人习惯把这个流程贴在工位旁边,遇到问题就对照着看。

最后说一句:数据源格式问题,90%都可以通过预处理解决。我建议在导入脚本里加一个数据校验模块,自动检查编码、格式、坐标系。这样能省下大量排查时间。

可可精品资料库