Skip to content

点聚合

地图点聚合组件,可以对地图上的点进行聚合。

基础示例

vue
<template>
  <tlbs-map
    ref="mapRef"
    api-key="OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77"
    :center="center"
    :zoom="8"
    :control="control"
    @click="onClick"
    @map_inited="onMapInited"
  >
    <tlbs-marker-cluster
      ref="markerClusterRef"
      :geometries="geometries"
      :options="options"
    />
    <div class="control-container">
      <button @click.stop="getLayerInstance">
        打印点聚合实例
      </button>
    </div>
  </tlbs-map>
</template>

<script lang="ts">
import { defineComponent, ref } from 'vue-demi';

export default defineComponent({
  name: 'MarkerClusterDemo',
  setup() {
    const mapRef = ref(null);
    const markerClusterRef = ref(null);
    const center = ref({ lat: 39.91799, lng: 116.397027 });
    const onClick = (e: Event) => {
      console.log(e);
    };

    const onMapInited = () => {
      // 地图加载完成后,可以获取地图实例、点聚合实例,调用地图实例、点聚合实例方法
      console.log(mapRef.value.map);
      console.log(markerClusterRef.value.markerCluster);
    };

    const getLayerInstance = () => {
      // 可以获取点聚合实例,调用点聚合实例方法
      console.log(markerClusterRef.value.markerCluster);
    };
    return {
      center,
      onClick,
      control: {
        scale: {},
        zoom: {
          position: 'topRight',
        },
      },
      mapRef,
      markerClusterRef,
      geometries: [
        { position: { lat: 39.99799, lng: 116.397027 } },
        { position: { lat: 39.89799, lng: 116.397027 } },
        { position: { lat: 39.79799, lng: 116.397027 } },
        { position: { lat: 39.89799, lng: 116.297027 } },
        { position: { lat: 39.89799, lng: 116.497027 } },
      ],
      options: {
        zIndex: 1,
      },
      onMapInited,
      getLayerInstance,
    };
  },
});
</script>

自定义点聚合

vue
<template>
  <tlbs-map
    ref="mapRef"
    api-key="OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77"
    :center="center"
    :zoom="8"
    @map_inited="onMapInited"
  >
    <tlbs-marker-cluster
      ref="markerClusterRef"
      :geometries="geometries"
      :options="{
        zIndex: 1,
      }"
      :enable-default-style="false"
      @clusterchange="clusterChange"
    />

    <!-- 聚合点 -->
    <div
      v-for="(item, index) of aggregationPoints"
      :key="index"
    >
      <tlbs-dom-overlay
        :position="item.center"
        :offset="offset"
      >
        <div
          class="polymerization formatClolr"
          :style="{
            width: item.width,
            height: item.height,
            'line-height': item['line-height']
          }"
          @click="domoOverlayClick(item)"
        >
          {{ item.content }}
        </div>
      </tlbs-dom-overlay>
    </div>

    <!-- 分散点 -->
    <div
      v-for="(item, index) of scatteredPoints"
      :key="index"
    >
      <tlbs-dom-overlay
        :position="item.center"
      >
        <div
          class="point_logo point_logo_0"
          :value="item.poiid"
          :style="item.transform"
          @click="openDetail(item)"
        >
          <div class="point_logo_polka_dot" />
        </div>
      </tlbs-dom-overlay>
    </div>
    <div class="control-container">
      <button @click.stop="getLayerInstance">
        打印点聚合实例
      </button>
    </div>
  </tlbs-map>
</template>

<script lang="ts">
import { defineComponent, ref } from 'vue-demi';
interface AggregationPointsObj {
  center: TMap.LatLng, // 中心点位置
  width: string, // 默认宽度
  height: string, // 默认高度
  'line-height': string,
  content: string, // 聚合元素个数
  sort: number[], // 所有图形聚合后的元素个数排序后结果
  data: TMap.ClusterInfo, //  聚合簇属性
}
interface ScatteredPointsObj {
  center: TMap.LatLng,
  x: number, // 像素x坐标
  y: number, // 像素y坐标
  data: TMap.ClusterInfo // 聚合簇属性
}
export default defineComponent({
  name: 'MarkerClusterOverlayDemo',
  setup() {
    const geometries = [
      { position: { lat: 39.99799, lng: 116.397027 } },
      { position: { lat: 39.89799, lng: 116.397027 } },
      { position: { lat: 39.79799, lng: 116.397027 } },
      { position: { lat: 39.89799, lng: 116.297027 } },
      { position: { lat: 39.89799, lng: 116.497027 } },
    ];
    const mapRef: any = ref(null);
    const markerClusterRef = ref(null);
    const center = ref({ lat: 39.91799, lng: 116.397027 });
    // 监听聚合簇变化
    const aggregationPoints = ref<AggregationPointsObj[]>([]);
    const scatteredPoints = ref<ScatteredPointsObj[]>([]);
    const offset = ref({ x: 0, y: -30 });
    const clusterChange = (scatteredPoint: ScatteredPointsObj[], aggregationPoint: AggregationPointsObj[]) => {
      aggregationPoints.value = aggregationPoint;
      scatteredPoints.value = scatteredPoint;
    };
    const domoOverlayClick = (item: AggregationPointsObj) => {
      mapRef.value.map.fitBounds(item.data.bounds);
    };
    const openDetail = (item: ScatteredPointsObj) => {
      console.log(item);
      console.log('查看详情');
    };

    const onMapInited = () => {
      // 地图加载完成后,可以获取地图实例、点聚合实例,调用地图实例、点聚合实例方法
      console.log(mapRef.value.map);
      console.log(markerClusterRef.value.markerCluster);
    };

    const getLayerInstance = () => {
      // 可以获取点聚合实例,调用点聚合实例方法
      console.log(markerClusterRef.value.markerCluster);
    };

    return {
      center,
      clusterChange,
      mapRef,
      markerClusterRef,
      geometries,
      offset,
      aggregationPoints,
      scatteredPoints,
      domoOverlayClick,
      openDetail,
      onMapInited,
      getLayerInstance,
    };
  },
});
</script>

