百度地图的坐标转换,在javascript版本中,已经提供了很强大的装换,由于项目中需要在百度地图上打的标注以及线路等自定义覆盖物数量较大,而百度的标注最多只能支持400个左右(个人测试),超过400就会加载很慢或者IE卡死,所以,不得已,使用了百度的静态图,这样就引发出了一个问题,静态图只是一张图片,实际上并没有javascript中的BMap对象,经纬度的转换比较的蛋疼,故总结了一套静态图上的经纬度的转换。
前提:获取静态图需要指定地图的中心点和层级,故中心点经纬度和地图层级已经知晓。
首先,先罗列一些javascript上百度地图原生的转换坐标的方法。
<script type="text/javascript"> var map = new BMap.Map("container"); var poi = new BMap.Point(120.219375, 30.259244); map.centerAndZoom(poi,16); //获得墨卡托坐标(投影坐标系) var mecator = map.getMapType().getProjection().lngLatToPoint(poi); //根据墨卡托获取经纬度(球面坐标系) console.log(map.getMapType().getProjection().pointToLngLat(mecator)); </script>
百度地图还提供了经纬度转成像素坐标以及像素坐标转成经纬度的做法,例如:
var testPoint = new BMap.Point(经度,纬度); var testPointXY = map.pointToPixel(testPoint); // testPoint为百度标准的点 alert(testPointXY.x+"----"+testPointXY.y); // 这里假设获取出来的像素坐标是423,298 var testPointXY = {x:423,y:298}; // 该值是上面alert出来的x与y的值 var tp = map.pixelToPoint(testPointXY); alert(tp.lng+"----"+tp.lat); // 转换成了百度的经纬度,这里注意一点,由于423、298是上面转换出来的值, // 在进行转换成经纬度,实际的到的值,与testPoint会有误差,因为在map.pointToPixel(testPoint)时, // 由于得到的是整数的像素坐标,省略去小数位,再次使用map.pixelToPoint(testPointXY)反转的时候,误差就是小数位, // 所以最后获取的tp经纬度和testPoint经纬度之间有些许误差。 // 地图图层越小,误差越大,测试过在8时,误差在250米左右,当图层为13的时候,误差在10米内。
接着,开始讲一下在静态图上,怎样把像素坐标转换成经纬度坐标,以及把经纬度坐标转换成像素坐标。
在github上找到一个例子,连接如下: https://gist.github.com/aisk/3735854
但是这段代码经过测试后发现该些许问题,这里一一罗列:
pixelToPoint = function(point, zoom, center, bounds) 函数中,参数使用上,
1.point传入的是静态图上的点,距离左上角的像素坐标。
2.center参数传入的是中心点经纬度转换成墨卡托坐标后的经纬度。
3.zoom是静态图当前所在地图的层级。
4.bounds是静态图的大小,传入为width、height的对象
5. var> var mercatorLat = Number(center.lat) - Number(zoomUnits * (point.y - bounds.height / 2));
在js中进行数量的加减,需要先使用Number()函数转换成数值类型,原文中没有转换。
pointToPixel = function(point, zoom, mCenter, bounds) 函数中,参数:
1.point为经纬度坐标的对象
2.zoom是静态图当前所在层级。
3.mCenter是中心点的墨卡托坐标的经纬度。
4.bounds是静态图的大小,传入为width、height的对象。
javascript测试例子:
测试原理很简单,就是将中心点和测试点,分别打标注在地图上,测试点经纬度事先获取,转换成像素点坐标后,
再把像素点坐标转换成经纬度坐标,打在地图上,看下经过二次转换后的testPoint点距离原testPoint点的距离。
var map = new BMap.Map("container"); // 创建地图实例 map.enableScrollWheelZoom(true); //设置地图可缩放 map.addControl(new BMap.NavigationControl()); map.addControl(new BMap.ScaleControl()); map.addControl(new BMap.OverviewMapControl()); map.addControl(new BMap.MapTypeControl()); var centerPoint = new BMap.Point(经度,纬度); map.centerAndZoom(centerPoint,13); var testPoint = new BMap.Point(经度,纬度); var testMarker = new BMap.Marker(testPoint); map.addOverlay(testMarker); var bounds = {width:900,height:450}; // 我设置的地图图片在我swing框中的大小 // 当前地图的中心点 var centerMarker = new BMap.Marker(centerPoint); map.addOverlay(centerMarker); // 获取中心点的墨卡托坐标 var mcp = lngLatToMercator(centerPoint); // 测试点距离左上角的像素点坐标,由你程序获得或者算出来,这里仅作为测试 // 具体计算使用 // var tpXY = map.pointToPixel(testPoint);alert(testPointXY.x+"----"+testPointXY.y); // 这里就不重复计算 var tpXY = {x:423,y:298}; var rsp2 = pixelToPoint(tpXY, 13, mcp, bounds); // tpXY像素坐标转换后的经纬度坐标 alert(rsp2.lng+","+rsp2.lat); /* * 将转换后的点打在地图上,用来与testPoint的点做比较看误差多少 * 存在误差的原因是tpXY的像素坐标与testPoint的实际像素坐标有距离, * 原理类似于上文中误差存在原因。 */ var resultPoint = new BMap.Point(rsp2.lng,rsp2.lat); var resultMarker = new BMap.Marker(resultPoint); map.addOverlay(resultMarker);
本文中的例子是在html中测试,具体的静态图中像素转换经纬度坐标,经纬度坐标转换像素坐标,已写成java代码,本人QQ号1553862454,如有需要java代码,请发QQ邮件。