小程序线多点路图绘制

需求

当接口返回一连串地图坐标,需要根据这些坐标串联起来,形成一个线路图(本次使用步行导航线路图)。

思路

  1. 首先优先想到使用小程序Map组件的polyline属性去进行展示。但是我们发现直接使用该属性进行坐标绘制画出来的数据都是直线。所以想要根据地图上的线路图进行绘制必须使用第三方提供的绘制线路图的api。这里使用腾讯地图api

  2. 将第三方api进行简单封装,然后根据后端返回的坐标组,两两相连调用api。

    js 复制代码
    const demo = [
    	{
    		longitude: 1,
    		latitude: 1
    	},
    	{
    		longitude: 2,
    		latitude: 2
    	},
    	{
    		longitude: 3,
    		latitude: 3
    	},
    	{
    		longitude: 4,
    		latitude: 4
    	},
    ]

    如上这样一组数据我们就应该传入demo1, demo2拿到线路,然后再传入demo2, demo3再次拿到下一段路线,知道拿到最后一个线路为止,最后进行拼接展示。

具体实现

1. 首先让我们对第三方的api进行简单封装

从官网给的参数列表来看,我们至少需要key,form,to三个参数,而且form跟to的传参方式比较特殊,而我们一般使用对象传递,所以需要我们进行参数转换

js 复制代码
export const apiGetPolylineList = (data) => {
	const [from, to] = data
	return new Promise((resolve, reject) => {
		uni.request({
			url: `https://apis.map.qq.com/ws/direction/v1/walking/?from=${from.latitude},${from.longitude}&to=${to.longitude},${to.longitude}&key=${txMapKey}`,
			complete: (res) => {
		        if (res.data.status === 0) {
		          resolve(res.data.result.routes[0])
		        }else {
		          uni.showToast({
		            title: '线路加载失败',
		            icon: 'error'
		          })
		          reject('线路加载失败')
		        }
		      }
		})
	})
}

2.接下来根据后端返回的坐标组,两两相连调用api。

js 复制代码
// 创建测试数据
const testData = [
	{
		latitude: 30.868603,
		longitude: 103.934669
	},
	{
		latitude: 30.852555,
		longitude: 103.934843
	},
	{
		latitude: 30.851977,
		longitude: 103.92361
	},
	{
		latitude: 30.843044,
		longitude: 103.962646
	}
]

既然需要两两调用,我们在一开始就将他们分好。

js 复制代码
const getTwoSpotList = (testData) => {
	const list = []
	testData.reduce((pre, next) => {
		list.push([pre, next])
		return next
	})
	return list
}

既然我们要进行接口的多次调用,那不如我们直接使用Promise.all对结果进行统一处理

js 复制代码
const getLineData = async () => {
	const twoSpotList= getTwoSpotList(testData)
	const apiList = twoSpotList.map(item => apiGetPolylineList(item))
	const lineData = await Promise.all(apiList)
	const polylineListRes = getLineData(lineData)
}

我们拿到的数据关于线路图的就是polyline字段,格式为:坐标1纬度 , 坐标1经度 , 坐标2纬度 , 坐标2经度 , 坐标3纬度 , 坐标3经度...,第一个坐标为原始未被压缩过的,之后的使用前向差分进行压缩,我们需要进行解压合并操作。

js 复制代码
const getLineData = async (lineData) => {
	//推荐使用lodash这样的成熟库里面的深拷贝方法,这里为了简单直接使用JSON.parse(JSON.stringify(lineData))  
	const polylineList = JSON.parse(JSON.stringify(lineData))  
    .map((item) => item.polyline)
    .reduce((pre, next) => {
      const newNext = next
      for (var i = 2; i < newNext.length; i++) {
        newNext[i] = newNext[i - 2] + newNext[i] / 1000000
      }
      let resList = []
      for (var j = 0; j < newNext.length; j++) {
        resList.push({
          latitude: parseFloat(newNext[j].toFixed(5)),
          longitude: parseFloat(newNext[j + 1].toFixed(5)),
        })
        j++
      }
      return pre.concat(resList)
    }, [])
	 return polylineList 
	}
   

虽然官网没有说,但是polyline其实是一个对象数组,每一个对象都是表示一段线段,所以我们线路一般有两种展示形式:1.直接合并在为一个数组放进points里面,这种方式适合每条线段样式一致,不需要单独处理的情况。如果我们需要针对每条线段做定制化的需求,可以创建多个对象的形式进行展示。本文使用第一种方式。

最后我们直接使用拿到的数据

html 复制代码
<map
  style="width: 100%; height: 800rpx"
  :longitude="103.934669"
  :latitude="30.868603"
  :polyline="[
    {
      points: polylineListRes,
      color: '#000',
      width: 3,
      dottedLine: false,
    },
  ]"
  ></map>

不积跬步无以至千里,不积小流无以成江海。

相关推荐
cfm_29144 小时前
Redis缓存规范设计与全方位性能优化实战
redis·缓存·性能优化
weelinking4 小时前
【产品】12_接入数据库——让数据永久保存
jvm·数据库·python·react.js·数据挖掘·前端框架·产品经理
稳联技术老娜4 小时前
DeviceNet主站怎么连接西门子PLC,Profinet网关配置手册(那智机器人)
服务器·网络·数据库
这个DBA有点耶4 小时前
云上运维新挑战:当数据库不再“看得见摸得着”
数据库·sql·程序人生·云原生·运维开发·学习方法·dba
AskHarries5 小时前
系统提示词、开发者指令和用户输入的优先级
java·前端·数据库
消失在人海中5 小时前
oracle 数据库多表关联查询
服务器·数据库·oracle
九皇叔叔6 小时前
PostgreSQL/openGauss pg_stats 视图从入门到精通:统计信息、执行计划与慢 SQL 优化实战
数据库·sql·postgresql
南极企鹅6 小时前
MySQL间隙锁&临键锁
数据库·sql·mysql
TDengine (老段)7 小时前
TDengine 压缩编码机制 — 双层压缩架构与类型特化算法
大数据·数据库·物联网·算法·时序数据库·tdengine·涛思数据
苏渡苇9 小时前
Redis 持久化——RDB 快照 vs AOF 日志
数据库·redis·缓存·redis持久化·aof vs rdb