地理空间数据基础
做地图可视化,第一件事就是搞懂地理空间数据。说白了,就是弄清楚「地球上的某个点,在计算机里怎么表示、怎么存、怎么用」。我刚开始接触这块时,也被一堆术语搞得头晕——经纬度、坐标系、GeoJSON……今天咱们一个一个捋清楚。
核心要点:地理空间数据的本质,就是用数字描述地球上的位置和形状。经纬度是基础,数据格式是载体,坐标系是规则。
经纬度坐标系——地球的「网格」
经纬度,大家中学地理都学过。但做开发时,有几个细节我吃过亏。
经度(Longitude):范围 -180° 到 180°,东经为正,西经为负。
纬度(Latitude):范围 -90° 到 90°,北纬为正,南纬为负。
嗯,这里要注意:顺序问题。很多新手会搞混。在 GeoJSON 标准里,顺序是 [经度, 纬度],也就是 [lng, lat]。但有些库(比如某些老版本的地图 API)用的是 [lat, lng]。我曾经因为这个顺序搞反,画出来的点跑到了非洲……排查了半天。
我的习惯:写代码时,我会在注释里明确标注「经度在前,纬度在后」,或者直接用命名参数。避免自己坑自己。
常见地理数据格式
实际项目中,地理数据不会只传一对经纬度。我们需要一种结构化的方式,来描述点、线、面,以及它们的属性。下面这三种格式,你一定会遇到。
GeoJSON——最通用的格式
GeoJSON 是基于 JSON 的轻量级格式。我特别喜欢它,因为前端直接就能用,不需要额外解析。
一个典型的 GeoJSON 长这样:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [116.397, 39.908]
},
"properties": {
"name": "天安门",
"city": "北京"
}
}
]
}
支持的类型有:Point、MultiPoint、LineString、MultiLineString、Polygon、MultiPolygon。说白了,点、线、面都能表达。
避坑指南:我曾经处理过一个 200MB 的 GeoJSON 文件,浏览器直接卡死。后来发现,数据量大的时候,GeoJSON 的冗余度很高。建议用 TopoJSON 或者服务端切片。
Shapefile——GIS 界的「老大哥」
Shapefile 是 ESRI 公司推出的格式,虽然名字叫「文件」,其实是一组文件的集合。至少需要 .shp(几何数据)、.shx(索引)、.dbf(属性数据)三个文件。
说实话,Shapefile 在 Web 开发中不太常用。因为它是二进制格式,前端不能直接解析。但如果你做后端数据处理,或者跟 GIS 系统对接,就绕不开它。
我一般用 Python 的 geopandas 库来读取:
import geopandas as gpd
gdf = gpd.read_file("path/to/file.shp")
print(gdf.head())
TopoJSON——更聪明的编码
TopoJSON 是 GeoJSON 的「压缩版」。它把共享的边界只存一次,而不是每个多边形都存一遍。你想想看,如果两个相邻的省份,它们的边界线是重合的。GeoJSON 会存两次,TopoJSON 只存一次。
实际效果:文件体积能减少 50%-80%。我在做全国地图时,用 TopoJSON 替代 GeoJSON,加载速度明显提升。
坐标参考系统(CRS)
这个问题,很多人一开始会忽略。为什么?因为大部分 Web 地图(比如 Leaflet、Mapbox)默认用的是 WGS 84 坐标系,也就是 GPS 用的那个。但如果你做专业 GIS 分析,或者对接国内的数据,事情就复杂了。
常见的 CRS 有:
| EPSG 编码 | 名称 | 用途 |
|---|---|---|
| 4326 | WGS 84 | GPS、Web 地图通用 |
| 3857 | Web Mercator | Google Maps、OpenStreetMap |
| 4490 | CGCS2000 | 中国国家大地坐标系 |
| 4547 | 高斯-克吕格投影 | 中国大比例尺地形图 |
为什么会这样?因为地球是椭球体,地图是平面。从椭球到平面,需要「投影」。不同的投影,适用于不同的场景。
我的建议:做 Web 可视化,统一用 EPSG:4326 存数据,用 EPSG:3857 渲染。后端分析时,再根据需求做投影转换。Python 里用 pyproj 或 geopandas.to_crs() 就能搞定。
地理编码与逆地理编码
这两个概念,说白了就是「地址 ↔ 坐标」的互相转换。
- 地理编码:把「北京市东城区东长安街」变成
[116.397, 39.908] - 逆地理编码:把
[116.397, 39.908]变成「北京市东城区东长安街」
实际项目中,我经常用地理编码来处理用户输入的地址。比如用户填了个「朝阳区望京SOHO」,我需要把它变成坐标点,才能在地图上展示。
常用的服务有:
- 高德地图 API(国内数据最准)
- 百度地图 API(有自己的坐标系,需要偏移)
- Nominatim(OpenStreetMap 的免费服务,适合全球数据)
注意:不同厂商的坐标系不一样。高德用的是 GCJ-02(火星坐标系),百度用的是 BD-09。如果你混用,坐标会偏移几百米。我曾经踩过这个坑,后来统一用高德的数据源,再用 coordTransform 库做转换。
知识体系总览
下面这张图,帮你把本章的核心逻辑串起来:
嗯,总结一下。地理空间数据这块,说白了就是三件事:用什么坐标(经纬度)、怎么存(GeoJSON 等格式)、怎么转(CRS 和编码)。把这些搞清楚了,后面的地图可视化就顺了。
可可精品资料库