1. 高德地图经纬度是采用的什么标准?
WGS-84:是国际标准,GPS坐标(Google Earth使用、或者GPS模块)
GCJ-02:中国坐标偏移标准,Google地图、高德、腾讯使用
BD-09 :百度坐标偏移标准,Baidu地图使用
2.EPSG:4326 与EPSG:3857是什么关系?
EPSG:4326 (WGS84)
前面说了 WGS84 是目前最流行的地理坐标系统。
在国际上,每个坐标系统都会被分配一个 EPSG 代码,EPSG:4326 就是 WGS84 的代码。
GPS是基于WGS84的,所以通常我们得到的坐标数据都是WGS84的。
一般我们在存储数据时,仍然按WGS84存储。
EPSG:3857 (Pseudo-Mercator)
伪墨卡托投影,也被称为球体墨卡托,Web Mercator。
它是基于墨卡托投影的,把 WGS84坐标系投影到正方形。
我们前面已经知道 WGS84 是基于椭球体的,但是伪墨卡托投影把坐标投影到球体上,这导致两极的失真变大,
但是却更容易计算。这也许是为什么被称为”伪“墨卡托吧。
另外,伪墨卡托投影还切掉了南北85.051129°纬度以上的地区,以保证整个投影是正方形的。
因为墨卡托投影等正形性的特点,在不同层级的图层上物体的形状保持不变,
一个正方形可以不断被划分为更多更小的正方形以显示更清晰的细节。
很明显,伪墨卡托坐标系是非常显示数据,但是不适合存储数据的,
通常我们使用WGS84 存储数据,使用伪墨卡托显示数据。
3.坐标转换插件
leaflet.js可以使用gcoord 插件
https://blog.csdn.net/weixin_42116924/article/details/117816754
高德地图有内置转换api:
4.web mecator(球形墨卡托投影)
1.普遍采用ws84存储经纬度坐标,但以球形墨卡托计算投影,进行渲染
投影公式推导过程https://www.jianshu.com/p/434feafd40a7
//下面为leaflet.js中的源码部分,project属性为投影,可以看到对公式做了三角函数变换优化,且纬度限制了范围
var earthRadius = 6378137
var SphericalMercator = {
R: earthRadius,
MAX_LATITUDE: 85.0511287798,
project: function (latlng) {
var d = Math.PI / 180,
max = this.MAX_LATITUDE,
lat = Math.max(Math.min(max, latlng.lat), -max),
sin = Math.sin(lat * d)
return new Point(this.R * latlng.lng * d, (this.R * Math.log((1 + sin) / (1 - sin))) / 2)
},
unproject: function (point) {
var d = 180 / Math.PI
return new LatLng((2 * Math.atan(Math.exp(point.y / this.R)) - Math.PI / 2) * d, (point.x * d) / this.R)
},
bounds: (function () {
var d = earthRadius * Math.PI
return new Bounds([-d, -d], [d, d])
})(),
}
//下面这种计算方式按照公式的方式编写更容易理解,两种方式计算结果一样
function project({ lng, lat }) {
let r = 6378137
let d = Math.PI / 180 //度数转弧度
let xFactor = lng * d //x转换因子
let yFactor = Math.log(Math.tan(Math.PI / 4 + (lat / 2) * d))//y转换因子
let x = r * xFactor
let y = r * yFactor
return { x, y }
}
5. 瓦片计算
参考链接https://blog.csdn.net/sinat_34719507/article/details/59855536
瓦片相关概念放在了链接里,比较重要的有瓦片大小一般定为256*256,瓦片数量与zoom间的关系为Math.pow(2, zoom)
获取指定经纬度对应瓦片坐标的思路如下:
- 获取整个世界地图的投影坐标范围
- 获取指定经纬度点的投影坐标
- 根据zoom得到所有瓦片的数量
- 根据单张瓦片的大小得到所有瓦片的坐标范围
- 根据点的投影坐标与世界地图坐标的线性的比例关系得到瓦片坐标对应所有瓦片坐标范围的关系,最终得出指定点的瓦片坐标
根据上面思路,当地图的zoom等级为0时,即瓦片数量为1,那么将地图绘制到一张瓦片上,设定瓦片大小为256*256,则{lat:0,lng:0}对应的瓦片坐标应为[128,128]
下面以{lat:0,lng:0}来演示计算过程
let rightLatlng = { lat: -90, lng: 180 }
let point = project(latlng) // { x: 0, y: -7.081154551613622e-10 }
let point1 = project(leftLatlng) //{ x: -20037508.342789244, y: 20037508.34278071 }
let point2 = project(rightLatlng) //{ x: 20037508.342789244, y: -20037508.342780735 }
let tilesPoint = getTiles(point,0) //{ x: 128, y: 128 }
function getTiles(point, z) {
let tilesNumber = Math.pow(2, z)
let tilesPixel = 256
let totalPixel = tilesPixel * tilesNumber
let distance = 20037508.342789244
let totalDistance = 20037508.342789244 *2
let { x, y } = point
let tilesX = ((distance + x) / totalDistance) * totalPixel
let tilesY = ((distance - y) / totalDistance) * totalPixel
return { x: tilesX, y: tilesY }
}
function project({ lng, lat }) {
let maxLat = 85.0511287798
lat = Math.max(Math.min(maxLat, lat), -maxLat)
let r = 6378137
let d = Math.PI / 180 //度数转弧度
let xFactor = lng * d //x转换因子
let yFactor = Math.log(Math.tan(Math.PI / 4 + (lat / 2) * d))
let x = r * xFactor
let y = r * yFactor
return { x, y }
}
在leaflet.js中 对过leaflet.CRS.EPSG3857.latLngToPoint方法可以直接得到对应缩放比例下的瓦片坐标,leaflet.js对上面过程做了简化,小伙伴们可以去看下leaflet.js关于这部分的源码,感兴趣的小伙伴可以去验证下