feat: Implement layer control and custom zoom functionality in ProjectsMapPage and LeafletMap components
This commit is contained in:
@@ -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='© <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
|
||||
|
||||
Reference in New Issue
Block a user