地图应用很是普遍,目前地图服务,都提供地图操做、标注、地点搜索、出行规划、地址解析、街景等接口,功能很是丰富。在实际开发过程当中,各有优劣。本次基于需求,使用腾讯位置服务做为一个公用厕所位置标注的H5页面开发。javascript
本次使用版本: JavaScript API 2.0版本。php
基于腾讯位置服务,实现微信扫描二维码后,在微信浏览器内,展现某县城的公用厕所分布图,按照用户当前定位与各个厕所之间的距离远近排序,点击标注点跳转到腾讯地图进行导航。html
基于上述需求,对使用到的腾讯位置服务接口予以分解以下:前端
腾讯地图加载; 自动定位; 信息点(POINTS)标注maker; 计算标注点之间的距离; 导航跳转连接API接口; 街道与卫星地图切换控件; 缩放控件;
<script charset="utf-8" src="https://map.qq.com/api/js?v=2.exp&libraries=drawing,geometry,autocomplete,convertor&key={$appkey}"></script> <script type="text/javascript" src="https://3gimg.qq.com/lightmap/components/geolocation/geolocation.min.js"></script>
<!--地图加载--> <div id="location" onclick="getLocation();"></div> <div id="txmap"></div>
因为项目须要屡次调用地图和定位,为此,在script脚本中map和geolocation都设置为全局函数。java
var map;//全局函数 var geolocation = new qq.maps.Geolocation(appkey, "{$referer}"); var options = {timeout: 8000}; function getLocation() { geolocation.getLocation(showPosition, showErr, options); }
getLocation(sucCallback, errCallback, [options: {timeout: number, failTipFlag: boolean}])方法web
获取当前所在地理位置,调用一次即从新定位一次,定位数据比较精确。 sucCallback为定位成功回调函数,必填; errCallback为定位失败回调函数,选填,若是不填,请设为null; options为定位选项,选填,能够经过timeout参数设置定位的超时时间,默认值为10s; failTipFlag: 是否在定位失败时给出提示引导用户打开受权或打开定位开关。(即将支持)
function showPosition(position) { }
获取位置坐标显示地图ajax
map = new qq.maps.Map(document.getElementById("txmap"), { // 地图的中心地理坐标。 center: new qq.maps.LatLng(position.lat, position.lng), zoom: 15 });
定义当前位置maker样式图片数据库
var imgUrl = "static/rooted/images/icon.png"; var anchor = new qq.maps.Point(6, 6), size = new qq.maps.Size(45, 46), origin = new qq.maps.Point(0, 0), icon = new qq.maps.MarkerImage(imgUrl, size, origin, anchor); var marker2 = new qq.maps.Marker({ icon: icon, map: map, position: new qq.maps.LatLng(position.lat, position.lng) });
读取信息点(POINTS)并在地图上标注编程
一、标准JSON数据格式json
为方便展现,此处仅展现数据格式,实际应用作,使用ajax获取便可。
[ { "toilet_id": "9", "toilet_name": "智慧广场", "toilet_address": "西溪路 智慧中心南", "toilet_url": "upload/preview/2020-11/15784affe0de0d45c5f33625851527e9.jpg", "toilet_lon": "115.965248", "toilet_lat": "35.597050" }, { "toilet_id": "14", "toilet_name": "唐塔公厕", "toilet_address": "东门街北段唐塔广场", "toilet_url": "upload/preview/2020-11/8e5bda8c5b12f87ebad80c247d8f2b26.jpg", "toilet_lon": "115.946365", "toilet_lat": "35.602218" } ]
二、地图标注并计算距离
//地图标注; getTxMap(newData, latlngs); //两点间的距离; getDistance(newData, latlngs);
经纬度标注封装函数
function getTxMap(newData, latlngs) { for (var i = 0; i < newData.length; i++) { (function (n) { var marker = new qq.maps.Marker({ position: latlngs[n], map: map }); qq.maps.event.addListener(marker, 'click', function () { var popHtml = '<div class="pop">到这里: <a href="https://apis.map.qq.com/uri/v1/routeplan?type=walk&from=起步位置&fromcoord=' + position.lat + ',' + position.lng + '&to=' + newData[n].toilet_name + '&tocoord=' + newData[n].toilet_lat + ',' + newData[n].toilet_lon + '&policy=0&referer={$referer}">' + newData[n].toilet_name + '</a></div>'; infoWin.open(); infoWin.setContent(popHtml); infoWin.setPosition(latlngs[n]); }); })(i); } }
计算两点间的距离函数封装
function getDistance(newData, latlngs) { var newArr = []; var start = new qq.maps.LatLng(position.lat, position.lng); for (var i = 0; i < latlngs.length; i++) { var end = latlngs[i]; var distance = Math.round(qq.maps.geometry.spherical.computeDistanceBetween(start, end) * 10) / 10; //拼接新的距离数组数据; newArr.push({ toilet_id: newData[i].toilet_id, toilet_name: newData[i].toilet_name, toilet_address: newData[i].toilet_address, toilet_url: newData[i].toilet_url, toilet_lon: newData[i].toilet_lon, toilet_lat: newData[i].toilet_lat, distance: distance }) } //升序排列; function compare(key) { return function (value1, value2) { var val1 = value1[key]; var val2 = value2[key]; return val1 - val2; } } newArr.sort(compare('distance')); console.log(newArr);
//定位失败,自动跳转页面; function showErr() { //alert("定位失败!"); window.location.href = "?m=Index&a=error" }
项目开发过程当中,须要本身拾取坐标经纬度,以知足初始数据的测试和演示使用。通常会使用腾讯提供的坐标拾取器。连接地址:https://lbs.qq.com/tool/getpo...
支持地址 精确/模糊 查询; 支持POI点坐标显示; 坐标鼠标跟随显示;
若是非要挑出点毛病的话,地图拾取框过小了,想为所欲为的拾取坐标,要缩放或拖拽不少次,心累。
在项目完成测试后,若是遇到成千上百的地址时,一个一个的拾取,好像不是一个合格的开发者的所为。此时,就须要使用到地址解析和逆解析的API接口,即:在数据导入到数据库的过程当中,自动批量地将地址转化为经纬度坐标,知足前端的调用。
本例中使用了腾讯位置服务的WebService API,后端语言使用PHP,简要的将该过程予以呈现。
一、封装WebService API接口函数
官方实例,若是在前端直接使用getJSON函数,会出现“同源策略”被阻止,为此须要后端爬取后,“曲线救国”。
//GET请求示例,注意参数值要进行URL编码 https://apis.map.qq.com/ws/geocoder/v1/?address=北京市海淀区彩和坊路海淀西大街74号&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77
/*地址转坐标封装函数,文件名称为points.php *$address,须要转化的地址,越详细经纬度精度越高; */ function getGeoCoding($address) { $url = "https://apis.map.qq.com/ws/geocoder/v1/?address=" . $address . "&key={$key}"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($ch); curl_close($ch); return $output; } //获取前端传入的地址参数; $address = $_GET["address"]; //输出json数据格式,供前端调用; die(getGeoCoding($address));
二、前端调用
//自動獲取經緯度; var getAddress = function transAddress() { var address = $("#address").val(); getPoints(address); } //前端页面输出; function getPoints(address) { $.getJSON("points.php", {address: address}, function (res) { if (res.status == 0) { $("#lng").val(res.result.location.lng); $("#lat").val(res.result.location.lat); } else { $("#message").html(res.message); } }); }
三、效果演示
在导入地址数据的时候,必定要是省市区街道门牌号,地址越详细精度越高,不然会解析不出来,谨记!
<script charset="utf-8" src="https://map.qq.com/api/js?v=2.exp&key=YOUR_KEY"></script>
在开发过程当中,默认会这样引入到前端文件。测试环境和生成环境一致,或者更换环境也是一直,不会出现问题的。可是若是是http和https不一致的协议环境下,引入文件就会出现错误提示。
建议的加载方式:src不使用协议名称,让其自动匹配。如:
<script charset="utf-8" src="//map.qq.com/api/js?v=2.exp&key=YOUR_KEY"></script>
学习一个新项目的最快捷方式是学会使用官方文档,由于这些文档是基础中的基础。但官方文档的有时太官方,有些细节没法清楚的展现出来。
官方文档不能解决的问题时,会“面对CSDN编程”,每一个开发者遇到的问题不一样,开发经验不一样,在CSDN上的记录更多的是为了不本身下次“入坑”提醒,没法完整的将项目的细节描述清楚,也是初学者看到人家明明解决了,为何本身不能够的。
这里就牵涉到腾讯地图附加库的引入。
<script charset="utf-8" src="://map.qq.com/api/js?v=2.exp&libraries=drawing,geometry,autocomplete,convertor&key={$appkey}"></script>
本项目中就碰见须要计算自动定位的经纬度和各个厕所之间的距离,须要使用geometry
几何运算库。在未理解官方文档的前提下,强行CSDN,走路不少弯路才发现:开发语法明明对了,可是却没有计算出距离,就是没引入对应的附加库。
<script type="text/javascript" src="//3gimg.qq.com/lightmap/components/geolocation/geolocation.min.js"></script>
使用自动定位功能,必须引入自动定位的geolocation.min.js
附加库,无须多言。
若是是首次开发地图就使用腾讯地图的话,出现这个错误的可能性比较低。若是有百度和高德地图开发的经验话,千万不要想固然。在这个问题上浪费了半个小时才发现,腾讯的经纬度和百度、高德的问题是互换的。
腾讯经纬度
new qq.maps.LatLng(39.914850, 116.403765); //构建对象的是(纬度,经度)
百度经纬度
map.centerAndZoom(new BMap.Point(116.4035,39.915),8); //构建对象的是(经度,纬度)
高德经纬度
position: new AMap.LngLat(116.39, 39.9),//构建点对象的是(经度,纬度)
在使用坐标拾取器时,必定要选择各个对应的工具,导航等牵涉到坐标的地方必定要注意。
对于不一样的厂家地图的使用,通常都有“先入为主” 的刻板印象,也有甲方缘由的客观要求。
对比项 | 腾讯地图 | 百度地图 | 高德地图 |
---|---|---|---|
功能 | 标注、信息框、覆盖物、计算距离、轨迹、导航等经常使用功能 | 同前 | 同前 |
坐标 | 火星坐标 | BD-09坐标 | 火星坐标 |
坐标结构 | (39.914850, 116.403765) | (116.4035,39.915) | (116.39, 39.9) |
语法结构 | 同高德 | 百度自有语法 | 同腾讯 |
开发文档 | 相对集中 | 百度地图开发平台已升级到3.0版本,文档多,类库多 | 相对集中 |
延伸 | 数据可视化API服务 | 同前 | 同前 |
本次使用版本: JavaScript API 2.0版本,目前咱们提供的JavaScript API GL版本,功能更炫酷齐全,你们能够尝试接入使用。
做者:漏刻有时
连接:https://lockdatav.blog.csdn.n...
来源:CSDN
著做权归做者全部。商业转载请联系做者得到受权,非商业转载请注明出处。