mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-21 22:46:32 +00:00
feat(map): group GL place markers into clusters on zoom-out (#1385)
MapLibre/Mapbox showed every place as its own rich HTML marker with no grouping when zoomed out, unlike the Leaflet map. Feed the place points through a clustered GeoJSON source: clustered points render as a dark count bubble (click to zoom in and expand) while the rich HTML photo markers are only drawn for the points the source reports as unclustered. Always on, matching the Leaflet MarkerClusterGroup.
This commit is contained in:
@@ -26,6 +26,10 @@ const glMap = vi.hoisted(() => ({
|
||||
getStyle: vi.fn().mockReturnValue({ layers: [] }),
|
||||
isStyleLoaded: vi.fn().mockReturnValue(true),
|
||||
getCanvasContainer: vi.fn(() => document.createElement('div')),
|
||||
getLayer: vi.fn().mockReturnValue(null),
|
||||
queryRenderedFeatures: vi.fn().mockReturnValue([]),
|
||||
querySourceFeatures: vi.fn().mockReturnValue([]),
|
||||
easeTo: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('mapbox-gl', () => ({
|
||||
@@ -101,7 +105,7 @@ vi.mock('./locationMarkerMapbox', () => ({
|
||||
|
||||
vi.mock('./reservationsMapbox', () => ({
|
||||
ReservationMapboxOverlay: vi.fn(function () {
|
||||
return { update: vi.fn() }
|
||||
return { update: vi.fn(), destroy: vi.fn() }
|
||||
}),
|
||||
}))
|
||||
|
||||
@@ -136,6 +140,13 @@ function buildMapPlace(overrides: Record<string, any> = {}) {
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
glMap.on.mockImplementation(() => glMap)
|
||||
glMap.off.mockImplementation(() => glMap)
|
||||
glMap.once.mockImplementation(() => glMap)
|
||||
glMap.getSource.mockReturnValue(null)
|
||||
glMap.getLayer.mockReturnValue(null)
|
||||
glMap.queryRenderedFeatures.mockReturnValue([])
|
||||
glMap.querySourceFeatures.mockReturnValue([])
|
||||
useSettingsStore.setState({
|
||||
settings: {
|
||||
...useSettingsStore.getState().settings,
|
||||
@@ -227,4 +238,31 @@ describe('MapViewGL', () => {
|
||||
expect(maplibregl.Map).toHaveBeenCalled()
|
||||
expect(mapboxgl.Map).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('FE-COMP-MAPVIEWGL-005: adds the clustered place source + layers so markers group on zoom-out (#1385)', async () => {
|
||||
glMap.on.mockImplementation((event: string, handlerOrLayer: unknown) => {
|
||||
if (event === 'load' && typeof handlerOrLayer === 'function') (handlerOrLayer as () => void)()
|
||||
return glMap
|
||||
})
|
||||
useSettingsStore.setState({
|
||||
settings: {
|
||||
...useSettingsStore.getState().settings,
|
||||
map_provider: 'maplibre-gl',
|
||||
mapbox_access_token: '',
|
||||
maplibre_style: 'https://tiles.openfreemap.org/styles/liberty',
|
||||
},
|
||||
} as any)
|
||||
|
||||
render(<MapViewGL places={[buildMapPlace({ id: 1, lat: 48.8584, lng: 2.2945 })]} fitKey={1} glProvider="maplibre-gl" />)
|
||||
await act(async () => {})
|
||||
|
||||
expect(glMap.addSource).toHaveBeenCalledWith('trip-place-clusters', expect.objectContaining({
|
||||
type: 'geojson',
|
||||
cluster: true,
|
||||
clusterRadius: 30,
|
||||
clusterMaxZoom: 10,
|
||||
}))
|
||||
expect(glMap.addLayer).toHaveBeenCalledWith(expect.objectContaining({ id: 'trip-place-clusters-circle' }))
|
||||
expect(glMap.addLayer).toHaveBeenCalledWith(expect.objectContaining({ id: 'trip-place-clusters-count' }))
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user