经常的我们在使用地图功能时,会发现在选择一个小区或者一个热门景点的时候,地图上面会给出其边界轮廓,能够方便我们知道其范围大小,有时候在我们使用地图组件的时候,也会面临着类似的需求。比如在地图上面标识出一个商场范围内的热力图,一个热门景点的游览情况等。那么,我们该如何利用地图功能来实现这类效果呢,今天我们一起来探讨一下。

最近我们就有一个需求,需要标识出一些热门场所的人流的热力图情况,同时需要给出该热门场所的边界轮廓。经过查看百度地图和高德地图的开发者API文档,发现并没有这类公共接口提供我们使用。目前地图能够提供我们使用的,基本只能是一些行政区划的边界范围,这个在我之前的文章中也有写过,大家可以参照《仿链家地图找房的简单实现》。

那么现在面临的需求该如何实现呢?

通过查看地图功能的接口调用情况和在网上查询相关资料,最终我们找到了下面这个“不算是方法的方法”。

  • 使用了地图的相关API接口获取相关数据
  • API接口不是官方给出的,所以也就面临着稳定性的问题,可能随时被关(高德的只能简单参考,本身就存在较大缺陷,后面会说)

实现思路

  • 通过地图的POI查询服务获取到兴趣点id

    那么什么是POI呢?

    检索服务提供某一特定地区的兴趣点位置查询服务(POI:Point of Interest,感兴趣点)

    相关的官方文档请参照以下地址:

    • 百度地图POI查询
    • 高德地图POI查询
  • 通过兴趣点id获取该兴趣点的详细信息

    这里面需要用到的相关API就需要我们查看地图的执行过程,找到对应的API了。(也希望各个地图官方能够给出官方的方法吧)

PS:地图功能的使用情况在本篇不做说明,具体申请相关Key的过程请分别参照官网说明即可。

下面我们来分别给出百度地图和高德地图的实现方法:

百度地图实现

闲话休谈,咱们直接上码

