首页 > 其他分享 >百度&高德地图小区景点边界轮廓实现(转载)

百度&高德地图小区景点边界轮廓实现(转载)

时间:2024-03-05 15:37:27浏览次数:23  
标签:function map 地图 callback 景点 var 高德 百度

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

转载地址:https://www.cnblogs.com/ld1024/p/9816628.html

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

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

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

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

实现思路

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

    那么什么是POI呢?

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

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

  • 通过兴趣点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数据及其边界经纬度(根据关键字在城市范围内搜索)

标签:function,map,地图,callback,景点,var,高德,百度
From: https://www.cnblogs.com/wjsqqj/p/18054141

相关文章

  • 百度地图API自定义地图
    <!DOCTYPEHTMLPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><htmlxmlns="http://www.w3.org/1999/xhtml"><head><metahttp-equiv="Content......
  • vue项目引入高德地图报错:Map container div not exist (火狐浏览器不加载地图)
    问题描述:谷歌浏览器正常显示地图,火狐浏览器不加载,并且报错:  Mapcontainerdivnotexist错误代码如下:  修改后代码如下:  参考大佬:https://blog.csdn.net/white_777/article/details/128286558  ......
  • 一键采集高德地图上的电话号码
    要将高德(或腾讯、百度)地图上的号码导出到通讯录,可以按照以下步骤操作:工具:微拓客APP工具二:手机操作:手机上应用商城搜索微拓客,下载安装。微拓客下载地址https://a.app.qq.com/o/simple.jsp?pkgname=com.lieluyun.tuoke关键词客源:关键词客源按地区和行业采集地图上商家、企业信......
  • 氢桌面【高德悬浮版】—更轻、更简洁的车载桌面【附带安装包下载地址】
    简介今天给大家推荐一款超好用的桌面【氢桌面】,支持4种首页布局方式,可根据自己喜好选择。支持开启小白点,非首页界面可以快速返回首页。如果用过CarPlay的车友会发现这个界面和CarPlay高度相似,中间显示地图小窗,右侧显示快捷导航天气音乐等界面。界面预览常见问题及方控设置......
  • 【JAVA】百度AI接入api使用流程-【黑图像上色】【步骤2】
    前言:根据API文档中java代码,使用idea编辑代码22.1进入网页,找到java代码https://cloud.baidu.com/doc/IMAGEPROCESS/s/Bk3bclns3 2.2新建java项目     2.3创建java类命名为 Colourize(就是刚才在网页里看到的Java代码的类名)  复制java代码  ......
  • 【JAVA】百度AI接入api使用流程-【黑图像上色】【步骤1】
    前言以【黑白图像上色】为例讲解百度AI接口使用,方便新手小白接入,以超级简单的方式操作百度AI库使用步骤1.创建应用获取AK(APIKey),SK(SecretKey)1.1进入: 百度AI官网,在开放能力下面找到:黑白图像上色 1.2选择:立即使用 1.3在创建新应用下,填写相应的信息。注意:接口选择......
  • 【转】打造大模型Agent:百度智能云千帆杯竞赛第一期解题思路
    随着大型语言模型的进步,使用大模型构建人工智能代理(AIAgents)逐渐成为学术界和业界关注的领域。在这些新兴的研究中,大型语言模型扮演着人工智能代理的核心智能,即它们的“大脑”。这些基于大型语言模型的智能代理(LLM-basedAgents)通过集成了先进的语言理解和生成能力的模型,展现出在......
  • 旅游景点 Tourist Attractions (壮压 DP)题解
    简化题意题目链接——不卡内存班题目链接——卡内存版给定\(n\)个点和\(m\)条边组成的无向图,按照一定限制要求停留\(2\simk+1\)共\(k\)个点(可以经过但不停留),求最短的从\(1\)出发到\(n\)的路径长。限制情况如下:共有\(q\)个限制,接下来\(q\)行,每行两个数\(x......
  • unigui 调用百度地图
    百度源代码如下:<styletype="text/css"> body,html,#allmap{width:100%;height:100%;overflow:hidden;margin:0;font-family:"微软雅黑";} #l-map{height:100%;width:78%;float:left;border-right:2pxsolid#bcbcbc;} #r-result{height:100%;width:......
  • 调用百度翻译api
    importrandomimporthashlibimporturllibimportrequestsimportjson#安装相应的库deftrans(word):src='en'#翻译的源语言obj='zh'......