前言

本文旨在以mpvue框架为基础,探讨地图类小程序的开发思路。 原作者利用mpvue + 腾讯地图的能力做了一个地铁路线规划的小程序,主要提供全球主要城市的地铁线网图及旅游介绍,其中国内城市支持查看地图和路线规划。

目前腾讯位置服务也推出了路线规划插件、地铁图插件,实现更加简单便捷,感兴趣的可点击查看。

运行截图

mpvue 介绍 及项目搭建

mpvue = miniprogram + vue framework,说白了就是用vue框架开发小程序。mpvue最近升级为2.x版本,支持微信、支付宝、百度和头条小程序。和传统方式相比,mpvue开发具有以下优点:

彻底的组件化开发能力:提高代码复用性

  • 完整的 Vue.js 开发体验

  • 方便的 Vuex 数据管理方案:方便构建复杂应用

  • 快捷的 webpack 构建机制:自定义构建策略、开发阶段 hotReload

  • 支持使用 npm 外部依赖

  • 使用 Vue.js 命令行工具 vue-cli 快速初始化项目

  • H5 代码转换编译成小程序目标代码的能力

就个人使用体验来看,还是挺丝滑顺畅的,传统web应用开发无缝切换至小程序开发,基本零门槛。要注意的就是小程序的限制及和vue的差异:

  • 小程序使用相对像素 rpx 进行样式布局

  • 部分css选择符不支持,目前只支持 #id | .class | tag | tag,tag | ::after ::before,所以要特别注意

  • 组合式生命周期,mpvue将小程序和vue的生命周期混在一块,详情见 mpvue.com/mpvue/#_3 ,目前这个地方还有很多坑,比如在小程序page unload时,vue实例却没被销毁,导致下次进入页面时,页面状态不变,必须在unLoad时手动重置状态等

  • mpvue 会封装小程序数据对象,通常以$mp开头,如event.$mp.detail.target

  • 小程序的组件和vue组件有差异,不要幻想vue组件的特性都能用,如slot,异步组件等等

  • vue store 和 wx localstorage 最好不要弄混,要根据不同需要选择不同的存储方式

  • 不要用vue路由,要采用小程序原生的导航机制

然后,我们搭建开发环境,mpvue脚手架是开箱即用的:

# 全局安装 vue-cli
# 一般是要 sudo 权限的
$ npm install --global vue-cli@2.9# 创建一个基于 mpvue-quickstart 模板的新项目
# 新手一路回车选择默认就可以了
$ vue init mpvue/mpvue-quickstart my-project# 安装依赖,走你
$ cd my-project
$ npm install
$ npm run dev

接着,完善文件结构,增加 config、store、mixins等模块,如图:

app.json是小程序专用文件,也需完善下:

{"pages": ["pages/citylist/main","pages/citydetail/main"],"permission": {"scope.userLocation": {"desc": "你的位置信息将用于小程序位置接口的效果展示"}},"window": {"backgroundTextStyle": "light","navigationBarBackgroundColor": "#eee","navigationBarTitleText": "全球地铁,全程为你","navigationBarTextStyle": "black"}
}

然后就可以愉快的写Vue代码了,咔咔一个页面,咔咔又是一个页面,组件,store,数据驱动,你喜欢的样子,它都有。

腾讯地图+ 小程序

着重说一下地图的接入,腾讯地图提供了两个对接入口给小程序,1是个性化地图展示,2是专用SDK,二者共同完善了小程序的地图生态。

1、个性地图展示需要开发者自行注册并申请开发者密钥(key),并在管理后台绑定小程序,然后设置个性地图的样式,才能使用:

<mapid="citymap"name="citymap":longitude="lng":latitude="lat":polyline="polyline":markers="markers"scale="12":subkey="YOUR_OWN_QQMAP_KEY"show-locationshow-compassenable-rotatestyle="width: 100%; height: 100%;"
><cover-view class="map-cover-view"><button class="explore-btn" type="primary" @tap="exploreCity">查看旅游攻略</button></cover-view>
</map>

其中,map是小程序的原生组件,原生组件脱离在 WebView 渲染流程外,它的层级是最高的,所以页面中的其他组件无论设置 z-index 为多少,都无法盖在原生组件上。说白了就是原生组件是微信客户端提供的,它不属于内置浏览器,为此,小程序专门提供了 cover-view 和 cover-image 组件,可以覆盖在部分原生组件上面。这两个组件也是原生组件,但是使用限制与其他原生组件有所不同。

