目录

1 问题描述

2 独立显示区域

3 自定义网格

4 显示自定义网格

5 延展

6 参考文献


1 问题描述

(1) 通过百度地图或者高德地图只展示某一个行政区域,例如整个地图只展示郑州市金水区,其他区域不显示。

(2) 整个地图只显示自定义的区域,并显示区域的自定义名称。

百度地图的JSAPI有关于显示行政区域边界的专用方法,参考百度官方的例子

百度官方api提供的这个功能,就是直接根据行政区域的名称来检索,并显示边界信息的。最多到县级,再往下就没有了,更不要说社区、乡村这些了,甚至有些边远地区的行政边界也是没有的。并且官方的这个例子,也不支持仅仅只显示指定的区域,无法屏蔽到其他地图的能力。

关于行政边界的数据不是公开的,只有专业的地图测绘相关的公司有比较准确的数据。我们想用,要么找破解工具下载相对老的数据零散数据,要么掏钱找第三方地图服务的公司买。当然,我们也可以通过自己确定社区或者乡村的边界,在地图上打点,自定义覆盖物边界的方式自行圈出所需区域的边界

2 独立显示区域

所谓独立显示指定区域,指的是在地图上我只显示某一区域的地图,其他地图不想显示。例如:我只显示郑州市金水区的地图,其他地方都是空白。如何实现?在放代码之前,说一点我自己的认识和理解,不管怎样,地图都是一层一层的,根据级别不同,显示的地图颗粒度不同,百度地图关于覆盖物有比较清晰的API定义,那么实现思路其实就是,通过自定义添加多层覆盖物的方式来实现独立显示某一区域,例如:我们先给以全局覆盖物,把整个地图都盖住,然后再给一个覆盖物,显示具体的行政区域数据。

代码如下:

<!DOCTYPE html><html>
<head><meta name="viewport" content="width=device-width" /><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title></title><script src="http://code.jquery.com/jquery-1.8.2.min.js"></script><script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=你的ak"></script><script type="text/javascript" src="http://api.map.baidu.com/library/AreaRestriction/1.2/src/AreaRestriction_min.js"></script><style type="text/css">html {height: 100%;}body {height: 100%;margin: 0px;padding: 0px;}#container {height: 100%;}</style>
</head><body>
<div id="container"></div><script type='text/javascript'>//提示:下面的代码用jquery,所以如果有不能运行的情况请引用后尝试//百度地图api container对应前端div名称 前端要引用2.0版本的百度地图api//需引用api.map.baidu.com/library/AreaRestriction/1.2/src/AreaRestriction_min.jsvar map = new BMap.Map("container", { enableMapClick: false }); // 创建地图实例,禁止点击地图底图//设置样式map.setMapStyle({styleJson: [{//不显示点信息"featureType": "poi","elementType": "all","stylers": {"color": "#ffffff","visibility": "off"}}]});map.disableDragging();//禁止拖动map.disableDoubleClickZoom();//禁止双击缩放var blist = [];var districtLoading = 0;function getBoundary() {addDistrict("郑州市金水区");}/*** 添加行政区划* @param {} districtName 行政区划名* @returns  无返回值*/function addDistrict(districtName) {//使用计数器来控制加载过程districtLoading++;var bdary = new BMap.Boundary();bdary.get(districtName, function (rs) {       //获取行政区域var count = rs.boundaries.length; //行政区域的点有多少个if (count === 0) {alert('未能获取当前输入行政区域');return;}for (var i = 0; i < count; i++) {blist.push({ points: rs.boundaries[i], name: districtName });};//加载完成区域点后计数器-1districtLoading--;if (districtLoading == 0) {//全加载完成后画端点drawBoundary();}});}/*** 各种鼠标事件绑定*/function click(evt) {alert(evt.target.name);}function mouseover(evt) {evt.target.label.setZIndex(99);evt.target.label.setPosition(evt.point);evt.target.label.show();}function mousemove(evt) {evt.target.label.setPosition(evt.point);}function mouseout(evt) {evt.target.label.hide();}function drawBoundary() {//包含所有区域的点数组var pointArray = [];/*画遮蔽层的相关方法*思路: 首先在中国地图最外画一圈,圈住理论上所有的中国领土,然后再将每个闭合区域合并进来,并全部连到西北角。*      这样就做出了一个经过多次西北角的闭合多边形*///定义中国东南西北端点,作为第一层var pNW = { lat: 59.0, lng: 73.0 }var pNE = { lat: 59.0, lng: 136.0 }var pSE = { lat: 3.0, lng: 136.0 }var pSW = { lat: 3.0, lng: 73.0 }//向数组中添加一次闭合多边形,并将西北角再加一次作为之后画闭合区域的起点var pArray = [];pArray.push(pNW);pArray.push(pSW);pArray.push(pSE);pArray.push(pNE);pArray.push(pNW);//循环添加各闭合区域for (var i = 0; i < blist.length; i++) {//添加显示用标签层var label = new BMap.Label(blist[i].name, { offset: new BMap.Size(20, -10) });label.hide();map.addOverlay(label);//添加多边形层并显示var ply = new BMap.Polygon(blist[i].points, { strokeWeight: 5, strokeColor: "#FF0000", fillOpacity: 0.01, fillColor: " #FFFFFF" }); //建立多边形覆盖物ply.name = blist[i].name;ply.label = label;ply.addEventListener("click", click);ply.addEventListener("mouseover", mouseover);ply.addEventListener("mouseout", mouseout);ply.addEventListener("mousemove", mousemove);map.addOverlay(ply);//添加名称标签层var centerlabel = new BMap.Label(blist[i].name, { offset: new BMap.Size(0, 0) });centerlabel.setPosition(ply.getBounds().getCenter());map.addOverlay(centerlabel);//将点增加到视野范围内var path = ply.getPath();pointArray = pointArray.concat(path);//将闭合区域加到遮蔽层上,每次添加完后要再加一次西北角作为下次添加的起点和最后一次的终点pArray = pArray.concat(path);pArray.push(pArray[0]);}//限定显示区域,需要引用api库var boundply = new BMap.Polygon(pointArray);BMapLib.AreaRestriction.setBounds(map, boundply.getBounds());map.setViewport(pointArray);    //调整视野//添加遮蔽层var plyall = new BMap.Polygon(pArray, { strokeOpacity: 0.0000001, strokeColor: "#000000", strokeWeight: 0.00001, fillColor: "#000000", fillOpacity: 0.7 }); //建立多边形覆盖物map.addOverlay(plyall);}setTimeout(function () {getBoundary();}, 100);
</script>
</body>

