Compare commits
2 Commits
d4f16d344d
...
daea67fddb
| Author | SHA1 | Date | |
|---|---|---|---|
| daea67fddb | |||
| e993d02a1b |
222
docs/LAYER_NOTES.md
Normal file
222
docs/LAYER_NOTES.md
Normal file
@@ -0,0 +1,222 @@
|
||||
# Map Layers - Implementation Notes & Documentation
|
||||
|
||||
Personal notes and official documentation references for each map layer implementation.
|
||||
|
||||
---
|
||||
|
||||
## Base Layers
|
||||
|
||||
### OpenStreetMap
|
||||
**Status:** ✅ Working
|
||||
**Type:** XYZ Tiles
|
||||
**URL:** `https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png`
|
||||
|
||||
**Implementation Notes:**
|
||||
- OSM - up to zoom 20
|
||||
|
||||
---
|
||||
|
||||
### 🇵🇱 Polish Orthophoto (Standard Resolution)
|
||||
**Status:** ✅ Working (minor issue)
|
||||
**Type:** WMTS
|
||||
**Service:** Polish Geoportal PZGIK/ORTO
|
||||
**URL:** `https://mapy.geoportal.gov.pl/wss/service/PZGIK/ORTO/WMTS/StandardResolution`
|
||||
|
||||
**Implementation Notes:**
|
||||
- Polish Ortophoto stantard - ok up to zoom 19
|
||||
|
||||
**Official Documentation:**
|
||||
- GetCapabilities WMTS: `https://mapy.geoportal.gov.pl/wss/service/PZGIK/ORTO/WMTS/StandardResolution?Service=WMTS&Request=GetCapabilities`
|
||||
- GetCapabilities WMS: `https://mapy.geoportal.gov.pl/wss/service/PZGIK/ORTO/WMS/StandardResolution?Service=WMS&Request=GetCapabilities`
|
||||
|
||||
---
|
||||
|
||||
### 🇵🇱 Polish Orthophoto (High Resolution)
|
||||
**Status:** Not Working
|
||||
**Type:** WMTS
|
||||
**Service:** Polish Geoportal PZGIK/ORTO
|
||||
**URL:** `https://mapy.geoportal.gov.pl/wss/service/PZGIK/ORTO/WMTS/HighResolution`
|
||||
|
||||
**Implementation Notes:**
|
||||
- Polish Ortophoto Hirez - doesnt load at all
|
||||
|
||||
**Official Documentation:**
|
||||
- GetCapabilities WMTS: `https://mapy.geoportal.gov.pl/wss/service/PZGIK/ORTO/WMTS/HighResolution?Service=WMTS&Request=GetCapabilities`
|
||||
- GetCapabilities WMS: `https://mapy.geoportal.gov.pl/wss/service/PZGIK/ORTO/WMS/HighResolution?Service=WMS&Request=GetCapabilities`
|
||||
|
||||
---
|
||||
|
||||
### 🌍 Google Satellite
|
||||
**Status:** ✅ Working
|
||||
**Type:** XYZ Tiles
|
||||
**URL:** `http://mt1.google.com/vt/lyrs=s&hl=pl&x={x}&y={y}&z={z}`
|
||||
|
||||
**Implementation Notes:**
|
||||
- Google sat - ok (20)
|
||||
|
||||
---
|
||||
|
||||
### 🌍 Google Hybrid
|
||||
**Status:** ✅ Working
|
||||
**Type:** XYZ Tiles
|
||||
**URL:** `http://mt1.google.com/vt/lyrs=y&hl=pl&x={x}&y={y}&z={z}`
|
||||
|
||||
**Implementation Notes:**
|
||||
- Google hyb - ok (20)
|
||||
|
||||
---
|
||||
|
||||
### Satellite (Esri)
|
||||
**Status:** ✅ Working
|
||||
**Type:** XYZ Tiles
|
||||
**Service:** ArcGIS Online World Imagery
|
||||
**URL:** `https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}`
|
||||
|
||||
**Implementation Notes:**
|
||||
- Esri - ok (20)
|
||||
|
||||
---
|
||||
|
||||
### Topographic
|
||||
**Status:** ✅ Working
|
||||
**Type:** XYZ Tiles
|
||||
**Service:** CARTO Voyager
|
||||
**URL:** `https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png`
|
||||
|
||||
**Implementation Notes:**
|
||||
- Topo - ok (20)
|
||||
|
||||
---
|
||||
|
||||
## Overlay Layers - Polish Government
|
||||
|
||||
### 📋 Polish Cadastral Data (Działki) - Server 1
|
||||
**Status:** - VERY SLOW
|
||||
**Type:** WMS 1.3.0
|
||||
**Service:** GUGiK - Krajowa Integracja Ewidencji Gruntów
|
||||
**URL:** `https://integracja01.gugik.gov.pl/cgi-bin/KrajowaIntegracjaEwidencjiGruntow`
|
||||
**Opacity:** 0.8
|
||||
|
||||
**Layers:** `powiaty,powiaty_obreby,zsin,obreby,dzialki,geoportal,numery_dzialek,budynki`
|
||||
|
||||
**Implementation Notes:**
|
||||
- Polish cadastral data server 1 - very slow, works only up to zoom 18
|
||||
|
||||
**Official Documentation:**
|
||||
- GetCapabilities: `https://integracja01.gugik.gov.pl/cgi-bin/KrajowaIntegracjaEwidencjiGruntow?Service=WMS&Request=GetCapabilities`
|
||||
|
||||
|
||||
---
|
||||
|
||||
### 📋 Polish Cadastral Data (Działki) - Server 2
|
||||
**Status:** - VERY SLOW
|
||||
**Type:** WMS 1.3.0
|
||||
**Service:** GUGiK - Krajowa Integracja Ewidencji Gruntów
|
||||
**URL:** `https://integracja.gugik.gov.pl/cgi-bin/KrajowaIntegracjaEwidencjiGruntow`
|
||||
**Opacity:** 0.8
|
||||
|
||||
**Layers:** `dzialki,obreby,numery_dzialek,budynki,kontury,uzytki`
|
||||
|
||||
**Implementation Notes:**
|
||||
- Polish cadastral data server 2 - very slow, works only up to zoom 18 (this is the current official one afaik)
|
||||
|
||||
**Official Documentation:**
|
||||
- GetCapabilities: `https://integracja.gugik.gov.pl/cgi-bin/KrajowaIntegracjaEwidencjiGruntow?Service=WMS&Request=GetCapabilities`
|
||||
|
||||
---
|
||||
|
||||
### 🏗️ Polish Spatial Planning
|
||||
**Status:** Not Working
|
||||
**Type:** WMS 1.3.0
|
||||
**Service:** Geoportal - Krajowa Integracja Miejscowych Planów Zagospodarowania Przestrzennego
|
||||
**URL:** `https://mapy.geoportal.gov.pl/wss/ext/KrajowaIntegracjaMiejscowychPlanowZagospodarowaniaPrzestrzennego`
|
||||
**Opacity:** 0.7
|
||||
|
||||
**Layers:** `raster,wektor-str,wektor-lzb,wektor-pow,wektor-lin,wektor-pkt,granice`
|
||||
|
||||
**Implementation Notes:**
|
||||
- doesnt seem to work, or is extremely slow
|
||||
|
||||
**Official Documentation:**
|
||||
- GetCapabilities: `https://mapy.geoportal.gov.pl/wss/ext/KrajowaIntegracjaMiejscowychPlanowZagospodarowaniaPrzestrzennego?Service=WMS&Request=GetCapabilities`
|
||||
-
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Overlay Layers - Utility
|
||||
|
||||
### 🌍 Google Roads
|
||||
**Status:** ✅ Working
|
||||
**Type:** XYZ Tiles Overlay
|
||||
**URL:** `http://mt1.google.com/vt/lyrs=h&hl=pl&x={x}&y={y}&z={z}`
|
||||
**Opacity:** 1.0
|
||||
|
||||
**Implementation Notes:**
|
||||
- Ok
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Technical Notes
|
||||
|
||||
### Coordinate Reference Systems
|
||||
- **EPSG:3857** - Web Mercator (current implementation for all layers)
|
||||
- **EPSG:2180** - Polish national projection (PUWG 1992)
|
||||
- Some Polish services support this natively
|
||||
- Would require proj4leaflet for proper support
|
||||
|
||||
### WMS Version Differences
|
||||
- **WMS 1.1.1:** Uses `SRS` parameter for coordinate system
|
||||
- **WMS 1.3.0:** Uses `CRS` parameter for coordinate system
|
||||
- Current implementation auto-detects and handles both
|
||||
|
||||
### Performance Considerations
|
||||
-
|
||||
|
||||
### Known Issues
|
||||
-
|
||||
|
||||
---
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
### Planned
|
||||
- [ ] Dynamic opacity controls
|
||||
- [ ] Layer legends/metadata panels
|
||||
- [ ] EPSG:2180 support via proj4leaflet
|
||||
- [ ] Layer error handling with fallbacks
|
||||
- [ ] Mobile-optimized layer control
|
||||
|
||||
### Ideas
|
||||
-
|
||||
|
||||
---
|
||||
|
||||
## References & Resources
|
||||
|
||||
### Polish Geoportal
|
||||
- Main portal: https://www.geoportal.gov.pl/
|
||||
- Service catalog: https://www.geoportal.gov.pl/uslugi
|
||||
-
|
||||
|
||||
### GUGiK (Główny Urząd Geodezji i Kartografii)
|
||||
- Main website: https://www.gugik.gov.pl/
|
||||
-
|
||||
|
||||
### LP-Portal
|
||||
- Website: https://lp-portal.pl/
|
||||
-
|
||||
|
||||
### Leaflet Documentation
|
||||
- WMS Layers: https://leafletjs.com/reference.html#tilelayer-wms
|
||||
-
|
||||
|
||||
---
|
||||
|
||||
## Changelog
|
||||
|
||||
### 2026-01-16
|
||||
- Created LAYER_NOTES.md for documentation and personal notes
|
||||
- Initial structure with all current layers documented
|
||||
788
docs/MAP_SYSTEM_UPDATE_PLAN.md
Normal file
788
docs/MAP_SYSTEM_UPDATE_PLAN.md
Normal file
@@ -0,0 +1,788 @@
|
||||
# Map System - Comprehensive Update & Fix Plan
|
||||
|
||||
Based on layer testing results from LAYER_NOTES.md
|
||||
Date: January 16, 2026
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
**Current Status:**
|
||||
- ✅ **6/7 base layers working** (1 broken: Polish Orthophoto High Resolution)
|
||||
- ⚠️ **2/9 overlay layers working** (2 very slow, 5 not tested, 2 broken)
|
||||
- 🎯 **Priority:** Fix broken layers, optimize slow WMS services, remove LP-Portal layers
|
||||
|
||||
**Key Issues Identified:**
|
||||
1. Polish Orthophoto High Resolution completely broken
|
||||
2. Polish Cadastral Data servers extremely slow (both servers)
|
||||
3. Polish Spatial Planning layer not working
|
||||
4. LP-Portal layers not tested/documented - likely region-specific
|
||||
5. No caching or performance optimization for WMS layers
|
||||
6. Missing zoom level restrictions causing tile request failures
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Critical Fixes (Week 1)
|
||||
|
||||
### 1.1 Fix Polish Orthophoto High Resolution
|
||||
**Issue:** Doesn't load at all
|
||||
**Root Cause:** Likely incorrect WMTS parameters or service endpoint change
|
||||
|
||||
**Action Plan:**
|
||||
1. Test GetCapabilities response:
|
||||
```bash
|
||||
curl "https://mapy.geoportal.gov.pl/wss/service/PZGIK/ORTO/WMTS/HighResolution?Service=WMTS&Request=GetCapabilities"
|
||||
```
|
||||
2. Compare with Standard Resolution working configuration
|
||||
3. Check for:
|
||||
- Different tile matrix sets
|
||||
- Different available zoom levels
|
||||
- Format differences (jpeg vs png)
|
||||
- Authentication requirements
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
// Test if service requires different parameters
|
||||
{
|
||||
name: "🇵🇱 Polish Orthophoto (High Resolution)",
|
||||
url: "https://mapy.geoportal.gov.pl/wss/service/PZGIK/ORTO/WMTS/HighResolution?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=ORTO&STYLE=default&TILEMATRIXSET=EPSG:3857&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&FORMAT=image/jpeg",
|
||||
maxZoom: 19, // May need adjustment based on GetCapabilities
|
||||
minZoom: 15, // High-res often only available at higher zoom
|
||||
}
|
||||
```
|
||||
|
||||
**Success Criteria:** Layer loads tiles without errors
|
||||
|
||||
---
|
||||
|
||||
### 1.2 Fix Polish Spatial Planning Layer
|
||||
**Issue:** Doesn't work or extremely slow
|
||||
**Service:** `https://mapy.geoportal.gov.pl/wss/ext/KrajowaIntegracjaMiejscowychPlanowZagospodarowaniaPrzestrzennego`
|
||||
|
||||
**Action Plan:**
|
||||
1. Verify service is still active via GetCapabilities
|
||||
2. Test with simplified layer list (may be requesting too many layers)
|
||||
3. Check if service moved to new endpoint
|
||||
4. Test with different WMS versions (1.1.1 vs 1.3.0)
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
// Simplified layer request
|
||||
{
|
||||
name: "🏗️ Polish Spatial Planning",
|
||||
type: "wms",
|
||||
url: "https://mapy.geoportal.gov.pl/wss/ext/KrajowaIntegracjaMiejscowychPlanowZagospodarowaniaPrzestrzennego",
|
||||
params: {
|
||||
layers: "raster", // Start with just raster
|
||||
format: "image/png",
|
||||
transparent: true,
|
||||
version: "1.3.0",
|
||||
},
|
||||
maxZoom: 18, // Limit to prevent overload
|
||||
}
|
||||
```
|
||||
|
||||
**Success Criteria:** Layer loads or is removed if permanently unavailable
|
||||
|
||||
---
|
||||
|
||||
### 1.3 Optimize Polish Cadastral Data Performance
|
||||
**Issue:** Both servers very slow, currently only work up to zoom 18
|
||||
**Impact:** Core functionality for land surveying projects
|
||||
|
||||
**Action Plan:**
|
||||
1. Implement tile loading indicators
|
||||
2. Add request debouncing
|
||||
3. Consider caching strategy
|
||||
4. Test alternate GUGiK services
|
||||
5. (Future) Enable zoom 19-20 with proper optimization
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
// Update both cadastral servers with performance optimizations
|
||||
{
|
||||
name: "📋 Polish Cadastral Data (Działki) - Server 2",
|
||||
type: "wms",
|
||||
url: "https://integracja.gugik.gov.pl/cgi-bin/KrajowaIntegracjaEwidencjiGruntow",
|
||||
params: {
|
||||
layers: "dzialki,numery_dzialek,budynki", // Simplified - remove slow layers
|
||||
format: "image/png",
|
||||
transparent: true,
|
||||
version: "1.3.0",
|
||||
},
|
||||
maxZoom: 18, // Current working limit (TODO: extend to 20 with optimization)
|
||||
minZoom: 13, // Don't load at far zoom levels
|
||||
opacity: 0.8,
|
||||
}
|
||||
```
|
||||
|
||||
**Additional Optimizations:**
|
||||
- Add WMS tiled parameter: `tiled: true`
|
||||
- Reduce requested layers to essential only
|
||||
- Implement progressive loading (load parcels first, then details)
|
||||
|
||||
**Success Criteria:** Acceptable load times (<3s) at zoom 15-18, prepare for zoom 20 support
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Layer Management (Week 2)
|
||||
|
||||
### 2.1 Remove/Document LP-Portal Layers
|
||||
**Issue:** 4 LP-Portal layers never tested, likely region-specific (Nowy Sącz)
|
||||
|
||||
**Action Plan:**
|
||||
1. Test if LP-Portal layers work outside Nowy Sącz region
|
||||
2. If region-specific: Move to separate optional configuration
|
||||
3. Document geographic limitations
|
||||
4. Consider conditional loading based on map center coordinates
|
||||
|
||||
**Options:**
|
||||
|
||||
**Option A - Remove Entirely:**
|
||||
```javascript
|
||||
// Remove from mapLayers.overlays array:
|
||||
// - LP-Portal Roads
|
||||
// - LP-Portal Street Names
|
||||
// - LP-Portal Parcels
|
||||
// - LP-Portal Survey Markers
|
||||
```
|
||||
|
||||
**Option B - Conditional Loading:**
|
||||
```javascript
|
||||
// Only show LP-Portal layers when in Nowy Sącz region
|
||||
const isInNowySecz = (lat, lng) => {
|
||||
return lat >= 49.5 && lat <= 49.7 && lng >= 20.5 && lng <= 20.8;
|
||||
};
|
||||
|
||||
// Filter overlays based on location
|
||||
const availableOverlays = mapLayers.overlays.filter(layer => {
|
||||
if (layer.name.includes('LP-Portal')) {
|
||||
return isInNowySecz(mapCenter[0], mapCenter[1]);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
```
|
||||
|
||||
**Recommendation:** Option B - Keep but make conditional
|
||||
|
||||
**Success Criteria:** Only relevant layers shown to users
|
||||
|
||||
---
|
||||
|
||||
### 2.2 Reorganize Layer Categories
|
||||
**Current:** Mixed organization, no clear hierarchy
|
||||
**Proposed:** Clear categorization with user-friendly names
|
||||
|
||||
**New Structure:**
|
||||
```javascript
|
||||
export const mapLayers = {
|
||||
base: [
|
||||
// International Base Maps
|
||||
{ name: "OpenStreetMap", ... },
|
||||
{ name: "🌍 Google Satellite", ... },
|
||||
{ name: "🌍 Google Hybrid", ... },
|
||||
{ name: "🗺️ Esri Satellite", ... },
|
||||
{ name: "🗺️ Topographic (CARTO)", ... },
|
||||
|
||||
// Polish Aerial Imagery
|
||||
{ name: "🇵🇱 Orthophoto (Standard)", ... },
|
||||
{ name: "🇵🇱 Orthophoto (High-Res)", ... }, // After fix
|
||||
],
|
||||
|
||||
overlays: {
|
||||
government: [
|
||||
{ name: "📋 Cadastral Data (Official)", ... },
|
||||
{ name: "🏗️ Spatial Planning", ... },
|
||||
],
|
||||
utility: [
|
||||
{ name: "🛣️ Google Roads", ... },
|
||||
],
|
||||
regional: [ // Only shown in specific regions
|
||||
{ name: "🏘️ LP-Portal Roads", region: "nowysacz", ... },
|
||||
{ name: "🏘️ LP-Portal Street Names", region: "nowysacz", ... },
|
||||
{ name: "🏘️ LP-Portal Parcels", region: "nowysacz", ... },
|
||||
{ name: "🏘️ LP-Portal Survey Markers", region: "nowysacz", ... },
|
||||
]
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
**Success Criteria:** Clearer user experience, better organization
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: Performance Optimization (Week 3)
|
||||
|
||||
### 3.1 Implement Tile Caching
|
||||
**Goal:** Reduce redundant WMS requests
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
// Add to WMSLayer component
|
||||
const WMSLayer = ({ url, params, opacity, attribution }) => {
|
||||
const map = useMap();
|
||||
|
||||
useEffect(() => {
|
||||
const wmsOptions = {
|
||||
// ... existing options ...
|
||||
// Add caching headers
|
||||
crossOrigin: true,
|
||||
updateWhenIdle: true,
|
||||
updateWhenZooming: false,
|
||||
keepBuffer: 2, // Keep tiles loaded from 2 screens away
|
||||
};
|
||||
|
||||
const wmsLayer = L.tileLayer.wms(url, wmsOptions);
|
||||
wmsLayer.addTo(map);
|
||||
|
||||
return () => map.removeLayer(wmsLayer);
|
||||
}, [map, url, params, opacity, attribution]);
|
||||
};
|
||||
```
|
||||
|
||||
**Success Criteria:** 30% reduction in WMS requests on pan/zoom
|
||||
|
||||
---
|
||||
|
||||
### 3.2 Add Loading States
|
||||
**Goal:** User feedback during slow WMS loads
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
// New LoadingOverlay component
|
||||
function MapLoadingOverlay({ isLoading }) {
|
||||
if (!isLoading) return null;
|
||||
|
||||
return (
|
||||
<div className="absolute top-16 right-4 bg-white dark:bg-gray-800 rounded-lg shadow-lg px-4 py-2 z-[1000]">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="animate-spin rounded-full h-4 w-4 border-2 border-blue-500 border-t-transparent"></div>
|
||||
<span className="text-sm text-gray-700 dark:text-gray-300">Loading map layers...</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Track loading state in LeafletMap
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
map.on('layeradd', () => setIsLoading(true));
|
||||
map.on('load', () => setIsLoading(false));
|
||||
}, [map]);
|
||||
```
|
||||
|
||||
**Success Criteria:** Visual feedback for all layer loads
|
||||
|
||||
---
|
||||
|
||||
### 3.3 Implement Progressive Layer Loading
|
||||
**Goal:** Load essential layers first, details later
|
||||
|
||||
**Strategy:**
|
||||
1. **Zoom 1-12:** Base map only
|
||||
2. **Zoom 13-15:** + Basic cadastral boundaries
|
||||
3. **Zoom 16-18:** + Parcel numbers, buildings
|
||||
4. **Zoom 19-20:** + Survey markers, detailed overlays
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
// Auto-enable/disable overlays based on zoom
|
||||
function ZoomBasedOverlayManager() {
|
||||
const map = useMap();
|
||||
const [currentZoom, setCurrentZoom] = useState(map.getZoom());
|
||||
|
||||
useEffect(() => {
|
||||
map.on('zoomend', () => {
|
||||
const zoom = map.getZoom();
|
||||
setCurrentZoom(zoom);
|
||||
|
||||
// Auto-manage overlay visibility
|
||||
if (zoom < 13) {
|
||||
// Disable all overlays at far zoom
|
||||
disableAllOverlays();
|
||||
} else if (zoom >= 16) {
|
||||
// Enable cadastral at close zoom
|
||||
enableCadastralLayer();
|
||||
}
|
||||
});
|
||||
}, [map]);
|
||||
}
|
||||
```
|
||||
|
||||
**Success Criteria:** Smooth performance at all zoom levels
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: Enhanced Features (Week 4)
|
||||
|
||||
### 4.1 Dynamic Opacity Controls
|
||||
**Goal:** User-adjustable layer transparency
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
// LayerOpacityControl component
|
||||
function LayerOpacityControl({ layerName, currentOpacity, onOpacityChange }) {
|
||||
return (
|
||||
<div className="flex items-center gap-2 px-2 py-1">
|
||||
<label className="text-xs text-gray-600 dark:text-gray-400 w-24 truncate">
|
||||
{layerName}
|
||||
</label>
|
||||
<input
|
||||
type="range"
|
||||
min="0"
|
||||
max="100"
|
||||
value={currentOpacity * 100}
|
||||
onChange={(e) => onOpacityChange(e.target.value / 100)}
|
||||
className="flex-1 h-1"
|
||||
/>
|
||||
<span className="text-xs text-gray-500 w-8 text-right">
|
||||
{Math.round(currentOpacity * 100)}%
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Add to layer control
|
||||
<LayersControl position="topright">
|
||||
<Overlay name="Cadastral Data">
|
||||
<WMSLayer {...layer} opacity={cadastralOpacity} />
|
||||
</Overlay>
|
||||
<LayerOpacityControl
|
||||
layerName="Cadastral"
|
||||
currentOpacity={cadastralOpacity}
|
||||
onOpacityChange={setCadastralOpacity}
|
||||
/>
|
||||
</LayersControl>
|
||||
```
|
||||
|
||||
**Success Criteria:** User can adjust opacity for all overlay layers
|
||||
|
||||
---
|
||||
|
||||
### 4.2 Layer Information Panels
|
||||
**Goal:** Show layer metadata, legends, data source info
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
// Layer metadata structure
|
||||
const layerMetadata = {
|
||||
"Polish Cadastral Data": {
|
||||
title: "Polish Cadastral Data (Działki)",
|
||||
description: "Official land parcel boundaries and property information from GUGiK",
|
||||
dataSource: "Główny Urząd Geodezji i Kartografii",
|
||||
updateFrequency: "Daily",
|
||||
coverage: "Poland nationwide",
|
||||
legend: "/images/legends/cadastral.png",
|
||||
moreInfo: "https://www.gugik.gov.pl/",
|
||||
usageNotes: "Best viewed at zoom levels 15-18. Performance may vary.",
|
||||
}
|
||||
};
|
||||
|
||||
// InfoButton component next to layer name
|
||||
<LayersControl>
|
||||
<Overlay name={
|
||||
<div className="flex items-center gap-1">
|
||||
📋 Cadastral Data
|
||||
<button onClick={() => showLayerInfo('Polish Cadastral Data')} className="...">
|
||||
ℹ️
|
||||
</button>
|
||||
</div>
|
||||
}>
|
||||
...
|
||||
</Overlay>
|
||||
</LayersControl>
|
||||
```
|
||||
|
||||
**Success Criteria:** Users understand what each layer shows
|
||||
|
||||
---
|
||||
|
||||
### 4.3 Error Handling & Fallbacks
|
||||
**Goal:** Graceful degradation when layers fail
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
// WMSLayer with error handling
|
||||
function WMSLayer({ url, params, opacity, attribution, fallbackLayer }) {
|
||||
const map = useMap();
|
||||
const [hasError, setHasError] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const wmsLayer = L.tileLayer.wms(url, wmsOptions);
|
||||
|
||||
// Track tile errors
|
||||
wmsLayer.on('tileerror', (error) => {
|
||||
console.error(`WMS tile error for ${params.layers}:`, error);
|
||||
setHasError(true);
|
||||
|
||||
// Show user notification
|
||||
showNotification({
|
||||
type: 'warning',
|
||||
message: `Layer "${params.layers}" is experiencing issues`,
|
||||
duration: 5000
|
||||
});
|
||||
});
|
||||
|
||||
wmsLayer.addTo(map);
|
||||
|
||||
// If too many errors, switch to fallback
|
||||
if (hasError && fallbackLayer) {
|
||||
setTimeout(() => {
|
||||
map.removeLayer(wmsLayer);
|
||||
fallbackLayer.addTo(map);
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
return () => map.removeLayer(wmsLayer);
|
||||
}, [map, url, params, hasError]);
|
||||
}
|
||||
```
|
||||
|
||||
**Success Criteria:** No silent failures, users informed of issues
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: Code Quality (Week 5)
|
||||
|
||||
### 5.1 Consolidate Map Components
|
||||
**Current Issue:** Multiple similar map components (ComprehensivePolishMap, ImprovedPolishOrthophotoMap, etc.)
|
||||
|
||||
**Action Plan:**
|
||||
1. Audit all map components:
|
||||
- LeafletMap.js (main)
|
||||
- ProjectMap.js (wrapper)
|
||||
- ComprehensivePolishMap.js
|
||||
- ImprovedPolishOrthophotoMap.js
|
||||
- PolishOrthophotoMap.js
|
||||
- AdvancedPolishOrthophotoMap.js
|
||||
- TransparencyDemoMap.js
|
||||
- CustomWMTSMap.js
|
||||
- EnhancedLeafletMap.js
|
||||
|
||||
2. Determine which are:
|
||||
- Production (keep)
|
||||
- Deprecated (remove)
|
||||
- Experimental (move to /docs/examples)
|
||||
|
||||
**Recommendation:**
|
||||
```
|
||||
KEEP:
|
||||
- LeafletMap.js (main production component)
|
||||
- ProjectMap.js (SSR wrapper)
|
||||
|
||||
MOVE TO /docs/examples:
|
||||
- TransparencyDemoMap.js (example of opacity controls)
|
||||
- CustomWMTSMap.js (example of custom WMTS)
|
||||
|
||||
DEPRECATE/REMOVE:
|
||||
- ComprehensivePolishMap.js (superseded by LeafletMap)
|
||||
- ImprovedPolishOrthophotoMap.js (experimental)
|
||||
- PolishOrthophotoMap.js (old version)
|
||||
- AdvancedPolishOrthophotoMap.js (experimental)
|
||||
- EnhancedLeafletMap.js (duplicate?)
|
||||
```
|
||||
|
||||
**Success Criteria:** Single source of truth for map rendering
|
||||
|
||||
---
|
||||
|
||||
### 5.2 Improve WMTS Capabilities Parsing
|
||||
**Current Issue:** wmtsCapabilities.js has placeholder code
|
||||
|
||||
**Options:**
|
||||
|
||||
**Option A - Complete XML Parsing:**
|
||||
```javascript
|
||||
export async function parseWMTSCapabilities(url) {
|
||||
const response = await fetch(`${url}?Service=WMTS&Request=GetCapabilities`);
|
||||
const xmlText = await response.text();
|
||||
const parser = new DOMParser();
|
||||
const xml = parser.parseFromString(xmlText, 'text/xml');
|
||||
|
||||
const layers = Array.from(xml.querySelectorAll('Layer')).map(layer => ({
|
||||
id: layer.querySelector('Identifier')?.textContent,
|
||||
title: layer.querySelector('Title')?.textContent,
|
||||
formats: Array.from(layer.querySelectorAll('Format')).map(f => f.textContent),
|
||||
tileMatrixSets: Array.from(layer.querySelectorAll('TileMatrixSet')).map(t => t.textContent),
|
||||
}));
|
||||
|
||||
return { layers };
|
||||
}
|
||||
```
|
||||
|
||||
**Option B - Remove and Document:**
|
||||
- Remove wmtsCapabilities.js
|
||||
- Document WMTS configuration in MAP_LAYERS.md
|
||||
- Use manual configuration (current working approach)
|
||||
|
||||
**Recommendation:** Option B - Keep it simple, current approach works
|
||||
|
||||
**Success Criteria:** No dead code, clear documentation
|
||||
|
||||
---
|
||||
|
||||
### 5.3 Add TypeScript/JSDoc Types
|
||||
**Goal:** Better IDE support and type safety
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
/**
|
||||
* @typedef {Object} LayerConfig
|
||||
* @property {string} name - Display name for the layer
|
||||
* @property {'tile'|'wms'} type - Layer type
|
||||
* @property {string} url - Service URL
|
||||
* @property {string} attribution - Attribution HTML
|
||||
* @property {number} [maxZoom=20] - Maximum zoom level
|
||||
* @property {number} [minZoom=0] - Minimum zoom level
|
||||
* @property {number} [opacity=1.0] - Layer opacity (0-1)
|
||||
* @property {boolean} [checked=false] - Default enabled state
|
||||
* @property {Object} [params] - WMS parameters (for WMS layers)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} MapLayersConfig
|
||||
* @property {LayerConfig[]} base - Base layer options
|
||||
* @property {LayerConfig[]} overlays - Overlay layer options
|
||||
*/
|
||||
|
||||
/** @type {MapLayersConfig} */
|
||||
export const mapLayers = {
|
||||
base: [...],
|
||||
overlays: [...]
|
||||
};
|
||||
```
|
||||
|
||||
**Success Criteria:** Better autocomplete and error detection
|
||||
|
||||
---
|
||||
|
||||
## Phase 6: Testing & Documentation (Week 6)
|
||||
|
||||
### 6.1 Create Layer Test Suite
|
||||
**Goal:** Automated testing of layer availability
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
// __tests__/map-layers.test.js
|
||||
describe('Map Layers', () => {
|
||||
describe('Base Layers', () => {
|
||||
test('OSM tiles are accessible', async () => {
|
||||
const response = await fetch('https://a.tile.openstreetmap.org/15/17560/11326.png');
|
||||
expect(response.status).toBe(200);
|
||||
});
|
||||
|
||||
test('Polish Orthophoto Standard is accessible', async () => {
|
||||
const url = 'https://mapy.geoportal.gov.pl/wss/service/PZGIK/ORTO/WMTS/StandardResolution?Service=WMTS&Request=GetCapabilities';
|
||||
const response = await fetch(url);
|
||||
expect(response.status).toBe(200);
|
||||
});
|
||||
});
|
||||
|
||||
describe('WMS Overlays', () => {
|
||||
test('Cadastral WMS GetCapabilities works', async () => {
|
||||
const url = 'https://integracja.gugik.gov.pl/cgi-bin/KrajowaIntegracjaEwidencjiGruntow?Service=WMS&Request=GetCapabilities';
|
||||
const response = await fetch(url);
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.headers.get('content-type')).toContain('xml');
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
**Success Criteria:** All layers validated before deployment
|
||||
|
||||
---
|
||||
|
||||
### 6.2 Update Documentation
|
||||
**Files to Update:**
|
||||
1. MAP_LAYERS.md - Add troubleshooting section
|
||||
2. LAYER_NOTES.md - Keep updated with testing
|
||||
3. README.md - Add maps usage section
|
||||
|
||||
**New Documentation:**
|
||||
```markdown
|
||||
## Troubleshooting Map Layers
|
||||
|
||||
### Slow Loading Cadastral Data
|
||||
- **Cause:** GUGiK WMS servers are resource-limited
|
||||
- **Solution:** Only enable at zoom 15+, limit to essential layers
|
||||
- **Alternative:** Pre-cache frequently used areas
|
||||
|
||||
### Polish Orthophoto Not Loading
|
||||
- **Check:** Zoom level (works up to 19, not 20)
|
||||
- **Check:** Network connectivity to geoportal.gov.pl
|
||||
- **Alternative:** Use Google Satellite or Esri
|
||||
|
||||
### Layer Control Not Showing
|
||||
- **Cause:** Map container too small
|
||||
- **Solution:** Minimum map height of 400px recommended
|
||||
```
|
||||
|
||||
**Success Criteria:** Users can self-service common issues
|
||||
|
||||
---
|
||||
|
||||
## Implementation Priority Matrix
|
||||
|
||||
| Priority | Phase | Task | Impact | Effort | Status |
|
||||
|----------|-------|------|--------|--------|--------|
|
||||
| 🔴 P0 | 1 | Fix Polish Orthophoto High-Res | High | Low | Not Started |
|
||||
| 🔴 P0 | 1 | Add zoom restrictions to Cadastral | High | Low | Not Started |
|
||||
| 🟡 P1 | 1 | Fix/Remove Spatial Planning | Medium | Medium | Not Started |
|
||||
| 🟡 P1 | 2 | Document LP-Portal region limits | Medium | Low | Not Started |
|
||||
| 🟡 P1 | 3 | Add loading indicators | Medium | Low | Not Started |
|
||||
| 🟢 P2 | 2 | Reorganize layer categories | Low | Medium | Not Started |
|
||||
| 🟢 P2 | 4 | Add opacity controls | Low | Medium | Not Started |
|
||||
| 🟢 P2 | 4 | Add layer info panels | Low | High | Not Started |
|
||||
| 🟢 P3 | 5 | Consolidate map components | Low | High | Not Started |
|
||||
| 🟢 P3 | 6 | Add automated tests | Low | Medium | Not Started |
|
||||
|
||||
---
|
||||
|
||||
## Quick Wins (Do First)
|
||||
|
||||
These can be implemented in 1-2 hours with immediate impact:
|
||||
|
||||
1. **Add minZoom to performance-heavy layers**
|
||||
- Prevent loading at far zoom levels (minZoom: 13 for Cadastral)
|
||||
- Reduce unnecessary requests at distant zoom
|
||||
|
||||
2. **Optimize Cadastral layer requests**
|
||||
- Reduce number of requested WMS layers
|
||||
- Add tiled parameter for better performance
|
||||
|
||||
3. **Remove broken Spatial Planning layer**
|
||||
- If GetCapabilities fails, just remove it
|
||||
- Better than showing broken functionality
|
||||
|
||||
4. **Update layer names for clarity**
|
||||
- "Polish Orthophoto Standard" → "🇵🇱 Aerial Imagery (Standard)"
|
||||
- Better user understanding
|
||||
|
||||
5. **Add loading spinner to ProjectMap**
|
||||
- Copy LoadingOverlay component
|
||||
- Better UX during slow loads
|
||||
|
||||
6. **Verify current zoom limits**
|
||||
- Document actual working zoom ranges per layer
|
||||
- Note: Goal is zoom 20 for all layers (future optimization)
|
||||
|
||||
---
|
||||
|
||||
## Success Metrics
|
||||
|
||||
### Performance
|
||||
- [ ] All base layers load in <2 seconds
|
||||
- [ ] Cadastral overlays load in <5 seconds at zoom 15-18
|
||||
- [ ] No console errors for working layers
|
||||
- [ ] 90%+ tile success rate
|
||||
|
||||
### User Experience
|
||||
- [ ] Layer control accessible on all screen sizes
|
||||
- [ ] Clear feedback during loading
|
||||
- [ ] No broken/blank layers in production
|
||||
- [ ] Layer purposes clear from names/descriptions
|
||||
|
||||
### Code Quality
|
||||
- [ ] Single production map component
|
||||
- [ ] All map files under 500 lines
|
||||
- [ ] JSDoc types for all exports
|
||||
- [ ] 80%+ test coverage for layer configs
|
||||
|
||||
---
|
||||
|
||||
## Rollout Plan
|
||||
|
||||
### Week 1: Emergency Fixes
|
||||
- Fix critical broken layers
|
||||
- Add zoom restrictions
|
||||
- Remove non-working layers
|
||||
|
||||
### Week 2: Optimization
|
||||
- Implement caching
|
||||
- Add loading states
|
||||
- Progressive loading
|
||||
|
||||
### Week 3: Features
|
||||
- Opacity controls
|
||||
- Layer info panels
|
||||
- Error handling
|
||||
|
||||
### Week 4: Cleanup
|
||||
- Consolidate components
|
||||
- Remove experimental code
|
||||
- Update documentation
|
||||
|
||||
### Week 5: Testing
|
||||
- Automated tests
|
||||
- User acceptance testing
|
||||
- Performance benchmarking
|
||||
|
||||
### Week 6: Release
|
||||
- Deploy to production
|
||||
- Monitor performance
|
||||
- Gather user feedback
|
||||
|
||||
---
|
||||
|
||||
## Rollback Strategy
|
||||
|
||||
If issues occur:
|
||||
1. **Keep old mapLayers.js** as `mapLayers.backup.js`
|
||||
2. **Feature flags** for new functionality
|
||||
3. **Incremental rollout** - enable for admin users first
|
||||
4. **Quick disable** - config flag to revert to old layers
|
||||
|
||||
---
|
||||
|
||||
## Future Considerations
|
||||
|
||||
### Potential New Features
|
||||
- [ ] **Universal zoom 20 support for all layers**
|
||||
- Optimize WMS services to handle zoom 19-20
|
||||
- Implement tile prefetching and caching
|
||||
- Add progressive detail loading at high zoom
|
||||
- [ ] Save user layer preferences
|
||||
- [ ] Share map view URLs (with layers/zoom)
|
||||
- [ ] Export map as image/PDF
|
||||
- [ ] Offline tile caching
|
||||
- [ ] Custom layer upload (GeoJSON, KML)
|
||||
|
||||
### Alternative Services to Explore
|
||||
- [ ] Planet imagery (if budget allows)
|
||||
- [ ] Bing Maps aerial imagery
|
||||
- [ ] Additional Polish regional services
|
||||
- [ ] CORS proxies for restricted services
|
||||
|
||||
### Advanced Optimizations
|
||||
- [ ] Service worker for tile caching
|
||||
- [ ] WebGL rendering for better performance
|
||||
- [ ] Vector tiles instead of raster
|
||||
- [ ] CDN for frequently accessed tiles
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- LP-Portal layers appear to be **Nowy Sącz specific** - need regional filtering
|
||||
- Polish government servers are **consistently slow** - can't fix, only mitigate
|
||||
- Google services are **unofficial** - may break without notice
|
||||
- WMTS is more performant than WMS - prefer when available
|
||||
- **Zoom 20 support:** Long-term goal for all layers; currently some layers work only to zoom 18-19
|
||||
- Requires server-side optimization or caching strategy
|
||||
- May need to implement client-side tile scaling/interpolation
|
||||
- Keep LAYER_NOTES.md updated as testing continues
|
||||
|
||||
---
|
||||
|
||||
## Approval & Sign-off
|
||||
|
||||
- [ ] Technical review completed
|
||||
- [ ] Performance benchmarks met
|
||||
- [ ] Documentation updated
|
||||
- [ ] Stakeholder approval
|
||||
- [ ] Ready for production deployment
|
||||
|
||||
**Last Updated:** January 16, 2026
|
||||
**Next Review:** After Phase 1 completion
|
||||
Reference in New Issue
Block a user