Examples
Clustered Points
Cluster large datasets of points for better performance. Click on a cluster to expand it, or zoom in to see individual points.
Installation
$ npx shadcn-vue@latest add https://mapcn-vue.geoql.in/r/map-layersUsage
<script setup lang="ts">
import { ref } from 'vue';
import { VMap, VLayerMaplibreCluster, VControlNavigation, VPopup } from '@geoql/v-maplibre';
import type { Map, GeoJSONSource, LngLatLike } from 'maplibre-gl';
const mapOptions = {
style: 'https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json',
center: [-74.006, 40.7128],
zoom: 10,
};
const pointsData = { type: 'FeatureCollection', features: [...] };
const mapRef = ref<Map | null>(null);
const showPopup = ref(false);
const popupCoordinates = ref<LngLatLike>([-74.006, 40.7128]);
const popupContent = ref<{ id: number } | null>(null);
const handleClusterClick = async (event) => {
if (!mapRef.value || !event.features[0]) return;
const feature = event.features[0];
const clusterId = feature.properties?.cluster_id;
const source = mapRef.value.getSource('cluster-source') as GeoJSONSource;
const zoom = await source.getClusterExpansionZoom(clusterId);
mapRef.value?.easeTo({
center: feature.geometry.coordinates,
zoom: zoom ?? 14,
duration: 500,
});
};
const handlePointClick = (event) => {
if (!event.features[0]) return;
const feature = event.features[0];
popupCoordinates.value = feature.geometry.coordinates;
popupContent.value = { id: feature.properties?.id ?? 0 };
showPopup.value = true;
};
</script>
<template>
<VMap :options="mapOptions" class="h-full w-full" @loaded="(map) => mapRef = map">
<VControlNavigation position="top-right" />
<VLayerMaplibreCluster
source-id="cluster-source"
base-layer-id="clusters"
:source="{ type: 'geojson', data: pointsData }"
:cluster-paint="{ colors: ['#10b981', '#059669', '#047857'], radii: [15, 22, 30] }"
:unclustered-paint="{ color: '#10b981', radius: 5 }"
:text-paint="{ color: '#ffffff', font: ['Noto Sans Medium'], size: 12 }"
@cluster-click="handleClusterClick"
@point-click="handlePointClick"
/>
<VPopup
v-if="showPopup && popupContent"
:coordinates="popupCoordinates"
:options="{ closeButton: true }"
@close="showPopup = false"
>
<div class="p-2">Point #{{ popupContent.id }}</div>
</VPopup>
</VMap>
</template> Components 4
<VMap />@geoql/v-maplibre<VLayerMaplibreCluster />@geoql/v-maplibre<VControlNavigation />@geoql/v-maplibre<VPopup />@geoql/v-maplibre