在vue2中引用高德地图,外卖骑手的路线规划

最近给之前的老项目增加的一个配送骑手地图显示,要应用高德地图,这里就简单的把代码摘点出来,做个小随笔。

参照路径规划-参考手册-地图 JS API 1.4 | 高德地图API

AMap.Riding

AMap.Riding骑行路径规划服务,提供起始、终点骑行路线查询服务。用户可以通过自定义回调函数取回并显示查询结果。若服务请求失败,系统将返回错误信息

相关示例:位置经纬度 + 骑行路线规划-骑行路径规划-示例中心-JS API 1.4 示例 | 高德地图API

构造函数

说明

AMap.Riding (opts:RidingOptions )

构造函数,提供步行路径规划功能

 

RidingOptions

类型

说明

map

Map

AMap.Map对象, 展现结果的地图实例。

当指定此参数后,搜索结果的标注、线路等均会自动添加到此地图上。可选参数

policy

Number

骑行路线规划策略;可选值为:

0:推荐路线及最快路线综合

1:推荐路线

2:最快路线

默认值:0

panel

String|HTMLElement

结果列表的HTML容器id或容器元素,提供此参数后,结果列表将在此容器中进行展示。可选参数

hideMarkers

Boolean

设置隐藏路径规划的起始点图标,设置为true:隐藏图标;设置false:显示图标 默认值为:false

isOutline

Boolean

使用map属性时,绘制的规划线路是否显示描边。缺省为true

outlineColor

String

使用map属性时,绘制的规划线路的描边颜色。缺省为'white'

autoFitView

Boolean

用于控制在路径规划结束后,是否自动调整地图视野使绘制的路线处于视口的可见范围

 

方法

返回值

说明

search(origin:LngLat,destination:LngLat,

callback:function(status:String,result:info/RidingResult))

或 search(point:Array.<Object>,

callback:function(status:String,result:info/RidingResult))                 

 

根据起点和终点坐标,实现骑行路径规划;

当按起点、终点名称时,point为包含起点、终点的数组,

例:[{keyword:‘方恒国际中心A座’},{keyword:‘望京站’}]

当数组超过两个元素时,取前两个元素为起点、终点,其余元素忽略;

当status为complete时,result为RidingResult;

当status为error时,result为错误信息info;

当status为no_data时,代表检索返回0结果。

clear()

 

清除搜索的结果

 

事件

参数

说明

complete

RidingResult

当查询成功时触发此事件

error

ErrorStatus

当查询失败时触发此事件

RidingResult 对象

属性

类型

说明

info

String

成功状态说明

origin

LngLat

骑行导航起点坐标

destination

LngLat

骑行导航终点坐标

start

Poi

骑行导航起点

end

Poi

骑行导航终点

count

Number

骑行导航路段数目

routes

Array.<RideRoute>

骑行规划路线列表

RideRoute 对象

属性

类型

说明

distance

Number

起点到终点总步行距离,单位:米

time

Number

步行时间预计,单位:秒

rides

Array.<RideStep>

路段列表,以道路名称作为分段依据,将整个骑行导航方案分隔成若干路段

RideStep 对象

属性

类型

说明

start_location

LngLat

本路段的起点坐标

end_location

LngLat

本路段的终点坐标

instruction

String

此路段说明,如“沿北京南站路骑行565米右转”

distance

Number

此路段距离,单位:米

time

Number

此路段预计使用时间,单位:秒

path

Array.<LngLat>

此路段坐标集合

action

String

本骑行子路段完成后动作

assist_action

String

本骑行子路段完成后辅助动作,一般为到达某个目的地时返回

orientation

String

步行方向

road

String

道路

 

具体示例:

一、 页面调取

<template>
	<!-- 骑手位置地图 start-->
	<view class="card-panel map-panel" v-if="riderLocationMap">
		<szyCommonMap ref="commonMapRef" :markers="markers" :refreshLoading="refreshLoading"
			:rider_status_level="rider_status_level" @refreshMap="refreshMap" />
	</view>
	<!-- 骑手位置地图 end -->
