|
|
@@ -3,7 +3,8 @@
|
|
|
wrapClassName="createTask-modal" :visible="visible">
|
|
|
<div class="content">
|
|
|
<div class="content-panel">
|
|
|
- <TaskPanel ref="taskPanelRef" :onClickConfirm="onClickConfirm" :onClickCancel="onClickCancel" />
|
|
|
+ <TaskPanel ref="taskPanelRef" :drawTrajectory="drawTrajectory" :onClickConfirm="onClickConfirm"
|
|
|
+ :onClickCancel="onClickCancel" />
|
|
|
</div>
|
|
|
<div class="content-map">
|
|
|
<div id="taskMap" :style="{ width: '100%', height: '100%' }"></div>
|
|
|
@@ -15,6 +16,7 @@
|
|
|
<script lang="ts" setup>
|
|
|
import { ref, reactive, onMounted } from 'vue';
|
|
|
import TaskPanel from './TaskPanel.vue';
|
|
|
+import sPointSrc from '/@/assets/icons/sPoint.svg';
|
|
|
import { useGMapManage } from '/@/hooks/use-g-map';
|
|
|
|
|
|
interface Props {
|
|
|
@@ -32,7 +34,9 @@ const taskPanelRef = ref();
|
|
|
|
|
|
const state = reactive({
|
|
|
loading: false,
|
|
|
- map: null,// 高德地图实例
|
|
|
+ AMap: null, // Map类
|
|
|
+ map: null, // 地图对象
|
|
|
+ mapCoverList: [] as any[],
|
|
|
})
|
|
|
|
|
|
// 高德地图Hook
|
|
|
@@ -40,6 +44,7 @@ const AmapHook = useGMapManage();
|
|
|
|
|
|
const init = async () => {
|
|
|
const AMap = await AmapHook.asyncInitMap();
|
|
|
+ state.AMap = AMap;
|
|
|
const map = new AMap.Map('taskMap', {
|
|
|
center: [121.48, 31.22],
|
|
|
zoom: 12
|
|
|
@@ -53,6 +58,96 @@ const init = async () => {
|
|
|
onMounted(() => {
|
|
|
init();
|
|
|
})
|
|
|
+
|
|
|
+// 绘制轨迹
|
|
|
+const drawTrajectory = (list: {
|
|
|
+ paths: number[],
|
|
|
+ isSPoint: boolean,
|
|
|
+}[]) => {
|
|
|
+ const AMap: any = state.AMap;
|
|
|
+ const map: any = state.map;
|
|
|
+ state.mapCoverList.forEach(cover => map.remove(cover));
|
|
|
+ const paths = list.map(item => item.paths);
|
|
|
+ if (!paths.length) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 绘制轨迹折线
|
|
|
+ const polyline = new AMap.Polyline({
|
|
|
+ path: paths,
|
|
|
+ strokeColor: '#3feb78',
|
|
|
+ showDir: true,// 显示路线白色方向箭头
|
|
|
+ strokeOpacity: 1,// 轮廓线透明度
|
|
|
+ strokeWeight: 6,//线宽
|
|
|
+ strokeStyle: 'solid',
|
|
|
+ })
|
|
|
+ const serialList = list.slice();
|
|
|
+ // 序号
|
|
|
+ const text = serialList.map((item, index) => {
|
|
|
+ return new AMap.Text({
|
|
|
+ position: new AMap.LngLat(item.paths[0], item.paths[1]),
|
|
|
+ offset: new AMap.Pixel(-8, -30),
|
|
|
+ text: index + 1,
|
|
|
+ style: {
|
|
|
+ backgroundColor: 'transparent',
|
|
|
+ borderColor: 'transparent',
|
|
|
+ }
|
|
|
+ })
|
|
|
+ })
|
|
|
+ // 序号下方圆形标记
|
|
|
+ const circles = serialList.map((item) => {
|
|
|
+ return new AMap.Circle({
|
|
|
+ center: new AMap.LngLat(item.paths[0], item.paths[1]),
|
|
|
+ radius: 0.5, // 半径
|
|
|
+ fillColor: '#FFFFFF',
|
|
|
+ fillOpacity: 1,
|
|
|
+ strokeWeight: 2,
|
|
|
+ });
|
|
|
+ })
|
|
|
+ // 计算并显示每段线的距离
|
|
|
+ const distances = [];
|
|
|
+ const serialPaths = serialList.map(item => item.paths)
|
|
|
+ for (let i = 0; i < serialPaths.length - 1; i++) {
|
|
|
+ const distance = AMap.GeometryUtil.distance(new AMap.LngLat(serialPaths[i][0], serialPaths[i][1]), new AMap.LngLat(serialPaths[i + 1][0], serialPaths[i + 1][1]));
|
|
|
+ // 计算两个点之间的中点坐标
|
|
|
+ const midLng = (serialPaths[i][0] + serialPaths[i + 1][0]) / 2;
|
|
|
+ const midLat = (serialPaths[i][1] + serialPaths[i + 1][1]) / 2;
|
|
|
+ const midPoint = new AMap.LngLat(midLng, midLat);
|
|
|
+ // 在中点位置放置文本以显示距离
|
|
|
+ const distanceText = new AMap.Text({
|
|
|
+ position: midPoint,
|
|
|
+ offset: new AMap.Pixel(-16, 10),
|
|
|
+ text: `${distance.toFixed(1)} m`,// 距离
|
|
|
+ style: {
|
|
|
+ fontSize: '10px',
|
|
|
+ color: '#FFFFFF',
|
|
|
+ backgroundColor: 'rgba(0, 0, 0, 0.75)',
|
|
|
+ borderColor: 'transparent',
|
|
|
+ },
|
|
|
+ });
|
|
|
+ distances.push(distanceText);
|
|
|
+ }
|
|
|
+ const other = [polyline, ...text, ...circles, ...distances];
|
|
|
+ const item = list.find(item => item.isSPoint);
|
|
|
+ if (item) {
|
|
|
+ // 绘制S点图标
|
|
|
+ const position = item.paths;
|
|
|
+ const icon = new AMap.Icon({
|
|
|
+ size: new AMap.Size(30, 30),
|
|
|
+ image: sPointSrc,
|
|
|
+ imageSize: new AMap.Size(30, 30)
|
|
|
+ })
|
|
|
+ const marker = new AMap.Marker({
|
|
|
+ position: new AMap.LngLat(position[0], position[position.length - 1]),
|
|
|
+ icon: icon,
|
|
|
+ offset: new AMap.Pixel(-20, -35),// 位置偏移
|
|
|
+ })
|
|
|
+ other.push(marker);
|
|
|
+ }
|
|
|
+ state.mapCoverList = other;
|
|
|
+ map.add(other);
|
|
|
+ // 自动缩放地图到合适的视野级别
|
|
|
+ map.setFitView(other);
|
|
|
+}
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|