小程序基于Map组件实现路线规划
来源:互联网 发布:软件开发参考文献 编辑:程序博客网 时间:2024/06/06 06:42
小程序基于Map组件实现路线规划
一、场景描述
这是一个连锁加盟的企业,数据库里储存了各经销商的位置,要求系统具备可以让用户点击位置规划出从用户所在位置到该经销商的路线图。在传统web端实现起来比较轻松,我们只需要通过H5的位置接口获取用户当前位置。然后引入第三方地图组件库,调用相关api。路线自然会渲染到页面中。
<script charset="utf-8" src="https://map.qq.com/api/js?v=2.exp"></script> <script> var start; // 起点位置 var drivingService; // 驾车服务实例 var option = JSON.parse(sessionStorage.getItem("end")); var end = new qq.maps.LatLng(option['lat'],option['lnt']); //数据库存储的位置 function callback( res ){ start = new qq.maps.LatLng(res.coords.latitude, res.coords.longitude); var map = new qq.maps.Map(document.getElementById("container"), { center: start }); //设置获取驾车线路方案的服务 drivingService = new qq.maps.DrivingService({ map: map, //展现结果 panel: document.getElementById('infoDiv') }); search(); } //设置搜索地点信息、驾车方案等属性 function search( ) { var type = ["LEAST_TIME","LEAST_DISTANCE","AVOID_HIGHWAYS","REAL_TRAFFIC","PREDICT_TRAFFIC"]; /** *LEAST_TIME => 最少时间 *LEAST_DISTANCE => 最短距离 *AVOID_HIGHWAYS => 避开高速 *REAL_TRAFFIC => 实时路况 *PREDICT_TRAFFIC => 预测路况*/ //设置驾车方案 drivingService.setPolicy(qq.maps.DrivingPolicy[type[0]]); //设置驾车的区域范围 drivingService.setLocation("天津"); //设置回调函数 drivingService.setComplete(function(result) { if (result.type == qq.maps.ServiceResultType.MULTI_DESTINATION) { alert("起终点不唯一"); } }); //设置检索失败回调函数 drivingService.setError(function(data) { alert(data); }); //设置驾驶路线的起点和终点 drivingService.search(start, end); } window.onload=function () {if (navigator.geolocation) { //判断浏览器是否支持地理位置接口 navigator.geolocation.getCurrentPosition(callback,function () { var citylocation,map,marker = null; var init = function() { var center = new qq.maps.LatLng(39.916527,116.397128); var city = document.getElementById("city"); map = new qq.maps.Map(document.getElementById('container'),{ center: center, zoom: 13 }); //获取 城市位置信息查询 接口 citylocation = new qq.maps.CityService({ //设置地图 map : map, complete : function(results){ console.log(results.detail.latLng); var latlng = results.detail.latLng; callback({coords:{"latitude": latlng.getLat(),"longitude":latlng.getLng()}}); } }); } init(); citylocation.searchCityByIP("{$ip}"); }); } } </script>
二、小程序实现思路
同样的功能我们要放到小程序里实现,自然要先看看小程序是否提供了相关的接口了呢。
上图就是小程序提供的位置地图相关api。我尝试调用了openLocation接口。
var address = wx.getStorageSync('latlng');//数据库存储的位置 wx.openLocation({ latitude: address.lat, longitude: address.lng, name:"茶业精品店", address:"河北省胡家庄兴园路567号", scale: 28 })
正如上图所示出现了我想要的去这里按钮,但是在苹果手机(iphone 6 ios9.3.2)上是调不起该组件的。后面经过一番查阅在社区里面找到了答案,苹果上会默认把参数当成字符串解析,我们需要手动转成Number类型。调整后代码如下:
var address = wx.getStorageSync('latlng');//数据库存储的位置 wx.openLocation({ latitude: Number(address.lat), longitude: Number(address.lng), name:"茶业精品店", address:"河北省胡家庄兴园路567号", scale: 28 })
我们可以点击右下角调用手机自带地图或者导航软件,进行路线规划。
三、需求升级
我们想直接一次性点击展现路线,在展现路线的同一页页面展现一些自定义的别的内容,控制地图的展现大小,或者要求不能让用户离开我们的小程序,那我们该怎么做呢?这个时候我们就需要借助小程序提供的map组件。
该组件的具体使用方法就不在这详述了,还没掌握的请参考@SoberLi小李君著的小程序入门教程,我在这里只介绍如何组成polyline参数并传给map组件。百度路线规划接口我这里采取的方式是小程序通过请求后端接口将起点和终点坐标传给后端,然后我在通过后端去和百度对接(方法不唯一)。
wx.request({ url: API+"/index.php?s=/Home/Address/wxaddress",//后端接口地址 data:{ "fromlat" : res.latitude,//起点纬度 "fromlng" : res.longitude,//起点经度 "tolat" : address.lat,//终点纬度 "tolng" : address.lng//终点经度 }, method: 'GET', success: function(ress){}});
以下是服务端php请求接口处理数据,如果不懂php得可以直接跳过看返回的json数据。
public function wxaddress(){$fromlat = $_GET['fromlat'];//接收起点纬度$fromlng = $_GET['fromlng'];//接收起点经度$tolat = $_GET['tolat'];//接收终点纬度$tolng = $_GET['tolng'];//接收终点经度$url = "http://api.map.baidu.com/direction/v2/transit?origin=$fromlat,$fromlng&destination=$tolat,$tolng&ak=l51Pp7gkTg8aqPNIgUh3UlClq8NBBeza";//接口地址$datajson = $this -> curl( "" , $url,"GET");//发送请求并接收结果$obj = json_decode($datajson,true);//将返回的json转换成php能操作的对象;if ( $obj && $obj['status'] ==0 ) {apiResponse( "success" , "返回成功!" , $obj['result']['routes'][0] );//返回给小程序端。}else{apiResponse( "error" , "返回错误!" );}}
后端处理完成的返回数据,我后端只返回了一条路线,如果大家想在这个地图上绘制多条路线,可以不做这个过滤。
{ "distance": 23270, "duration": 10677, "arrive_time": "2017-04-26 20:44:00", "price": 129.5, "price_detail": [], "steps": [ [ { "distance": 1277, "duration": 1021, "instructions": "步行1277米", "path": "116.94460025367,36.63355502879;116.94460025367,36.63355502879;116.94469906728,36.633236457119;116.94454635534,36.630839886738;116.9444744909,36.627690201059;116.94443855868,36.627552625622;116.94437567729,36.627444013259;116.94434872813,36.627393327437;116.94181550659,36.629724840449;116.94146516744,36.6299710209;116.94062974332,36.630673354884;116.94056686193,36.630246162817;116.9405129636,36.62979000594", "traffic_condition": [], "start_location": { "lng": 116.94528296586, "lat": 36.633772235985 }, "end_location": { "lng": 116.94048601443, "lat": 36.62979000594 }, "vehicle_info": { "type": 5, "detail": null } }, { "distance": 3828, "duration": 878, "instructions": "前魏华庄站乘9路(火车站方向)经过8站到经十路段兴西路站", "path": "116.94048601443,36.62979000594;116.94055787888,36.632671713166;116.94045906527,36.635176827602;116.94089923497,36.641895341563;116.94060279415,36.645609093992;116.94040516694,36.64725959265;116.94048601443,36.647599822587;116.940252455,36.651009277163;116.9400727939,36.651972004283;116.94000991251,36.656937456611;116.94080042136,36.656951932676;116.94708855993,36.65657555409;116.94730415326,36.656691363083;116.94893906928,36.656568316022", "traffic_condition": [], "start_location": { "lng": 116.94048601443, "lat": 36.62979000594 }, "end_location": { "lng": 116.94893906928, "lat": 36.65657555409 }, "vehicle_info": { "type": 3, "detail": { "name": "9路", "type": 0, "stop_num": 8, "on_station": "前魏华庄站", "off_station": "经十路段兴西路站", "first_time": "05:30", "last_time": "21:00" } } } ] ]}// 以上steps数据只节选了一部分
以上数据的详细解析我就不写了,大家不明白的可以去百度地图文档查看,steps是该条路线的步骤集合类型是数组,经过简单分析我们需要拿到的是每一步里面的path路径经纬度集合,而微信文档里面给出的格式是这样的[{latitude: 0, longitude: 0}];所以我们需要循环遍历取出里面的每一个path,具体js代码实现如下:
var steps = server.data.steps;//获取步骤集合var polyline = [];steps.map(function(item,index){//item 为路线里面的每一大步 if(item && item.length > 0){ item.map(function(step,index){//step 为每一大步里面的每一小阶段 var path = step.path;//取出该阶段的path,关键点的经纬度集合。 if(path){ var arr = path.split(";");//通过上面的json数据,我们可以看到path存储的关键点使用“;”隔开的,这里我们通过这一项把它转换成数组进行操作。 arr.map(function(point,index){//point为每一个坐标点,格式为"116.94048601443,36.62979000594",逗号前面是longitude,逗号后面是latitude; var pointarr = point.split(",");//我们再把每一个点转成数组,以方便我们操作。 if(pointarr.length == 2){//把我们取到的每一个点以微信官方要求的数据结构push到一个polyline数组里面去。 polyline.push({ longitude : pointarr[0], latitude : pointarr[1] }); } }); } })//最后我们将polyline数组setData到微信组件里去。that.setData({ "polyline":[{ "points" : polyline, "color" : "#ff000088", "width" : 5 }]});// wxml是这个样子的<map polyline="{{polyline}}" longitude="{{centerlng}}" latitude="{{centerlat}}" scale="8"></map>
当你顺利完成以上步骤时,那么恭喜你就可以看到这个效果了。喜欢的话点个赞,关注一下小编吧。
补充:
1.以上方法仅供参考,实现方法各式各样。
2.小编开发过程中用的是百度地图,后来发现腾讯地图路线规划更好使一点。(腾讯地图direction API提供步行(walking),驾车(driving),公交(transit)三种出行方式的路线规划服务。)腾讯支持jsonp跨域请求。(建议尝试)
3.如果发现小编哪里写的不好,欢迎指点。
- 小程序基于Map组件实现路线规划
- 小程序组件实现
- 百度地图实现路线规划
- Chronometer组件实现计时器小程序
- 基于百度地图api实现的起终点路线规划和自定义覆盖物启动APP
- 基于WIN32下写的map小程序
- 百度地图路线规划功能的实现
- 高德地图实现路线规划
- java map小程序
- 规划路线
- 路线规划
- 小程序 组件
- 小程序 基础组件
- 手把手教你实现小程序中的自定义组件
- Android 高德的路线规划一个小坑
- 菜鸟小白的web前端开发的路线规划
- 基于html5技术实现路线简意图
- 基于QT的TCP协议实现的通信小程序
- Redis事务介绍
- (转)IntelliJ IDEA 创建Web项目(全教程)
- 【分布式文件系统】MFS、Ceph、GlusterFS、Lustre的比较
- Linux常用命令
- html contenteditable="true" ctrl+v黏貼時會帶標籤的處理方式
- 小程序基于Map组件实现路线规划
- display:list-item和display:block区别
- 判断n以内的素数(高效算法)
- 实施微服务架构模式所面临的挑战
- mysql的2表关联进行更新
- 关于 多态 ,重载,覆盖的一点 认知
- RabbitMQ(part3广播发消息到不同消费者)----Publish/Subscribe
- 安卓6.0运行时权限处理
- 分布式哈希算法