目录
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博客