小程序线多点路图绘制

需求

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

思路

  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
    	},
    ]

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

具体实现

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>

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

相关推荐
jakeswang40 分钟前
应用缓存不止是Redis!——亿级流量系统架构设计系列
redis·分布式·后端·缓存
秋难降1 小时前
零基础学SQL(八)——事务
数据库·sql·mysql
Starry_hello world1 小时前
MySql 表的约束
数据库·笔记·mysql·有问必答
RestCloud2 小时前
ETLCloud中的数据转化规则是什么意思?怎么执行
数据库·数据仓库·etl
一个天蝎座 白勺 程序猿2 小时前
Apache IoTDB(4):深度解析时序数据库 IoTDB 在Kubernetes 集群中的部署与实践指南
数据库·深度学习·kubernetes·apache·时序数据库·iotdb
.Shu.3 小时前
Redis zset 渐进式rehash 实现原理、触发条件、执行流程以及数据一致性保障机制【分步源码解析】
数据库·redis·缓存
君不见,青丝成雪3 小时前
大数据技术栈 —— Redis与Kafka
数据库·redis·kafka
悟能不能悟3 小时前
排查Redis数据倾斜引发的性能瓶颈
java·数据库·redis
切糕师学AI3 小时前
.net core web程序如何设置redis预热?
redis·.netcore
DemonAvenger3 小时前
事务管理:ACID特性与隔离级别详解
数据库·mysql·性能优化