vue 地图路线渲染

Vue 3 + TypeScript

javascript 复制代码
<template>
	<div ref="mapContainerRef" class="real-map"></div>
</template>

<script setup lang="ts">
// 下载插件 @amap/amap-jsapi-loader
import AMapLoader from '@amap/amap-jsapi-loader'
import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
import * as api from '@/api'

const mapContainerRef = ref<HTMLElement | null>(null)

const amapInstance = ref<any>(null)
const routeLine = ref<any>(null)
const startMarker = ref<any>(null)
const endMarker = ref<any>(null)

onMounted(() => {
    currentOrderId.value = route.query.orderId ?? route.params.orderId ?? ''
    getdata()
})
onBeforeUnmount(() => {
    if (amapInstance.value) {
        amapInstance.value.destroy()
        amapInstance.value = null
    }
})

const getdata = () => {
//接口
    api.enterprise_orderDetail({ orderId: currentOrderId.value }).then(res => {
        complaintTag.value = res.data.complaintTag
        detail.value = res.data.order
        initMap(res.data.order, res.data)
    })
   
}
// 获取两个经纬度中间点
 const getCenterPoint = (point1: any, point2: any) => {
  // console.log(point1, point2);
  // 角度转弧度(JS 数学函数用弧度计算)
  const rad = Math.PI / 180;
  const lat1 = Number(point1.lat) * rad;
  const lng1 = Number(point1.lng) * rad;
  const lat2 = Number(point2.lat) * rad;
  const lng2 = Number(point2.lng) * rad;
  // 球面中点计算公式
  const Bx = Math.cos(lat2) * Math.cos(lng2 - lng1);
  const By = Math.cos(lat2) * Math.sin(lng2 - lng1);
  const latMid = Math.atan2(
      Math.sin(lat1) + Math.sin(lat2),
      Math.sqrt((Math.cos(lat1) + Bx) ** 2 + By ** 2)
  );
  const lngMid = lng1 + Math.atan2(By, Math.cos(lat1) + Bx);
  
  // 弧度转回角度
  return {
      lat: Number((latMid / rad).toFixed(6)),
      lng: Number((lngMid / rad).toFixed(6))
  };
}

const initMap = async (datas: any, elseData: any): Promise<void> => {
    mapLoading.value = true
    mapError.value = ''
    try {
        // await nextTick()
        if (!mapContainerRef.value) return
        const AMap = await AMapLoader.load({
            key: '', //高德key 带秘钥那个
            version: '2.0',
            plugins: ['AMap.Driving'], // 路线规划插件
        })

        let center = getCenterPoint(
            { lat: datas.arriveLatitude, lng: datas.arriveLongitude },
            { lat: datas.departLatitude, lng: datas.departLongitude }
        )
        let radiusNum = Math.abs((datas.arriveLatitude - center.lat) * 100000)
        console.log(radiusNum);
        let scale = ref(14)
        if (radiusNum < 3000) {
            scale = 14.5
        } else if (radiusNum >= 3000 && radiusNum < 6000) {
            scale = 13
        } else if (radiusNum >= 6000 && radiusNum < 9000) {
            scale = 12
        } else if (radiusNum >= 9000 && radiusNum < 12000) {
            scale = 11
        } else if (radiusNum >= 12000) {
            scale = 10
        }

        amapInstance.value = new AMap.Map(mapContainerRef.value, {
            zoom: scale,
            center: [center.lng, center.lat],
            mapStyle: 'amap://styles/whitesmoke',
            viewMode: '2D',
        })
        // var points = [];

        startMarker.value = new AMap.Marker({
            position: [datas.departLongitude, datas.departLatitude],
            content: '<div class="map-pin start">起</div>',
            offset: new AMap.Pixel(-12, -12),
        })
        endMarker.value = new AMap.Marker({
            position: [datas.arriveLongitude, datas.arriveLatitude],
            content: '<div class="map-pin end">终</div>',
            offset: new AMap.Pixel(-12, -12),
        })
        var steps = JSON.parse(datas.steps)
        // console.log(steps)
        for (let i = 0; i < steps.length; i++) {
            const poLen = steps[i].polyline.split(";");
            for (let j = 0; j < poLen.length; j++) {
                console.log()
                points.value.push(poLen[j].split(",").map(Number));
            }
        }
       
        routeLine.value = new AMap.Polyline({
            path: points.value,
            strokeColor: '#d85f3a',
            strokeWeight: 6,
            lineJoin: 'round',
            lineCap: 'round',
        })
        // if ([4, 5, 6].indexOf(datas.orderStatus) > -1) {
        //     carMarker.value = new AMap.Marker({
        //         position: [datas.driverLongitude, datas.driverLatitude],
        //         content: '<div class="map-car">🚕</div>',
        //         offset: new AMap.Pixel(-12, -16),
        //     })
        // }
        // amapInstance.value.add([routeLine.value, startMarker.value, endMarker.value, carMarker.value])
        amapInstance.value.add([routeLine.value, startMarker.value, endMarker.value])

    } catch {
        // '地图加载失败,请检查 key 或网络'
    } finally {

    }
}
</script>
相关推荐
小番茄夫斯基6 分钟前
全球大模型的价格和能力排行汇总
前端·后端·架构
YYRAN_ZZU16 分钟前
Ubuntu22.04搭建QEMU嵌入式开发环境全攻略
linux·嵌入式硬件·ubuntu
小小小小宇19 分钟前
前端领域 30 个值得安装的 Agent Skills
前端
xkxnq21 分钟前
第八阶段:工程化、质量管控与高级拓展(132天),Vue项目文档自动化:VuePress搭建组件文档(组件示例+API说明)
javascript·vue.js·自动化
喵了几个咪23 分钟前
基于 Next.js 的 Headless CMS 前端架构:技术解析与二次开发导引
前端·javascript·架构
星栈24 分钟前
Makepad 不只是画界面:事件、状态和组件通信,到底怎么写
前端·rust
dsyyyyy110126 分钟前
只用HTML和CSS实现换一换效果
前端·css·html
青山Coding40 分钟前
Cesium应用(七):地形开挖的实现思路
前端·cesium
风骏时光牛马42 分钟前
Verilog常见问题及代码易错点梳理
前端
用户21816970493043 分钟前
swift (一) var let 字符串 int double 元组 数组[] 字典[:] 可选类型 if while for 函数func 可选类型?
前端