</template>
<script>
	import szyCommonMap from '@/components/szy-common/szy-common-map/szy-common-map.vue'
	export default {
		components: {
			szyCommonMap
		},
		data() {
			return {
				refreshLoading: false, // 点击刷新
				riderLocationMap: false, // 骑手位置地图
				refresh: 0, // 地图自动刷新时间
				latitude: 0,
				longitude: 0,
				rider_status_level: 0,
				markers: [{
					id: 0,
					latitude: 0,
					longitude: 0,
					callout: {
						content: '配送骑手'
					},
				}, {
					id: 1,
					latitude: 0,
					longitude: 0,
					callout: {
						content: '发货商家'
					}
				}, {
					id: 2,
					latitude: 0,
					longitude: 0,
					callout: {
						content: '我的位置'
					}
				}],
			}
		},
		async created() {
			this.initData();
		},
		methods: {
			initData: function(load = true) {
				let url = this.getUrl('info');
				this.$http.get(url, {
						id: this.order_id,
					}, {
						load: load
					}).then(data => {

						// 骑手初始位置
						if (data.dada_info) {
							this.latitude = Number(data.dada_info.rider_lat);
							this.longitude = Number(data.dada_info.rider_lng);
							this.markers[0].latitude = Number(data.dada_info.rider_lat);
							this.markers[0].longitude = Number(data.dada_info.rider_lng);
							this.markers[1].latitude = Number(data.dada_info.store_address_lat);
							this.markers[1].longitude = Number(data.dada_info.store_address_lng);
							this.markers[2].latitude = Number(data.dada_info.user_address_lat);
							this.markers[2].longitude = Number(data.dada_info.user_address_lng);

							// 判断地图是否显示
							if (data.dada_info.rider_lat != '' && data.dada_info.rider_lng != '') {
								this.riderLocationMap = true;
								this.rider_status_level = data.rider_status.level;
							}
							if (this.order_info.order_status == 1 && data.rider_status && data.rider_status
								.level == 4 || data.rider_status == null) {
								this.riderLocationMap = false;
							}
						}

						// 骑手位置地图自动刷新倒计时
						if (data.dada_info) {
							let timer = Number(data.dada_info.refresh);
							if (timer != 0) {
								if (this.refresh) clearInterval(this.refresh);
								this.refresh = setInterval(() => {
									if (timer > 0) {
										timer -= 1;
									} else {
										this.refreshMap();
										timer = Number(data.dada_info.refresh);
									}
								}, 1000);
							}
						}

					}),



			},

			// 骑手位置地图刷新
			refreshMap: function() {
				this.refreshLoading = true;
				this.$http.post('/user/order/get-dada-position', {
					order_id: this.order_id
				}, {
					isFactory: false
				}).then(res => {
					let data = res.data;
					if (data.code == 0) {
						this.latitude = Number(data.data.rider_lat);
						this.longitude = Number(data.data.rider_lng);
						this.markers[0].latitude = Number(this.latitude);
						this.markers[0].longitude = Number(this.longitude);
						this.refreshLoading = false;
						this.$refs.commonMapRef.initMap();
					}
				})
			},

		}
	}a
</script>

二、 地图组件

