123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- <template>
- <div>
- <div id="map" ref="areaRef" class="area-map"></div>
- </div>
- </template>
- <script setup>
- 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 RegionLayer from "./map/regionLayer";
- import eventBus from "@/api/eventBus";
- 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 才可框选(可去掉)
- });
- // 添加键盘事件监听
- 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);
- }
- });
- });
- };
- const handleKeyDown = (e) => {
- if (e.ctrlKey) {
- areaRef.value.style.cursor = "crosshair";
- }
- };
- const handleKeyUp = (e) => {
- if (!e.ctrlKey) {
- areaRef.value.style.cursor = "";
- }
- };
- const stopBoxSelect = () => {
- addCluster(mapPoint.value);
- kmap.map.removeInteraction(dragBox);
- // 移除事件监听
- window.removeEventListener("keydown", handleKeyDown);
- window.removeEventListener("keyup", handleKeyUp);
- };
- 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);
- regionLayer = new RegionLayer(kmap);
- });
- let styleCache = {};
- let listenKey;
- const mapPoint = ref([]);
- let clusterSource;
- // --------聚合-----------
- function addCluster(treeListData, distanceVal) {
- if (!distanceVal) {
- mapPoint.value = treeListData;
- }
- clearCluster();
- let that = this;
- let features = [];
- // 根据状态加上对应的图标
- for (let item of treeListData) {
- let point = newPoint(item);
- features.push(point);
- console.log('item', item.icon, item);
- }
- const source = new VectorSource({
- features: features,
- });
- clusterSource = new Cluster({
- distance: distanceVal ? distanceVal : 20, // 集合范围
- // minDistance: 60,
- source: source,
- });
- 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;
- }
- const imgIcon = featureOne.get('icon')
- console.log('imgIcon', imgIcon);
- if (imgIcon) {
- style = new Style({
- image: new Icon({
- src: require("@/assets/images/map/owner1.png"),
- scale: 1,
- }),
- });
- }
- return style;
- }
- // 多个点位聚合,循环处理得到图标
- const featureObj = feature.get("features")[0];
- // let pointId = featureObj.get('fosterStatus')
- // let style = styleCache[pointId];
- const imgIcon = featureObj.get('icon')
- console.log('imgIcon22222', imgIcon);
- 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 {
- // 已认养--显示图标
- if (imgIcon) {
- style = new Style({
- image: new Icon({
- src: require("@/assets/images/map/owner1.png"),
- scale: 1,
- }),
- zIndex: 22,
- });
- } 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];
- },
- });
- kmap.addLayer(treeClusterLayer.layer);
- 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) => {
- let hasFeatures = false
- if (clickedFeatures.length) {
- const features = clickedFeatures[0].get("features");
- if (features.length > 1) {
- hasFeatures = true
- const extent = boundingExtent(features.map((r) => r.getGeometry().getCoordinates()));
- kmap.getView().fit(extent, { duration: 1000, padding: [250, 250, 250, 250] });
- const currentZoom = kmap.getView().getZoom();
- if (currentZoom > 17) {
- // this.kmap.getView().setZoom(16);
- // kmap.getView().animate({
- // zoom: 14,
- // duration: 0 // 动画持续时间,单位为毫秒
- // });
- kmap.getView().setZoom(17)
- }
- }
- if (isDrawing.value) {
- features[0].set("highlight", true);
- // features[0].setStyle(selectedStyle)
- } else if (!hasFeatures) {
- eventBus.emit("clickMapPoint", features[0])
- }
- }
- });
- }
- });
- }
- // 清除聚合图层,解除绑定
- function clearCluster() {
- if (treeClusterLayer) {
- treeClusterLayer.layer.getSource().getSource().clear();
- treeClusterLayer.layer.getSource().clear();
- treeClusterLayer = null;
- unByKey(listenKey);
- }
- }
- function zoomToFeatures(features) {
- const extent = boundingExtent(features.map((r) => r.getGeometry().getCoordinates()));
- kmap.getView().fit(extent, { duration: 500, padding: [200, 250, 120, 250] });
- }
- defineExpose({ addCluster, enableBoxSelect, stopBoxSelect, initAreaMap });
- // 分区
- let regionLayer = null;
- function initAreaMap(arr) {
- regionLayer.initData(arr);
- }
- </script>
- <style lang="less" scoped>
- .area-map {
- width: 100%;
- height: 100%;
- }
- </style>
|