对于接触互联网地图的同学来说,最开始接触的恐怕就是坐标转换的过程了。由于地球是个近似椭球的形状,有各种各样的椭球模型来模拟地球,最著名的也就是GPS系统使用的WGS84椭球了。但是这些椭球体的坐标使用的是经纬度,单位是角度。目前我们的地图大多是二维平面上展示,使用角度为基础来计算多有不便,所以有众多数学家提出各种不同的转换方式来将经纬度表示的位置转换成平面坐标,这个转换过程地图学上成为投影。投影的方式多种多样,对我们做互联网地图的来说,最重要的就是墨卡托投影的变体——Web墨卡托投影。我们先来看一下墨卡托投影的转换过程
(以赤道本初子午线为原点)
投影完毕后的结果就是:
先不要头疼数学公式,已经有很多类库做好了代码实现,比如leaflet:
L.Projection.Mercator = { R: 6378137, R_MINOR: 6356752.314245179, bounds: L.bounds([-20037508.34279, -15496570.73972], [20037508.34279, 18764656.23138]), project: function (latlng) { var d = Math.PI / 180, r = this.R, y = latlng.lat * d, tmp = this.R_MINOR / r, e = Math.sqrt(1 - tmp * tmp), con = e * Math.sin(y); var ts = Math.tan(Math.PI / 4 - y / 2) / Math.pow((1 - con) / (1 + con), e / 2); y = -r * Math.log(Math.max(ts, 1E-10)); return new L.Point(latlng.lng * d * r, y); }, unproject: function (point) { var d = 180 / Math.PI, r = this.R, tmp = this.R_MINOR / r, e = Math.sqrt(1 - tmp * tmp), ts = Math.exp(-point.y / r), phi = Math.PI / 2 - 2 * Math.atan(ts); for (var i = 0, dphi = 0.1, con; i < 15 && Math.abs(dphi) > 1e-7; i++) { con = e * Math.sin(phi); con = Math.pow((1 - con) / (1 + con), e / 2); dphi = Math.PI / 2 - 2 * Math.atan(ts * con) - phi; phi += dphi; } return new L.LatLng(phi * d, point.x * d / r); } };