小程序线多点路图绘制

需求

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

思路

  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>

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

相关推荐
The_Ticker31 分钟前
CFD平台如何接入实时行情源
java·大数据·数据库·人工智能·算法·区块链·软件工程
Elastic 中国社区官方博客37 分钟前
Elasticsearch 开放推理 API 增加了对 IBM watsonx.ai Slate 嵌入模型的支持
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
企鹅侠客41 分钟前
ETCD调优
数据库·etcd
Json_181790144801 小时前
电商拍立淘按图搜索API接口系列,文档说明参考
前端·数据库
HerayChen1 小时前
微信小程序混合 h5 wx.miniProgram是 undefined
微信小程序·小程序·h5
煎饼小狗1 小时前
Redis五大基本类型——Zset有序集合命令详解(命令用法详解+思维导图详解)
数据库·redis·缓存
永乐春秋1 小时前
WEB-通用漏洞&SQL注入&CTF&二次&堆叠&DNS带外
数据库·sql
打鱼又晒网2 小时前
【MySQL】数据库精细化讲解:内置函数知识穿透与深度学习解析
数据库·mysql
大白要努力!2 小时前
android 使用SQLiteOpenHelper 如何优化数据库的性能
android·数据库·oracle
tatasix3 小时前
MySQL UPDATE语句执行链路解析
数据库·mysql