笔者就因为这个坑耽误了不少时间,有时候开发工具可以用,但到了真机上组件就完全乱了,所以还是要以真机调试为准。对于原生组件,不要用太复杂的css,它的很多css属性支持的都不好。

map可以定义多个参数,经纬度不用说,scale指放缩比例,也就是地图比例尺,polyline在地图上绘制折线,markers用于标记地图上的点,show-location用于显示用户所在位置,show-compass显示指北针。

2、专用SDK,目前提供这些能力:

  • search(options:Object) 地点搜索,搜索周边poi,比如:“酒店” “餐饮” “娱乐” “学校” 等等

  • getSuggestion(options:Object) 用于获取输入关键字的补完与提示,帮助用户快速输入

  • reverseGeocoder(options:Object) 提供由坐标到坐标所在位置的文字描述的转换。输入坐标返回地理位置信息和附近poi列表

  • geocoder(options:Object) 提供由地址描述到所述位置坐标的转换,与逆地址解析的过程正好相反

  • direction(options:Object) 提供驾车,步行,骑行,公交的路线规划能力

  • getCityList() 获取全国城市列表数据

  • getDistrictByCityId(options:Object) 通过城市ID返回城市下的区县

  • calculateDistance(options:Object) 计算一个点到多点的步行、驾车距离

我们以公共交通路线规划为例来看下(以下代码经过简化处理):

第一步,初始化地图SDK对象

import config from '@/config'
import QQMapWX from '../../assets/lib/qqmap-wx-jssdk.js' // 这里用未压缩版的代码
const QQMapSDK = new QQMapWX({key: config.qqMapKey || ''
})

第二步,获取起止坐标点,并进行路线查询

