前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >腾讯地图手把手教你实现微信小程序路线规划

腾讯地图手把手教你实现微信小程序路线规划

作者头像
腾讯位置服务
发布于 2021-03-05 04:34:32
发布于 2021-03-05 04:34:32
1.6K0
举报
文章被收录于专栏:腾讯位置服务腾讯位置服务

前言

本文旨在以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脚手架是开箱即用的:

代码语言:txt
AI代码解释
复制
# 全局安装 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是小程序专用文件,也需完善下:

代码语言:txt
AI代码解释
复制
{
  "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),并在管理后台绑定小程序,然后设置个性地图的样式,才能使用:

代码语言:txt
AI代码解释
复制
<map
  id="citymap"
  name="citymap"
  :longitude="lng"
  :latitude="lat"
  :polyline="polyline"
	:markers="markers"
  scale="12"
  :subkey="YOUR_OWN_QQMAP_KEY"
  show-location
  show-compass
  enable-rotate
  style="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对象

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

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

代码语言:txt
AI代码解释
复制
// 坐标从上一页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)
    }
  })
}

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

代码语言:txt
AI代码解释
复制
// 解析路线,包括距离,时间,描述,路线,起止点等
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 = 0
  let midPointIndex = Math.floor(result.points.length / 2)
  result.latitude = result.points[midPointIndex].latitude
  result.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