<style>
.polymerization {
  border-radius: 50%;
  color: #fff;
  font-weight: 500;
  text-align: center;
  opacity: 0.95;
  box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.2);
  position: absolute;
  top: 0px;
  left: 0px;
  cursor: pointer;
}

.formatClolr {
  background: linear-gradient(138.59deg, rgba(255, 118, 118, 0.9) 11.12%, rgba(255, 61, 61, 0.9) 75.89%);
  box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.12), 0px 0px 8px rgba(0, 0, 0, 0.08);
}
.point_logo {
  width: 42px;
  height: 49px;
  position: absolute;
  text-align: center;
  line-height: 42px;
}
.point_logo_polka_dot {
  width: 16px;
  height: 16px;
  text-align: center;
  cursor: pointer;
  display: inline-block;
  background: #f36d78;
  border-radius: 50%;
}
</style>

props

名称类型说明
idString图层 id,参考官网文档
geometriesTMap.PointGeometry[]标注点数据数组,参考官网文档
gridSizeNumber聚合距离,距离小于该值的点会聚合至一起,默认为60px,参考官网文档
maxZoomNumber聚合策略的最大缩放级别,若地图缩放级别大于该值,则不进行聚合, 默认为20,参考官网文档
minimumClusterSizeNumber最小聚合点数, 默认为2,参考官网文档
averageCenterBoolean每个聚和簇的中心是否应该是聚类中所有标记的平均值,默认为false,参考官网文档
enableDefaultStyleBoolean使用默认样式,默认为true,参考官网文档
zoomOnClickBoolean点击聚合数字放大展开,默认为true,参考官网文档
optionsTMap.MarkerClusterOptions除了上述属性的其他配置参数,参考TMap.MarkerClusterOptions

TMap.MarkerClusterOptions

属性名称类型说明
zIndexNumber图层绘制顺序
collisionOptionsCollisionOptions图层碰撞配置参数

事件

名称参数说明
clusterchange(scatteredPoint: TMap.PointGeometry[], aggregationPoint: TMap.PointGeometry[])聚合状态变化时触发,scatteredPoint(分散点的坐标集合),aggregationPoint(聚合点的坐标集合)
clickevt: TMap.MarkerClusterEvent点击聚合点或分散点时触发

组件实例属性

名称类型说明
markerClusterTMap.MarkerCluster点聚合实例。实例方法参考TMap.MarkerCluster方法

TMap.MarkerCluster方法

方法返回值说明
setMap(map:Map)this设置地图对象,如果map为null意味着将点聚合图层从地图中移除
setGeometries(geometries:PointGeometry[])this更新点数据,如果参数为null或undefined不会做任何处理
getMap()Map获取地图对象,若为空返回null
getClusters()ClusterInfo[]获取当前地图视野范围内,聚合后的聚合簇数据;聚合是异步操作,可以绑定cluster_changed事件获取每次地图上最新的聚合簇
getGeometries()PointGeometry[]获取点数据
getGeometryById(id:String)PointGeometry根据点数据id来获取点数据
updateGeometries(geometry: PointGeometry[])this更新标注点数据,如果geometry的id存在于聚合点的集合中,会更新对id的数据,如果之前不存在于集合中,会作为新的点标注添加到集合中进行聚合;如果参数为null或undefined不会做任何处理
add(geometries: PointGeometry[])this向图层中添加标注点,如果geometry的id已经存在集合中,则该geometry不会被重复添加,如果geometry没有id或者id不存在于集合中会被添加到集合中进行聚合,没有id的geometry会被赋予一个唯一id;如果要添加到集合中的标注存在重复id,这些标注点会被重新分配id;如果参数为null或undefined不会做任何处理
remove(ids: String[])this移除指定id的标注点,如果参数为null或undefined不会做任何处理
on(eventName:String, listener:Function)this添加listener到eventName事件的监听器数组中
off(eventName:String, listener:Function)this从eventName事件的监听器数组中移除指定的listener
destroy()销毁图层对象