百度地图坐标系相关学习总结

来源:互联网 发布:百度关键字排名软件 编辑:程序博客网 时间:2024/05/29 15:50

百度地图API详解之地图坐标系统



我们都知道地球是圆的,电脑显示器是平的,要想让位于球面的形状显示在平面的显示器上就必然需要


一个转换过程,这个过程就叫做投影(Projection)。在地球上我们通过经纬度来描述某个位置,而经


过投影之后的地图也有自己的坐标系统,本篇文章就来详细介绍在百度地图API中涉及的各种坐标体系。
在百度地图API中,你需要了解如下坐标系:
经纬度:通过经度(longitude)和纬度(latitude)描述的地球上的某个位置。
平面坐标:投影之后的坐标(用x和y描述),用于在平面上标识某个位置。
像素坐标:描述不同级别下地图上某点的位置。
图块坐标:地图图块编号(用x和y描述)。
可视区域坐标:地图可视区域的坐标系(用x和y描述)。
覆盖物坐标:覆盖物相对于容器的坐标(用x和y描述)。
别被这么多的坐标系吓着,看完了后面的讲解相信你会逐渐理解它们。


经纬度
这个就不多说了,不熟悉的可以翻翻地理书。但需要注意的是即便同是经纬度坐标也可 能属于不同的坐


标体系。一般GPS设备获取的经纬度属于WGS84坐标系,这是一个比较通用的坐标体系。由于某些原因国


内不能直接使用WGS84坐标,因 此百度地图API的经纬度是经过加密偏移的。


平面坐标
前面说过,球面上的形状需要经过投影才能变换为平面上的形状,变换后就需要有一个平面坐标系统来


描述地图上某个位置。百度地图API默认使用墨卡托投影(Mercator Projection),同样需要注意的是


由于投影参数不同,同样是墨卡托投影也会有所差别。
平面坐标系的原点与经纬度的原点一致,即赤道与0度经线相交的位置:
百度地图API详解之地图坐标系统(转)
在百度地图API中,平面坐标是以最大级别18级为基准的。就是说在18级下,平 面坐标的一个单位就代


表了屏幕上的1个像素。平面坐标与地图所展示的级别没有关系,也就是说在1级和18级下,天安门位置


的平面坐标都是一致的。那么如何 知道某个位置的平面坐标呢?可通过BMap.MercatorProjection类来


完成,该类提供经纬度与平面坐标互相转换的方法。例如天安门的经纬 度大约为116.404, 39.915,经


过转换即可得到平面坐标:
var projection = new BMap.MercatorProjection();
var point = projection.lngLatToPoint(new BMap.Point(116.404, 39.915));
alert(point.x + ", " + point.y);
结果如下:
百度地图API详解之地图坐标系统(转)
这个就是平面坐标。你可以这样理解它的含义:第18级下,天安门距离坐标原点的位置差为:12958175, 


4825923.77,单位为像素。


像素坐标
在第18级下,我们直接将平面坐标向下取整就得到了像素坐标,而在其他级别下可以通过如下公式进行


换算(这里取整为向下取整):
像素坐标 = |平面坐标 × 2 zoom - 18|
比如经过计算,在第4级天安门位置的像素坐标是:790, 294
百度地图API详解之地图坐标系统(转)
不同级别下,同一个地理位置的像素坐标是不一样的,它与当前地图的级别相关。


图块坐标
百度地图API在展示地图时是将整个地图图片切割成若干图块来显示的,当地图初始化或是地图级别、中


心点位置发生变化时,地图API会根据当前像素坐标计算出视野内需要的图块坐标(也叫图块编号),从


而加载对应的图块用以显示地图。
百度地图的图块坐标原点与平面坐标一致,从原点向右上方开始编号为0, 0:
百度地图API详解之地图坐标系统(转)
如何知道某个位置的图块坐标呢?通过如下公式计算即可(这里为向下取整):
图块坐标 = |像素坐标 ÷ 256|
256实际上是每个图块的宽度和高度,我们用像素坐标除以这个数就知道图块坐标了。还以天安门为例,


在第4级下天安门所在的图块编号为:3, 1,而在第18级下,图块编号为:50617, 18851


可视区域坐标
地图都是显示在确定大小的矩形框中的,这个矩形框通常是开发者在初始化地图传入的某个容器元素。


这个矩形框也有自己的坐标系,在百度地图API中称之为可视区域坐标系,它的原点位于矩形的左上角。
百度地图API详解之地图坐标系统(转)
通过Map类的pointToPixel和pixelToPoint方法可以相互转换经纬度坐标与可视区域坐标。


