根据坐标获取详细地址方法 For 百度地图0+
107,070 views / 2012.05.07 / 5:05 下午
先看官方给出的文档,可以很简单的根据坐标获取详细地址:
<div style="width:200px;height:200px" id="container"></div> <script> var map = new BMap.Map("container"); map.centerAndZoom(new BMap.Point(116.404, 39.915), 11); // 创建地理编码实例 function d(){ var myGeo = new BMap.Geocoder(); // 根据坐标得到地址描述 myGeo.getLocation(new BMap.Point(116.364, 39.993), function(result){ if (result){ alert(result.address); } }); } </script> <input type="button" onclick="d()" value="do" /> |
但是我们在做移动终端研发的时候,往往只能通过SDK获取到用户的坐标,如何才能让服务器获取用户的详细位置呢?(大众点评有实现)。我们运行上面的代码,抓包后分析发现,浏览器请求了这个地址:
http://api.map.baidu.com/?qt=rgc&x=12953722.17&y=4837205.83&dis_poi=100&poi_num=10&ie=utf-8&oue=1&res=api&callback=BMap._rd._cbk81902
看参数,这个x y 应该是坐标啊,可为什么跟我们传入的不一样呢?NND,原来百度给转换成了MC坐标,貌似这是搜过的算法啊! 算了,在这个互相山寨的年代,也管不了这么多了。献出我的php算法:
<?php function getRange($cF, $cE, $T) { if ($cE != null) { $cF = max($cF, $cE); } if ($T != null) { $cF = min($cF, $T); } return $cF; } function getLoop($cF, $cE, $T) { while ($cF > $T) { $cF -= $T - $cE; } while ($cF < $cE) { $cF += $T - $cE; } return $cF; } function convertLL2MC($T) { $LLBAND = array(75, 60, 45, 30, 15, 0); $LL2MC = array(array(- 0.0015702102444, 111320.7020616939, 1704480524535203, -10338987376042340, 26112667856603880, -35149669176653700, 26595700718403920, -10725012454188240, 1800819912950474, 82.5), array(0.0008277824516172526, 111320.7020463578, 647795574.6671607, -4082003173.641316, 10774905663.51142, -15171875531.51559, 12053065338.62167, -5124939663.577472, 913311935.9512032, 67.5), array(0.00337398766765, 111320.7020202162, 4481351.045890365, -23393751.19931662, 79682215.47186455, -115964993.2797253, 97236711.15602145, -43661946.33752821, 8477230.501135234, 52.5), array(0.00220636496208, 111320.7020209128, 51751.86112841131, 3796837.749470245, 992013.7397791013, -1221952.21711287, 1340652.697009075, -620943.6990984312, 144416.9293806241, 37.5), array(- 0.0003441963504368392, 111320.7020576856, 278.2353980772752, 2485758.690035394, 6070.750963243378, 54821.18345352118, 9540.606633304236, -2710.55326746645, 1405.483844121726, 22.5), array(- 0.0003218135878613132, 111320.7020701615, 0.00369383431289, 823725.6402795718, 0.46104986909093, 2351.343141331292, 1.58060784298199, 8.77738589078284, 0.37238884252424, 7.45)); $T['lng'] = getLoop($T['lng'], -180, 180); $T['lat'] = getRange($T['lat'], -74, 74); for ($cF = 0; $cF < count($LLBAND); $cF++) { if ($T['lat'] >= $LLBAND[$cF]) { $cG = $LL2MC[$cF]; break; } } if (!$cG) { for ($cF = count($LLBAND) - 1; $cF >= 0; $cF--) { if ($T['lng'] <= - $LLBAND[$cF]) { $cG = $LL2MC[$cF]; break; } } } $cH = convertor($T, $cG); $T = array(round($cH['lng'], 2), round($cH['lat'], 2)); return $T; } function convertor($cF, $cG) { if (!$cF || !$cG) { return false; } $T = $cG[0] + $cG[1] * abs($cF['lng']); $cE = abs($cF['lat']) / $cG[9]; $cH = $cG[2] + $cG[3] * $cE + $cG[4] * $cE * $cE + $cG[5] * $cE * $cE * $cE + $cG[6] * $cE * $cE * $cE * $cE + $cG[7] * $cE * $cE * $cE * $cE * $cE + $cG[8] * $cE * $cE * $cE * $cE * $cE * $cE; $T *= ($cF['lng'] < 0 ? -1: 1); $cH *= ($cF['lat'] < 0 ? -1: 1); return array("lng" => $T, "lat" => $cH); } $d = convertLL2MC(array("lng" => "116.364", "lat" => "39.993")); echo file_get_contents("<a href="http://api.map.baidu.com/?qt=rgc&x">http://api.map.baidu.com/?qt=rgc&x</a>=" . $d[0] . "&y=" . $d[1] . "&dis_poi=100&poi_num=10&ie=utf-8&oue=1&res=api&callback="); |
?>
怎样,实现了吧?这事之所以这么麻烦,还是nodejs不够高级啊,不然直接架设个nodejs服务器,专门运行js脚本,我们就不用这么麻烦了。
杜工原创,转载注明来源,否则必究。