</html>
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title>百度地图DEMO</title><script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=你申请的AK"></script><script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script><script type="text/javascript">$(document).ready(function() {var queryHouseOutline = function(hid, callback) {var baseURL = 'http://map.baidu.com/?reqflag=pcmap&coord_type=3&from=webmap&qt=ext&ext_ver=new&l=18';var url = baseURL + "&uid=" + hid;callback && (window.queryHouseOutlineCallback = callback);$.ajax({type: "get",async: false,url: url,dataType: "jsonp",jsonpCallback: "queryHouseOutlineCallback",success: function(datas) {}});};/*** 模糊查询小区信息, 无返回值* @param {} house  小区名称* @param {} city   所属城市名称* @param {} ak     百度地图AK* @param {} callback   回调函数,该函数可以接收到请求的返回值*/var queryHouse = function(house, city, ak, callback) {var baseURL = 'http://api.map.baidu.com/place/v2/search?output=json&scope=2';var url = baseURL + "&q=" + house + "&region=" + city + "&ak=" + ak;callback && (window.queryHouseCallback = callback);$.ajax({type: "get",async: false,url: url,dataType: "jsonp",jsonpCallback: "queryHouseCallback",success: function(datas) {}});};/*** 墨卡托坐标转百度坐标* @param {} coordinate* @return {}*/var coordinateToPoints = function(map, coordinate) {var points = [];if (coordinate) {var arr = coordinate.split(";");if (arr) {for (var i = 0; i < arr.length; i++) {var coord = arr[i].split(",");if (coord && coord.length == 2) {var mctXY = new BMap.Pixel(coord[0], coord[1]);var project = map.getMapType().getProjection();var point = project.pointToLngLat(mctXY);points.push(new BMap.Point(point.lng, point.lat));}}}}return points;};/*** 墨卡托坐标解析* @param {} mocator* @return {}*/var parseGeo = function(mocator) {if (typeof mocator != 'string') {return {};}var t = mocator.split("|");var n = parseInt(t[0]);var i = t[1];var r = t[2];var o = r.split(";");if (n === 4) {for (var a = [], s = 0; s < o.length - 1; s++) {"1" === o[s].split("-")[0] && a.push(o[s].split("-")[1]);}o = a;o.push("");}var u = [];switch (n) {case 1:u.push(o[0]);break;case 2:case 3:case 4:for (var s = 0; s < o.length - 1; s++) {var l = o[s];if (l.length > 100) {l = l.replace(/(-?[1-9]\d*\.\d*|-?0\.\d*[1-9]\d*|-?0?\.0+|0|-?[1-9]\d*),(-?[1-9]\d*\.\d*|-?0\.\d*[1-9]\d*|-?0?\.0+|0|-?[1-9]\d*)(,)/g,"$1,$2;");u.push(l);} else {for (var c = [], d = l.split(","), f = 0; f < d.length; f += 2) {var p = d[f];var h = d[f + 1];c.push(p + "," + h);}u.push(c.join(";"))}}break;default:break;}if (u.length <= 1) {u = u.toString();}var result = {type: n,bound: i,points: u};return result;};var map = new BMap.Map("allmap"); // 创建Map实例map.centerAndZoom("北京", 19);map.addControl(new BMap.MapTypeControl()); //添加地图类型控件map.enableScrollWheelZoom(false); //开启鼠标滚轮缩放/*** 第一个参数是城市名,第二参数是小区名 */var showArea = function(city, area) {queryHouse(area, city, "你申请的AK", function(data) {if (data.message == 'ok') {var houses = data.results;if (houses && houses.length > 0) {var house = houses[0];queryHouseOutline(house.uid, function(houseOutline) {var geo = houseOutline.content.geo;if (!geo) {var location = house.location;var point = new BMap.Point(location.lng, location.lat);map.centerAndZoom(point, 19);var marker = new BMap.Marker(point);marker.setAnimation(BMAP_ANIMATION_BOUNCE);map.addOverlay(marker);} else {map.clearOverlays();var geoObj = parseGeo(geo);//边界点var points = coordinateToPoints(map, geoObj.points);var ply = new BMap.Polygon(points, {strokeWeight: 2,strokeColor: "#F01B2D",strokeOpacity: 0.9,fillColor: "transparent"}); //建立多边形覆盖物map.addOverlay(ply); //添加覆盖物map.setViewport(ply.getPath()); //调整视野 }});}}});};showArea($('#cityId').val(), $('#areaId').val());$('#showBtn').click(function() {debugger;showArea($('#cityId').val(), $('#areaId').val());});$("#areaId").keydown(function(e) {if (event.keyCode == "13") {showArea($('#cityId').val(), $('#areaId').val());}})});</script>
</head><body><table><tr><td>城市:</td><td><input id="cityId" type="text" value="北京" /></td><td>小区:</td><td><input id="areaId" type="text" value="故宫博物院" /></td><td><button id="showBtn">显示</button></td></tr></table><div id="allmap" style="width: 90vw; height: 90vh;"></div>
</body></html>
复制代码

相关的代码注释都有所添加,参照即可。其中需要注意的是百度地图获取到的坐标点需要进行转换成百度地图识别的点位形式。 另外,边界的描画使用到的是地图的Polygon功能,相关内容请参照

高德地图实现

