空间数据基础:坐标系、投影、常用数据格式

做空间图谱的人,第一道坎儿往往不是算法有多难——而是数据本身「长」什么样儿。你从设备拿到的坐标,跟你从在线地图抠出来的坐标,很可能根本不在一个参考系里。这事我早年吃过亏:两个团队各自接了同一批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),根据分析需求选投影,最后用合适的格式落地存储。

空间数据基础:坐标系 → 投影 → 格式流程 原始观测数据(GPS / 测量) 地理坐标系(WGS84) 投影坐标系(Web Mercator / UTM / Albers) 数据格式:Shapefile(.shp + .shx + .dbf) / GeoJSON(.geojson) 空间分析 / 可视化 / 图谱构建 📌 关键注意: • 经纬度计算距离先投影 • Shapefile 勿丢配套文件 • GeoJSON 默认投影为 4326

说白了,坐标系选错了,后面所有分析都是白做。投影选对了,算面积、算距离才准。格式选对了,开发效率翻倍。这三个东西我建议你在每一个新项目开始之前都花五分钟确认一遍——相信我,这五分钟能省下后面两天调试时间。