小程序线多点路图绘制

需求

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

思路

  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>

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

相关推荐
Hacker_LaoYi1 小时前
【渗透技术总结】SQL手工注入总结
数据库·sql
岁月变迁呀1 小时前
Redis梳理
数据库·redis·缓存
独行soc1 小时前
#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍06-基于子查询的SQL注入(Subquery-Based SQL Injection)
数据库·sql·安全·web安全·漏洞挖掘·hw
你的微笑,乱了夏天2 小时前
linux centos 7 安装 mongodb7
数据库·mongodb
工业甲酰苯胺2 小时前
分布式系统架构:服务容错
数据库·架构
独行soc3 小时前
#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍08-基于时间延迟的SQL注入(Time-Based SQL Injection)
数据库·sql·安全·渗透测试·漏洞挖掘
郭wes代码3 小时前
Cmd命令大全(万字详细版)
python·算法·小程序
White_Mountain3 小时前
在Ubuntu中配置mysql,并允许外部访问数据库
数据库·mysql·ubuntu
Code apprenticeship3 小时前
怎么利用Redis实现延时队列?
数据库·redis·缓存
百度智能云技术站3 小时前
广告投放系统成本降低 70%+,基于 Redis 容量型数据库 PegaDB 的方案设计和业务实践
数据库·redis·oracle