openlayers点位聚合+overlay弹窗

目录

1、效果图

2、点位聚合核心代码

3、overlayer弹窗核心代码

4、完整代码

1、效果图

2、点位聚合核心代码

      let features = []
      points.forEach(point => {
        let ele = new Feature({
          geometry: new Point(fromLonLat([point.center.lng, point.center.lat])),
          name: point.name,
          value: point.value
        })
        features.push(ele)
      })
      const clusterLayer = new VectorLayer({
        source: new Cluster({
          distance: 35, //设置聚合的范围
          source: new VectorSource({
            features: features
          })
        })
      })
      this.map.addLayer(clusterLayer);

3、overlayer弹窗核心代码

      let container = document.getElementById("overlay-popup");

      this.overlay = new Overlay({
        position: fromLonLat([113.304788, 28.013391]),
        offset: [20, -20],
        autoPan: true, // 定义弹出窗口在边缘点击时候可能不完整 设置自动平移效果
        element: document.getElementById("overlay-popup"),
        stopEvent: true, //地图的事件传播是否停止,默认是 true;单击OverlayPopup可以查看效果
      });
      this.map.addOverlay(this.overlay);

4、完整代码

<!--世界地图 - overlay标注 - 点位聚合-->
<script>
import { ref } from 'vue'
import {Map, Overlay, View} from 'ol';
import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer";
import Feature from "ol/Feature";
import { OSM, Vector as VectorSource, XYZ, Cluster } from "ol/source";
import { defaults as DefaultsControl } from "ol/control"
import { fromLonLat, transform } from "ol/proj";
import { MultiPolygon, Polygon, Point } from "ol/geom"
import { Fill, Stroke, Style, Text } from "ol/style";
import {defaults as DefaultsInteraction} from "ol/interaction/defaults.js";
import {DragRotateAndZoom} from "ol/interaction.js";
import {FullScreen, MousePosition} from "ol/control.js";
import {Circle} from "ol/style.js";
export default {
  name: 'tree',
  data () {
    return {
      map: null,
      count: ref(0),
      overlay: null
    }
  },
  components: {},
  methods: {
    initMap () {
      this.map = new Map({
        view: new View({
          center: transform([113.304788, 28.013391], "EPSG:4326", "EPSG:3857"), //两个投影之间进行坐标转换
          // center: fromLonLat([112.93, 28.23], "EPSG:3857"), //地图中心坐标
          zoom: 5, //缩放级别
          // rotation: Math.PI / 2
        }),
        layers: [
          new TileLayer({
            title: 'worldLayer',
            source: new XYZ({
              url: 'https://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}'
              // url: 'http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}'
            }),
          })
        ],
        target: 'map', //对应绑定地图div的id标签 - map
        interactions: DefaultsInteraction({
          doubleClickZoom: false, //是否鼠标或手指双击缩放地图
          altShiftDragRotate: false // alt + Shift + 鼠标旋转地图
        }).extend([
          new DragRotateAndZoom() // shift + 鼠标拖拽进行缩放和旋转地图
        ]),
        controls: DefaultsControl({
          zoom: false,
          rotate: false
        }).extend([
          new FullScreen(),
          new MousePosition({
            //地图投影坐标系(若未设置则输出为默认投影坐标系下的坐标)
            projection: "EPSG:4326",
            //显示鼠标位置信息的目标容器
            target: document.getElementById("mouse-position")
          }),
        ])
      });
    },
    addOverlayPopup () {

      let container = document.getElementById("overlay-popup");

      this.overlay = new Overlay({
        // position: fromLonLat([113.304788, 28.013391]),
        // offset: [20, -20],
        autoPan: true, // 定义弹出窗口在边缘点击时候可能不完整 设置自动平移效果
        element: document.getElementById("overlay-popup"),
        stopEvent: true, //地图的事件传播是否停止,默认是 true;单击OverlayPopup可以查看效果
      });
      this.map.addOverlay(this.overlay);

      let _that = this
      // 设置双击弹窗隐藏
      container.onclick = function () {
        _that.overlay.setPosition(undefined)
        return false
      }

      this.map.on("click", function (event) {
        let coordinate = transform(event.coordinate, "EPSG:3857", "EPSG:4326");
        container.innerHTML = `<span>坐标:</span><br/><span>${coordinate[0]}</span><br/><span>${coordinate[1]}</span>`
        _that.overlay.setPosition(event.coordinate)
      })
    },
    initClusterData () {
      let points = [
        { name: "邵阳", value: 85, center: { lng: 111.46660755304138, lat: 27.255154768748213 } },
        { name: "长沙", value: 36, center: { lng: 112.98859969921804, lat: 28.212126824260267 } },
        { name: "吉安", value: 50, center: { lng: 114.98465497289236, lat: 27.12199185188713 } },
        { name: "郴州", value: 555, center: { lng: 112.98859969921804, lat: 25.796699988931664 } },
        { name: "张家界", value: 55, center: { lng: 110.42449496603331, lat: 29.123432208161148 } },
        { name: "南昌", value: 666, center: { lng: 115.85214830478819, lat: 28.691041267421284 } },
        { name: "铜仁", value: 777, center: { lng: 109.22741646913224, lat: 27.73925470951059 } }
      ];
      this.addCluster(points);
    },
    addCluster (points) {
      let features = []
      points.forEach(point => {
        let ele = new Feature({
          geometry: new Point(fromLonLat([point.center.lng, point.center.lat])),
          name: point.name,
          value: point.value
        })
        features.push(ele)
      })
      const clusterLayer = new VectorLayer({
        source: new Cluster({
          distance: 35, //设置聚合的范围
          source: new VectorSource({
            features: features
          })
        }),
        style: (feature) => {
          let total = 0
          feature.get('features').forEach((item) => {
            total += item.get("value")
          })
          return new Style({
            image: new Circle({
              radius: 15,
              stroke: new Stroke({
                color: "blue"
              }),
              fill: new Fill({
                color: "rgba(24,144,255,100)"
              })
            }),
            text: new Text({
              text: total.toString(),
              fill: new Fill({
                color: "#FFF"
              }),
              stroke: new Stroke({
                color: "red",
                width: 5
              })
            })
          })
        }
      })
      this.map.addLayer(clusterLayer);
    }
  },
  mounted() {
    this.initMap()
    this.addOverlayPopup()
    this.initClusterData()
  }
}
</script>

<template>
  <div class="content">
    <!--  绑定map地图  -->
    <div id="map" ref="map"></div>
    <div id="mouse-position" class="mousePosition"></div>
    <div id="overlay-popup" class="overlay-popup"></div>
  </div>
</template>

<style scoped>
.content{
  width: 100%;
  height: 100%;
  #map {
    width: calc(100vw);
    height: calc(100vh);
  }
  .mousePosition{
    width: 350px;
    position: absolute;
    top: 10px;
    color: #000;
  }
  .overlay-popup{
    position: absolute;
    background-color: white;
    padding: 15px;
    border-radius: 10px;
    bottom: 12px;
    left: -50px;
    text-align: left;
  }
  .overlay-popup:before {
    position: absolute;
    top: 100%;
    border: 10px solid transparent;
    border-top-color: #ffffff;
    content: " ";
    left: 38px;
  }
  button {
    font-weight: bold;
  }
}
</style>

参考:

openlayers6【二十】vue Cluster类实现聚合标注效果_vue+openlayers点聚合自定义样式-CSDN博客

openlayers6【十一】vue 使用overlay实现弹窗框popup效果_vue overlay-CSDN博客

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值