Documentation

Clustering

When many annotations share a clusteringIdentifier, MapKit groups nearby ones into a single cluster annotation as the user zooms out, and splits them apart as they zoom in. You control how each cluster renders.

Basic Clustering

Give annotations a shared clustering-identifier and supply a cluster-annotation factory on <VMap> that returns the annotation to render for each group.

<script setup lang="ts">
  import { VMap, VMarkerAnnotation } from '@geoql/v-mapkit';

  const markers = Array.from({ length: 40 }, (_, id) => ({
    id,
    at: [
      37.7749 + (Math.random() - 0.5) * 0.12,
      -122.4194 + (Math.random() - 0.5) * 0.12,
    ] as [number, number],
  }));

  function clusterAnnotation(cluster: mapkit.Annotation) {
    return new mapkit.MarkerAnnotation(cluster.coordinate, {
      color: '#0a84ff',
      glyphText: String(cluster.memberAnnotations.length),
      title: `${cluster.memberAnnotations.length} places`,
    });
  }
</script>

<template>
  <VMap :access-token="token" :cluster-annotation="clusterAnnotation">
    <VMarkerAnnotation
      v-for="m in markers"
      :key="m.id"
      :coordinates="m.at"
      clustering-identifier="places"
    />
  </VMap>
</template>

The factory receives the cluster annotation MapKit creates — it carries coordinate and memberAnnotations (the grouped annotations sharing the identifier) — and must return the annotation to render in its place.

clustering-identifier

Every annotation component (VMarkerAnnotation, VImageAnnotation, VPlaceAnnotation, VCustomAnnotation, VMapFeatureAnnotation) accepts a clusteringIdentifier string. Annotations only cluster with others sharing the same identifier — use distinct identifiers to keep categories separate.

<VMap :access-token="token" :cluster-annotation="clusterAnnotation">
  <VMarkerAnnotation
    v-for="cafe in cafes"
    :key="cafe.id"
    :coordinates="cafe.at"
    clustering-identifier="cafes"
  />
  <VMarkerAnnotation
    v-for="park in parks"
    :key="park.id"
    :coordinates="park.at"
    clustering-identifier="parks"
  />
</VMap>

useCluster

useCluster is the composable behind the cluster-annotation prop. Use it directly when you want to attach (and later detach) the cluster delegate yourself — for example, toggling clustering at runtime.

<script setup lang="ts">
  import { onBeforeUnmount } from 'vue';
  import { useCluster } from '@geoql/v-mapkit';

  const { cleanup } = useCluster({
    createClusterAnnotation: (cluster) =>
      new mapkit.MarkerAnnotation(cluster.coordinate, {
        color: '#5e5ce6',
        glyphText: String(cluster.memberAnnotations.length),
      }),
  });

  onBeforeUnmount(cleanup);
</script>
OptionTypeDescription
createClusterAnnotation(cluster: mapkit.Annotation) => mapkit.AnnotationBuild the annotation rendered for each cluster (required)

Returns { cleanup }cleanup() removes the annotationForCluster delegate from the map.

Tip

Prefer the cluster-annotation prop on <VMap> for the common case — it wires useCluster for you and tears it down on unmount. Reach for useCluster directly only when you need manual control.

See the live Clustering example.