显示效果如下:

我们可以通过调整plyall遮罩层的颜色来改变底层的透明度,也可以完全不显示。

3 自定义网格

实际使用过程中,很多的社区、乡村的边界数据是没有的,我们无法直接通过bdary.get方式获取到,此时我们可以通过自定义划边界打点的功能来自定义边界区域,获取边界的所有点坐标,然后在以覆盖物的方式显示出来,就能满足需要。这个工具主要是来自参考文献2,我这里仅仅根据自己的需要做了微量调整,具体代码如下:

<!DOCTYPE html>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=gb2312" /><title>自动以选取行政区域的工具</title><script type="text/javascript" src="http://api.map.baidu.com/api?v=1.2"></script>
</head>
<body>
<div>
<div style="width:1200px;height:700px;border:1px solid gray;float: left;" id="container"></div>
<div style="float: right;width: calc(100% - 1220px);height: 1200px;padding-top: 350px;"><input id="startBtn" type="button" onclick="startTool();" value="开启取点工具" /><input type="button" onclick="clearInfos();" value="清除" />
</div>
</div>
<div id="info"></div>
<br/>
<h1>拷贝下面的数据信息到test2中去展示这个网格吧,相应的,你也可以把这个数据保存到数据库里,前端按需展示</h1>
<div id="code_infos"></div>
</body>
</html>
<script type="text/javascript">var map = new BMap.Map("container");// 创建Map实例map.centerAndZoom("郑州", 11);     // 初始化地图,设置中心点坐标和地图级别map.enableScrollWheelZoom();    //开启鼠标滚轮缩放var key = 1;    //开关var newpoint;   //一个经纬度var points = [];    //数组,放经纬度信息var polyline = new BMap.Polyline(); //折线覆盖物function clearInfos(){map.clearOverlays();document.getElementById('info').innerHTML = '';document.getElementById('code_infos').innerHTML = '';points=[];}function startTool(){   //开关函数if(key==1){document.getElementById("startBtn").style.background = "green";document.getElementById("startBtn").style.color = "white";document.getElementById("startBtn").value = "开启状态";key=0;}else{document.getElementById("startBtn").style.background = "red";document.getElementById("startBtn").value = "关闭状态";key=1;}}map.addEventListener("click",function(e){   //单击地图,形成折线覆盖物newpoint = new BMap.Point(e.point.lng,e.point.lat);if(key==0){//    if(points[points.length].lng==points[points.length-1].lng){alert(111);}points.push(newpoint);  //将新增的点放到数组中polyline.setPath(points);   //设置折线的点数组map.addOverlay(polyline);   //将折线添加到地图上document.getElementById("info").innerHTML += "new BMap.Point(" + e.point.lng + "," + e.point.lat + "),</br>";    //输出数组里的经纬度}});map.addEventListener("dblclick",function(e){   //双击地图,形成多边形覆盖物if(key==0){map.disableDoubleClickZoom();   //关闭双击放大var polygon = new BMap.Polygon(points);console.log(points);var c_points ='';for(var i=0;i<points.length;i++){if(i>0){c_points+=';'}c_points+=points[i].lng+', '+ points[i].lat;}var codeinfos ={points: c_points, name: '网格名称'}console.log(codeinfos);document.getElementById("code_infos").innerHTML = JSON.stringify(codeinfos);map.addOverlay(polygon);   //将折线添加到地图上}});
</script>

