diff --git a/src/components/map/layers/custom/GeodsPointsOfInterestLayer.tsx b/src/components/map/layers/custom/GeodsPointsOfInterestLayer.tsx index 9fe1ca9b..51fdf3ce 100644 --- a/src/components/map/layers/custom/GeodsPointsOfInterestLayer.tsx +++ b/src/components/map/layers/custom/GeodsPointsOfInterestLayer.tsx @@ -1,7 +1,6 @@ import { Icon, type LatLngBounds } from "leaflet"; import { useMemo } from "react"; import { Marker } from "react-leaflet"; -import MarkerClusterGroup from "react-leaflet-cluster"; import { useCachedQuery } from "../../../../hooks/useCachedQuery"; import { useErrorToast } from "../../../../hooks/useErrorToast"; import { useGeodsPOI } from "../../../../hooks/useGeodsPOI"; @@ -37,7 +36,7 @@ export function GeodsPointsOfInterestLayer({ bounds }: GeodsPointsOfInterestLaye }, []); return ( - + <> {data?.results?.map((result) => ( ))} - + ); } diff --git a/src/components/map/layers/custom/GeographLayer.tsx b/src/components/map/layers/custom/GeographLayer.tsx index 67cf8a95..aa3b4274 100644 --- a/src/components/map/layers/custom/GeographLayer.tsx +++ b/src/components/map/layers/custom/GeographLayer.tsx @@ -1,6 +1,5 @@ import { LatLngBounds } from "leaflet"; import { Marker, useMap } from "react-leaflet"; -import MarkerClusterGroup from "react-leaflet-cluster"; import { useErrorToast } from "../../../../hooks/useErrorToast"; import { useGeograph } from "../../../../hooks/useGeograph"; import { blueMarker } from "../../../../icons"; @@ -21,7 +20,7 @@ export function GeographLayer({ bounds }: GeographLayerProps) { useErrorToast("geograph-error", "Error loading Geograph images", error); return ( - + <> {data?.map((item) => ( ))} - + ); } diff --git a/src/components/map/layers/custom/GpsRoutesLayer.tsx b/src/components/map/layers/custom/GpsRoutesLayer.tsx index 299c532d..8884c994 100644 --- a/src/components/map/layers/custom/GpsRoutesLayer.tsx +++ b/src/components/map/layers/custom/GpsRoutesLayer.tsx @@ -1,6 +1,5 @@ import { type LatLngBounds } from "leaflet"; import { Marker } from "react-leaflet"; -import MarkerClusterGroup from "react-leaflet-cluster"; import { useCachedQuery } from "../../../../hooks/useCachedQuery"; import { useErrorToast } from "../../../../hooks/useErrorToast"; import { useGpsRoutes } from "../../../../hooks/useGpsRoutes"; @@ -16,7 +15,7 @@ export function GpsRoutesLayer({ bounds }: GpsRoutesLayerProps) { useErrorToast("gps-routes-error", "Error loading GPS routes", error); return ( - + <> {data?.hits.map((result) => ( ))} - + ); } diff --git a/src/components/map/layers/custom/UnifiedClusterLayer.tsx b/src/components/map/layers/custom/UnifiedClusterLayer.tsx new file mode 100644 index 00000000..49fa9c29 --- /dev/null +++ b/src/components/map/layers/custom/UnifiedClusterLayer.tsx @@ -0,0 +1,37 @@ +import { type LatLngBounds } from "leaflet"; +import { useMap } from "react-leaflet"; +import MarkerClusterGroup from "react-leaflet-cluster"; +import { CompanyDataLayer } from "./CompanyDataLayer"; +import { GeodsPointsOfInterestLayer } from "./GeodsPointsOfInterestLayer"; +import { GeographLayer } from "./GeographLayer"; +import { GpsRoutesLayer } from "./GpsRoutesLayer"; + +interface UnifiedClusterLayerProps { + bounds: LatLngBounds; +} + +// Define min/max zoom for each layer +const LAYER_ZOOM = { + gpsRoutes: { minZoom: 10 }, + geograph: { minZoom: 16 }, + geodsPoi: { minZoom: 14 }, + companyData: { minZoom: 16 }, +} as const; + +export function UnifiedClusterLayer({ bounds }: UnifiedClusterLayerProps) { + const map = useMap(); + const currentZoom = map.getZoom(); + + const shouldRenderLayer = (minZoom: number) => { + return currentZoom > minZoom; + }; + + return ( + + {shouldRenderLayer(LAYER_ZOOM.gpsRoutes.minZoom) && } + {shouldRenderLayer(LAYER_ZOOM.geograph.minZoom) && } + {shouldRenderLayer(LAYER_ZOOM.geodsPoi.minZoom) && } + {shouldRenderLayer(LAYER_ZOOM.companyData.minZoom) && } + + ); +} diff --git a/src/config/layer.tsx b/src/config/layer.tsx index ef75ced2..bdde0c3c 100644 --- a/src/config/layer.tsx +++ b/src/config/layer.tsx @@ -1,11 +1,8 @@ import { createListCollection } from "@chakra-ui/react"; import { LatLngBounds } from "leaflet"; import { TileLayer, WMSTileLayer } from "react-leaflet"; -import { CompanyDataLayer } from "../components/map/layers/custom/CompanyDataLayer"; -import { GeodsPointsOfInterestLayer } from "../components/map/layers/custom/GeodsPointsOfInterestLayer"; -import { GeographLayer } from "../components/map/layers/custom/GeographLayer"; -import { GpsRoutesLayer } from "../components/map/layers/custom/GpsRoutesLayer"; import { PostcodePolygonsLayer } from "../components/map/layers/custom/PostcodePolygonsLayer"; +import { UnifiedClusterLayer } from "../components/map/layers/custom/UnifiedClusterLayer"; import { WeatherLayer } from "../components/map/layers/custom/WeatherLayer"; export type Tile = { @@ -191,10 +188,7 @@ const BASE_LAYERS: LayerOption[] = [ ]; export const OVERLAYS: Record = { - "GPS Routes": { minZoom: 10, component: GpsRoutesLayer }, - Geograph: { minZoom: 16, component: GeographLayer }, - "GeoDS POI": { minZoom: 14, component: GeodsPointsOfInterestLayer }, - "Company Data": { minZoom: 16, component: CompanyDataLayer }, + "Clustered Markers": { minZoom: 6, component: UnifiedClusterLayer }, Postcodes: { minZoom: 11, component: PostcodePolygonsLayer }, "Waymarked Hiking Trails": { minZoom: 6,