空间数据基础:坐标系、投影、常用数据格式
做空间图谱的人,第一道坎儿往往不是算法有多难——而是数据本身「长」什么样儿。你从设备拿到的坐标,跟你从在线地图抠出来的坐标,很可能根本不在一个参考系里。这事我早年吃过亏:两个团队各自接了同一批GPS轨迹,一个用WGS84入库,一个按GCJ-02处理,结果聚合出来的热力图偏移了两百多米……后来排查了整整两天。
所以这一章我们踏踏实实把地基打牢。坐标系、投影、常见格式,这三样东西搞清楚,后面所有处理才不会跑偏。
坐标系:地理坐标系 vs 投影坐标系
先说坐标系。地理坐标系用经纬度描述地球上的位置,本质是一个球面坐标。最常用的是 WGS84(GPS 的默认坐标系),原点在地球质心,椭球体参数全球统一。国内还有 CGCS2000、北京54、西安80——不过现在新项目基本都向 WGS84 或 CGCS2000 靠拢了。
而投影坐标系,是把球面展平到二维平面上。这时候单位变成米、英尺之类的线性单位。每个投影坐标系都基于一个地理坐标系“挂”在上面。举个例子:Web Mercator(EPSG:3857)用了WGS84的椭球,但做了墨卡托投影,结果就是南极北极被拉得巨大——这也是为什么你在谷歌地图上觉得格陵兰岛跟非洲差不多大,它俩实际面积差远了。
地理坐标 = 球面上的度(°)
投影坐标 = 平面上的米(m)
为什么要区分?因为我发现很多新手直接拿经纬度算距离,算出来的是“度距”,不是真距离。1度经度在赤道上是111km,到了高纬度只剩下55km。我建议:只要涉及距离、面积计算,先转成投影坐标系再动手。
地图投影:你选对了吗?
投影这件事其实没那么玄乎——就是把橘子皮剥下来压平,怎么压都会裂开。不同的压法对应不同的变形性质:有些保持角度(等角),有些保持面积(等积),有些保持距离(等距)。
我项目里最频繁接触的有三种:
- Web Mercator(EPSG:3857) — 在线地图默认,等角投影,导航友好。但面积变形严重,不适合做区域面积统计。
- UTM 投影(EPSG:326xx / 327xx) — 分带投影,每个带6度宽,变形很小。适合城市级、省市级分析。我处理国内数据时常用 UTM 50N(东经114°~120°)。
- Albers 等积投影 — 中国全境常用,保持面积准确,适合做人口密度、土地利用这类需要面积量的分析。
| 投影类型 | 变形倾向 | 常用场景 | 典型 EPSG |
|---|---|---|---|
| Web Mercator | 等角,面积变形大 | 瓦片地图、可视化 | 3857 |
| UTM | 等角,局部变形极小 | 城市测量、导航 | 32650 / 32750 |
| Albers | 等积 | 全国面分析 | 未统一(常用自定义) |
| Lambert 等角圆锥 | 等角 | 中纬度国家地图 | 未统一 |
我接手过一个项目,原始数据标注为“WGS84”,但实际用的是 GCJ-02(火星坐标系)。如果不先做坐标系校验直接转投影,结果会整体偏移几百米。所以拿到数据第一步:看元数据,或者拿已知坐标点测试一下。
常用空间数据格式:Shapefile 与 GeoJSON
数据格式决定了你怎么读、怎么存、怎么交换。目前在空间图谱管道里最主流的就两种:Shapefile(传统GIS老朋友)和 GeoJSON(Web开发者心头好)。
Shapefile
Shapefile 不是单个文件,而是至少三个文件的组合:.shp(几何)、.shx(索引)、.dbf(属性)。实际项目里还可能见到 .prj(投影定义)、.cpg(编码)等配套文件。我习惯用一个 zip 包打包整个 Shapefile 分发,省得丢文件。
它的优点:成熟、几乎所有GIS软件都支持。缺点也挺明显:属性列名限10个字符(当年的DOS遗毒),单个文件不能超过2GB,而且几何类型单一(一个图层只能一种几何)。
GeoJSON
GeoJSON 是纯文本,基于 JSON 结构。一个 FeatureCollection 里可以混装点、线、面。语法清晰,coordinates 数组里按经度、纬度排列。示例:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [113.3, 23.1]
},
"properties": {
"name": "广州塔",
"height_m": 600
}
}
]
}
我通常在以下场景偏爱 GeoJSON:
- Web 前端直接渲染(Leaflet、Mapbox、D3.js 原生支持)
- 数据量不大(几百个要素以内)
- 需要跨平台交换(Python 的 dict 几乎可直接用)
如果数据量超过 100MB,别用单文件 GeoJSON。可以转成 GeoJSON 序列或直接上 Parquet + 空间索引。我曾经试过用超大 GeoJSON 在浏览器里加载,页面直接卡死——后来切了矢量瓦片才好。
另外注意 GeoJSON 的坐标系默认是 WGS84(EPSG:4326),如果你用了其他坐标系,必须在 crs 字段里注明,否则解析器会按 4326 处理。我习惯在写入前就强制转好。
知识结构总览
下面这张图可以帮助你建立本章的整体脉络。核心流程是:从原始观测数据出发,选好地理坐标系(通常 WGS84),根据分析需求选投影,最后用合适的格式落地存储。
说白了,坐标系选错了,后面所有分析都是白做。投影选对了,算面积、算距离才准。格式选对了,开发效率翻倍。这三个东西我建议你在每一个新项目开始之前都花五分钟确认一遍——相信我,这五分钟能省下后面两天调试时间。