覆盖物坐标
覆盖物在实现上就是若干DOM元素,这些元素会被放在若干覆盖物容器内(具体请参 考地图API开发指南


),那么覆盖物的坐标实际上就是相对于这些覆盖物容器的坐标。在地图初始化完成后,覆盖物容器的


左上角与地图可视区域左上角位置相 同,一旦地图被移动、缩放,覆盖物容器位置就会发生变化。在自


定义覆盖物的时候API提供经纬度信息,而开发者需要自行将经纬度转换为覆盖物的像素坐标, 从而覆


盖物才能显示在正确的位置上。这个转换过程可以通过Map的pointToOverlayPixel和


overlayPixelToPoint两个 方法来实现。 
讲这么多都快晕了吧,我们最后通过一个完整的代码示例来回顾上面所提到的坐标系概念:
复制代码
DOCTYPE html>
<</span>html>
<</span>head>
<</span>meta charset="utf-8" />
<</span>title>地图坐标概念</</span>title>
<</span>script src="http://api.map.baidu.com/api?v=1.2"></</span>script>
</</span>head>
<</span>body>
<</span>div id="map_container" style="width:500px;height:320px;"></</span>div>
<</span>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 = "
平面坐标:" + 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 = "
像素坐标:" + pixelCoordinate.x + ", " + pixelCoordinate.y;


var tileCoordinate = new BMap.Pixel(Math.floor(pixelCoordinate.x / 256),
Math.floor(pixelCoordinate.y / 256));
var tileCoordStr = "
图块坐标:" + tileCoordinate.x + ", " + tileCoordinate.y;


var viewportCoordinate = map.pointToPixel(lngLat);
var viewportCoordStr = "
可视区域坐标:" + viewportCoordinate.x + ", " + viewportCoordinate.y;


var overlayCoordinate = map.pointToOverlayPixel(lngLat);
var overlayCoordStr = "
覆盖物坐标:" + overlayCoordinate.x + ", " + overlayCoordinate.y;


info.setContent(lngLatStr + worldCoordStr + pixelCoordStr + tileCoordStr + 
viewportCoordStr + overlayCoordStr);
map.openInfoWindow(info, lngLat);
});
</</span>script>
</</span>body>
</</span>html>
复制代码
效果如图:
百度地图API详解之地图坐标系统(转)


原文地址:http://www.cnblogs.com/jz1108/archive/2011/07/02/2095376.html


========


关于百度地图API的地图坐标转换问题

http://malagis.com/baidu-maps-api-map-coordinate-conversion.html


我在之前的文章利用html5获取经纬度并且在百度地图中显示位置中使用了百度地图的API来显示html5获


取的地理位置,在文中我说过这样的话,我说百度地图的准确度不怎么精确,偏差很大。这里我要更正


下:


国际经纬度坐标标准为WGS-84,国内必须至少使用国测局制定的GCJ-02,对地理位置进行首次加密。百度


坐标在此基础上,进行了BD-09二次加密措施,更加保护了个人隐私。百度对外接口的坐标系并不是GPS采


集的真实经纬度,需要通过坐标转换接口进行转换。


由此可以看出小编之前冤枉了百度地图,所以如果对您有误导还请见谅。所以写了篇关于百度地图API坐


标转换的文章,并且对之前的模型做了修正。


实现代码:


//在百度 map中显示地址
    var map = new BMap.Map("map_canvas");
    var point = new BMap.Point(longitudeP , latitudeP);  // 创建点坐标  
    map.centerAndZoom(point, 15);// 初始化地图,设置中心点坐标和地图级别  
    var marker = new BMap.Marker(point);    
    map.addOverlay(marker); 
    BMap.Convertor.translate(point,0,translateCallback);     //真实经纬度转成百度坐标
回调函数代码:


//坐标转换完之后的回调函数
function translateCallback(point1){
    var marker1 = new BMap.Marker(point1);
    map.addOverlay(marker1);
    var label = new BMap.Label("转换后的百度坐标",{offset:new BMap.Size(20,-10)});
    marker1.setLabel(label); //添加百度label
    map.setCenter(point1);
}
这是新的效果图:


undefined


可以看出转换出的效果还是相当精确的,并且从我这里的demo来看要比谷歌地图精确的多!所以如果也有


像我一样的用户发现调用baidu map坐标有偏差的话,很有可能就是没有进行坐标转换。


========

0 0