微信小顺序 + 腾讯舆图SDK 完成线路计划

原文链接

近来小顺序的生长愈来愈火了,作为各个产品线的extra效劳进口,以轻巧、疾速、壮大的交际链吸引着大批的用户和开辟者。业内开辟框架屡见不鲜,wepy,mpvue,taro等等,都在朝着更快,更壮大的方向生长,有一致 H5、微信、支付宝、百度和头条小顺序的大趋势。

本文旨在以mpvue框架为基础,讨论舆图类小顺序的开辟思绪,权当分享和总结。 话不多说,先体验一下:

《微信小顺序 + 腾讯舆图SDK 完成线路计划》

github源码所在: https://github.com/WarpPrism/…

运转截图

《微信小顺序 + 腾讯舆图SDK 完成线路计划》《微信小顺序 + 腾讯舆图SDK 完成线路计划》《微信小顺序 + 腾讯舆图SDK 完成线路计划》《微信小顺序 + 腾讯舆图SDK 完成线路计划》

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的生命周期混在一块,概况见 http://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等模块,如图:

《微信小顺序 + 腾讯舆图SDK 完成线路计划》

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),并在治理背景绑定小顺序,然后设置特性舆图的款式,才运用:

<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对象

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 = 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

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
}

末了,绑定到舆图上并输出,我们能够获得一个大抵如许的效果:

广州火车站 -> 广州塔
15km 1小时
地铁5号线 广州火车站 -> 珠江新城,门路6站
地铁3号线 珠江新城 -> 广州塔,门路1站

如许我们就经由过程direction接口举行了简朴的线路计划功用,接着把天生的数据绑定到舆图组件上,一个浅易的小顺序就做好了,是否是很简朴?固然假如想做得更好,就要挪用其他类似接口,逐步完美细节。

<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>

更多完成请参照源码和小顺序自身,假如对你有协助,能够star支撑。

其他

这里另有一款音频类的 web运用,宣布在gitee page上

http://crystalworld.gitee.io/…

感兴趣的朋侪能够看下,以后有时候笔者会补上开辟教程和源码,另作分享。

    原文作者:棱镜
    原文地址: https://segmentfault.com/a/1190000018690607
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