</html>
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title>高德地图DEMO</title><script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.10&key=你申请的AK"></script><script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script><script type="text/javascript">$(document).ready(function() {var map = new AMap.Map('allmap', {zoom: 19,center: [116.397428, 39.90923]}); // 创建Map实例/*** 第一个参数是城市名,第二参数是小区名 */var showArea = function(city, area) {queryHouse(area, city, "你申请的AK", function(data) {console.error(data)if (data.status == 1) {var houses = data.pois;if (houses && houses.length > 0) {var house = houses[0];queryHouseOutline(house.id, function(houseOutline) {console.error("get outline success");var pathPoints = houseOutline.data.spec.mining_shape.shape;var tmpPath = pathPoints.split(";");var points = [];tmpPath.forEach(function(value, index, array) {points.push(value.split(","))});map.clearMap();var ply = new AMap.Polygon({map: map,path: points,strokeColor: "#F01B2D",fillColor: "transparent"}); //建立多边形覆盖物map.setFitView(); //调整最佳显示});}}});};var queryHouseOutline = function(hid, callback) {var baseURL = 'https://www.amap.com/detail/get/detail';$.ajax({type: "get",data: {id: hid},url: baseURL,dataType: "json",success: function(datas) {callback(datas)}});};/*** 模糊查询小区信息, 无返回值* @param {} house  小区名称* @param {} city   所属城市名称* @param {} ak     高德地图AK* @param {} callback   回调函数,该函数可以接收到请求的返回值*/var queryHouse = function(house, city, ak, callback) {var baseURL = 'http://restapi.amap.com/v3/place/text?&keywords=' + house + '&city=' + city + '&output=json&offset=20&page=1&key=' + ak;callback && (window.queryHouseCallback = callback);$.ajax({type: "get",async: false,url: baseURL,dataType: "jsonp",jsonpCallback: "queryHouseCallback",success: function(datas) {}});};showArea($('#cityId').val(), $('#areaId').val());$('#showBtn').click(function() {showArea($('#cityId').val(), $('#areaId').val());});$("#areaId").keydown(function(e) {if (event.keyCode == "13") {showArea($('#cityId').val(), $('#areaId').val());}})});</script>
</head><body><table><tr><td>城市:</td><td><input id="cityId" type="text" value="北京" /></td><td>小区:</td><td><input id="areaId" type="text" value="故宫博物院" /></td><td><button id="showBtn">显示</button></td></tr></table><div id="allmap" style="width: 90vw; height: 90vh;"></div>
</body></html>
复制代码

高德地图的实现方式根据实际的效果来看,本身应该是做了API接口限制的处理,经常会出现获取不到详细信息或者给出的详细信息中的边界信息数据不准确。 这里只是作为一个对比参照,高德地图不推荐来做这个需求,API接口稳定性太差。

后记

①百度地图会涉及到功能接口配额的问题

主要会涉及到上面的地点检索配额,如果只是个人简单使用的,可以注册个人开发者,基本配额就够使用了

②高德地图没有找到配额相关的数据,毕竟走的非正规手段吧

③百度地图和高德地图对于一些位置的边界数据不同

有些地点只会在其中一个能够获取到(高德地图能够返回数据的情况下)

④高德地图在检索位置时,能够支持全拼音输入,也能检索出来(感觉这个厉害,但是中文多音字处理不知道会怎么样)


参考资料:

百度地图小区边界(轮廓)处理

高德地图之python爬取POI数据及其边界经纬度(根据关键字在城市范围内搜索)

