|
@@ -1,462 +1,275 @@
|
|
|
<template>
|
|
|
- <div id="map-container"></div>
|
|
|
+ <div>
|
|
|
+ <div id="map" ref="areaRef" class="area-map"></div>
|
|
|
+ </div>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-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";
|
|
|
-
|
|
|
-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 mapEventType = ref("rectangle");
|
|
|
-
|
|
|
-// 自定义圆点样式
|
|
|
-const createMarkerContent = (color = "rgba(0, 0, 0, 0.4)") => {
|
|
|
- return `
|
|
|
- <div style="
|
|
|
- width: 15px;
|
|
|
- height: 15px;
|
|
|
- background-color: ${color};
|
|
|
- border: 1px solid #fff;
|
|
|
- border-radius: 50%;
|
|
|
- ">
|
|
|
- </div>
|
|
|
- `;
|
|
|
-};
|
|
|
-
|
|
|
-//高亮样式
|
|
|
-const createMarkerImg = () => {
|
|
|
- return `
|
|
|
- <img style="width: 38px;height: 38px;" src="${require("@/assets/images/map/status/active-icon.png")}">
|
|
|
- `;
|
|
|
-};
|
|
|
-// 初始化地图
|
|
|
-const initMap = async (mapData, callback) => {
|
|
|
- try {
|
|
|
- const AMap = await AMapLoader.load({
|
|
|
- key: "41769169f0f157e13a197e7eb0dd7b5b", // 替换为你的高德地图 Key
|
|
|
- version: "2.0", // SDK 版本
|
|
|
- plugins: ["AMap.MouseTool", "AMap.MarkerCluster"], // 加载 MouseTool 插件
|
|
|
- }).then(async (AMap) => {
|
|
|
- // 创建地图实例
|
|
|
- map.value = new AMap.Map("map-container", {
|
|
|
- zoom: 18, // 初始缩放级别
|
|
|
- center: [111.01055729572, 21.7743543],
|
|
|
- layers: [
|
|
|
- // 天地图卫星
|
|
|
- new AMap.TileLayer({
|
|
|
- tileSize: 256, // 瓦片大小
|
|
|
- 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`
|
|
|
- return `https://t${s}.tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX=${z}&TILEROW=${y}&TILECOL=${x}&tk=e95115c454a663cd052d96019fd83840`;
|
|
|
- },
|
|
|
- }),
|
|
|
- //天地图路网
|
|
|
- new AMap.TileLayer({
|
|
|
- tileSize: 256, // 瓦片大小
|
|
|
- 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`;
|
|
|
- },
|
|
|
- }),
|
|
|
- //正射影像
|
|
|
- new AMap.TileLayer({
|
|
|
- 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,
|
|
|
- }),
|
|
|
- ],
|
|
|
- });
|
|
|
-
|
|
|
- // // 初始化点聚合
|
|
|
- // const cluster = new AMap.MarkerCluster(map, markers, {
|
|
|
- // gridSize: 60, // 聚合网格像素大小
|
|
|
- // maxZoom: 15, // 最大聚合级别
|
|
|
- // renderClusterMarker: customizeCluster // 自定义聚合样式
|
|
|
- // });
|
|
|
-
|
|
|
- // 初始化 MouseTool
|
|
|
- mouseTool.value = new AMap.MouseTool(map.value);
|
|
|
-
|
|
|
- // startRectangleSelection()
|
|
|
-
|
|
|
- // 监听框选完成事件
|
|
|
- mouseTool.value.on("draw", (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 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, // 自定义非聚合点样式
|
|
|
+import * as KMap from "@/utils/ol-map/KMap";
|
|
|
+import * as util from "@/common/ol_common.js";
|
|
|
+import "ol/ol.css";
|
|
|
+import Map from "ol/Map";
|
|
|
+import View from "ol/View";
|
|
|
+import TileLayer from "ol/layer/Tile";
|
|
|
+import OSM from "ol/source/OSM";
|
|
|
+import VectorLayer from "ol/layer/Vector";
|
|
|
+// import VectorSource from "ol/source/Vector";
|
|
|
+import Feature from "ol/Feature";
|
|
|
+import Point from "ol/geom/Point";
|
|
|
+import Icon from "ol/style/Icon";
|
|
|
+import { fromLonLat } from "ol/proj";
|
|
|
+import DragBox from "ol/interaction/DragBox";
|
|
|
+import { platformModifierKeyOnly } from "ol/events/condition";
|
|
|
+import { newPoint } from "@/utils/map.js";
|
|
|
+import { Circle, Fill, Stroke, Style, Text } from "ol/style.js";
|
|
|
+import { Cluster, Vector as VectorSource } from "ol/source.js";
|
|
|
+import { boundingExtent } from "ol/extent.js";
|
|
|
+
|
|
|
+import { onMounted, ref } from "vue";
|
|
|
+import { useStore } from "vuex";
|
|
|
+import { unByKey } from "ol/Observable";
|
|
|
+let store = useStore();
|
|
|
+
|
|
|
+// 选中样式(高亮)
|
|
|
+// const selectedStyle = new Style({
|
|
|
+// image: new Icon({
|
|
|
+// src: require("@/assets/images/map/status/active-icon.png"),
|
|
|
+// scale: 0.6,
|
|
|
+// }),
|
|
|
+// });
|
|
|
+
|
|
|
+let kmap = null;
|
|
|
+const areaRef = ref(null);
|
|
|
+let dragBox;
|
|
|
+
|
|
|
+const isDrawing = ref(false);
|
|
|
+const enableBoxSelect = () => {
|
|
|
+ const data = mapPoint.value.filter((item) => item.fosterStatus === 0);
|
|
|
+ addCluster(data, 1);
|
|
|
+ isDrawing.value = true;
|
|
|
+ dragBox = new DragBox({
|
|
|
+ condition: platformModifierKeyOnly, // 按住 Ctrl 才可框选(可去掉)
|
|
|
});
|
|
|
|
|
|
- // 创建 AMap.Marker 实例数组
|
|
|
- const markers = allPoints.value.map((item) => {
|
|
|
- return new window.AMap.Marker({
|
|
|
- position: item.lnglat
|
|
|
+ // 添加键盘事件监听
|
|
|
+ window.addEventListener("keydown", handleKeyDown);
|
|
|
+ window.addEventListener("keyup", handleKeyUp);
|
|
|
+
|
|
|
+ kmap.map.addInteraction(dragBox);
|
|
|
+ // areaRef.value.style.cursor = 'crosshair';
|
|
|
+ dragBox.on("boxend", () => {
|
|
|
+ const extent = dragBox.getGeometry().getExtent();
|
|
|
+
|
|
|
+ treeClusterLayer.layer.getSource().getSource().getFeatures().forEach((feature) => {
|
|
|
+ const isInside = feature.getGeometry().intersectsExtent(extent);
|
|
|
+ if (isInside) {
|
|
|
+ // feature.setStyle(selectedStyle);
|
|
|
+ feature.set("highlight", true);
|
|
|
+ }
|
|
|
});
|
|
|
});
|
|
|
- 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; // 释放引用
|
|
|
+const handleKeyDown = (e) => {
|
|
|
+ if (e.ctrlKey) {
|
|
|
+ areaRef.value.style.cursor = "crosshair";
|
|
|
}
|
|
|
- // if (markersPoints.value) {
|
|
|
- // markersPoints.value.map(marker => {
|
|
|
- // map.value.remove(marker)
|
|
|
- // })
|
|
|
- // }
|
|
|
-
|
|
|
- // 初始化点聚合
|
|
|
- // console.log('data',data);
|
|
|
- clusterInstance = new window.AMap.MarkerCluster(map.value, data, {
|
|
|
- gridSize: 20, // 聚合网格像素大小
|
|
|
- // maxZoom: 15, // 最大聚合级别
|
|
|
- renderClusterMarker: _renderClusterMarker, // 自定义聚合样式
|
|
|
- renderMarker: _renderMarker, // 自定义非聚合点样式
|
|
|
- });
|
|
|
-}
|
|
|
-
|
|
|
-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));
|
|
|
+const handleKeyUp = (e) => {
|
|
|
+ if (!e.ctrlKey) {
|
|
|
+ areaRef.value.style.cursor = "";
|
|
|
}
|
|
|
- // 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;
|
|
|
- mouseTool.value.rectangle({
|
|
|
- strokeColor: "#ffffff", // 框选区域边框颜色
|
|
|
- strokeOpacity: 1, // 边框透明度
|
|
|
- strokeWeight: 2, // 边框宽度
|
|
|
- fillColor: "#000000", // 填充颜色
|
|
|
- fillOpacity: 0.5, // 填充透明度
|
|
|
- }); // 启用矩形框选工具
|
|
|
- map.value.setDefaultCursor("crosshair");
|
|
|
- }
|
|
|
+const stopBoxSelect = () => {
|
|
|
+ addCluster(mapPoint.value);
|
|
|
+ kmap.map.removeInteraction(dragBox);
|
|
|
+ // 移除事件监听
|
|
|
+ window.removeEventListener("keydown", handleKeyDown);
|
|
|
+ window.removeEventListener("keyup", handleKeyUp);
|
|
|
};
|
|
|
|
|
|
-// 停止绘制矩形
|
|
|
-const stopDrawRectangle = () => {
|
|
|
- mouseTool.value.close(); // 关闭 mouseTool
|
|
|
- map.value.setDefaultCursor("default");
|
|
|
- startDraw.value = false;
|
|
|
- updateClusterData(true)
|
|
|
-};
|
|
|
+let treeClusterLayer;
|
|
|
+onMounted(() => {
|
|
|
+ let level = 16;
|
|
|
+ let coordinate = util.wktCastGeom(store.getters.userinfo.location).getFirstCoordinate();
|
|
|
+ kmap = new KMap.Map(areaRef.value, level, coordinate[0], coordinate[1], null, 1, 22, "img", true, true);
|
|
|
|
|
|
-// 清除框选
|
|
|
-const clearSelection = () => {
|
|
|
- if (selectedArea.value) {
|
|
|
- map.value.remove(selectedArea.value); // 移除框选区域
|
|
|
- selectedArea.value = null;
|
|
|
+});
|
|
|
+let styleCache = {};
|
|
|
+let listenKey;
|
|
|
+const mapPoint = ref([]);
|
|
|
+let clusterSource;
|
|
|
+// --------聚合-----------
|
|
|
+function addCluster(treeListData, distanceVal) {
|
|
|
+ if (!distanceVal) {
|
|
|
+ mapPoint.value = treeListData;
|
|
|
}
|
|
|
- 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); // 判断点位是否在框选区域内
|
|
|
+ clearCluster();
|
|
|
+ let that = this;
|
|
|
+ let features = [];
|
|
|
+ // 根据状态加上对应的图标
|
|
|
+ for (let item of treeListData) {
|
|
|
+ let point = newPoint(item);
|
|
|
+ features.push(point);
|
|
|
+ }
|
|
|
+ const source = new VectorSource({
|
|
|
+ features: features,
|
|
|
});
|
|
|
|
|
|
- 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";
|
|
|
- }
|
|
|
+ clusterSource = new Cluster({
|
|
|
+ distance: distanceVal ? distanceVal : 20, // 集合范围
|
|
|
+ // minDistance: 60,
|
|
|
+ source: source,
|
|
|
});
|
|
|
-};
|
|
|
-
|
|
|
-const totalList = ref([]);
|
|
|
-
|
|
|
-function getSelectPoint() {
|
|
|
- totalList.value = selectedPoints.value.concat(pointList.value);
|
|
|
- const arr = totalList.value.filter((item) => item.type === "activeIcon");
|
|
|
- return arr;
|
|
|
-}
|
|
|
-
|
|
|
-function getRegionList(farmId) {
|
|
|
- // 先清除所有现有多边形
|
|
|
- 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),
|
|
|
- });
|
|
|
- });
|
|
|
+ treeClusterLayer = new KMap.VectorLayer("forest-cluster", 1000, {
|
|
|
+ minZoom: 15,
|
|
|
+ source: clusterSource,
|
|
|
+ style: (feature) => {
|
|
|
+ const size = feature.get("features").length;
|
|
|
+ let testStyle;
|
|
|
+ // 只有一个数据,不需要聚合,直接使用第一项数据的图标
|
|
|
+ if (size == 1) {
|
|
|
+ let featureOne = feature.get("features")[0];
|
|
|
+ const key = featureOne.get('fosterStatus')+"status"
|
|
|
+ // let style = styleCache[key];
|
|
|
+ let style = false;
|
|
|
+ if (!style) {
|
|
|
+ const highlight = featureOne.get("highlight");
|
|
|
+ if (highlight) {
|
|
|
+ style = new Style({
|
|
|
+ image: new Icon({
|
|
|
+ src: require("@/assets/images/map/status/active-icon.png"),
|
|
|
+ scale: 0.6,
|
|
|
+ }),
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ style = new Style({
|
|
|
+ image: new Circle({
|
|
|
+ radius: featureOne.get("fosterStatus") === 0 || !featureOne.get("fosterStatus") ? 10 : 12,
|
|
|
+ fill: new Fill({
|
|
|
+ color:
|
|
|
+ featureOne.get("fosterStatus") === 0
|
|
|
+ ? "#ffffff00"
|
|
|
+ : featureOne.get("fosterStatus") === 1
|
|
|
+ ? "#EEEEEE"
|
|
|
+ : featureOne.get("fosterStatus") === 2
|
|
|
+ ? "#F0AC37"
|
|
|
+ : "#ffffff00",
|
|
|
+ }),
|
|
|
+ stroke: new Stroke({
|
|
|
+ color: "#fff",
|
|
|
+ width: 1,
|
|
|
+ }),
|
|
|
+ }),
|
|
|
+ });
|
|
|
+ }
|
|
|
+ // styleCache[key] = style;
|
|
|
+ }
|
|
|
+ return style;
|
|
|
+ }
|
|
|
+ // 多个点位聚合,循环处理得到图标
|
|
|
+ const featureObj = feature.get("features")[0];
|
|
|
+ // let pointId = featureObj.get('fosterStatus')
|
|
|
+ // let style = styleCache[pointId];
|
|
|
+ let style = false;
|
|
|
+ if (!style) {
|
|
|
+ testStyle = new Style({
|
|
|
+ text: new Text({
|
|
|
+ text: size + "",
|
|
|
+ offsetX: 0,
|
|
|
+ offsetY: 0,
|
|
|
+ font: "bold 10px sans-serif",
|
|
|
+ fill: new Fill({ color: featureObj.get("fosterStatus") === 1 ? "#000" : "#fff" }), // 字体颜色
|
|
|
+ // stroke: new Stroke({ color: "green" }), // 字体颜色
|
|
|
+ }),
|
|
|
+ zIndex: 3,
|
|
|
+ });
|
|
|
+
|
|
|
+ const highlight = featureObj.get("highlight");
|
|
|
+ if (highlight) {
|
|
|
+ style = new Style({
|
|
|
+ image: new Icon({
|
|
|
+ src: require("@/assets/images/map/status/active-icon.png"),
|
|
|
+ scale: 0.6,
|
|
|
+ }),
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ style = new Style({
|
|
|
+ image: new Circle({
|
|
|
+ radius: featureObj.get("fosterStatus") === 0 || !featureObj.get("fosterStatus") ? 10 : 12,
|
|
|
+ fill: new Fill({
|
|
|
+ color:
|
|
|
+ featureObj.get("fosterStatus") === 0
|
|
|
+ ? "#ffffff00"
|
|
|
+ : featureObj.get("fosterStatus") === 1
|
|
|
+ ? "#EEEEEE"
|
|
|
+ : featureObj.get("fosterStatus") === 2
|
|
|
+ ? "#F0AC37"
|
|
|
+ : "#ffffff00",
|
|
|
+ }),
|
|
|
+ stroke: new Stroke({
|
|
|
+ color: "#fff",
|
|
|
+ width: 1,
|
|
|
+ }),
|
|
|
+ }),
|
|
|
+ });
|
|
|
+ }
|
|
|
+ // styleCache[pointId] = style;
|
|
|
+ }
|
|
|
+ return [style, testStyle];
|
|
|
+ },
|
|
|
});
|
|
|
-}
|
|
|
|
|
|
-let polygons = []; // 存储所有多边形实例的数组
|
|
|
+ kmap.addLayer(treeClusterLayer.layer);
|
|
|
|
|
|
-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],
|
|
|
+ if(!distanceVal) {
|
|
|
+ zoomToFeatures(features)
|
|
|
+ }
|
|
|
+ // kmap.getView().fit(this.treeClusterLayer.layer.getSource().getSource().getExtent(), { duration: 1000, padding: [120, 120, 200, 120] });
|
|
|
+ // 监听聚合点位的点击,点击后缩放到范围内
|
|
|
+ listenKey = kmap.on("click", (e) => {
|
|
|
+ if (treeClusterLayer) {
|
|
|
+ treeClusterLayer.layer.getFeatures(e.pixel).then((clickedFeatures, layer) => {
|
|
|
+ if (clickedFeatures.length) {
|
|
|
+ const features = clickedFeatures[0].get("features");
|
|
|
+ if (features.length > 1) {
|
|
|
+ const extent = boundingExtent(features.map((r) => r.getGeometry().getCoordinates()));
|
|
|
+ kmap.getView().fit(extent, { duration: 1000, padding: [250, 250, 250, 250] });
|
|
|
+ }
|
|
|
+ if (isDrawing.value) {
|
|
|
+ features[0].set("highlight", true);
|
|
|
+ // features[0].setStyle(selectedStyle)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
});
|
|
|
- map.value.add(polygon);
|
|
|
- polygons.push(polygon);
|
|
|
}
|
|
|
|
|
|
-// 清除所有多边形函数
|
|
|
-function clearAllPolygons() {
|
|
|
- if (polygons.length > 0) {
|
|
|
- polygons.forEach((polygon) => {
|
|
|
- map.value.remove(polygon);
|
|
|
- });
|
|
|
- polygons = []; // 清空数组
|
|
|
+// 清除聚合图层,解除绑定
|
|
|
+function clearCluster() {
|
|
|
+ if (treeClusterLayer) {
|
|
|
+ treeClusterLayer.layer.getSource().getSource().clear();
|
|
|
+ treeClusterLayer.layer.getSource().clear();
|
|
|
+ treeClusterLayer = null;
|
|
|
+ unByKey(listenKey);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// 分区名称
|
|
|
-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>
|
|
|
- `;
|
|
|
+function zoomToFeatures(features) {
|
|
|
+ const extent = boundingExtent(features.map((r) => r.getGeometry().getCoordinates()));
|
|
|
+ kmap.getView().fit(extent, { duration: 500, padding: [200, 250, 120, 250] });
|
|
|
}
|
|
|
|
|
|
-defineExpose({
|
|
|
- getSelectPoint,
|
|
|
- initData,
|
|
|
- initMap,
|
|
|
- startRectangleSelection,
|
|
|
- stopDrawRectangle,
|
|
|
- clearSelection,
|
|
|
- getRegionList,
|
|
|
-});
|
|
|
-
|
|
|
-// 组件挂载时初始化地图
|
|
|
-onMounted(() => {
|
|
|
- // nextTick(() => {
|
|
|
- // initMap();
|
|
|
- // })
|
|
|
-});
|
|
|
-
|
|
|
-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");
|
|
|
- return [];
|
|
|
- }
|
|
|
-
|
|
|
- // MULTIPOLYGON 的坐标结构:[[[ [环1], [环2], ... ]]],取第一个环
|
|
|
- return geoJSON.coordinates[0][0].map((coord) => [coord[0], coord[1]]);
|
|
|
-}
|
|
|
+defineExpose({ addCluster, enableBoxSelect, stopBoxSelect });
|
|
|
</script>
|
|
|
|
|
|
-<style scoped>
|
|
|
-#map-container {
|
|
|
+<style lang="less" scoped>
|
|
|
+.area-map {
|
|
|
width: 100%;
|
|
|
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>
|