本篇介绍一下使用vue3-openlayers 要素聚合(cluster),icon聚合
1 需求
- 要素聚合(cluster),icon聚合
2 分析
使用ol-source-cluster
4 实现
<template>
<ol-map
:loadTilesWhileAnimating="true"
:loadTilesWhileInteracting="true"
style="width: 100%; height: 100%"
ref="mapRef"
>
<ol-view ref="view" :center="center" :zoom="zoom" :projection="projection" />
<ol-tile-layer>
<ol-source-tianditu
layerType="img"
:projection="projection"
:tk="key"
:hidpi="true"
ref="sourceRef"
></ol-source-tianditu>
</ol-tile-layer>
<ol-tile-layer>
<ol-source-tianditu
:isLabel="true"
layerType="img"
:projection="projection"
:tk="key"
:hidpi="true"
></ol-source-tianditu>
</ol-tile-layer>
<ol-vector-layer>
<ol-source-cluster :distance="distance" :minDistance="minDistance" ref="clusterSourceRef">
<ol-source-vector>
<ol-feature v-for="index in 300" :key="index">
<ol-geom-point
:coordinates="coordinates[index - 1]"
></ol-geom-point>
</ol-feature>
</ol-source-vector>
</ol-source-cluster>
<ol-style :overrideStyleFunction="overrideStyleFunction">
<ol-style-circle :radius="10">
<ol-style-fill :color="'rgba(228, 147, 87,0.8)'"></ol-style-fill>
<ol-style-stroke color="#fff" :width="1"></ol-style-stroke>
</ol-style-circle>
<ol-style-text>
<ol-style-fill color="#fff"></ol-style-fill>
</ol-style-text>
</ol-style>
</ol-vector-layer>
</ol-map>
<div class="toolbar">
<div>距离</div>
<el-slider
v-model="distance"
:min="1"
:max="300"
:step="1"
@change="handleChangeDistance"
></el-slider>
<div>最小距离</div>
<el-slider
v-model="minDistance"
:min="1"
:max="300"
:step="1"
@change="handleChangeMinDistance"
></el-slider>
</div>
</template>
<script setup lang="ts">
const center = ref([121, 31]);
const projection = ref('EPSG:4326');
const zoom = ref(5);
const mapRef = ref();
const key = '替换为天地图key';
const sourceRef = ref(null);
const clusterSourceRef = shallowRef();
const distance = ref(1);
const minDistance = ref(1);
const count = 1000;
const coordinates = ref(new Array(count));
for (let i = 0; i < count; ++i) {
coordinates.value[i] = [Math.random() + 120, Math.random() + 30];
}
const overrideStyleFunction = (feature, style, resolution) => {
const size = feature.get("features").length;
style.getText().setText(size.toString());
return style;
};
const handleChangeDistance = () => {
clusterSourceRef.value.source.setDistance(distance.value);
};
const handleChangeMinDistance = () => {
clusterSourceRef.value.source.setMinDistance(minDistance.value);
};
</script>
<style scoped lang="scss">
.toolbar {
position: absolute;
top: 20px;
left: 100px;
display: flex;
justify-content: center;
align-items: center;
}
.toolbar {
position: absolute;
top: 20px;
left: 100px;
width: 500px;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
.el-slider {
margin-right: 50px;
}
div {
width: 100px;
height: 30px;
display: flex;
justify-content: center;
align-items: center;
}
}
</style>