// 坐标从上一页query传进来,坐标为浮点数,可通过geocoder接口获取
this.fromLocation = {latitude: +query.from.split(',')[0] || -1,longitude: +query.from.split(',')[1] || -1
}this.toLocation = {latitude: +query.to.split(',')[0] || -1,longitude: +query.to.split(',')[1] || -1
}// 查询地图路线
queryMapRoutine() {QQMapSDK.direction({mode: 'transit', // 'transit'(公交路线规划)// from参数不填默认当前地址from: this.fromLocation,to: this.toLocation,success: (res) => {console.log('路线规划结果', res);let routes = res.result.routes;this.routes = routes.map(r => {// 对每一种路线方案,分别进行解析return this.parseRoute(r)})console.log('parsed routes', this.routes)}})
}

第三步,路线解析,生成路线描述等

// 解析路线,包括距离,时间,描述,路线,起止点等
parseRoute(route) {let result = {}// 出发时间result.setOutTime = formatTime(new Date())result.distance = route.distance < 1000 ?`${route.distance}米` :`${(route.distance / 1000).toFixed(2)}公里`result.duration = route.duration < 60 ?`${route.duration}分钟` :`${parseInt(route.duration / 60)}小时${route.duration % 60}分钟`result.desc = []// 每一个路线分很多步,如先步行,后乘公交,再搭地铁等route.steps.forEach(step => {// if (step.mode == 'WALKING' && step.distance > 0) {//   result.desc.push(`向${step.direction}步行${step.distance}米`)// }if (step.mode == 'TRANSIT' && step.lines[0]) {let line = step.lines[0]if (line.vehicle == 'BUS') line.title = `公交车-${line.title}`if (line.vehicle == 'RAIL') line.title = `铁路`result.desc.push(`${line.title}: ${line.geton.title} —> ${line.getoff.title},途经 ${line.station_count} 站。`)}})result.polyline = []result.points = []//获取各个步骤的polyline,也就是路线图for(let i = 0; i < route.steps.length; i++) {let step = route.steps[i]let polyline = this.getStepPolyline(step)if (polyline) {result.points = result.points.concat(polyline.points)result.polyline.push(polyline)}}// 标记路线整体显示坐标this.getStepPolyline.colorIndex = 0let midPointIndex = Math.floor(result.points.length / 2)result.latitude = result.points[midPointIndex].latituderesult.longitude = result.points[midPointIndex].longitude// 标记路线起止点let startPoint = result.points[0]let endPoint = result.points[result.points.length - 1]result.markers = [{iconPath: this.startIcon,id: 0,latitude: startPoint.latitude,longitude: startPoint.longitude,width: 28,height: 28,zIndex: -1,anchor: {x: 0.5, y: 1}},{iconPath: this.endIcon,id: 1,latitude: endPoint.latitude,longitude: endPoint.longitude,width: 28,height: 28,zIndex: -1,anchor: {x: 0.5, y: 1}}]return result
},

第四步,getStepPolyline函数 获取路线每一步的路线polyline

getStepPolyline(step) {let coors = [];// 随机颜色let colorArr = ['#1aad19', '#10aeff', '#d84e43']let _dottedLine = trueif (step.mode == 'WALKING' && step.polyline) {coors.push(step.polyline);_dottedLine = false} else if (step.mode == 'TRANSIT' && step.lines[0].polyline) {coors.push(step.lines[0].polyline);} else {return null}//坐标解压(返回的点串坐标,通过前向差分进行压缩)let kr = 1000000;for (let i = 0 ; i < coors.length; i++){for (let j = 2; j < coors[i].length; j++) {coors[i][j] = Number(coors[i][j - 2]) + Number(coors[i][j]) / kr;}}//定义新数组,将coors中的数组合并为一个数组let coorsArr = [];let _points = [];for (let i = 0 ; i < coors.length; i ++){coorsArr = coorsArr.concat(coors[i]);}//将解压后的坐标放入点串数组_points中for (let i = 0; i < coorsArr.length; i += 2) {_points.push({ latitude: coorsArr[i], longitude: coorsArr[i + 1] })}if (!this.getStepPolyline.colorIndex) {this.getStepPolyline.colorIndex = 0}let colorIndex = this.getStepPolyline.colorIndex % colorArr.lengththis.getStepPolyline.colorIndex++// 最终polyline结果let polyline = {width: 7,points: _points,color: colorArr[colorIndex],dottedLine: _dottedLine,arrowLine: true, // 带箭头的线, 开发者工具暂不支持该属性borderColor: '#fff',borderWidth: 1}return polyline
}

最后,绑定到地图上并输出,我们可以得到一个大致这样的结果:

广州火车站 -> 广州塔
9.88km 30分钟
地铁5号线 广州火车站 -> 珠江新城,途径7站
地铁3号线 珠江新城 -> 广州塔,途径1站

这样我们就通过direction接口进行了简单的路线规划功能,接着把生成的数据绑定到地图组件上,一个简易的小程序就做好了,是不是很简单?当然如果想做得更好,就要调用其他相似接口,慢慢完善细节。

<mapid="citymap"name="citymap":latitude="currentRoute.latitude":longitude="currentRoute.longitude":polyline="currentRoute.polyline":markers="currentRoute.markers"scale="12":subkey="qqMapKey"show-locationshow-compassenable-rotatestyle="width: 100%; height: 100%;"
></map>

效果

作者:棱镜_jh

链接:https://juejin.cn/post/6844903809420886029

来源:掘金

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

微信小程序 + 腾讯位置服务SDK 实现路线规划相关推荐

  1. 微信小程序使用腾讯位置服务地图选点实现地址的选取|微信小程序腾讯位置服务地图选点请求来源未被授权

    效果图 首先要在微信开放平台的小程序里 添加插件 具体配置,可以参考官方文档 腾讯位置服务地图选点 | 小程序插件 | 微信公众平台 (qq.com) 同时还要申请接口的权限,不然小程序上线的时候不能 ...

  2. 【微信小程序腾讯位置服务】获取用户所在城市信息实战

    背景 实现小程序进去后获取用户当前所在城市,然后显示该城市的数据,并且显示在导航栏和 Tab上. 微信小程序中,我们可以通过调用wx.getLocation()获取到设备当前的地理位置信息,这个信息是 ...

  3. 微信小程序 ‘腾讯位置服务地图选点插件申请失败’

    1.登录微信公众平台 2.登录后设置-第三方设置-插件管理-添加插件 3.微信小程序插件 | 腾讯位置服务 将官网上的 配置值复制到app.json中,切记是官网上的值不是自己生成的值!!!!然后再进 ...

  4. 微信小程序腾讯位置服务城市选择器

    腾讯城市选择器插件微信小程序插件 | 腾讯位置服务 先看文档,下面为操作步骤 1.登录 微信公众平台 设置 - 第三方设置 - 插件管理 - 添加插件 - 搜索腾讯位置服务城市选择器 - 添加 2.注 ...

  5. 微信小程序 腾讯位置服务地图选点和路线规划

    微信小程序使用 腾讯位置服务插件 实现 地图选点和路线规划 效果图: 实现过程 点击"开发指南",根据对应打开网页中的接入指引进行开发实现. 腾讯位置服务地图选点:开发指南 腾讯位 ...

  6. 小程序腾讯位置服务路线规划插件申请方法

    如果用以下常规的方法个人小程序大概率是通过不了的 在腾讯微信公众平台中, "微信小程序官方后台-设置-第三方服务-插件管理" 里点击 "添加插件",搜索 &qu ...

  7. 微信小程序控制硬件 第14篇 微信小程序腾讯地图控制 4G Cat.1模组 ,安信可CA-01加载定位显示当前位置。

    文章目录 一.前言 通讯协议 技术问题点 二.4G模组业务逻辑 上报基站信息 三.微信小程序控制 另外,不要把我的博客作为学习标准,我的只是笔记,难有疏忽之处,如果有,请指出来,也欢迎留言哈! 微信物 ...

  8. php qcloud sdk weapp_微信小程序腾讯云php后台解决方案

    微信小程序腾讯云php后台解决方案 微信小程序前段需要添加必要的文件以配合后端 (1)wafer2-client-sdk sdk提供了几种接口包括登陆,获取用户openid,图片上传等 (2)conf ...

  9. 微信小程序获取当前位置和城市名

    这篇文章主要介绍了微信小程序获取当前位置和城市名的思路,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下 目录 一.授权并获取经纬度 腾讯地图API **简介** Hello world! 一. ...

  10. 微信小程序-获取用户位置(经纬度+所在城市)

    微信小程序-获取用户位置(经纬度+所在城市) 文章目录 微信小程序-获取用户位置(经纬度+所在城市) 一.目标 二.实现思路 三.实现步骤 3.1 用到的接口函数 3.2 具体步骤 3.2.1 创建界 ...

最新文章

  1. ubuntu16.04分区
  2. halcon知识:【1】二维码原理
  3. xgboost模型在centos系统下的可视化
  4. 计算机网络-思维导图(6)应用层
  5. GeoServer之styles定制
  6. JSP的改动需要重启应用服务器才能生效?
  7. C#利用委托实现窗体间的值传递
  8. Modbus通讯协议学习 - 认识篇
  9. 【优化算法】精子群优化算法(SSO)【含Matlab源码 1465期】
  10. php在线安装ipa,网页安装ipa
  11. diskpart clean 误操作恢复
  12. Win10 安装Docker 杂记
  13. 精彩的“利益均衡”,尤其是“四”
  14. .Net 中使用Farpoint Web Spread 自定义CellType
  15. vs2013如何调用监视窗口实现调试(如何打断点、逐步调试、逐过程调试、退出调试、条件调试)
  16. 楼层标高怎么引上去_楼层标高怎么引上去
  17. Gitee使用时TimeOut问题解决
  18. Thinkphp入门-创建一个最简单的ThinkPhp项目工程
  19. 【SA8295P 源码分析】00 - 系列文章链接汇总
  20. Stanford CS230深度学习(一)

热门文章

  1. 为什么你要用卡片笔记法?
  2. 电磁干扰类型以及--电感和磁珠
  3. linux红帽8怎么安yum,RedHat Linux 8本地Yum源配置方法
  4. css 面包屑 30个字节,css3面包屑设计
  5. 计算机自动维护有用吗,Win10系统关闭自动维护功能提高系统运行速度
  6. 英语学习详细笔记(五)WH问句、祈使句、感叹句
  7. python面向对象游戏_【Python之旅】第四篇(四):基于面向对象的模拟人生游戏类...
  8. 记录一次自己搭建服务器的历程(机架式服务器,Linux系统)
  9. log_archive_dest_2参数配置错误导致的dataguard主库无法传文件到备库
  10. LeetCode:459.重复的子字符串 Python3 | 判断输入的字符串是不是可以由子串多次重复构成