vue3-openlayers 要素聚合(cluster)、icon聚合

发布于:2024-07-02 ⋅ 阅读:(17) ⋅ 点赞:(0)

本篇介绍一下使用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>