一、背景需求:
在百度地图上查询一个住宅小区, 界面会显示一个小区的边界阴影。大小区、新小区有;一些老小区也没有。我们老大看到了让我也整一个出来,大概就是输入小区名称,地图上展示出这个小区的边界轮廓。
要想展示边界轮廓,那么势必要获取小区的边界坐标。查遍百度地图api,只有获取行政区域轮廓图的方法。所以我采用抓包的方法,看了一下百度地图是怎么操作的。总结出了以下几个步骤。
二、实现方法:
1、获取小区的uid
获取小区id有两种方法:
a、根据抓包得到的百度获取小区uid的链接为:http://map.baidu.com/su?wd=金鹰国际城&cid=347&type=0&pc_ver=2,访问地址,得到结果:
其中s内的几个都是uid,取第一个bbb467bd96bc0a9ccac3db61
b、通过百度提供的JS接口LocalSearch的Search方法搜索小区名称,返回LocalResult中包含POI的uid.
得到返回值pois:
取第一个得到uid:
2、根据小区uid获取小区信息
通过Firefox的Httpfox插件抓包分析,与展示的小区范围相关的url串如下:
经测,其中content里面的geo,就是小区边界坐标集合。
3、获取小区边界坐标进行坐标转换
我们现在所获取到的小区边界坐标集合是百度的米制坐标,现在需要将米制坐标转换为经纬度。百度提供了BMAP_NORMAL_MAP.getProjection()。这个类里面的pointToLngLat(new BMap.Pixel(pos.lng, pos.lat));方法,可以将百度米制坐标转为经纬度。下面,我提供一个批量转换的方法,也就是直接可以把第二步获取的geo作为参数传进方法:
4、根据坐标集画多边形(小区边界轮廓)
现在我们已经取到了小区边界坐标集合,调用百度api,根据坐标点画多边形就好啦~~~
三、源码
<!DOCTYPE html>
<html>
<head>
<title>test6.html</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<script type="text/javascript" src="jquery.min-1.11.3.js"></script>
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=你自己的密钥"></script>
</head>
<body>
<div id="allmap" style="width:100%;height:600px;"></div>
<div class="layout">
<input id="value" value="淮海工学院东港学院-郁洲书院" type="text">
<input type="submit" onclick="pd()" value="定位">
</div>
</body>
<script type="text/javascript">
//初始化地图
var value='';
var map = new BMap.Map("allmap");
map.centerAndZoom('连云港市',10);
map.enableScrollWheelZoom();
//定位区域,小地名,使用本地检索方法
var dw=function(){
var local = new BMap.LocalSearch(map, {
renderOptions:{map: map}
});
local.setMarkersSetCallback(function(pois){
console.log(pois);
//清除所有覆盖物后,在叠加第一个点
map.clearOverlays();
for(var i=0;i<pois.length;i++){
var marker = new BMap.Marker(pois[i].point);
map.addOverlay(marker);
}
//根据获取到的poi id,查询边界坐标集合,画多边形
var uid = pois[0].uid;
queryUid(uid);
})
local.search(value);
map.clearOverlays();
}
//获取小区信息
function queryUid(uid){
$.ajax({
async: false,
url:"http://map.baidu.com/?pcevaname=pc4.1&qt=ext&ext_ver=new&l=12&uid="+uid,
dataType:'jsonp',
jsonp:'callback',
success:function(result) {
content = result.content;
if(null!=content.geo && content.geo!=undefined){
var geo = content.geo;
var points = coordinateToPoints(geo);
//point分组,得到多边形的每一个点,画多边形
if (points && points.indexOf(";") >= 0) {
points = points.split(";");
}
var arr=[];
for (var i=0;i<points.length-1;i++){
var temp = points[i].split(",");
arr.push(new BMap.Point(parseFloat(temp[0]),parseFloat(temp[1])));
}
var polygon = new BMap.Polygon(arr, {strokeColor:"blue", strokeWeight:2, strokeOpacity:0.5}); //创建多边形
map.addOverlay(polygon); //增加多边形
}
},
timeout:3000
});
}
//获取边界
function getBoundary(){//获取边界
var bdary = new BMap.Boundary();
bdary.get(value, function(rs){ //获取行政区域
map.clearOverlays(); //清除地图覆盖物
var count = rs.boundaries.length; //行政区域的点有多少个
for(var i = 0; i < count; i++){
var ply = new BMap.Polygon(rs.boundaries[i], {
strokeWeight: 1,
strokeColor: "#ff0000"
}); //建立多边形覆盖物
map.addOverlay(ply); //添加覆盖物
map.setViewport(ply.getPath()); //调整视野
}
});
}
//正则表达式,满足条件后调用
var patter=/['省'|'市'|'区'|'县']$/;
var pd=function(){
value=document.getElementById('value').value;
if(patter.test(value)==true){//关键字结尾是省市县区就调用下面方法
getBoundary();
if(/社区|小区$/.test(value)==true){//因为区后面结尾,会有小区和社区,即做了一个字方法
dw();
}
}else{//关键字结尾没有省市县区结尾就调用此方法
dw();
}
}
//坐标转换
function coordinateToPoints(coordinate) {
console.log(coordinate);
var points ="";
if (coordinate) {
var projection = BMAP_NORMAL_MAP.getProjection();
if (coordinate && coordinate.indexOf("-") >= 0) {
coordinate = coordinate.split('-');
}
//取点集合
var tempco = coordinate[1];
if (tempco && tempco.indexOf(",") >= 0) {
tempco = tempco.replace(";","").split(",");
}
//分割点,两个一组,组成百度米制坐标
var temppoints=[];
for(var i = 0, len = tempco.length; i < len; i++){
var obj = new Object();
obj.lng=tempco[i];
obj.lat=tempco[i+1];
temppoints.push(obj);
i++;
}
//遍历米制坐标,转换为经纬度
for ( var i = 0, len = temppoints.length; i < len; i++) {
//var pos = coordinate[i].split(',');
var pos = temppoints[i];
var point = projection.pointToLngLat(new BMap.Pixel(pos.lng, pos.lat));
points += ([ point.lng, point.lat ].toString() + ";");
}
}
return points;
}
</script>
</html>