feat: Add Leaflet map integration and project coordinates handling

- Updated package.json to include dependencies for Leaflet and Playwright testing.
- Added new images for Leaflet markers and layers.
- Created scripts for generating test data with project coordinates.
- Enhanced ProjectViewPage to display project coordinates and integrated ProjectMap component.
- Modified ProjectForm to include coordinates input field.
- Implemented CustomWMTSMap and EnhancedLeafletMap components for improved map functionality.
- Created ProjectMap component to dynamically render project location on the map.
- Added mapLayers configuration for various base layers including Polish Geoportal.
- Implemented WMTS capabilities handling for dynamic layer loading.
- Updated database initialization to include coordinates column in projects table.
- Modified project creation and update functions to handle coordinates.
- Added utility functions for formatting project status and deadlines.
This commit is contained in:
2025-06-18 12:47:04 +02:00
parent c983ba9882
commit 603634e8a4
21 changed files with 8022 additions and 36 deletions

View File

@@ -0,0 +1,74 @@
"use client";
import { MapContainer, TileLayer, Marker, Popup, LayersControl } from 'react-leaflet';
import 'leaflet/dist/leaflet.css';
import { useEffect } from 'react';
import { mapLayers } from './mapLayers';
// Fix for default markers in react-leaflet
const fixLeafletIcons = () => {
if (typeof window !== 'undefined') {
const L = require('leaflet');
delete L.Icon.Default.prototype._getIconUrl;
L.Icon.Default.mergeOptions({
iconRetinaUrl: '/leaflet/marker-icon-2x.png',
iconUrl: '/leaflet/marker-icon.png',
shadowUrl: '/leaflet/marker-shadow.png',
});
}
};
export default function EnhancedLeafletMap({
center,
zoom = 13,
markers = [],
showLayerControl = true,
defaultLayer = 'OpenStreetMap'
}) {
useEffect(() => {
fixLeafletIcons();
}, []);
const { BaseLayer } = LayersControl;
return (
<MapContainer
center={center}
zoom={zoom}
style={{ height: '100%', width: '100%' }}
scrollWheelZoom={true}
>
{showLayerControl ? (
<LayersControl position="topright">
{mapLayers.base.map((layer, index) => (
<BaseLayer
key={index}
checked={layer.checked || layer.name === defaultLayer}
name={layer.name}
>
<TileLayer
attribution={layer.attribution}
url={layer.url}
maxZoom={layer.maxZoom}
tileSize={layer.tileSize || 256}
/>
</BaseLayer>
))}
</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"
/>
)}
{markers.map((marker, index) => (
<Marker key={index} position={marker.position}>
{marker.popup && <Popup>{marker.popup}</Popup>}
</Marker>
))}
</MapContainer>
);
}