主要是添加了一个div用来把自定义划好网格区域的points数据放到一个对象种,并展示出来,使用的时候,直接拿这串数据去展示即可。关于工具有几点说明:

(1) 开启取点工具后,即可在地图上单击选点,从第二次点击开始,后续每次单击都会画一条线连接当前点和上一个点

(2) 双击鼠标会自动连接当前点和起始点,形成一个闭环的覆盖物显示到地图上,并将相关points信息在页面展示出来

4 显示自定义网格

在自定义工具中获取到的边界数据信息格式如下:

{points:"113.673169, 34.792905;113.673349, 34.791423;113.673313, 34.789289;113.673241, 34.787154;113.673493, 34.785969;113.673349, 34.785583;113.667312, 34.785583;113.664438, 34.785553;113.662318, 34.785731;113.658221, 34.792016;113.657143, 34.793706;113.657, 34.793943;113.66318, 34.79338;113.665372, 34.79335;113.666953, 34.793232;113.669792, 34.793083;113.673169, 34.792965;113.673169, 34.792965",name:"网格名称"};

我们优化改造下显示指定行政区域地图的代码,在通过bdary.get获取不到百度官方的行政区域数据的时候,使用自定义覆盖物的数据来展示,核心调整代码如下:

function getBoundary() {var points_code={points:"113.673169, 34.792905;113.673349, 34.791423;113.673313, 34.789289;113.673241, 34.787154;113.673493, 34.785969;113.673349, 34.785583;113.667312, 34.785583;113.664438, 34.785553;113.662318, 34.785731;113.658221, 34.792016;113.657143, 34.793706;113.657, 34.793943;113.66318, 34.79338;113.665372, 34.79335;113.666953, 34.793232;113.669792, 34.793083;113.673169, 34.792965;113.673169, 34.792965",name:"网格名称"};addDistrict("郑州大学",points_code);}/*** 添加行政区划* @param {} districtName 行政区划名* @returns  无返回值*/function addDistrict(districtName,points_code) {//使用计数器来控制加载过程districtLoading++;var bdary = new BMap.Boundary();bdary.get(districtName, function (rs) {       //获取行政区域var count = rs.boundaries.length; //行政区域的点有多少个if (count === 0) {alert("没有找到官方关于"+districtName+"的行政边界信息,使用自定义区域显示");blist.push(points_code);}else{for (var i = 0; i < count; i++) {blist.push({ points: rs.boundaries[i], name: districtName });};}//加载完成区域点后计数器-1districtLoading--;if (districtLoading == 0) {//全加载完成后画端点drawBoundary();}});}

显示效果如下

.

5 延展

有时候,客户可能因为安全原因或者网络缘故,要求使用离线地图,而且为了避免业务数据被百度或者高德抓取,要求不让使用百度或者高德的地图,这里推荐一个前端开源的js地图框架,OpenLayer,非常的强大,配合GeoServer以及postgis数据库,通过下载离线的瓦片数据,可以实现非常强大的地图效果。

6 参考文献

【1】百度地图api(javascript)只显示某一行政区域的地图,其他周边地区的都不显示

【2】【百度地图API】自行获取区域经纬度的工具

百度地图获取行政区域以及自定义显示网格相关推荐

  1. iOS 开发 百度地图 在模拟器上只显示网格!

    虚拟机上不显示地图,只显示格子了,如下图: 因为模拟器上面默认得不是国内得位置,而国外得位置或者港澳台地区, 百度地图不支持,所以显示空白, 解决方法:点击模拟器-->(菜单导航栏)调试--&g ...

  2. android百度地图覆盖物异步加载图片,Android 百度地图marker中图片不显示的解决方法(推荐)...

    目的: 根据提供的多个经纬度,显示所在地的marker样式,如下: 问题: 1.发现marker中在线加载的图片无法显示出来: 2.获取多个对象后,却只显示出了一个marker: 以下为官网实现方法: ...

  3. 高德地图获取行政区域以及中心点

    高德地图设置行政区域以及自定义文本内容,文本内容能够自动放置到中心位置,如果位置有偏差支持手动调整.(ps: turf.js地理空间分析库,处理各种地图算法) /*** type,显示级别distri ...

  4. 调用百度地图API,如何只显示某个省份的地图

    需求如下 1.调用百度地图API 2.只显示某个省份的地图如安徽省,其他的都不要显示 实现步骤如下 1.调用百度地图Api,显示地图 https://blog.csdn.net/tian_jiangn ...

  5. android 百度地图拖动定位,百度地图获取定位,实现拖动marker定位,返回具体的位置名...

    body, html,#allmap {width: 100%;height: 100%;overflow: hidden;margin:0;font-family:"微软雅黑"; ...

  6. 百度地图 添加行政区域

    找资料的时候看到很多大佬写过关于百度地图添加行政区域但是由于我的是离线地图直接用百度地图api获取不到,所以自己写了一遍 记录一下. function getBoundary(){ var areas ...

  7. 百度地图绘画行政区域

    百度地图绘画行政区域 因为有个需求是要用在线地图只展示市的行政区域,还有ui设计的样式,所以只能自己绘画了. 效果图: 上代码 <baidu-map ref="baiduMap&quo ...

  8. 百度地图获取当前位置街道_轻松查看街道地址位置地图

    百度地图获取当前位置街道 Have you found the address for a place that you would like to visit while browsing but ...

  9. 【百度地图】路书轨迹显示

    [百度地图]路书轨迹显示 通过后端返回的坐标点列表,然后在地图上展示出轨迹,并且显示标点和显示窗口文案.效果如下 引入百度地图,因为百度地图的轨迹(路书)模式只能是3.0才可以使用,所以注意自己引入的 ...

最新文章

  1. [文档].Altera - 可选择的Nios II的Boot方法
  2. mysql提供的六种约束_SQL的六种约束
  3. 云服务器mqtt协议,云服务器mqtt协议
  4. PyCherm的常用快捷键总结
  5. Websocket实现即时通讯
  6. 推荐一本学javascript的书籍---经典
  7. php文件流播放拖动,自定义实现可以播放暂停、进度拖拽、音量控制及全屏的H5播放器...
  8. sans serif字体_30种免费的Sans Serif字体下载
  9. 2020最新的eclipse之安卓开发环境搭建
  10. Win10如何开启IIS服务以及如何打开IIS管理器
  11. 性能测试20--Analysis -- 内存与硬盘
  12. Google 展示广告
  13. 在阿里云里怎么样可以连接阿里云数据库
  14. 安利——程序猿必备笔记软件typora+坚果云
  15. 利用AVISPA证明D2D协议
  16. android 设置壁纸,在Android中使用WallpaperManager设置壁纸
  17. 阿里云配置域名CDN加速
  18. 打印表格用什么软件好?
  19. 中国各省份名字的由来
  20. RT5350使用uboot从U盘启动linux成功

热门文章

  1. 阿语python美多商城-商品-商品详情页之第6.6.1节商品详情页分析和准备
  2. 别样肉客与星巴克继续合作 在内地推出别样牛肉™烧烤风味三明治
  3. L1-6 福到了 (模拟)
  4. 熬夜整理了70个Python经典实用练手项目(附源码)
  5. python能做什么-你都用 Python 来做什么?
  6. 【起航计划 001】2015 起航计划 踏在起跑线上
  7. 通过 Moya + RxSwift + Argo 完成网络请求
  8. 熊猫怎么用html5看直播,熊猫TV HTML5播放器自动网页全屏
  9. Axure中继器怎么用
  10. 赵本山小品之跟紧急集合似的铃声 赵本山小品之跟紧急集合似的...