代码语言:txt
AI代码解释
复制
getStepPolyline(step) {
	let coors = [];
	// 随机颜色
  let colorArr = ['#1aad19', '#10aeff', '#d84e43']
  let _dottedLine = true
  if (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.length
	this.getStepPolyline.colorIndex++
	// 最终polyline结果
  let polyline = {
    width: 7,
    points: _points,
    color: colorArr[colorIndex],
    dottedLine: _dottedLine,
    arrowLine: true, // 带箭头的线, 开发者工具暂不支持该属性
    borderColor: '#fff',
    borderWidth: 1
  }
  return polyline
}

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

代码语言:txt
AI代码解释
复制
广州火车站 -> 广州塔
9.88km 30分钟
地铁5号线 广州火车站 -> 珠江新城,途径7站
地铁3号线 珠江新城 -> 广州塔,途径1站

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

代码语言:txt
AI代码解释
复制
<map
  id="citymap"
  name="citymap"
  :latitude="currentRoute.latitude"
  :longitude="currentRoute.longitude"
  :polyline="currentRoute.polyline"
  :markers="currentRoute.markers"
  scale="12"
  :subkey="qqMapKey"
  show-location
  show-compass
  enable-rotate
  style="width: 100%; height: 100%;"
></map>

效果

作者:棱镜_jh

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

来源:掘金

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

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
华为在高端智能手机市场再次撕开了一道深深的口子
8月29日,华为宣布推出“HUAWEI Mate 60 Pro先锋计划”,并于当天中午在官方商城、部分线下门店上线销售新机Mate 60 Pro,它是全球首款支持卫星通话的大众智能手机,即使在没有地面网络信号的情况下也可以与外界联系,令人欣喜。
刘旷
2023/09/11
2430
华为小米vivo向上,苹果荣耀OPPO向下
日前,Counterpoint发布的手机销量月度报告显示,中国智能手机销量在2024年第四季度同比下降3.2%,成为2024年唯一出现同比下滑的季度。而对于各大智能手机品牌来说,他们的市场份额和格局也在悄然发生变化。
刘旷
2025/01/22
1240
高端机市场卡位战:iQOO能否博得一席之地?
短短三年时间从无名小辈到国内手机厂商前列,iQOO刷新了消费者对手机如何更好打电竞的认知,现如今其又试图在高端市场内再上演一次“突围战”。
用户2908108
2022/02/28
4080
高端机市场卡位战:iQOO能否博得一席之地?
折叠屏,vivo的高端打手?
2022年开年国产机销量大跳水,各实力玩家的出货成绩也都不尽人意,行业走向不景气的信号逐渐明显。
用户9702975
2022/05/30
5480
小米、OPPO狠狠盯上华为的欧洲份额
近日,雷军在其个人微博发文称,小米手机业务近两年主攻欧洲市场,已经进入市场份额前三。
刘旷
2020/09/07
4440
OPPO们的内外新困局
鉴于此,国内互联网企业纷纷出手相助。OPPO通过与旗下的海外分支机构了解当地疫情情况,征询需求后迅速组织物资捐赠。目前已向海外肺炎疫情重灾区意大利、西班牙、德国、法国和日本捐赠寄出30万只N95/FFP3口罩。
刘旷
2020/03/19
6910
苹果拿下全球智能手机市场50%销售额、90%利润!
2月5日消息,近日,市场研究机构Counterpoint Research发布的一份最新报告显示,在2023年的全球智能手机市场,苹果依然是最赚钱的智能手机厂商,他们2023年的iPhone销售收入达到了创纪录的2030亿美,并且首次占到了整个智能手机市场营收的50%。这主要得益于高端智能手机市场的需求的持续增长,以及苹果iPhone平均售价的增长。
芯智讯
2024/02/06
1930
苹果拿下全球智能手机市场50%销售额、90%利润!
华为、苹果、三星的手机终结之战
过去10年中,智能手机的快速普及,改变了全世界大多数人的生活和工作方式,而在这场变革背后,苹果、三星、华为这些科技巨头的积极推动作用不容忽视。
刘旷
2020/08/04
3920
线下失守、高端难攻,vivo 2020开年太难
疫情黑天鹅让一众手机厂商们开始了前所未有的操作,以往热闹喧嚣的线下发布会失去了声音,而为了抢占先机,线上发布会成了最好的选择。
刘旷
2020/03/18
3660
线下失守、高端难攻,vivo 2020开年太难
拨开迷雾 看见vivo穿越周期的秘密
任何一个行业都有周期性,就好像我们在做股票投资的时候,提到最多的就是周期规律,因为只有掌握规律才可以让我们赚到钱。所以不论是哪家公司都逃脱不了行业周期的宿命。
用户2908108
2023/02/26
3120
拨开迷雾 看见vivo穿越周期的秘密
高端手机格局再生变数,华为赋魅、苹果祛魅
历经二十多年发展,智能手机产业链高度成熟,消费者换机需求疲软,智能手机厂商艰难创新,市场存量竞争早已进入白热化阶段。
刘旷
2024/05/13
1530
得益于5G iPhone,中国消费者推动苹果在中国实现第二季度新高
总部位于加州的Cupertino周三表示,在5G iPhone的强劲需求以及首次购买Mac电脑和iPad的推动下,苹果在包括香港和台湾在内的大中华区的销售额在截至3月的季度几乎翻了一番。
海大指南针
2022/05/16
2420
得益于5G iPhone,中国消费者推动苹果在中国实现第二季度新高
跳脱低迷,华为、苹果、荣耀OV小米激战2024
尽管2023一整年,很多行业都在逐渐复苏,但是对于手机圈来说,这股“春风”似乎就跟没吹过一样。整整一年哪怕厂商穷尽力气去卷,但行业低迷、市场体量下滑的局面,仍然没有得到有效扭转。
刘旷
2024/01/22
2220
与苹果的「高端市场」之争,国产手机只能指望「折叠屏」?
2022年半导体大会正式开启,点击图片立刻参与! 抢占市场,需要一个新的思路。 作者 | 来自镁客星球的家衡 4月11日晚间,vivo在自家新品发布会上公布了首款折叠屏产品。 就产品本身而言,这款名为“vivo X Fold”的手机并没有太多颠覆性的创新,但当8999元的起售价公布之后,弹幕还是纷纷刷起来“真香”:一款售价不到1万元的折叠屏手机,确实诱人。 时间回到2018年,折叠屏手机“出道即巅峰”。柔宇科技给智能手机带来了全新形态,随后三星与华为迅速跟进,推出相关产品。 但相较于折叠屏的惊艳,易碎的屏
镁客网
2022/04/12
2690
与苹果的「高端市场」之争,国产手机只能指望「折叠屏」?
华为强势回归,高通却成了最大输家?
8月29日,在没有召开新品发布会的情况下,华为基于自研麒麟芯片的新一代旗舰手机Mate 60 Pro正式开售,虽然定价高达6999元,但仍是备受追捧,线上线下均一机难求。今天,华为Mate 60 Pro+和新一代折叠旗舰机Mate X5也正式开启预订,在预售开启之后,上线十多秒首批已被抢购完毕。
芯智讯
2023/09/08
2660
华为强势回归,高通却成了最大输家?
OPPO拿下一季度国内智能手机市场及折叠屏市场双料第一!
2023年4月27日,市场研究机构IDC公布的最新数据显示,2023年第一季度,中国智能手机市场出货量约6,544万台,同比下降11.8%。2023年开年依然低迷,延续2022年以来每季度出货量同比下降幅度超10%。
芯智讯
2023/05/09
1600
OPPO拿下一季度国内智能手机市场及折叠屏市场双料第一!
荣耀独立一周年,能接替华为之后的高端市场吗?
12月16日,荣耀举行八周年庆,CEO赵明是这样定位荣耀的,“对于荣耀而言,我们更看重的就是要坚持好自己对于方向的判断,不跟随别人的指挥棒,或者是不被别人牵着鼻子走,而是基于现有的供应和技术发展的方向和节奏,做出最好的选择”。
用户2908108
2022/02/10
3300
荣耀独立一周年,能接替华为之后的高端市场吗?
线下渠道失势:5G 能否让vivo重生
手机市场有一个奇怪的现象,华为、小米、OPPO、vivo同属国内一线手机品牌,但vivo的形象总给人一种比华为、小米矮一截的感觉,与其齐名的OPPO同样如此。
刘旷
2020/01/22
5710
机构数据总打架,微博终于把手机市场的事儿说清楚了
日前微博与知名市场调研公司赛诺联合发布《2016年智能手机微报告》,从一个超级App的视角呈现中国智能手机市场的全貌。在我看来,微博发布的智能手机报告对于行业可以说是雪中送炭,它让我们看到一个更加真实
罗超频道
2018/04/25
8270
机构数据总打架,微博终于把手机市场的事儿说清楚了
2023Q2全球智能手机市场销量八连跌!高端市场成唯一亮点
近日,市场研究机构Counterpoint发布的最新研究报告显示,2023年第二季度,全球智能手机市场的销售额同比下降8%,季度环比下降5%。这是连续第八个季度出现同比下降。
芯智讯
2023/08/09
2740
2023Q2全球智能手机市场销量八连跌!高端市场成唯一亮点
推荐阅读
相关推荐
华为在高端智能手机市场再次撕开了一道深深的口子
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档