引自:http://www.cnblogs.com/jz1108/archive/2011/07/02/2095376.htmlhtml
咱们都知道地球是圆的,电脑显示器是平的,要想让位于球面的形状显示在平面的显示器上就必然须要一个转换过程,这个过程就叫作投影(Projection)。在地球上咱们经过经纬度来描述某个位置,而通过投影以后的地图也有本身的坐标系统,本篇文章就来详细介绍在百度地图API中涉及的各类坐标体系。git
在百度地图API中,你须要了解以下坐标系:web
咱们都知道地球是圆的,电脑显示器是平的,要想让位于球面的形状显示在平面的显示器上就必然须要一个转换过程,这个过程就叫作投影(Projection)。在地球上咱们经过经纬度来描述某个位置,而通过投影以后的地图也有本身的坐标系统,本篇文章就来详细介绍在百度地图API中涉及的各类坐标体系。api
在百度地图API中,你须要了解以下坐标系:post
别被这么多的坐标系吓着,看完了后面的讲解相信你会逐渐理解它们。this
经纬度加密
这个就很少说了,不熟悉的能够翻翻地理书。但须要注意的是即使同是经纬度坐标也可 能属于不一样的坐标体系。通常GPS设备获取的经纬度属于WGS84坐标系,这是一个比较通用的坐标体系。因为某些缘由国内不能直接使用WGS84坐标,因 此百度地图API的经纬度是通过加密偏移的。url
平面坐标spa
前面说过,球面上的形状须要通过投影才能变换为平面上的形状,变换后就须要有一个平面坐标系统来描述地图上某个位置。百度地图API默认使用墨卡托投影(Mercator Projection),一样须要注意的是因为投影参数不一样,一样是墨卡托投影也会有所差异。3d
平面坐标系的原点与经纬度的原点一致,即赤道与0度经线相交的位置:
结果以下:
这个就是平面坐标。你能够这样理解它的含义:第18级下,天安门距离坐标原点的位置差为:12958175, 4825923.77,单位为像素。
像素坐标
在第18级下,咱们直接将平面坐标向下取整就获得了像素坐标,而在其余级别下能够经过以下公式进行换算(这里取整为向下取整):
好比通过计算,在第4级天安门位置的像素坐标是:790, 294
不一样级别下,同一个地理位置的像素坐标是不同的,它与当前地图的级别相关。
图块坐标
百度地图API在展现地图时是将整个地图图片切割成若干图块来显示的,当地图初始化或是地图级别、中心点位置发生变化时,地图API会根据当前像素坐标计算出视野内须要的图块坐标(也叫图块编号),从而加载对应的图块用以显示地图。
百度地图的图块坐标原点与平面坐标一致,从原点向右上方开始编号为0, 0:
如何知道某个位置的图块坐标呢?经过以下公式计算便可(这里为向下取整):
256其实是每一个图块的宽度和高度,咱们用像素坐标除以这个数就知道图块坐标了。还以天安门为例,在第4级下天安门所在的图块编号为:3, 1,而在第18级下,图块编号为:50617, 18851
可视区域坐标
地图都是显示在肯定大小的矩形框中的,这个矩形框一般是开发者在初始化地图传入的某个容器元素。这个矩形框也有本身的坐标系,在百度地图API中称之为可视区域坐标系,它的原点位于矩形的左上角。
经过Map类的pointToPixel和pixelToPoint方法能够相互转换经纬度坐标与可视区域坐标。
覆盖物坐标
覆盖物在实现上就是若干DOM元素,这些元素会被放在若干覆盖物容器内(具体请参 考地图API开发指南),那么覆盖物的坐标实际上就是相对于这些覆盖物容器的坐标。在地图初始化完成后,覆盖物容器的左上角与地图可视区域左上角位置相 同,一旦地图被移动、缩放,覆盖物容器位置就会发生变化。在自定义覆盖物的时候API提供经纬度信息,而开发者须要自行将经纬度转换为覆盖物的像素坐标, 从而覆盖物才能显示在正确的位置上。这个转换过程能够经过Map的pointToOverlayPixel和overlayPixelToPoint两个 方法来实现。
讲这么多都快晕了吧,咱们最后经过一个完整的代码示例来回顾上面所提到的坐标系概念:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>地图坐标概念</title> <script src="http://api.map.baidu.com/api?v=1.2"></script> </head> <body> <div id="map_container" style="width:500px;height:320px;"></div> <script> var map = new BMap.Map('map_container', {defaultCursor: 'default'}); map.centerAndZoom(new BMap.Point(116.404, 39.915), 11); var TILE_SIZE = 256; map.addEventListener('click', function(e){ var info = new BMap.InfoWindow('', {width: 260}); var projection = this.getMapType().getProjection(); var lngLat = e.point; var lngLatStr = "经纬度:" + lngLat.lng + ", " + lngLat.lat; var worldCoordinate = projection.lngLatToPoint(lngLat); var worldCoordStr = "<br />平面坐标:" + worldCoordinate.x + ", " + worldCoordinate.y; var pixelCoordinate = new BMap.Pixel(Math.floor(worldCoordinate.x * Math.pow(2, this.getZoom() - 18)), Math.floor(worldCoordinate.y * Math.pow(2, this.getZoom() - 18))); var pixelCoordStr = "<br />像素坐标:" + pixelCoordinate.x + ", " + pixelCoordinate.y; var tileCoordinate = new BMap.Pixel(Math.floor(pixelCoordinate.x / 256), Math.floor(pixelCoordinate.y / 256)); var tileCoordStr = "<br />图块坐标:" + tileCoordinate.x + ", " + tileCoordinate.y; var viewportCoordinate = map.pointToPixel(lngLat); var viewportCoordStr = "<br />可视区域坐标:" + viewportCoordinate.x + ", " + viewportCoordinate.y; var overlayCoordinate = map.pointToOverlayPixel(lngLat); var overlayCoordStr = "<br />覆盖物坐标:" + overlayCoordinate.x + ", " + overlayCoordinate.y; info.setContent(lngLatStr + worldCoordStr + pixelCoordStr + tileCoordStr + viewportCoordStr + overlayCoordStr); map.openInfoWindow(info, lngLat); }); </script> </body> </html>
效果如图:
点击嵌在webbrowser中的html,使用click得到的point用 pointToPixel方法获得当前点在屏幕上的坐标