地图小区景点边界轮廓实现相关推荐

  1. 百度amp;高德地图小区景点边界轮廓实现

    经常的我们在使用地图功能时,会发现在选择一个小区或者一个热门景点的时候,地图上面会给出其边界轮廓,能够方便我们知道其范围大小,有时候在我们使用地图组件的时候,也会面临着类似的需求.比如在地图上面标识出 ...

  2. python 乡镇轮廓 高德_百度高德地图小区景点边界轮廓实现

    经常的我们在使用地图功能时,会发现在选择一个小区或者一个热门景点的时候,地图上面会给出其边界轮廓,能够方便我们知道其范围大小,有时候在我们使用地图组件的时候,也会面临着类似的需求.比如在地图上面标识出 ...

  3. 高德地图小区边界获取(2017.05)

    单个小区边界的获取: chrome打开高德地图,缩放到相应区域 打开控制台,搜索小区名,使得地图上就会出现小区正确的轮廓 控制台network中有个poiInfo的请求,打开这个请求,就会看到相应数据 ...

  4. 百度地图POI的边界GEOJSON数据采集

    经过数天的技术攻关,终于成功从百度地图APP采集到POI的边界数据,并成功进行了坐标数据还原和边界数据验证.下面详细介绍一下. 如下所示,是从百度地图APP采集到的某小区(uid为ba9b506a87 ...

  5. python百度地图poi_百度地图POI的边界GEOJSON数据采集

    经过鲲之鹏技术人员数天的技术攻关,终于成功从百度地图APP采集到POI的边界数据,并成功进行了坐标数据还原和边界数据验证.下面详细介绍一下. 如下所示,是从百度地图APP采集到的某小区(uid为ba9 ...

  6. HALCON示例程序circles.hdev边界轮廓的圆形拟合

    HALCON示例程序circles.hdev边界轮廓的圆形拟合 小哥哥小姐姐觉得有用点个赞呗! 示例程序源码(加注释) 读入图片 read_image (Image, 'double_circle') ...

  7. 滁州市区地图小区楼盘图矢量高清cdr|pdf2021年(高品质)

    滁州市区地图小区楼盘图矢量高清cdr|pdf2021年(高品质).pdf导入cdr,ai软件里面另保存cdr,ai格式可以编辑内容,修改文字>下载图看:https://download.csdn ...

  8. 2021年中国地图省市县区边界shp格式arcgis数据(预览图)

    2021年中国地图省市县区边界shp格式arcgis数据(预览图) 下载地址 https://download.csdn.net/download/zhongguonanren99/16063641 ...

  9. 地图上分成一块一块区域 高德地图_在谷歌地图上绘制行政区域轮廓【结合高德地图的API】...

    实现思路: 1.利用高德地图行政区域API获得坐标列表 2.将坐标列表绘制在谷歌地图上[因为高德地图和国内的谷歌地图都是采用GCJ02坐标系,所有误差很小,可以不进行坐标误差转换] 注意点: 1.用百 ...

最新文章

  1. linux程序计数器,如何在C中打印程序计数器的确切值
  2. 《区块链原理、设计与应用》一1.4 潜在的商业价值
  3. 冒泡排序用c语言实现
  4. BRCM5.02编译八: ERROR: you are missing a basic functioning perl installation
  5. 异常检测-LocalOutlierFactor的理解与应用
  6. python magic文档
  7. python-判断元素是否在字典中
  8. PHP算法使用__call优化代码
  9. mysql事务吞吐量_MySQL 5.5和MySQL 5.6的吞吐量测试
  10. 出现画面抖动_连续抖动20小时!虎门大桥桥面如波浪翻滚,专家:个人感觉没问题...
  11. php价格结算,PHP根据用户折扣计算商品价格
  12. Build your own distribution based on Fedora CoreOS
  13. PHP23 AJAX分页
  14. 传输层协议TCP和UDP
  15. SOCKET 478/775是两种主板的CPU接口类型
  16. struts2与struts1区别二
  17. 共享经济开始崩溃,区块链能否再续共享经济神话?
  18. 设计模式之禅【门面模式】
  19. 数字图像处理---低高通滤波实验(MATLAB实现)
  20. 少儿编程和机器人编程哪个更好一点

热门文章

  1. Http协议和抓包工具
  2. 三步掩模行业调研报告 - 市场现状分析与发展前景预测
  3. 东北大学清退52名博士生研究生!其中一学生已读博18年之久
  4. SSL/TLS类安全漏洞及SLB安全漏洞问题
  5. 华为手机备忘录,到底有多好用?花粉看完,纷纷点赞
  6. wsl(Windows Subsystem for Linux)启动多个子系统和设置默认启动子系统
  7. 195号段是哪个运营商,195号段是正规移动卡吗?
  8. 微信中网页分享开发遇到的坑
  9. 通俗理解计算机操作系统的作用
  10. Activiti 学习笔记十:开始活动节点(判断流程是否结束及查询历史)