/**
* 组件名称:高德地图组件
*/
<template>
	<view class="map-box">
		<div id="container" style="height: 650rpx;"></div>
		<view class="refresh-btn" @click="refreshMap"><i class="icon iconfont">&#xe639;</i></view>
		<view class="refresh-mark" v-if="refreshLoading"></view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				jsKey: '这里调取你的js_key',
                jsCode: '这里调取你的js_code',
				riderRemainingDistance: 0, // 距离
				riderRemainingTime: 0, // 时间
				rider_lat: 0, // 骑手位置
				rider_lng: 0,
				store_address_lat: 0, //商家位置
				store_address_lng: 0,
				user_address_lat: 0, // 用户位置
				user_address_lng: 0,
			}
		},
		props: {
			// 标记点 [0]骑手,[1]发货商家,[2]用户
			markers: {
				type: [Object, Array]
			},
			// 判断骑手取货状态
			rider_status_level: {
				type: Number,
			},
			// 遮罩
			refreshLoading: {
				type: Boolean,
				default: false
			}
		},

		methods: {
			refreshMap() {
				this.$emit('refreshMap');
			},
			initMap() {
				this.rider_lat = this.markers[0].latitude;
				this.rider_lng = this.markers[0].longitude;
				this.store_address_lat = this.markers[1].latitude;
				this.store_address_lng = this.markers[1].longitude;
				this.user_address_lat = this.markers[2].latitude;
				this.user_address_lng = this.markers[2].longitude;
				
				var map = new AMap.Map("container", {
					resizeEnable: true,
					center: [this.rider_lng, this.rider_lat], //地图中心点 - 骑手位置
					zoom: 16 //地图显示的缩放级别
				});

				// 从骑手取到货开始计算与用户的距离和时间
				if (this.rider_status_level == 3) {
					//骑行导航
					var riding = new AMap.Riding({
						map: map,
						policy: 1,
						hideMarkers: false,
						isOutline: true,
						outlineColor: '#ffeeee',
						autoFitView: true
					});

					//根据起终点坐标规划骑行路线
					var that = this;
					riding.search([this.rider_lng, this.rider_lat], [this.user_address_lng, this
						.user_address_lat
					], function(status,
						result) {
						// result即是对应的骑行路线数据信息,相关数据结构文档请参考  https://lbs.amap.com/api/javascript-api/reference/route-search#m_RidingResult
						if (status === 'complete') {
							console.log('绘制骑行路线完成', result);
							that.riderRemainingDistance = Number(result.routes[0].distance); // 距离,单位:米
							that.riderRemainingTime = Math.ceil(result.routes[0].time /
								60); // 时间,单位:分钟,向上取整
						} else {
							console.log('骑行路线数据查询失败' + result)
						}
					});
				}

				setTimeout(() => {
					// 途经点 -发货商家
					var viaMarkerContent = `<div class="custom-content-marker store">
<img src="../../../static/image/store.png">
</div>`;
					var viaMarker = new AMap.Marker({
						content: viaMarkerContent,
						position: new AMap.LngLat(this.store_address_lng, this
							.store_address_lat), // 商家位置
						offset: new AMap.Pixel(-25, -50),
						label: {
							content: this.rider_status_level <= 2 ? "商家备货中" : "商家已发货", //文本内容
							position: 'TM',
							minZoom: 15, //label的最小显示级别,即文本标注在地图15级及以上,才会显示
						},
					});

					// 起点 - 骑手
					var startMarkerContent = `<div class="custom-content-marker rider">
<img src="../../../static/image/rider.png">
</div>`;
					var startMarker = new AMap.Marker({
						content: startMarkerContent,
						position: new AMap.LngLat(this.rider_lng, this.rider_lat), // 骑手位置
						offset: new AMap.Pixel(-25, -50), // 图标偏移
						label: {
							content: this.rider_status_level <= 2 ? "骑手正赶往商家" :
								"骑手正在配送</br>距用户<strong class='c-red'>" + this
								.riderRemainingDistance +
								'米 ' + this.riderRemainingTime + "分钟</strong>",
							position: 'TM',
							minZoom: 15, //label的最小显示级别,即文本标注在地图15级及以上,才会显示
						},
					});


					// 终点 - 用户
					var endMarkerContent = `<div class="custom-content-marker user">
				<img src="../../../static/image/location.png">
				</div>`;
					var endMarker = new AMap.Marker({
						content: endMarkerContent,
						position: new AMap.LngLat(this.user_address_lng, this
							.user_address_lat), // 用户位置
						offset: new AMap.Pixel(-25, -50),
						label: {
							content: "我的位置", //文本内容
							position: 'TM',
							minZoom: 15, //label的最小显示级别,即文本标注在地图15级及以上,才会显示
						},
					});

					// 将 markers 添加到地图
					map.add([viaMarker, startMarker, endMarker]);
				}, 500);
			},
		},
		mounted() {
			window._AMapSecurityConfig = {
				securityJsCode: this.jsCode,
			}
			const script1 = document.createElement('script');
			script1.src = 'https://webapi.amap.com/maps?v=2.0&key=' + this.jsKey + '&plugin=AMap.Riding';
			script1.onload = () => {
				this.initMap(); // 确保地图初始化代码在脚本加载完成后执行
			};
			document.head.appendChild(script1);

			const script2 = document.createElement('script');
			script2.src = 'https://a.amap.com/jsapi_demos/static/demo-center/js/demoutils.js';
			document.head.appendChild(script2);
		},
	}
</script>

<style lang="scss">
	.map-box {
		position: relative;
	}

	::v-deep div {
		line-height: 40rpx !important;
	}

	::v-deep a .csssprite,
	::v-deep .amap-logo {
		display: none !important;
	}

	::v-deep .amap-markers {
		.custom-content-marker {
			width: 100rpx;
			height: 100rpx;

			img {
				max-width: 100% !important;
				max-height: 100% !important;
			}
		}

		.amap-lib-marker-to,
		.amap-lib-marker-from {
			display: none;
		}

		.amap-marker-label {
			border-color: #eee;
			border-radius: 4rpx;
			font-size: 28rpx;
			padding: 12rpx;
			color: #222;
			left: 50% !important;
			top: -26px !important;
			transform: translate(-50%, -50%);

			&:after {
				position: absolute;
				z-index: -1;
				content: '';
				bottom: -30rpx;
				content: '';
				width: 0;
				height: 0;
				left: 50%;
				border-width: 18rpx;
				transform: translate(-50%, 0%);
				border-style: solid dashed dashed dashed;
				border-color: #fff transparent transparent transparent;
				display: block;
			}

			.c-red {
				color: red;
			}
		}
	}


	.refresh-mark {
		position: absolute;
		top: 0;
		right: 0;
		left: 0;
		bottom: 0;
		z-index: 3;
		background: rgba(255, 255, 255, 0.6);
	}

	.refresh-btn {
		position: absolute;
		top: 20rpx;
		right: 20rpx;
		z-index: 2;
		background: #fff;
		width: 65rpx;
		height: 65rpx;
		display: flex;
		align-items: center;
		justify-content: center;
		border-radius: 10rpx;
		overflow: hidden;
		box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.3);

		&:active {
			background: #ccc;

			.icon {
				color: #000;
			}
		}

		.icon {
			color: #666;
			font-size: 34rpx;
		}
	}
</style>

 展示效果:

 

这里把图标也给你们带上,不用再去做图标了,右击保存吧。 图标存放目录:项目\src\static\image下

posted @ 2025-03-15 11:10  蓦然JL  阅读(477)  评论(0)    收藏  举报
访问主页
关注我
关注微博
私信我
返回顶部