|
@@ -3,26 +3,26 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import { ref, onMounted, onUnmounted } from "vue";
|
|
|
+import { ref, onMounted, onUnmounted, nextTick } from "vue";
|
|
|
import AMapLoader from "@amap/amap-jsapi-loader";
|
|
|
import eventBus from "@/api/eventBus";
|
|
|
import { convertPointToArray } from "@/utils/index";
|
|
|
import { deepClone } from "@/common/commonFun";
|
|
|
-import wellknown from 'wellknown';
|
|
|
-import {base_img_url,base_img_url3} from "@/api/config";
|
|
|
+import wellknown from "wellknown";
|
|
|
+import { base_img_url, base_img_url3 } from "@/api/config";
|
|
|
|
|
|
const map = ref(null);
|
|
|
const mouseTool = ref(null);
|
|
|
const selectedArea = ref(null);
|
|
|
const selectedPoints = ref([]);
|
|
|
const allPoints = ref([]);
|
|
|
-const defalutAllPoints = ref([])
|
|
|
-const pointList = ref([])
|
|
|
+const defalutAllPoints = ref([]);
|
|
|
+const pointList = ref([]);
|
|
|
|
|
|
-const mapEventType = ref('rectangle')
|
|
|
+const mapEventType = ref("rectangle");
|
|
|
|
|
|
// 自定义圆点样式
|
|
|
-const createMarkerContent = (color = 'rgba(0, 0, 0, 0.4)') => {
|
|
|
+const createMarkerContent = (color = "rgba(0, 0, 0, 0.4)") => {
|
|
|
return `
|
|
|
<div style="
|
|
|
width: 15px;
|
|
@@ -33,21 +33,21 @@ const createMarkerContent = (color = 'rgba(0, 0, 0, 0.4)') => {
|
|
|
">
|
|
|
</div>
|
|
|
`;
|
|
|
-}
|
|
|
+};
|
|
|
|
|
|
//高亮样式
|
|
|
const createMarkerImg = () => {
|
|
|
return `
|
|
|
- <img style="width: 38px;height: 38px;" src="${require('@/assets/images/map/status/active-icon.png')}">
|
|
|
+ <img style="width: 38px;height: 38px;" src="${require("@/assets/images/map/status/active-icon.png")}">
|
|
|
`;
|
|
|
-}
|
|
|
+};
|
|
|
// 初始化地图
|
|
|
-const initMap = async () => {
|
|
|
+const initMap = async (mapData, callback) => {
|
|
|
try {
|
|
|
const AMap = await AMapLoader.load({
|
|
|
key: "41769169f0f157e13a197e7eb0dd7b5b", // 替换为你的高德地图 Key
|
|
|
version: "2.0", // SDK 版本
|
|
|
- plugins: ["AMap.MouseTool","AMap.MarkerCluster"], // 加载 MouseTool 插件
|
|
|
+ plugins: ["AMap.MouseTool", "AMap.MarkerCluster"], // 加载 MouseTool 插件
|
|
|
}).then(async (AMap) => {
|
|
|
// 创建地图实例
|
|
|
map.value = new AMap.Map("map-container", {
|
|
@@ -57,7 +57,7 @@ const initMap = async () => {
|
|
|
// 天地图卫星
|
|
|
new AMap.TileLayer({
|
|
|
tileSize: 256, // 瓦片大小
|
|
|
- getTileUrl: function(x, y, z) {
|
|
|
+ getTileUrl: function (x, y, z) {
|
|
|
// 天地图影像 WMTS 地址
|
|
|
const s = Math.floor(Math.random() * 8); // 随机选择服务器节点
|
|
|
// return `https://t{0-7}.tianditu.gov.cn/img_c/w mts?tk=e95115c454a663cd052d96019fd83840`
|
|
@@ -67,7 +67,7 @@ const initMap = async () => {
|
|
|
//天地图路网
|
|
|
new AMap.TileLayer({
|
|
|
tileSize: 256, // 瓦片大小
|
|
|
- getTileUrl: function(x, y, z) {
|
|
|
+ getTileUrl: function (x, y, z) {
|
|
|
// 天地图影像 WMTS 地址
|
|
|
const s = Math.floor(Math.random() * 8); // 随机选择服务器节点
|
|
|
return `https://t${s}.tianditu.gov.cn/cva_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX=${z}&TILEROW=${y}&TILECOL=${x}&tk=e95115c454a663cd052d96019fd83840`;
|
|
@@ -75,13 +75,13 @@ const initMap = async () => {
|
|
|
}),
|
|
|
//正射影像
|
|
|
new AMap.TileLayer({
|
|
|
- tileUrl: base_img_url + 'map/lby/[z]/[x]/[y].png',
|
|
|
- zIndex:2
|
|
|
+ tileUrl: base_img_url + "map/lby/[z]/[x]/[y].png",
|
|
|
+ zIndex: 2,
|
|
|
}),
|
|
|
new AMap.TileLayer({
|
|
|
- tileUrl: base_img_url3 + 'map/lby/[z]/[x]/[y].png',
|
|
|
- zIndex:2
|
|
|
- })
|
|
|
+ tileUrl: base_img_url3 + "map/lby/[z]/[x]/[y].png",
|
|
|
+ zIndex: 2,
|
|
|
+ }),
|
|
|
],
|
|
|
});
|
|
|
|
|
@@ -94,96 +94,188 @@ const initMap = async () => {
|
|
|
|
|
|
// 初始化 MouseTool
|
|
|
mouseTool.value = new AMap.MouseTool(map.value);
|
|
|
-
|
|
|
+
|
|
|
// startRectangleSelection()
|
|
|
|
|
|
// 监听框选完成事件
|
|
|
mouseTool.value.on("draw", (event) => {
|
|
|
- if(mapEventType.value==='click') return
|
|
|
- const { obj} = event;
|
|
|
+ if (mapEventType.value === "click") return;
|
|
|
+ const { obj } = event;
|
|
|
if (obj instanceof AMap.Rectangle) {
|
|
|
selectedArea.value = obj;
|
|
|
map.value.remove(selectedArea.value);
|
|
|
checkPointsInArea(); // 检查框选区域内的点位
|
|
|
}
|
|
|
});
|
|
|
-
|
|
|
});
|
|
|
+ initData(mapData, true);
|
|
|
+ callback && callback();
|
|
|
} catch (error) {
|
|
|
console.error("地图加载失败:", error);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
//重置数据
|
|
|
-const resetData = () =>{
|
|
|
- allPoints.value = defalutAllPoints.value
|
|
|
- allPoints.value.forEach(item =>{
|
|
|
- item.icon.setContent(createMarkerContent(item.color))
|
|
|
- item.icon.setOffset(new window.AMap.Pixel(-7, -7))
|
|
|
- item.type = 'defalutIcon'
|
|
|
- })
|
|
|
-}
|
|
|
+const resetData = () => {
|
|
|
+ allPoints.value = defalutAllPoints.value;
|
|
|
+ allPoints.value.forEach((item) => {
|
|
|
+ item.icon.setContent(createMarkerContent(item.color));
|
|
|
+ // item.icon.setOffset(new window.AMap.Pixel(-7, -7));
|
|
|
+ item.type = "defalutIcon";
|
|
|
+ });
|
|
|
+};
|
|
|
|
|
|
//初始化数据
|
|
|
-const initData = (data) =>{
|
|
|
- allPoints.value = data
|
|
|
- defalutAllPoints.value = []
|
|
|
- totalList.value.forEach(item => map.value.remove(item.icon))
|
|
|
- totalList.value = []
|
|
|
- allPoints.value.forEach(item =>{
|
|
|
- item.icon = new window.AMap.Marker({
|
|
|
- position: item.lnglat,
|
|
|
- map: map.value,
|
|
|
- content: createMarkerContent(item.color),
|
|
|
- offset: new window.AMap.Pixel(-7, -7),
|
|
|
- extData: { id: item.id, priority: item.status > item.noImg > item.wys } // 标记优先级
|
|
|
- });
|
|
|
- item.type = 'defalutIcon'
|
|
|
-
|
|
|
- // 绑定点击事件
|
|
|
- item.icon.on('click', () => {
|
|
|
- mapEventType.value = 'click'
|
|
|
- if(item.type === 'defalutIcon'){
|
|
|
- if (startDraw.value) {
|
|
|
- item.icon.setContent(createMarkerImg());
|
|
|
- item.icon.setOffset(new window.AMap.Pixel(-18, -18))
|
|
|
- item.type = 'activeIcon'
|
|
|
- const arr = pointList.value.filter(ele => ele.id === item.id)
|
|
|
- if(arr.length===0){
|
|
|
- pointList.value.push(item)
|
|
|
- }
|
|
|
- }
|
|
|
- }else{
|
|
|
- item.icon.setContent(createMarkerContent(item.color));
|
|
|
- item.icon.setOffset(new window.AMap.Pixel(-7, -7))
|
|
|
- item.type = 'defalutIcon'
|
|
|
- }
|
|
|
-
|
|
|
- console.log('item', item);
|
|
|
- eventBus.emit("clickMapPoint", item)
|
|
|
- setTimeout(()=>{
|
|
|
- mapEventType.value = 'draw'
|
|
|
- },100)
|
|
|
+const initData = (data) => {
|
|
|
+ allPoints.value = data;
|
|
|
+ defalutAllPoints.value = [];
|
|
|
+ totalList.value.forEach((item) => map.value.remove(item.icon));
|
|
|
+ totalList.value = [];
|
|
|
+ // allPoints.value.forEach(item =>{
|
|
|
+ // item.icon = new window.AMap.Marker({
|
|
|
+ // position: item.lnglat,
|
|
|
+ // map: map.value,
|
|
|
+ // content: createMarkerContent(item.color),
|
|
|
+ // offset: new window.AMap.Pixel(-7, -7),
|
|
|
+ // extData: { id: item.id, priority: item.status > item.noImg > item.wys } // 标记优先级
|
|
|
+ // });
|
|
|
+ // item.type = 'defalutIcon'
|
|
|
+
|
|
|
+ // // 绑定点击事件
|
|
|
+ // item.icon.on('click', () => {
|
|
|
+ // mapEventType.value = 'click'
|
|
|
+ // if(item.type === 'defalutIcon'){
|
|
|
+ // if (startDraw.value) {
|
|
|
+ // item.icon.setContent(createMarkerImg());
|
|
|
+ // item.icon.setOffset(new window.AMap.Pixel(-18, -18))
|
|
|
+ // item.type = 'activeIcon'
|
|
|
+ // const arr = pointList.value.filter(ele => ele.id === item.id)
|
|
|
+ // if(arr.length===0){
|
|
|
+ // pointList.value.push(item)
|
|
|
+ // }
|
|
|
+ // } else {
|
|
|
+ // eventBus.emit("clickMapPoint", item)
|
|
|
+ // }
|
|
|
+ // }else{
|
|
|
+ // item.icon.setContent(createMarkerContent(item.color));
|
|
|
+ // item.icon.setOffset(new window.AMap.Pixel(-7, -7))
|
|
|
+ // item.type = 'defalutIcon'
|
|
|
+ // }
|
|
|
+
|
|
|
+ // setTimeout(()=>{
|
|
|
+ // mapEventType.value = 'draw'
|
|
|
+ // },100)
|
|
|
+ // });
|
|
|
+ // defalutAllPoints.value.push(item)
|
|
|
+ // })
|
|
|
+
|
|
|
+ // 先清除现有的聚合实例
|
|
|
+ if (clusterInstance.value) {
|
|
|
+ clusterInstance.value.setMap(null); // 从地图上移除
|
|
|
+ clusterInstance.value = null; // 释放引用
|
|
|
+ }
|
|
|
+
|
|
|
+ // 初始化点聚合
|
|
|
+ // console.log('data',data);
|
|
|
+ clusterInstance.value = new window.AMap.MarkerCluster(map.value, allPoints.value, {
|
|
|
+ gridSize: 20, // 聚合网格像素大小
|
|
|
+ // maxZoom: 15, // 最大聚合级别
|
|
|
+ renderClusterMarker: _renderClusterMarker, // 自定义聚合样式
|
|
|
+ renderMarker: _renderMarker, // 自定义非聚合点样式
|
|
|
+ });
|
|
|
+
|
|
|
+ // 创建 AMap.Marker 实例数组
|
|
|
+ const markers = allPoints.value.map((item) => {
|
|
|
+ return new window.AMap.Marker({
|
|
|
+ position: item.lnglat
|
|
|
});
|
|
|
- defalutAllPoints.value.push(item)
|
|
|
- })
|
|
|
+ });
|
|
|
+ setTimeout(() => {
|
|
|
+ map.value.setFitView(markers);
|
|
|
+ }, 100);
|
|
|
+};
|
|
|
+
|
|
|
+function updateClusterData(isAll) {
|
|
|
+ let data = []
|
|
|
+ console.log('updateClusterData', isAll);
|
|
|
+ if (isAll) {
|
|
|
+ data = allPoints.value
|
|
|
+ } else {
|
|
|
+ // 筛选待开放点位
|
|
|
+ data = allPoints.value.filter((item) => item.fosterStatus === 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 先清除现有的聚合实例
|
|
|
+ if (clusterInstance.value) {
|
|
|
+ clusterInstance.value.setMap(null); // 从地图上移除
|
|
|
+ clusterInstance.value = null; // 释放引用
|
|
|
+ }
|
|
|
+ // if (markersPoints.value) {
|
|
|
+ // markersPoints.value.map(marker => {
|
|
|
+ // map.value.remove(marker)
|
|
|
+ // })
|
|
|
+ // }
|
|
|
+
|
|
|
// 初始化点聚合
|
|
|
// console.log('data',data);
|
|
|
- // const cluster = new window.AMap.MarkerCluster(map.value, data, {
|
|
|
- // gridSize: 30, // 聚合网格像素大小
|
|
|
- // // maxZoom: 15, // 最大聚合级别
|
|
|
- // // renderClusterMarker: customizeCluster // 自定义聚合样式
|
|
|
- // });
|
|
|
- setTimeout(()=>{
|
|
|
- map.value.setFitView(null, false, [0, 0, 0, 0]);
|
|
|
- },100)
|
|
|
+ clusterInstance = new window.AMap.MarkerCluster(map.value, data, {
|
|
|
+ gridSize: 20, // 聚合网格像素大小
|
|
|
+ // maxZoom: 15, // 最大聚合级别
|
|
|
+ renderClusterMarker: _renderClusterMarker, // 自定义聚合样式
|
|
|
+ renderMarker: _renderMarker, // 自定义非聚合点样式
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
-const startDraw = ref(false)
|
|
|
+let clusterInstance = ref(null); // 存储聚合实例
|
|
|
+let markersPoints = null; // 存储点位实例
|
|
|
+
|
|
|
+// 聚合样式
|
|
|
+const _renderClusterMarker = function (context) {
|
|
|
+ const isActive = context.clusterData[0].activePoint
|
|
|
+ console.log('isActive', isActive);
|
|
|
+ context.marker.setContent(createMarkerContent(context.clusterData[0].color));
|
|
|
+ // context.marker.setOffset(new window.AMap.Pixel(-7, -7));
|
|
|
+
|
|
|
+ context.marker.on("click", function (e) {
|
|
|
+ if (startDraw.value) {
|
|
|
+ context.data[0].activePoint = true;
|
|
|
+ e.target.setContent(createMarkerImg());
|
|
|
+ e.target.setOffset(new window.AMap.Pixel(-19, -44));
|
|
|
+ } else {
|
|
|
+ eventBus.emit("clickMapPoint", context.clusterData[0]);
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+// 单个非聚合样式
|
|
|
+const _renderMarker = function (context) {
|
|
|
+ const isActive = context.data[0].activePoint
|
|
|
+ console.log('aaaaisActive', isActive);
|
|
|
+ if (isActive) {
|
|
|
+ context.marker.setContent(createMarkerImg());
|
|
|
+ } else {
|
|
|
+ context.marker.setContent(createMarkerContent(context.data[0].color));
|
|
|
+ }
|
|
|
+ // context.marker.setOffset(new window.AMap.Pixel(-7, -7));
|
|
|
+
|
|
|
+ context.marker.on("click", function (e) {
|
|
|
+ if (startDraw.value) {
|
|
|
+ context.data[0].activePoint = true;
|
|
|
+ e.target.setContent(createMarkerImg());
|
|
|
+ e.target.setOffset(new window.AMap.Pixel(-19, -42));
|
|
|
+ } else {
|
|
|
+ eventBus.emit("clickMapPoint", context.data[0]);
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+const startDraw = ref(false);
|
|
|
// 开始框选
|
|
|
const startRectangleSelection = () => {
|
|
|
+ // 筛选聚合点位数据
|
|
|
+ updateClusterData();
|
|
|
if (mouseTool.value) {
|
|
|
- startDraw.value = true
|
|
|
+ startDraw.value = true;
|
|
|
mouseTool.value.rectangle({
|
|
|
strokeColor: "#ffffff", // 框选区域边框颜色
|
|
|
strokeOpacity: 1, // 边框透明度
|
|
@@ -195,10 +287,12 @@ const startRectangleSelection = () => {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
- // 停止绘制矩形
|
|
|
+// 停止绘制矩形
|
|
|
const stopDrawRectangle = () => {
|
|
|
mouseTool.value.close(); // 关闭 mouseTool
|
|
|
map.value.setDefaultCursor("default");
|
|
|
+ startDraw.value = false;
|
|
|
+ updateClusterData(true)
|
|
|
};
|
|
|
|
|
|
// 清除框选
|
|
@@ -207,81 +301,130 @@ const clearSelection = () => {
|
|
|
map.value.remove(selectedArea.value); // 移除框选区域
|
|
|
selectedArea.value = null;
|
|
|
}
|
|
|
- resetData()
|
|
|
+ resetData();
|
|
|
selectedPoints.value = []; // 清空选中的点位
|
|
|
};
|
|
|
|
|
|
// 检查框选区域内的点位
|
|
|
const checkPointsInArea = () => {
|
|
|
if (!selectedArea.value) return;
|
|
|
+ console.log('selectedArea.value', selectedArea.value);
|
|
|
const bounds = selectedArea.value.getBounds(); // 获取框选区域的边界
|
|
|
selectedPoints.value = allPoints.value.filter((point) => {
|
|
|
return bounds.contains(point.lnglat); // 判断点位是否在框选区域内
|
|
|
});
|
|
|
-
|
|
|
- selectedPoints.value.forEach(item =>{
|
|
|
- if(item.type==='defalutIcon'){
|
|
|
- item.icon.setContent(createMarkerImg())
|
|
|
- item.icon.setOffset(new window.AMap.Pixel(-18, -18))
|
|
|
- item.type = 'activeIcon'
|
|
|
- }else{
|
|
|
- item.icon.setContent(createMarkerContent(item.color))
|
|
|
- item.icon.setOffset(new window.AMap.Pixel(-7, -7))
|
|
|
- item.type = 'defalutIcon'
|
|
|
+
|
|
|
+ selectedPoints.value.forEach((item) => {
|
|
|
+ if (item.type === "defalutIcon") {
|
|
|
+ item.icon.setContent(createMarkerImg());
|
|
|
+ // item.icon.setOffset(new window.AMap.Pixel(-18, -18));
|
|
|
+ item.type = "activeIcon";
|
|
|
+ } else {
|
|
|
+ item.icon.setContent(createMarkerContent(item.color));
|
|
|
+ // item.icon.setOffset(new window.AMap.Pixel(-7, -7));
|
|
|
+ item.type = "defalutIcon";
|
|
|
}
|
|
|
- })
|
|
|
+ });
|
|
|
};
|
|
|
|
|
|
-const totalList = ref([])
|
|
|
+const totalList = ref([]);
|
|
|
|
|
|
-function getSelectPoint(){
|
|
|
- totalList.value = selectedPoints.value.concat(pointList.value)
|
|
|
- const arr = totalList.value.filter(item =>item.type==='activeIcon')
|
|
|
- return arr
|
|
|
+function getSelectPoint() {
|
|
|
+ totalList.value = selectedPoints.value.concat(pointList.value);
|
|
|
+ const arr = totalList.value.filter((item) => item.type === "activeIcon");
|
|
|
+ return arr;
|
|
|
}
|
|
|
|
|
|
function getRegionList(farmId) {
|
|
|
- VE_API.region.list({farmId}).then(({data}) =>{
|
|
|
- data.map(item => {
|
|
|
- addPolygon(wktToAmapPolygon(item.wkt))
|
|
|
- })
|
|
|
- })
|
|
|
+ // 先清除所有现有多边形
|
|
|
+ clearAllPolygons();
|
|
|
+ VE_API.region.list({ farmId }).then(({ data }) => {
|
|
|
+ data.map((item) => {
|
|
|
+ // 分区区域
|
|
|
+ addPolygon(wktToAmapPolygon(item.wkt));
|
|
|
+
|
|
|
+ // 分区名称
|
|
|
+ new window.AMap.Marker({
|
|
|
+ position: convertPointToArray(item.pointWkt),
|
|
|
+ map: map.value,
|
|
|
+ content: createTextContent(item),
|
|
|
+ zIndex: 99,
|
|
|
+ offset: new window.AMap.Pixel(-80, -10),
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
+let polygons = []; // 存储所有多边形实例的数组
|
|
|
+
|
|
|
function addPolygon(data) {
|
|
|
let polygon = new window.AMap.Polygon({
|
|
|
- path: data,
|
|
|
- fillColor: '#FFE17E',
|
|
|
- strokeOpacity: 1,
|
|
|
- fillOpacity: 0.1,
|
|
|
- strokeColor: 'rgba(255, 255, 255, 0.3)',
|
|
|
- strokeWeight: 1,
|
|
|
- strokeStyle: 'solid',
|
|
|
- // strokeDasharray: [5, 5],
|
|
|
+ path: data,
|
|
|
+ fillColor: "#FFE17E",
|
|
|
+ strokeOpacity: 1,
|
|
|
+ fillOpacity: 0.1,
|
|
|
+ strokeColor: "rgba(255, 255, 255, 0.3)",
|
|
|
+ strokeWeight: 1,
|
|
|
+ strokeStyle: "solid",
|
|
|
+ // strokeDasharray: [5, 5],
|
|
|
});
|
|
|
- map.value.add(polygon)
|
|
|
+ map.value.add(polygon);
|
|
|
+ polygons.push(polygon);
|
|
|
}
|
|
|
|
|
|
-defineExpose({getSelectPoint,initData,startRectangleSelection,stopDrawRectangle,clearSelection, getRegionList})
|
|
|
+// 清除所有多边形函数
|
|
|
+function clearAllPolygons() {
|
|
|
+ if (polygons.length > 0) {
|
|
|
+ polygons.forEach((polygon) => {
|
|
|
+ map.value.remove(polygon);
|
|
|
+ });
|
|
|
+ polygons = []; // 清空数组
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 分区名称
|
|
|
+function createTextContent(item) {
|
|
|
+ console.log("item", item);
|
|
|
+ return `
|
|
|
+ <div class="area-name">
|
|
|
+ ${item.name}
|
|
|
+ <div class="area-count" style="display: ${item.pointCount ? "block" : "none"}">
|
|
|
+ ${item.pointCount}/${item.pointCount}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ `;
|
|
|
+}
|
|
|
+
|
|
|
+defineExpose({
|
|
|
+ getSelectPoint,
|
|
|
+ initData,
|
|
|
+ initMap,
|
|
|
+ startRectangleSelection,
|
|
|
+ stopDrawRectangle,
|
|
|
+ clearSelection,
|
|
|
+ getRegionList,
|
|
|
+});
|
|
|
|
|
|
// 组件挂载时初始化地图
|
|
|
onMounted(() => {
|
|
|
- initMap()
|
|
|
+ // nextTick(() => {
|
|
|
+ // initMap();
|
|
|
+ // })
|
|
|
});
|
|
|
|
|
|
-onUnmounted(()=>{
|
|
|
- map.value.destroy()// 销毁地图实例以释放资源
|
|
|
-})
|
|
|
+onUnmounted(() => {
|
|
|
+ map.value.destroy(); // 销毁地图实例以释放资源
|
|
|
+});
|
|
|
|
|
|
function wktToAmapPolygon(wkt) {
|
|
|
const geoJSON = wellknown.parse(wkt);
|
|
|
- if (!geoJSON || geoJSON.type !== 'MultiPolygon') {
|
|
|
- console.error('Invalid WKT or not a MULTIPOLYGON');
|
|
|
+ if (!geoJSON || geoJSON.type !== "MultiPolygon") {
|
|
|
+ console.error("Invalid WKT or not a MULTIPOLYGON");
|
|
|
return [];
|
|
|
}
|
|
|
|
|
|
// MULTIPOLYGON 的坐标结构:[[[ [环1], [环2], ... ]]],取第一个环
|
|
|
- return geoJSON.coordinates[0][0].map(coord => [coord[0], coord[1]]);
|
|
|
+ return geoJSON.coordinates[0][0].map((coord) => [coord[0], coord[1]]);
|
|
|
}
|
|
|
</script>
|
|
|
|
|
@@ -291,3 +434,29 @@ function wktToAmapPolygon(wkt) {
|
|
|
height: 100%;
|
|
|
}
|
|
|
</style>
|
|
|
+
|
|
|
+<style lang="less">
|
|
|
+.area-name {
|
|
|
+ width: 155px;
|
|
|
+ height: 40px;
|
|
|
+ line-height: 40px;
|
|
|
+ font-size: 30px;
|
|
|
+ color: #fff;
|
|
|
+ font-family: "PangMenZhengDao";
|
|
|
+ text-align: center;
|
|
|
+ position: relative;
|
|
|
+ background: linear-gradient(90deg, rgba(0, 0, 0, 0.1) 20%, rgba(0, 0, 0, 0.5) 50%, rgba(0, 0, 0, 0.1) 100%);
|
|
|
+}
|
|
|
+.area-count {
|
|
|
+ position: absolute;
|
|
|
+ font-family: "PangMenZhengDao";
|
|
|
+ left: calc(100% - 48px);
|
|
|
+ top: -22px;
|
|
|
+ font-size: 16px;
|
|
|
+ padding: 0px 12px;
|
|
|
+ height: 32px;
|
|
|
+ line-height: 32px;
|
|
|
+ border-radius: 40px;
|
|
|
+ background: linear-gradient(162deg, #ffcf80, #d18100);
|
|
|
+}
|
|
|
+</style>
|