1. 无人机地图基础:坐标系与投影
做无人机地图开发,第一个绕不开的就是坐标系。我刚开始接触这个领域时,也被 WGS84、UTM、Web Mercator 这些术语搞得头晕。说白了,它们就是描述地球位置的「语言」——不同场景下得用不同的语言,否则你的无人机航迹就会飞到天上去。
1.1 三个核心坐标系
先记住一个结论:WGS84 是地理坐标系,UTM 是投影坐标系,Web Mercator 是显示坐标系。三者的关系,我画了张图帮你理清。
WGS84 — 全球定位的基准
WGS84 是目前 GPS 系统使用的坐标系。无人机飞控输出的经纬度,就是 WGS84 坐标。它的单位是度(°),描述的是地球表面上的点。
- 优点:全球统一,所有 GPS 设备都支持
- 缺点:经纬度不是等距单位——1°经度在赤道和北极的长度不一样
- 典型数据:
39.9042°N, 116.4074°E(北京天安门)
UTM — 局部精确计算
UTM 把地球分成 60 个投影带,每个带 6° 经度宽。它将球面投影到平面,单位是米。做无人机航迹规划时,我习惯用 UTM 算距离和面积。
| 特性 | WGS84 | UTM |
|---|---|---|
| 单位 | 度(°) | 米(m) |
| 适用场景 | GPS 定位、数据交换 | 距离计算、路径规划 |
| 精度 | 全球统一,但不等距 | 带内精度高(<1m) |
| 中国常用带号 | — | 49N~53N(东经 108°~132°) |
Web Mercator — 地图显示的标准
Web Mercator(EPSG:3857)是 Google Maps、OSM、高德等在线地图使用的投影。它本质上是把 WGS84 经纬度「伪投影」到平面,单位是米,但只在显示层面使用。
- 特点:保持角度不变(等角),但面积变形严重——格陵兰看起来和非洲一样大
- 用途:地图瓦片渲染、航迹叠加显示
- 转换公式:
x = lon * 20037508.34 / 180,y = ln(tan(45° + lat/2)) * 20037508.34 / 180
1.2 地图瓦片原理
你想想看,一张全球地图有多大?如果直接加载,你的浏览器会直接崩溃。瓦片(Tile)就是解决这个问题的——把地图切成 256×256 像素的小方块,按层级组织,按需加载。
瓦片层级与编号
Web Mercator 的瓦片系统从第 0 级开始:
- 第 0 级:1 张瓦片覆盖全球(256×256 像素)
- 第 1 级:4 张瓦片(2×2)
- 第 n 级:2n × 2n 张瓦片
每张瓦片有唯一的 z/x/y 编号。比如 14/12345/6789.png 表示第 14 级、x 方向第 12345 列、y 方向第 6789 行的瓦片。
瓦片加载的核心逻辑:
// 伪代码:根据经纬度和层级计算瓦片编号
function latLonToTile(lat, lon, zoom) {
let x = Math.floor((lon + 180) / 360 * Math.pow(2, zoom));
let y = Math.floor((1 - Math.log(Math.tan(lat * Math.PI / 180) + 1 / Math.cos(lat * Math.PI / 180)) / Math.PI) / 2 * Math.pow(2, zoom));
return { z: zoom, x: x, y: y };
}
瓦片服务 URL 模板
不同的地图服务商,瓦片 URL 格式略有不同:
| 服务商 | URL 模板 |
|---|---|
| OpenStreetMap | https://tile.openstreetmap.org/{z}/{x}/{y}.png |
| Google Maps | https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z} |
| 高德地图 | https://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z} |
1.3 常见地图服务对比
做无人机地图开发,选对地图服务很重要。我整理了一张对比表:
| 特性 | OpenStreetMap | Google Maps | 高德地图 |
|---|---|---|---|
| 数据源 | 开源社区 | 商业数据 | 国内测绘数据 |
| 国内精度 | 一般(偏远地区差) | 较好 | 优秀(有偏移校正) |
| 瓦片协议 | 完全开放 | 需 | 需 |
| 坐标系 | WGS84 | WGS84(显示用 Web Mercator) | GCJ-02(火星坐标系) |
| 适合场景 | 全球通用、原型开发 | 商业项目、国外飞行 | 国内飞行、高精度需求 |
coordtransform 库处理。
1.4 实战:坐标系转换代码
下面是我在项目中常用的 WGS84 转 GCJ-02 代码片段:
// WGS84 转 GCJ-02(简化版)
function wgs84ToGcj02(lat, lon) {
const a = 6378245.0; // 长半轴
const ee = 0.00669342162296594323; // 偏心率平方
let dLat = transformLat(lon - 105.0, lat - 35.0);
let dLon = transformLon(lon - 105.0, lat - 35.0);
let radLat = lat / 180.0 * Math.PI;
let magic = Math.sin(radLat);
magic = 1 - ee * magic * magic;
let sqrtMagic = Math.sqrt(magic);
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * Math.PI);
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * Math.PI);
return {
lat: lat + dLat,
lon: lon + dLon
};
}
嗯,这一章的内容就到这里。坐标系和瓦片原理是后续所有开发的基础——航迹规划、地图加载、实时显示,都离不开这些概念。你先把 WGS84、UTM、Web Mercator 的关系理清楚,后面写代码时就会顺手很多。