feat: Implement layer control and custom zoom functionality in ProjectsMapPage and LeafletMap components

This commit is contained in:
2025-06-24 12:01:48 +02:00
parent 96da5212d4
commit 4c11801ab1
2 changed files with 445 additions and 176 deletions

View File

@@ -8,7 +8,9 @@ import {
Popup,
LayersControl,
useMapEvents,
useMap,
} from "react-leaflet";
import L from "leaflet";
import "leaflet/dist/leaflet.css";
import { useEffect } from "react";
import { mapLayers } from "./mapLayers";
@@ -70,26 +72,55 @@ function MapEventHandler({ onViewChange }) {
return null;
}
// Custom zoom control component that handles external events
function CustomZoomHandler() {
const map = useMap();
useEffect(() => {
if (!map) return;
const handleZoomIn = () => {
map.zoomIn();
};
const handleZoomOut = () => {
map.zoomOut();
};
// Listen for custom zoom events
window.addEventListener('mapZoomIn', handleZoomIn);
window.addEventListener('mapZoomOut', handleZoomOut);
return () => {
window.removeEventListener('mapZoomIn', handleZoomIn);
window.removeEventListener('mapZoomOut', handleZoomOut);
};
}, [map]);
return null;
}
export default function EnhancedLeafletMap({
center,
zoom = 13,
markers = [],
showLayerControl = true,
defaultLayer = "OpenStreetMap",
activeOverlays = [],
onViewChange,
}) {
useEffect(() => {
fixLeafletIcons();
}, []);
const { BaseLayer, Overlay } = LayersControl;
return (
}, []); const { BaseLayer, Overlay } = LayersControl;
return (
<MapContainer
center={center}
zoom={zoom}
style={{ height: "100%", width: "100%" }}
scrollWheelZoom={true}
zoomControl={false}
>
{/* Handle map view changes */}
<CustomZoomHandler />
{onViewChange && <MapEventHandler onViewChange={onViewChange} />}
{showLayerControl ? (
@@ -135,13 +166,52 @@ export default function EnhancedLeafletMap({
)}
</Overlay>
))}
</LayersControl>
) : (
// Default layer when no layer control
<TileLayer
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
</LayersControl> ) : (
// Custom layer rendering when no layer control
<>
{/* Base Layer */}
{(() => {
const baseLayer = mapLayers.base.find(layer => layer.name === defaultLayer) || mapLayers.base[0];
return (
<TileLayer
attribution={baseLayer.attribution}
url={baseLayer.url}
maxZoom={baseLayer.maxZoom}
tileSize={baseLayer.tileSize || 256}
/>
);
})()}
{/* Active Overlay Layers */}
{mapLayers.overlays && mapLayers.overlays
.filter(layer => activeOverlays.includes(layer.name))
.map((layer, index) => {
if (layer.type === "wms") {
return (
<WMSTileLayer
key={`custom-overlay-${index}`}
attribution={layer.attribution}
url={layer.url}
params={layer.params}
format={layer.params.format}
transparent={layer.params.transparent}
opacity={layer.opacity}
/>
);
} else {
return (
<TileLayer
key={`custom-overlay-${index}`}
attribution={layer.attribution}
url={layer.url}
maxZoom={layer.maxZoom}
opacity={layer.opacity}
/>
);
}
})
}
</>
)}{" "}
{markers.map((marker, index) => (
<Marker