feat: Add Improved Polish Orthophoto Map component with WMTS support
- Introduced ImprovedPolishOrthophotoMap component for displaying Polish orthophoto layers using WMTS. - Implemented custom WMTSLayer for handling tile requests. - Added Google Satellite and OpenStreetMap layers for comparison. - Included debug information for network requests to Geoportal. - Enhanced LeafletMap to support WMS overlays and improved layer control. - Created PolishGeoLayers module for easy access to various Polish geospatial layers. - Added TransparencyDemoMap for adjustable layer opacity controls. - Updated mapLayers configuration to include new Polish orthophoto layers and WMS overlays. - Refactored wmtsCapabilities to use updated URLs and parameters for better compatibility.
This commit is contained in:
347
src/app/comprehensive-polish-map/page.js
Normal file
347
src/app/comprehensive-polish-map/page.js
Normal file
@@ -0,0 +1,347 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from 'react';
|
||||
import ComprehensivePolishMap from '../../components/ui/ComprehensivePolishMap';
|
||||
|
||||
export default function ComprehensivePolishMapPage() {
|
||||
const [selectedLocation, setSelectedLocation] = useState('krakow');
|
||||
|
||||
// Different locations to test the layers
|
||||
const locations = {
|
||||
krakow: {
|
||||
center: [50.0647, 19.9450],
|
||||
zoom: 14,
|
||||
name: "Kraków",
|
||||
description: "Historic city center with good cadastral data coverage"
|
||||
},
|
||||
warsaw: {
|
||||
center: [52.2297, 21.0122],
|
||||
zoom: 14,
|
||||
name: "Warszawa",
|
||||
description: "Capital city with extensive planning data"
|
||||
},
|
||||
gdansk: {
|
||||
center: [54.3520, 18.6466],
|
||||
zoom: 14,
|
||||
name: "Gdańsk",
|
||||
description: "Port city with detailed property boundaries"
|
||||
},
|
||||
wroclaw: {
|
||||
center: [51.1079, 17.0385],
|
||||
zoom: 14,
|
||||
name: "Wrocław",
|
||||
description: "University city with good orthophoto coverage"
|
||||
},
|
||||
poznan: {
|
||||
center: [52.4064, 16.9252],
|
||||
zoom: 14,
|
||||
name: "Poznań",
|
||||
description: "Industrial center with road network data"
|
||||
}
|
||||
};
|
||||
|
||||
const currentLocation = locations[selectedLocation];
|
||||
|
||||
// Test markers for selected location
|
||||
const testMarkers = [
|
||||
{
|
||||
position: currentLocation.center,
|
||||
popup: `${currentLocation.name} - ${currentLocation.description}`
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-100">
|
||||
<div className="container mx-auto px-4 py-8">
|
||||
<h1 className="text-4xl font-bold text-gray-800 mb-6">
|
||||
🇵🇱 Comprehensive Polish Geospatial Data Platform
|
||||
</h1>
|
||||
|
||||
<div className="bg-green-50 border border-green-200 rounded-lg p-6 mb-6">
|
||||
<h2 className="text-xl font-semibold text-green-800 mb-3">
|
||||
All Polish Layers Implementation Complete! 🎉
|
||||
</h2>
|
||||
<p className="text-green-700 mb-4">
|
||||
This comprehensive map includes all layers from your OpenLayers implementation,
|
||||
converted to work seamlessly with your Leaflet-based React/Next.js project.
|
||||
</p>
|
||||
<div className="grid md:grid-cols-2 gap-4 text-sm">
|
||||
<div>
|
||||
<strong className="text-green-800">Base Layers:</strong>
|
||||
<ul className="mt-1 text-green-700">
|
||||
<li>• Polish Orthophoto (Standard & High Resolution)</li>
|
||||
<li>• OpenStreetMap, Google Maps, Esri Satellite</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<strong className="text-green-800">Overlay Layers:</strong>
|
||||
<ul className="mt-1 text-green-700">
|
||||
<li>• Cadastral Data, Spatial Planning</li>
|
||||
<li>• LP-Portal Roads, Street Names, Parcels, Surveys</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Location Selector */}
|
||||
<div className="bg-white rounded-lg shadow-lg p-4 mb-6">
|
||||
<h3 className="text-lg font-semibold text-gray-800 mb-3">
|
||||
🎯 Select Test Location:
|
||||
</h3>
|
||||
<div className="grid grid-cols-2 md:grid-cols-5 gap-2">
|
||||
{Object.entries(locations).map(([key, location]) => (
|
||||
<button
|
||||
key={key}
|
||||
onClick={() => setSelectedLocation(key)}
|
||||
className={`px-3 py-2 rounded-lg text-sm transition-colors ${
|
||||
selectedLocation === key
|
||||
? 'bg-blue-600 text-white'
|
||||
: 'bg-gray-200 text-gray-700 hover:bg-gray-300'
|
||||
}`}
|
||||
>
|
||||
{location.name}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<p className="text-sm text-gray-600 mt-2">
|
||||
<strong>Current:</strong> {currentLocation.description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Map Container */}
|
||||
<div className="bg-white rounded-lg shadow-lg overflow-hidden">
|
||||
<div className="p-4 bg-blue-600 text-white">
|
||||
<h2 className="text-xl font-semibold">
|
||||
Interactive Map: {currentLocation.name}
|
||||
</h2>
|
||||
<p className="text-blue-100 mt-2">
|
||||
Use the layer control (top-right) to toggle between base layers and enable overlay layers.
|
||||
Combine orthophoto with cadastral data for detailed property analysis.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="h-96 md:h-[700px]">
|
||||
<ComprehensivePolishMap
|
||||
key={selectedLocation} // Force re-render when location changes
|
||||
center={currentLocation.center}
|
||||
zoom={currentLocation.zoom}
|
||||
markers={testMarkers}
|
||||
showLayerControl={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Layer Information */}
|
||||
<div className="mt-8 grid md:grid-cols-2 gap-6">
|
||||
{/* Base Layers */}
|
||||
<div className="bg-white rounded-lg shadow-lg p-6">
|
||||
<h3 className="text-lg font-semibold text-gray-800 mb-4 flex items-center">
|
||||
🗺️ Base Layers
|
||||
</h3>
|
||||
<div className="space-y-3 text-sm">
|
||||
<div className="flex items-start">
|
||||
<span className="w-4 h-4 bg-green-500 rounded-full mr-3 mt-0.5 flex-shrink-0"></span>
|
||||
<div>
|
||||
<strong>Polish Orthophoto (Standard)</strong>
|
||||
<p className="text-gray-600 mt-1">High-quality aerial imagery from Polish Geoportal</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start">
|
||||
<span className="w-4 h-4 bg-emerald-500 rounded-full mr-3 mt-0.5 flex-shrink-0"></span>
|
||||
<div>
|
||||
<strong>Polish Orthophoto (High Resolution)</strong>
|
||||
<p className="text-gray-600 mt-1">Ultra-high resolution aerial imagery for detailed analysis</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start">
|
||||
<span className="w-4 h-4 bg-blue-500 rounded-full mr-3 mt-0.5 flex-shrink-0"></span>
|
||||
<div>
|
||||
<strong>OpenStreetMap</strong>
|
||||
<p className="text-gray-600 mt-1">Community-driven map data</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start">
|
||||
<span className="w-4 h-4 bg-red-500 rounded-full mr-3 mt-0.5 flex-shrink-0"></span>
|
||||
<div>
|
||||
<strong>Google Maps</strong>
|
||||
<p className="text-gray-600 mt-1">Satellite imagery and road overlay</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Overlay Layers */}
|
||||
<div className="bg-white rounded-lg shadow-lg p-6">
|
||||
<h3 className="text-lg font-semibold text-gray-800 mb-4 flex items-center">
|
||||
📊 Overlay Layers
|
||||
</h3> <div className="space-y-3 text-sm">
|
||||
<div className="flex items-start">
|
||||
<span className="w-4 h-4 bg-orange-500 rounded-full mr-3 mt-0.5 flex-shrink-0"></span>
|
||||
<div>
|
||||
<strong>📋 Polish Cadastral Data</strong>
|
||||
<p className="text-gray-600 mt-1">Property boundaries, parcels, and building outlines</p>
|
||||
<p className="text-xs text-gray-500">Opacity: 80% - Semi-transparent overlay</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start">
|
||||
<span className="w-4 h-4 bg-purple-500 rounded-full mr-3 mt-0.5 flex-shrink-0"></span>
|
||||
<div>
|
||||
<strong>🏗️ Polish Spatial Planning</strong>
|
||||
<p className="text-gray-600 mt-1">Zoning data and urban planning information</p>
|
||||
<p className="text-xs text-gray-500">Opacity: 70% - Semi-transparent overlay</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start">
|
||||
<span className="w-4 h-4 bg-teal-500 rounded-full mr-3 mt-0.5 flex-shrink-0"></span>
|
||||
<div>
|
||||
<strong>🛣️ LP-Portal Roads</strong>
|
||||
<p className="text-gray-600 mt-1">Detailed road network data</p>
|
||||
<p className="text-xs text-gray-500">Opacity: 90% - Mostly opaque for visibility</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start">
|
||||
<span className="w-4 h-4 bg-indigo-500 rounded-full mr-3 mt-0.5 flex-shrink-0"></span>
|
||||
<div>
|
||||
<strong>🏷️ LP-Portal Street Names</strong>
|
||||
<p className="text-gray-600 mt-1">Street names and road descriptions</p>
|
||||
<p className="text-xs text-gray-500">Opacity: 100% - Fully opaque for readability</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start">
|
||||
<span className="w-4 h-4 bg-pink-500 rounded-full mr-3 mt-0.5 flex-shrink-0"></span>
|
||||
<div>
|
||||
<strong>📐 LP-Portal Parcels & Surveys</strong>
|
||||
<p className="text-gray-600 mt-1">Property parcels and survey markers</p>
|
||||
<p className="text-xs text-gray-500">Opacity: 60-80% - Variable transparency</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Transparency Information */}
|
||||
<div className="mt-8 bg-green-50 border border-green-200 rounded-lg p-6">
|
||||
<h3 className="text-lg font-semibold text-green-800 mb-4">
|
||||
🎨 Layer Transparency Handling
|
||||
</h3>
|
||||
<div className="grid md:grid-cols-2 gap-6 text-sm">
|
||||
<div>
|
||||
<h4 className="font-semibold text-green-700 mb-3">Base Layers (Opaque):</h4>
|
||||
<div className="space-y-2">
|
||||
<div className="flex justify-between">
|
||||
<span>Polish Orthophoto</span>
|
||||
<span className="bg-green-200 px-2 py-1 rounded text-xs">100% Opaque</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span>Google Satellite/Roads</span>
|
||||
<span className="bg-green-200 px-2 py-1 rounded text-xs">100% Opaque</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h4 className="font-semibold text-green-700 mb-3">Overlay Layers (Transparent):</h4>
|
||||
<div className="space-y-2">
|
||||
<div className="flex justify-between">
|
||||
<span>📋 Cadastral Data</span>
|
||||
<span className="bg-yellow-200 px-2 py-1 rounded text-xs">80% Opacity</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span>🏗️ Spatial Planning</span>
|
||||
<span className="bg-yellow-200 px-2 py-1 rounded text-xs">70% Opacity</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span>🛣️ Roads</span>
|
||||
<span className="bg-blue-200 px-2 py-1 rounded text-xs">90% Opacity</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span>🏷️ Street Names</span>
|
||||
<span className="bg-green-200 px-2 py-1 rounded text-xs">100% Opacity</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span>📐 Parcels</span>
|
||||
<span className="bg-orange-200 px-2 py-1 rounded text-xs">60% Opacity</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span>📍 Survey Markers</span>
|
||||
<span className="bg-yellow-200 px-2 py-1 rounded text-xs">80% Opacity</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-4 p-3 bg-green-100 rounded">
|
||||
<p className="text-green-800 text-sm">
|
||||
<strong>Smart Transparency:</strong> Each overlay layer has been optimized with appropriate transparency levels.
|
||||
Property boundaries are semi-transparent (60-80%) so you can see the underlying imagery,
|
||||
while text labels are fully opaque (100%) for maximum readability.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Usage Guide */}
|
||||
<div className="mt-8 bg-blue-50 border border-blue-200 rounded-lg p-6">
|
||||
<h3 className="text-lg font-semibold text-blue-800 mb-4">
|
||||
📋 How to Use This Comprehensive Map
|
||||
</h3>
|
||||
<div className="grid md:grid-cols-2 gap-6">
|
||||
<div>
|
||||
<h4 className="font-semibold text-blue-700 mb-2">Basic Navigation:</h4>
|
||||
<ul className="text-blue-600 space-y-1 text-sm">
|
||||
<li>• Use mouse wheel to zoom in/out</li>
|
||||
<li>• Click and drag to pan around</li>
|
||||
<li>• Use layer control (top-right) to switch layers</li>
|
||||
<li>• Select different Polish cities above to test</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-blue-700 mb-2">Advanced Features:</h4>
|
||||
<ul className="text-blue-600 space-y-1 text-sm">
|
||||
<li>• Combine orthophoto with cadastral overlay</li>
|
||||
<li>• Enable multiple overlays simultaneously</li>
|
||||
<li>• Use high-resolution orthophoto for detail work</li>
|
||||
<li>• Compare with Google/OSM base layers</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Technical Implementation */}
|
||||
<div className="mt-8 bg-gray-50 border border-gray-200 rounded-lg p-6">
|
||||
<h3 className="text-lg font-semibold text-gray-800 mb-4">
|
||||
⚙️ Technical Implementation Details
|
||||
</h3>
|
||||
<div className="grid md:grid-cols-3 gap-6 text-sm">
|
||||
<div>
|
||||
<h4 className="font-semibold text-gray-700 mb-2">WMTS Integration:</h4>
|
||||
<ul className="text-gray-600 space-y-1">
|
||||
<li>• Proper KVP URL construction</li>
|
||||
<li>• EPSG:3857 coordinate system</li>
|
||||
<li>• Standard and high-res orthophoto</li>
|
||||
<li>• Multiple format support (JPEG/PNG)</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-gray-700 mb-2">WMS Overlays:</h4>
|
||||
<ul className="text-gray-600 space-y-1">
|
||||
<li>• Polish government services</li>
|
||||
<li>• LP-Portal municipal data</li>
|
||||
<li>• Transparent overlay support</li>
|
||||
<li>• Multiple layer combinations</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-gray-700 mb-2">React/Leaflet:</h4>
|
||||
<ul className="text-gray-600 space-y-1">
|
||||
<li>• React-Leaflet component integration</li>
|
||||
<li>• Dynamic layer switching</li>
|
||||
<li>• Responsive design</li>
|
||||
<li>• Performance optimized</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
103
src/app/debug-polish-orthophoto/page.js
Normal file
103
src/app/debug-polish-orthophoto/page.js
Normal file
@@ -0,0 +1,103 @@
|
||||
"use client";
|
||||
|
||||
import DebugPolishOrthophotoMap from '../../components/ui/DebugPolishOrthophotoMap';
|
||||
|
||||
export default function DebugPolishOrthophotoPage() {
|
||||
// Test marker in Poland
|
||||
const testMarkers = [
|
||||
{
|
||||
position: [50.0647, 19.9450], // Krakow
|
||||
popup: "Kraków - Test Location"
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-100">
|
||||
<div className="container mx-auto px-4 py-8">
|
||||
<h1 className="text-3xl font-bold text-gray-800 mb-6">
|
||||
Debug Polish Geoportal Orthophoto
|
||||
</h1>
|
||||
|
||||
<div className="bg-red-50 border border-red-200 rounded-lg p-4 mb-6">
|
||||
<h2 className="text-lg font-semibold text-red-800 mb-2">
|
||||
Debug Mode Active
|
||||
</h2>
|
||||
<p className="text-red-700">
|
||||
This page tests multiple URL formats for Polish Geoportal orthophoto tiles.
|
||||
Check the browser console and the debug panel on the map for network request information.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-white rounded-lg shadow-lg overflow-hidden">
|
||||
<div className="p-4 bg-blue-600 text-white">
|
||||
<h2 className="text-xl font-semibold">Debug Map with Multiple Orthophoto Options</h2>
|
||||
<p className="text-blue-100 mt-2">
|
||||
Try switching between different Polish orthophoto options using the layer control.
|
||||
Google layers are included as working references.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="h-96 md:h-[600px]">
|
||||
<DebugPolishOrthophotoMap
|
||||
center={[50.0647, 19.9450]} // Centered on Krakow
|
||||
zoom={12}
|
||||
markers={testMarkers}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-8 bg-white rounded-lg shadow-lg p-6">
|
||||
<h3 className="text-lg font-semibold text-gray-800 mb-4">
|
||||
URL Formats Being Tested:
|
||||
</h3>
|
||||
<div className="space-y-4 text-sm"> <div className="bg-gray-50 p-3 rounded">
|
||||
<strong>Option 1 (WMTS KVP EPSG:3857):</strong>
|
||||
<code className="block mt-1 text-xs">
|
||||
?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=ORTO&STYLE=default&TILEMATRIXSET=EPSG:3857&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&FORMAT=image/jpeg
|
||||
</code>
|
||||
<span className="text-gray-600">Standard Web Mercator projection</span>
|
||||
</div>
|
||||
|
||||
<div className="bg-gray-50 p-3 rounded">
|
||||
<strong>Option 2 (WMTS KVP EPSG:2180):</strong>
|
||||
<code className="block mt-1 text-xs">
|
||||
?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=ORTO&STYLE=default&TILEMATRIXSET=EPSG:2180&TILEMATRIX=EPSG:2180:{z}&TILEROW={y}&TILECOL={x}&FORMAT=image/jpeg
|
||||
</code>
|
||||
<span className="text-gray-600">Polish coordinate system</span>
|
||||
</div>
|
||||
|
||||
<div className="bg-gray-50 p-3 rounded">
|
||||
<strong>Option 3 (Alternative TILEMATRIXSET):</strong>
|
||||
<code className="block mt-1 text-xs">
|
||||
?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=ORTO&STYLE=default&TILEMATRIXSET=GoogleMapsCompatible&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&FORMAT=image/jpeg
|
||||
</code>
|
||||
<span className="text-gray-600">Google Maps compatible matrix</span>
|
||||
</div>
|
||||
|
||||
<div className="bg-gray-50 p-3 rounded">
|
||||
<strong>Option 4 (PNG format):</strong>
|
||||
<code className="block mt-1 text-xs">
|
||||
?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=ORTO&STYLE=default&TILEMATRIXSET=EPSG:3857&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&FORMAT=image/png
|
||||
</code>
|
||||
<span className="text-gray-600">PNG format instead of JPEG</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-8 bg-yellow-50 border border-yellow-200 rounded-lg p-6">
|
||||
<h3 className="text-lg font-semibold text-yellow-800 mb-2">
|
||||
Debug Instructions:
|
||||
</h3>
|
||||
<ol className="text-yellow-700 space-y-2">
|
||||
<li><strong>1.</strong> Open browser Developer Tools (F12) and go to Network tab</li>
|
||||
<li><strong>2.</strong> Switch between different Polish orthophoto options in the layer control</li>
|
||||
<li><strong>3.</strong> Look for requests to geoportal.gov.pl in the Network tab</li>
|
||||
<li><strong>4.</strong> Check the debug panel on the map for request/response info</li>
|
||||
<li><strong>5.</strong> Note which options return 200 OK vs 404/403 errors</li>
|
||||
<li><strong>6.</strong> Compare with working Google layers</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
99
src/app/test-improved-wmts/page.js
Normal file
99
src/app/test-improved-wmts/page.js
Normal file
@@ -0,0 +1,99 @@
|
||||
"use client";
|
||||
|
||||
import ImprovedPolishOrthophotoMap from '../../components/ui/ImprovedPolishOrthophotoMap';
|
||||
|
||||
export default function ImprovedPolishOrthophotoPage() {
|
||||
const testMarkers = [
|
||||
{
|
||||
position: [50.0647, 19.9450], // Krakow
|
||||
popup: "Kraków - Testing WMTS"
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-100">
|
||||
<div className="container mx-auto px-4 py-8">
|
||||
<h1 className="text-3xl font-bold text-gray-800 mb-6">
|
||||
Improved Polish WMTS Implementation
|
||||
</h1>
|
||||
|
||||
<div className="bg-green-50 border border-green-200 rounded-lg p-4 mb-6">
|
||||
<h2 className="text-lg font-semibold text-green-800 mb-2">
|
||||
Custom WMTS Layer Implementation
|
||||
</h2>
|
||||
<p className="text-green-700">
|
||||
This version uses a custom WMTS layer that properly constructs KVP URLs based on the GetCapabilities response.
|
||||
Check the debug panel on the map to see the actual requests being made.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-white rounded-lg shadow-lg overflow-hidden">
|
||||
<div className="p-4 bg-blue-600 text-white">
|
||||
<h2 className="text-xl font-semibold">Custom WMTS Layer with Proper KVP URLs</h2>
|
||||
<p className="text-blue-100 mt-2">
|
||||
This implementation builds proper WMTS GetTile requests with all required parameters.
|
||||
Monitor the debug panel and browser network tab for request details.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="h-96 md:h-[600px]">
|
||||
<ImprovedPolishOrthophotoMap
|
||||
center={[50.0647, 19.9450]}
|
||||
zoom={12}
|
||||
markers={testMarkers}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-8 bg-white rounded-lg shadow-lg p-6">
|
||||
<h3 className="text-lg font-semibold text-gray-800 mb-4">
|
||||
WMTS Parameters Being Tested:
|
||||
</h3>
|
||||
<div className="grid md:grid-cols-2 gap-4 text-sm">
|
||||
<div className="bg-gray-50 p-3 rounded">
|
||||
<strong>Tile Matrix Sets Available:</strong>
|
||||
<ul className="mt-2 space-y-1">
|
||||
<li>• EPSG:3857 (Web Mercator)</li>
|
||||
<li>• EPSG:4326 (WGS84)</li>
|
||||
<li>• EPSG:2180 (Polish National Grid)</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="bg-gray-50 p-3 rounded">
|
||||
<strong>Formats Available:</strong>
|
||||
<ul className="mt-2 space-y-1">
|
||||
<li>• image/jpeg (default)</li>
|
||||
<li>• image/png</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-6 bg-blue-50 border border-blue-200 rounded-lg p-6">
|
||||
<h3 className="text-lg font-semibold text-blue-800 mb-2">
|
||||
Testing Instructions:
|
||||
</h3>
|
||||
<ol className="text-blue-700 space-y-2">
|
||||
<li><strong>1.</strong> Open Browser Developer Tools (F12) → Network tab</li>
|
||||
<li><strong>2.</strong> Filter by "geoportal.gov.pl" to see WMTS requests</li>
|
||||
<li><strong>3.</strong> Switch between different Polish WMTS options</li>
|
||||
<li><strong>4.</strong> Check if requests return 200 OK or error codes</li>
|
||||
<li><strong>5.</strong> Compare with Google Satellite (known working)</li>
|
||||
<li><strong>6.</strong> Monitor the debug panel for request URLs</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<div className="mt-6 bg-yellow-50 border border-yellow-200 rounded-lg p-6">
|
||||
<h3 className="text-lg font-semibold text-yellow-800 mb-2">
|
||||
Expected Behavior:
|
||||
</h3>
|
||||
<p className="text-yellow-700">
|
||||
If the Polish orthophoto tiles appear, you should see aerial imagery of Poland.
|
||||
If they don't load, check the network requests - they should show proper WMTS GetTile URLs
|
||||
with all required parameters (SERVICE, REQUEST, LAYER, TILEMATRIXSET, etc.).
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
202
src/app/test-polish-map/page.js
Normal file
202
src/app/test-polish-map/page.js
Normal file
@@ -0,0 +1,202 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from 'react';
|
||||
import PolishOrthophotoMap from '../../components/ui/PolishOrthophotoMap';
|
||||
import AdvancedPolishOrthophotoMap from '../../components/ui/AdvancedPolishOrthophotoMap';
|
||||
|
||||
export default function PolishOrthophotoTestPage() {
|
||||
const [activeMap, setActiveMap] = useState('basic');
|
||||
|
||||
// Test markers - various locations in Poland
|
||||
const testMarkers = [
|
||||
{
|
||||
position: [50.0647, 19.9450], // Krakow
|
||||
popup: "Kraków - Main Market Square"
|
||||
},
|
||||
{
|
||||
position: [52.2297, 21.0122], // Warsaw
|
||||
popup: "Warszawa - Palace of Culture and Science"
|
||||
},
|
||||
{
|
||||
position: [54.3520, 18.6466], // Gdansk
|
||||
popup: "Gdańsk - Old Town"
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-100">
|
||||
<div className="container mx-auto px-4 py-8">
|
||||
<h1 className="text-3xl font-bold text-gray-800 mb-6">
|
||||
Polish Geoportal Orthophoto Integration
|
||||
</h1>
|
||||
|
||||
{/* Map Type Selector */}
|
||||
<div className="mb-6 bg-white rounded-lg shadow-lg p-4">
|
||||
<h2 className="text-lg font-semibold text-gray-800 mb-3">
|
||||
Choose Map Implementation:
|
||||
</h2>
|
||||
<div className="flex space-x-4">
|
||||
<button
|
||||
onClick={() => setActiveMap('basic')}
|
||||
className={`px-4 py-2 rounded-lg transition-colors ${
|
||||
activeMap === 'basic'
|
||||
? 'bg-blue-600 text-white'
|
||||
: 'bg-gray-200 text-gray-700 hover:bg-gray-300'
|
||||
}`}
|
||||
>
|
||||
Basic Polish Orthophoto
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveMap('advanced')}
|
||||
className={`px-4 py-2 rounded-lg transition-colors ${
|
||||
activeMap === 'advanced'
|
||||
? 'bg-blue-600 text-white'
|
||||
: 'bg-gray-200 text-gray-700 hover:bg-gray-300'
|
||||
}`}
|
||||
>
|
||||
Advanced with WMS Overlays
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Map Container */}
|
||||
<div className="bg-white rounded-lg shadow-lg overflow-hidden">
|
||||
<div className="p-4 bg-blue-600 text-white">
|
||||
<h2 className="text-xl font-semibold">
|
||||
{activeMap === 'basic'
|
||||
? 'Basic Polish Orthophoto Map'
|
||||
: 'Advanced Polish Orthophoto with WMS Overlays'
|
||||
}
|
||||
</h2>
|
||||
<p className="text-blue-100 mt-2">
|
||||
{activeMap === 'basic'
|
||||
? 'Demonstrates working Polish Geoportal orthophoto tiles with multiple base layer options.'
|
||||
: 'Advanced version includes Polish cadastral data (działki) and spatial planning (MPZT) as overlay layers.'
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="h-96 md:h-[600px]">
|
||||
{activeMap === 'basic' ? (
|
||||
<PolishOrthophotoMap
|
||||
center={[50.0647, 19.9450]} // Centered on Krakow
|
||||
zoom={12}
|
||||
markers={testMarkers}
|
||||
showLayerControl={true}
|
||||
/>
|
||||
) : (
|
||||
<AdvancedPolishOrthophotoMap
|
||||
center={[50.0647, 19.9450]} // Centered on Krakow
|
||||
zoom={12}
|
||||
markers={testMarkers}
|
||||
showLayerControl={true}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Features Overview */}
|
||||
<div className="mt-8 grid md:grid-cols-2 gap-6">
|
||||
<div className="bg-white rounded-lg shadow-lg p-6">
|
||||
<h3 className="text-lg font-semibold text-gray-800 mb-4">
|
||||
Basic Map Features:
|
||||
</h3>
|
||||
<ul className="space-y-2 text-gray-600">
|
||||
<li className="flex items-center">
|
||||
<span className="w-3 h-3 bg-green-500 rounded-full mr-3"></span>
|
||||
Polish Geoportal Orthophoto (Working)
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<span className="w-3 h-3 bg-blue-500 rounded-full mr-3"></span>
|
||||
OpenStreetMap base layer
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<span className="w-3 h-3 bg-red-500 rounded-full mr-3"></span>
|
||||
Google Satellite imagery
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<span className="w-3 h-3 bg-yellow-500 rounded-full mr-3"></span>
|
||||
Google Roads overlay
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<span className="w-3 h-3 bg-purple-500 rounded-full mr-3"></span>
|
||||
Esri World Imagery
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="bg-white rounded-lg shadow-lg p-6">
|
||||
<h3 className="text-lg font-semibold text-gray-800 mb-4">
|
||||
Advanced Map Features:
|
||||
</h3>
|
||||
<ul className="space-y-2 text-gray-600">
|
||||
<li className="flex items-center">
|
||||
<span className="w-3 h-3 bg-green-500 rounded-full mr-3"></span>
|
||||
Standard & High Resolution Orthophoto
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<span className="w-3 h-3 bg-orange-500 rounded-full mr-3"></span>
|
||||
Polish Cadastral Data (WMS)
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<span className="w-3 h-3 bg-teal-500 rounded-full mr-3"></span>
|
||||
Spatial Planning Data (MPZT)
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<span className="w-3 h-3 bg-indigo-500 rounded-full mr-3"></span>
|
||||
Overlay layer support
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<span className="w-3 h-3 bg-pink-500 rounded-full mr-3"></span>
|
||||
Multiple base layers
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Technical Implementation Details */}
|
||||
<div className="mt-8 bg-white rounded-lg shadow-lg p-6">
|
||||
<h3 className="text-lg font-semibold text-gray-800 mb-4">
|
||||
Technical Implementation:
|
||||
</h3>
|
||||
<div className="grid md:grid-cols-2 gap-6">
|
||||
<div>
|
||||
<h4 className="font-semibold text-gray-700 mb-2">Key Improvements:</h4>
|
||||
<ul className="text-sm text-gray-600 space-y-1">
|
||||
<li>• Uses REST tile service instead of WMTS for better compatibility</li>
|
||||
<li>• Proper tile size (512px) with zoomOffset=-1</li>
|
||||
<li>• proj4 integration for EPSG:2180 coordinate system</li>
|
||||
<li>• Multiple fallback layers for reliability</li>
|
||||
<li>• WMS overlay support for cadastral data</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-gray-700 mb-2">Based on OpenLayers Code:</h4>
|
||||
<ul className="text-sm text-gray-600 space-y-1">
|
||||
<li>• Converted from OpenLayers to Leaflet implementation</li>
|
||||
<li>• Maintains same layer structure and URLs</li>
|
||||
<li>• Includes Polish projection definitions</li>
|
||||
<li>• Compatible with existing React/Next.js setup</li>
|
||||
<li>• Extensible for additional WMS services</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Usage Instructions */}
|
||||
<div className="mt-8 bg-blue-50 border border-blue-200 rounded-lg p-6">
|
||||
<h3 className="text-lg font-semibold text-blue-800 mb-2">
|
||||
How to Use:
|
||||
</h3>
|
||||
<div className="text-blue-700 space-y-2">
|
||||
<p><strong>1.</strong> Use the layer control (top-right) to switch between base layers</p>
|
||||
<p><strong>2.</strong> In advanced mode, enable overlay layers for cadastral/planning data</p>
|
||||
<p><strong>3.</strong> Click on markers to see location information</p>
|
||||
<p><strong>4.</strong> Zoom in to see high-resolution orthophoto details</p>
|
||||
<p><strong>5.</strong> Combine orthophoto with cadastral overlay for property boundaries</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
98
src/app/test-polish-orthophoto/page.js
Normal file
98
src/app/test-polish-orthophoto/page.js
Normal file
@@ -0,0 +1,98 @@
|
||||
"use client";
|
||||
|
||||
import PolishOrthophotoMap from '../../components/ui/PolishOrthophotoMap';
|
||||
|
||||
export default function TestPolishOrthophotoPage() {
|
||||
// Test markers - various locations in Poland
|
||||
const testMarkers = [
|
||||
{
|
||||
position: [50.0647, 19.9450], // Krakow
|
||||
popup: "Kraków - Main Market Square"
|
||||
},
|
||||
{
|
||||
position: [52.2297, 21.0122], // Warsaw
|
||||
popup: "Warszawa - Palace of Culture and Science"
|
||||
},
|
||||
{
|
||||
position: [54.3520, 18.6466], // Gdansk
|
||||
popup: "Gdańsk - Old Town"
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-100">
|
||||
<div className="container mx-auto px-4 py-8">
|
||||
<h1 className="text-3xl font-bold text-gray-800 mb-6">
|
||||
Polish Geoportal Orthophoto Map Test
|
||||
</h1>
|
||||
|
||||
<div className="bg-white rounded-lg shadow-lg overflow-hidden">
|
||||
<div className="p-4 bg-blue-600 text-white">
|
||||
<h2 className="text-xl font-semibold">Interactive Map with Polish Orthophoto</h2>
|
||||
<p className="text-blue-100 mt-2">
|
||||
This map demonstrates working Polish Geoportal orthophoto tiles.
|
||||
Use the layer control (top-right) to switch between different map layers.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="h-96 md:h-[600px]">
|
||||
<PolishOrthophotoMap
|
||||
center={[50.0647, 19.9450]} // Centered on Krakow
|
||||
zoom={12}
|
||||
markers={testMarkers}
|
||||
showLayerControl={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-8 bg-white rounded-lg shadow-lg p-6">
|
||||
<h3 className="text-lg font-semibold text-gray-800 mb-4">
|
||||
Map Layers Available:
|
||||
</h3>
|
||||
<ul className="space-y-2 text-gray-600">
|
||||
<li className="flex items-center">
|
||||
<span className="w-3 h-3 bg-green-500 rounded-full mr-3"></span>
|
||||
<strong>Polish Geoportal Orthophoto:</strong> High-resolution aerial imagery from Polish Geoportal
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<span className="w-3 h-3 bg-blue-500 rounded-full mr-3"></span>
|
||||
<strong>OpenStreetMap:</strong> Standard OpenStreetMap tiles
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<span className="w-3 h-3 bg-red-500 rounded-full mr-3"></span>
|
||||
<strong>Google Satellite:</strong> Google satellite imagery
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<span className="w-3 h-3 bg-yellow-500 rounded-full mr-3"></span>
|
||||
<strong>Google Roads:</strong> Google road overlay
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<span className="w-3 h-3 bg-purple-500 rounded-full mr-3"></span>
|
||||
<strong>Esri Satellite:</strong> Esri world imagery
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="mt-8 bg-yellow-50 border border-yellow-200 rounded-lg p-6">
|
||||
<h3 className="text-lg font-semibold text-yellow-800 mb-2">
|
||||
Implementation Notes:
|
||||
</h3>
|
||||
<div className="text-yellow-700 space-y-2">
|
||||
<p>
|
||||
• The Polish Geoportal orthophoto uses REST tile service instead of WMTS for better compatibility
|
||||
</p>
|
||||
<p>
|
||||
• Tile size is set to 512px with zoomOffset=-1 for proper tile alignment
|
||||
</p>
|
||||
<p>
|
||||
• proj4 library is included for coordinate system transformations (EPSG:2180)
|
||||
</p>
|
||||
<p>
|
||||
• Multiple fallback layers are provided for comparison and reliability
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
254
src/components/ui/AdvancedPolishOrthophotoMap.js
Normal file
254
src/components/ui/AdvancedPolishOrthophotoMap.js
Normal file
@@ -0,0 +1,254 @@
|
||||
"use client";
|
||||
|
||||
import { MapContainer, TileLayer, WMSTileLayer, Marker, Popup, LayersControl } from 'react-leaflet';
|
||||
import 'leaflet/dist/leaflet.css';
|
||||
import { useEffect, useState } from 'react';
|
||||
import proj4 from 'proj4';
|
||||
|
||||
// Define Polish coordinate system EPSG:2180
|
||||
proj4.defs("EPSG:2180", "+proj=tmerc +lat_0=0 +lon_0=19 +k=0.9993 +x_0=500000 +y_0=-5300000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs +type=crs");
|
||||
|
||||
// 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',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Polish Geoportal Orthophoto - Standard Resolution
|
||||
function PolishOrthophotoStandardLayer() {
|
||||
return (
|
||||
<TileLayer
|
||||
attribution='© <a href="https://www.geoportal.gov.pl/">Geoportal</a>'
|
||||
url="https://mapy.geoportal.gov.pl/wss/service/PZGIK/ORTO/WMTS/StandardResolution?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}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Polish Geoportal Orthophoto - High Resolution
|
||||
function PolishOrthophotoHighResLayer() {
|
||||
return (
|
||||
<TileLayer
|
||||
attribution='© <a href="https://www.geoportal.gov.pl/">Geoportal</a>'
|
||||
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}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Polish Land Records (Cadastral) - using WMS
|
||||
function PolishCadastralLayer() {
|
||||
return (
|
||||
<WMSTileLayer
|
||||
attribution='© <a href="https://www.gugik.gov.pl/">GUGiK</a>'
|
||||
url="https://integracja01.gugik.gov.pl/cgi-bin/KrajowaIntegracjaEwidencjiGruntow"
|
||||
params={{
|
||||
service: 'WMS',
|
||||
request: 'GetMap',
|
||||
layers: 'powiaty,powiaty_obreby,zsin,obreby,dzialki,geoportal,numery_dzialek,budynki',
|
||||
styles: ',,,,,,,',
|
||||
format: 'image/png',
|
||||
transparent: true,
|
||||
version: '1.3.0',
|
||||
crs: 'EPSG:3857',
|
||||
width: 256,
|
||||
height: 256
|
||||
}}
|
||||
format="image/png"
|
||||
transparent={true}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Polish Spatial Planning (MPZT) - WMS
|
||||
function PolishSpatialPlanningLayer() {
|
||||
return (
|
||||
<WMSTileLayer
|
||||
attribution='© <a href="https://www.geoportal.gov.pl/">Geoportal</a>'
|
||||
url="https://mapy.geoportal.gov.pl/wss/ext/KrajowaIntegracjaMiejscowychPlanowZagospodarowaniaPrzestrzennego"
|
||||
params={{
|
||||
service: 'WMS',
|
||||
request: 'GetMap',
|
||||
layers: 'raster,wektor-str,wektor-lzb,wektor-pow,wektor-lin,wektor-pkt,granice',
|
||||
styles: ',,,,,,',
|
||||
format: 'image/png',
|
||||
transparent: true,
|
||||
version: '1.3.0',
|
||||
crs: 'EPSG:3857',
|
||||
width: 256,
|
||||
height: 256
|
||||
}}
|
||||
format="image/png"
|
||||
transparent={true}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// LP-Portal Roads Layer
|
||||
function LPPortalRoadsLayer() {
|
||||
return (
|
||||
<WMSTileLayer
|
||||
attribution='© <a href="https://lp-portal.pl/">LP-Portal</a>'
|
||||
url="https://geoserver.lp-portal.pl/geoserver/pzdnowysacz/wms"
|
||||
params={{
|
||||
service: 'WMS',
|
||||
request: 'GetMap',
|
||||
layers: '00_6_mapainteraktywna_drogi',
|
||||
styles: '',
|
||||
format: 'image/png8',
|
||||
transparent: true,
|
||||
version: '1.3.0',
|
||||
crs: 'EPSG:3857',
|
||||
width: 256,
|
||||
height: 256,
|
||||
tiled: true
|
||||
}}
|
||||
format="image/png8"
|
||||
transparent={true}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// LP-Portal Street Names Layer
|
||||
function LPPortalStreetNamesLayer() {
|
||||
return (
|
||||
<WMSTileLayer
|
||||
attribution='© <a href="https://lp-portal.pl/">LP-Portal</a>'
|
||||
url="https://geoserver.lp-portal.pl/geoserver/pzdnowysacz/wms"
|
||||
params={{
|
||||
service: 'WMS',
|
||||
request: 'GetMap',
|
||||
layers: '00_5_mapainteraktywna_opisy_drog,00_3_mapainteraktywna_nazwy_ulic',
|
||||
styles: '',
|
||||
format: 'image/png8',
|
||||
transparent: true,
|
||||
version: '1.1.1',
|
||||
crs: 'EPSG:3857',
|
||||
width: 256,
|
||||
height: 256,
|
||||
tiled: true
|
||||
}}
|
||||
format="image/png8"
|
||||
transparent={true}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Google Maps layers
|
||||
function GoogleSatelliteLayer() {
|
||||
return (
|
||||
<TileLayer
|
||||
attribution='© Google'
|
||||
url="http://mt1.google.com/vt/lyrs=y&hl=pl&x={x}&y={y}&z={z}"
|
||||
maxZoom={20}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function GoogleRoadsLayer() {
|
||||
return (
|
||||
<TileLayer
|
||||
attribution='© Google'
|
||||
url="http://mt1.google.com/vt/lyrs=h&hl=pl&x={x}&y={y}&z={z}"
|
||||
maxZoom={20}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default function AdvancedPolishOrthophotoMap({
|
||||
center = [50.0647, 19.9450], // Default to Krakow, Poland
|
||||
zoom = 13,
|
||||
markers = [],
|
||||
showLayerControl = true
|
||||
}) {
|
||||
const [mapLoaded, setMapLoaded] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
fixLeafletIcons();
|
||||
setMapLoaded(true);
|
||||
}, []);
|
||||
|
||||
const { BaseLayer, Overlay } = LayersControl;
|
||||
|
||||
if (!mapLoaded) {
|
||||
return <div>Loading map...</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<MapContainer
|
||||
center={center}
|
||||
zoom={zoom}
|
||||
style={{ height: '100%', width: '100%' }}
|
||||
scrollWheelZoom={true}
|
||||
>
|
||||
{showLayerControl ? (
|
||||
<LayersControl position="topright">
|
||||
{/* Base Layers */}
|
||||
<BaseLayer name="OpenStreetMap">
|
||||
<TileLayer
|
||||
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||||
maxZoom={19}
|
||||
/>
|
||||
</BaseLayer>
|
||||
|
||||
<BaseLayer checked name="Polish Geoportal Orthophoto (Standard)">
|
||||
<PolishOrthophotoStandardLayer />
|
||||
</BaseLayer>
|
||||
|
||||
<BaseLayer name="Polish Geoportal Orthophoto (High Resolution)">
|
||||
<PolishOrthophotoHighResLayer />
|
||||
</BaseLayer>
|
||||
|
||||
<BaseLayer name="Google Satellite">
|
||||
<GoogleSatelliteLayer />
|
||||
</BaseLayer>
|
||||
|
||||
<BaseLayer name="Google Roads">
|
||||
<GoogleRoadsLayer />
|
||||
</BaseLayer>
|
||||
|
||||
<BaseLayer name="Esri Satellite">
|
||||
<TileLayer
|
||||
attribution='© <a href="https://www.esri.com/">Esri</a> — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
|
||||
url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"
|
||||
maxZoom={19}
|
||||
/>
|
||||
</BaseLayer> {/* Overlay Layers */}
|
||||
<Overlay name="📋 Polish Cadastral Data (Działki)">
|
||||
<PolishCadastralLayer />
|
||||
</Overlay>
|
||||
|
||||
<Overlay name="🏗️ Polish Spatial Planning (MPZT)">
|
||||
<PolishSpatialPlanningLayer />
|
||||
</Overlay>
|
||||
|
||||
<Overlay name="🛣️ LP-Portal Roads">
|
||||
<LPPortalRoadsLayer />
|
||||
</Overlay>
|
||||
|
||||
<Overlay name="🏷️ LP-Portal Street Names">
|
||||
<LPPortalStreetNamesLayer />
|
||||
</Overlay>
|
||||
</LayersControl>
|
||||
) : (
|
||||
// Default to Polish orthophoto when no layer control
|
||||
<PolishOrthophotoStandardLayer />
|
||||
)}
|
||||
|
||||
{markers.map((marker, index) => (
|
||||
<Marker key={index} position={marker.position}>
|
||||
{marker.popup && <Popup>{marker.popup}</Popup>}
|
||||
</Marker>
|
||||
))}
|
||||
</MapContainer>
|
||||
);
|
||||
}
|
||||
322
src/components/ui/ComprehensivePolishMap.js
Normal file
322
src/components/ui/ComprehensivePolishMap.js
Normal file
@@ -0,0 +1,322 @@
|
||||
"use client";
|
||||
|
||||
import { MapContainer, TileLayer, WMSTileLayer, Marker, Popup, LayersControl } from 'react-leaflet';
|
||||
import 'leaflet/dist/leaflet.css';
|
||||
import { useEffect, useState } from 'react';
|
||||
import proj4 from 'proj4';
|
||||
|
||||
// Define Polish coordinate system EPSG:2180
|
||||
proj4.defs("EPSG:2180", "+proj=tmerc +lat_0=0 +lon_0=19 +k=0.9993 +x_0=500000 +y_0=-5300000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs +type=crs");
|
||||
|
||||
// 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',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 1. Polish Geoportal Orthophoto - Standard Resolution
|
||||
function PolishOrthophotoStandardLayer() {
|
||||
return (
|
||||
<TileLayer
|
||||
attribution='© <a href="https://www.geoportal.gov.pl/">Geoportal</a>'
|
||||
url="https://mapy.geoportal.gov.pl/wss/service/PZGIK/ORTO/WMTS/StandardResolution?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}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// 2. Polish Geoportal Orthophoto - High Resolution
|
||||
function PolishOrthophotoHighResLayer() {
|
||||
return (
|
||||
<TileLayer
|
||||
attribution='© <a href="https://www.geoportal.gov.pl/">Geoportal</a>'
|
||||
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}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// 3. Polish Cadastral Data (Działki) - WMS Transparent Overlay
|
||||
function PolishCadastralLayer() {
|
||||
return (
|
||||
<WMSTileLayer
|
||||
attribution='© <a href="https://www.gugik.gov.pl/">GUGiK</a>'
|
||||
url="https://integracja01.gugik.gov.pl/cgi-bin/KrajowaIntegracjaEwidencjiGruntow"
|
||||
params={{
|
||||
service: 'WMS',
|
||||
request: 'GetMap',
|
||||
layers: 'powiaty,powiaty_obreby,zsin,obreby,dzialki,geoportal,numery_dzialek,budynki',
|
||||
styles: ',,,,,,,',
|
||||
format: 'image/png',
|
||||
transparent: true,
|
||||
version: '1.3.0',
|
||||
crs: 'EPSG:3857',
|
||||
width: 256,
|
||||
height: 256
|
||||
}}
|
||||
format="image/png"
|
||||
transparent={true}
|
||||
opacity={0.8} // Semi-transparent for overlay
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// 4. Polish Spatial Planning (MPZT) - WMS Transparent Overlay
|
||||
function PolishSpatialPlanningLayer() {
|
||||
return (
|
||||
<WMSTileLayer
|
||||
attribution='© <a href="https://www.geoportal.gov.pl/">Geoportal</a>'
|
||||
url="https://mapy.geoportal.gov.pl/wss/ext/KrajowaIntegracjaMiejscowychPlanowZagospodarowaniaPrzestrzennego"
|
||||
params={{
|
||||
service: 'WMS',
|
||||
request: 'GetMap',
|
||||
layers: 'raster,wektor-str,wektor-lzb,wektor-pow,wektor-lin,wektor-pkt,granice',
|
||||
styles: ',,,,,,',
|
||||
format: 'image/png',
|
||||
transparent: true,
|
||||
version: '1.3.0',
|
||||
crs: 'EPSG:3857',
|
||||
width: 256,
|
||||
height: 256,
|
||||
tiled: true
|
||||
}}
|
||||
format="image/png"
|
||||
transparent={true}
|
||||
opacity={0.7} // Semi-transparent for overlay
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// 5. LP-Portal Roads Layer - Transparent Overlay
|
||||
function LPPortalRoadsLayer() {
|
||||
return (
|
||||
<WMSTileLayer
|
||||
attribution='© <a href="https://lp-portal.pl/">LP-Portal</a>'
|
||||
url="https://geoserver.lp-portal.pl/geoserver/pzdnowysacz/wms"
|
||||
params={{
|
||||
service: 'WMS',
|
||||
request: 'GetMap',
|
||||
layers: '00_6_mapainteraktywna_drogi',
|
||||
styles: '',
|
||||
format: 'image/png8',
|
||||
transparent: true,
|
||||
version: '1.3.0',
|
||||
crs: 'EPSG:3857',
|
||||
width: 256,
|
||||
height: 256,
|
||||
tiled: true
|
||||
}}
|
||||
format="image/png8"
|
||||
transparent={true}
|
||||
opacity={0.9} // Mostly opaque for roads
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// 6. LP-Portal Street Names Layer - Transparent Overlay
|
||||
function LPPortalStreetNamesLayer() {
|
||||
return (
|
||||
<WMSTileLayer
|
||||
attribution='© <a href="https://lp-portal.pl/">LP-Portal</a>'
|
||||
url="https://geoserver.lp-portal.pl/geoserver/pzdnowysacz/wms"
|
||||
params={{
|
||||
service: 'WMS',
|
||||
request: 'GetMap',
|
||||
layers: '00_5_mapainteraktywna_opisy_drog,00_3_mapainteraktywna_nazwy_ulic',
|
||||
styles: '',
|
||||
format: 'image/png8',
|
||||
transparent: true,
|
||||
version: '1.1.1',
|
||||
crs: 'EPSG:3857',
|
||||
width: 256,
|
||||
height: 256,
|
||||
tiled: true
|
||||
}}
|
||||
format="image/png8"
|
||||
transparent={true}
|
||||
opacity={1.0} // Fully opaque for text labels
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// 7. LP-Portal Property Parcels (Działki) - Transparent Overlay
|
||||
function LPPortalParcelsLayer() {
|
||||
return (
|
||||
<WMSTileLayer
|
||||
attribution='© <a href="https://lp-portal.pl/">LP-Portal</a>'
|
||||
url="https://geoserver.lp-portal.pl/geoserver/pzdnowysacz/wms"
|
||||
params={{
|
||||
service: 'WMS',
|
||||
request: 'GetMap',
|
||||
layers: 'dzialki',
|
||||
styles: '',
|
||||
format: 'image/png',
|
||||
transparent: true,
|
||||
version: '1.1.1',
|
||||
crs: 'EPSG:3857',
|
||||
width: 256,
|
||||
height: 256,
|
||||
tiled: true
|
||||
}}
|
||||
format="image/png"
|
||||
transparent={true}
|
||||
opacity={0.6} // Semi-transparent for property boundaries
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// 8. LP-Portal Survey Markers (Pikietarz) - Transparent Overlay
|
||||
function LPPortalSurveyMarkersLayer() {
|
||||
return (
|
||||
<WMSTileLayer
|
||||
attribution='© <a href="https://lp-portal.pl/">LP-Portal</a>'
|
||||
url="https://geoserver.lp-portal.pl/geoserver/pzdnowysacz/wms"
|
||||
params={{
|
||||
service: 'WMS',
|
||||
request: 'GetMap',
|
||||
layers: '00_2_view_geop_odcinek_pikietaz_glob_multi',
|
||||
styles: '',
|
||||
format: 'image/png8',
|
||||
transparent: true,
|
||||
version: '1.1.1',
|
||||
crs: 'EPSG:3857',
|
||||
width: 256,
|
||||
height: 256,
|
||||
tiled: true
|
||||
}}
|
||||
format="image/png8"
|
||||
transparent={true}
|
||||
opacity={0.8} // Semi-transparent for survey markers
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Google Maps layers for comparison
|
||||
function GoogleSatelliteLayer() {
|
||||
return (
|
||||
<TileLayer
|
||||
attribution='© Google'
|
||||
url="http://mt1.google.com/vt/lyrs=y&hl=pl&x={x}&y={y}&z={z}"
|
||||
maxZoom={20}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function GoogleRoadsLayer() {
|
||||
return (
|
||||
<TileLayer
|
||||
attribution='© Google'
|
||||
url="http://mt1.google.com/vt/lyrs=h&hl=pl&x={x}&y={y}&z={z}"
|
||||
maxZoom={20}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default function ComprehensivePolishMap({
|
||||
center = [50.0647, 19.9450], // Default to Krakow, Poland
|
||||
zoom = 13,
|
||||
markers = [],
|
||||
showLayerControl = true
|
||||
}) {
|
||||
const [mapLoaded, setMapLoaded] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
fixLeafletIcons();
|
||||
setMapLoaded(true);
|
||||
}, []);
|
||||
|
||||
const { BaseLayer, Overlay } = LayersControl;
|
||||
|
||||
if (!mapLoaded) {
|
||||
return <div>Loading comprehensive Polish map...</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<MapContainer
|
||||
center={center}
|
||||
zoom={zoom}
|
||||
style={{ height: '100%', width: '100%' }}
|
||||
scrollWheelZoom={true}
|
||||
>
|
||||
{showLayerControl ? (
|
||||
<LayersControl position="topright">
|
||||
{/* Base Layers */}
|
||||
<BaseLayer name="OpenStreetMap">
|
||||
<TileLayer
|
||||
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||||
maxZoom={19}
|
||||
/>
|
||||
</BaseLayer>
|
||||
|
||||
<BaseLayer checked name="Polish Orthophoto (Standard)">
|
||||
<PolishOrthophotoStandardLayer />
|
||||
</BaseLayer>
|
||||
|
||||
<BaseLayer name="Polish Orthophoto (High Resolution)">
|
||||
<PolishOrthophotoHighResLayer />
|
||||
</BaseLayer>
|
||||
|
||||
<BaseLayer name="Google Satellite">
|
||||
<GoogleSatelliteLayer />
|
||||
</BaseLayer>
|
||||
|
||||
<BaseLayer name="Google Roads">
|
||||
<GoogleRoadsLayer />
|
||||
</BaseLayer>
|
||||
|
||||
<BaseLayer name="Esri Satellite">
|
||||
<TileLayer
|
||||
attribution='© <a href="https://www.esri.com/">Esri</a> — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
|
||||
url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"
|
||||
maxZoom={19}
|
||||
/>
|
||||
</BaseLayer>
|
||||
|
||||
{/* Polish Government Overlay Layers */}
|
||||
<Overlay name="📋 Polish Cadastral Data (Działki)">
|
||||
<PolishCadastralLayer />
|
||||
</Overlay>
|
||||
|
||||
<Overlay name="🏗️ Polish Spatial Planning (MPZT)">
|
||||
<PolishSpatialPlanningLayer />
|
||||
</Overlay>
|
||||
|
||||
{/* LP-Portal Overlay Layers */}
|
||||
<Overlay name="🛣️ LP-Portal Roads">
|
||||
<LPPortalRoadsLayer />
|
||||
</Overlay>
|
||||
|
||||
<Overlay name="🏷️ LP-Portal Street Names">
|
||||
<LPPortalStreetNamesLayer />
|
||||
</Overlay>
|
||||
|
||||
<Overlay name="📐 LP-Portal Property Parcels">
|
||||
<LPPortalParcelsLayer />
|
||||
</Overlay>
|
||||
|
||||
<Overlay name="📍 LP-Portal Survey Markers">
|
||||
<LPPortalSurveyMarkersLayer />
|
||||
</Overlay>
|
||||
</LayersControl>
|
||||
) : (
|
||||
// Default to Polish orthophoto when no layer control
|
||||
<PolishOrthophotoStandardLayer />
|
||||
)}
|
||||
|
||||
{markers.map((marker, index) => (
|
||||
<Marker key={index} position={marker.position}>
|
||||
{marker.popup && <Popup>{marker.popup}</Popup>}
|
||||
</Marker>
|
||||
))}
|
||||
</MapContainer>
|
||||
);
|
||||
}
|
||||
@@ -48,14 +48,13 @@ export default function CustomWMTSMap({ center, zoom = 13, markers = [] }) {
|
||||
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||||
/>
|
||||
</BaseLayer>
|
||||
|
||||
<BaseLayer name="Polish Geoportal ORTO (WMTS)">
|
||||
<CustomWMTSLayer
|
||||
url="https://mapy.geoportal.gov.pl/wss/service/PZGIK/ORTO/WMTS/StandardResolution"
|
||||
layer="ORTO"
|
||||
style="default"
|
||||
tilematrixSet="EPSG:3857"
|
||||
format="image/jpeg"
|
||||
<BaseLayer name="Polish Geoportal ORTO (Working)">
|
||||
<TileLayer
|
||||
attribution='© <a href="https://www.geoportal.gov.pl/">Geoportal</a>'
|
||||
url="https://mapy.geoportal.gov.pl/wss/service/PZGIK/ORTO/REST/StandardResolution/tile/{z}/{y}/{x}.png"
|
||||
maxZoom={19}
|
||||
tileSize={512}
|
||||
zoomOffset={-1}
|
||||
/>
|
||||
</BaseLayer>
|
||||
|
||||
|
||||
213
src/components/ui/DebugPolishOrthophotoMap.js
Normal file
213
src/components/ui/DebugPolishOrthophotoMap.js
Normal file
@@ -0,0 +1,213 @@
|
||||
"use client";
|
||||
|
||||
import { MapContainer, TileLayer, Marker, Popup, LayersControl } from 'react-leaflet';
|
||||
import 'leaflet/dist/leaflet.css';
|
||||
import { useEffect, useState } from 'react';
|
||||
import proj4 from 'proj4';
|
||||
|
||||
// Define Polish coordinate system EPSG:2180 (from your OpenLayers code)
|
||||
proj4.defs("EPSG:2180", "+proj=tmerc +lat_0=0 +lon_0=19 +k=0.9993 +x_0=500000 +y_0=-5300000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs +type=crs");
|
||||
|
||||
// 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',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Multiple attempts at Polish Geoportal Orthophoto URLs
|
||||
function PolishOrthophotoOption1() {
|
||||
console.log("Loading Polish Orthophoto Option 1: WMTS KVP Standard");
|
||||
return (
|
||||
<TileLayer
|
||||
attribution='© <a href="https://www.geoportal.gov.pl/">Geoportal</a> (Option 1 - WMTS KVP)'
|
||||
url="https://mapy.geoportal.gov.pl/wss/service/PZGIK/ORTO/WMTS/StandardResolution?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}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function PolishOrthophotoOption2() {
|
||||
console.log("Loading Polish Orthophoto Option 2: WMTS KVP with EPSG:2180");
|
||||
return (
|
||||
<TileLayer
|
||||
attribution='© <a href="https://www.geoportal.gov.pl/">Geoportal</a> (Option 2 - WMTS EPSG:2180)'
|
||||
url="https://mapy.geoportal.gov.pl/wss/service/PZGIK/ORTO/WMTS/StandardResolution?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=ORTO&STYLE=default&TILEMATRIXSET=EPSG:2180&TILEMATRIX=EPSG:2180:{z}&TILEROW={y}&TILECOL={x}&FORMAT=image/jpeg"
|
||||
maxZoom={16}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function PolishOrthophotoOption3() {
|
||||
console.log("Loading Polish Orthophoto Option 3: Alternative WMTS URL");
|
||||
return (
|
||||
<TileLayer
|
||||
attribution='© <a href="https://www.geoportal.gov.pl/">Geoportal</a> (Option 3 - Alt WMTS)'
|
||||
url="https://mapy.geoportal.gov.pl/wss/service/PZGIK/ORTO/WMTS/StandardResolution?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=ORTO&STYLE=default&TILEMATRIXSET=GoogleMapsCompatible&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&FORMAT=image/jpeg"
|
||||
maxZoom={19}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function PolishOrthophotoOption4() {
|
||||
console.log("Loading Polish Orthophoto Option 4: PNG format");
|
||||
return (
|
||||
<TileLayer
|
||||
attribution='© <a href="https://www.geoportal.gov.pl/">Geoportal</a> (Option 4 - PNG)'
|
||||
url="https://mapy.geoportal.gov.pl/wss/service/PZGIK/ORTO/WMTS/StandardResolution?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=ORTO&STYLE=default&TILEMATRIXSET=EPSG:3857&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&FORMAT=image/png"
|
||||
maxZoom={19}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Working Google Maps layers for comparison
|
||||
function GoogleSatelliteLayer() {
|
||||
console.log("Loading Google Satellite (known working)");
|
||||
return (
|
||||
<TileLayer
|
||||
attribution='© Google'
|
||||
url="http://mt1.google.com/vt/lyrs=y&hl=pl&x={x}&y={y}&z={z}"
|
||||
maxZoom={20}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function GoogleRoadsLayer() {
|
||||
console.log("Loading Google Roads (known working)");
|
||||
return (
|
||||
<TileLayer
|
||||
attribution='© Google'
|
||||
url="http://mt1.google.com/vt/lyrs=h&hl=pl&x={x}&y={y}&z={z}"
|
||||
maxZoom={20}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default function DebugPolishOrthophotoMap({
|
||||
center = [50.0647, 19.9450], // Krakow, Poland
|
||||
zoom = 13,
|
||||
markers = []
|
||||
}) {
|
||||
const [mapLoaded, setMapLoaded] = useState(false);
|
||||
const [debugInfo, setDebugInfo] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
fixLeafletIcons();
|
||||
setMapLoaded(true);
|
||||
|
||||
// Add debug logging
|
||||
const originalFetch = window.fetch;
|
||||
window.fetch = function(...args) {
|
||||
const url = args[0];
|
||||
if (typeof url === 'string' && url.includes('geoportal.gov.pl')) {
|
||||
console.log('Geoportal request:', url);
|
||||
setDebugInfo(prev => [...prev, `Request: ${url}`]);
|
||||
}
|
||||
return originalFetch.apply(this, args)
|
||||
.then(response => {
|
||||
if (typeof url === 'string' && url.includes('geoportal.gov.pl')) {
|
||||
console.log('Geoportal response status:', response.status, 'for:', url);
|
||||
setDebugInfo(prev => [...prev, `Response: ${response.status} for ${url}`]);
|
||||
}
|
||||
return response;
|
||||
})
|
||||
.catch(error => {
|
||||
if (typeof url === 'string' && url.includes('geoportal.gov.pl')) {
|
||||
console.error('Geoportal error:', error, 'for:', url);
|
||||
setDebugInfo(prev => [...prev, `Error: ${error.message} for ${url}`]);
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
};
|
||||
|
||||
return () => {
|
||||
window.fetch = originalFetch;
|
||||
};
|
||||
}, []);
|
||||
|
||||
const { BaseLayer } = LayersControl;
|
||||
|
||||
if (!mapLoaded) {
|
||||
return <div>Loading debug map...</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ height: '100%', width: '100%' }}>
|
||||
{/* Debug Info Panel */}
|
||||
<div style={{
|
||||
position: 'absolute',
|
||||
top: '10px',
|
||||
left: '10px',
|
||||
background: 'rgba(255,255,255,0.9)',
|
||||
padding: '10px',
|
||||
maxWidth: '300px',
|
||||
maxHeight: '200px',
|
||||
overflow: 'auto',
|
||||
zIndex: 1000,
|
||||
fontSize: '12px',
|
||||
borderRadius: '5px'
|
||||
}}>
|
||||
<strong>Debug Info:</strong>
|
||||
{debugInfo.slice(-10).map((info, index) => (
|
||||
<div key={index}>{info}</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<MapContainer
|
||||
center={center}
|
||||
zoom={zoom}
|
||||
style={{ height: '100%', width: '100%' }}
|
||||
scrollWheelZoom={true}
|
||||
>
|
||||
<LayersControl position="topright">
|
||||
{/* Working layers first for comparison */}
|
||||
<BaseLayer checked name="Google Satellite (Working)">
|
||||
<GoogleSatelliteLayer />
|
||||
</BaseLayer>
|
||||
|
||||
<BaseLayer name="Google Roads (Working)">
|
||||
<GoogleRoadsLayer />
|
||||
</BaseLayer>
|
||||
|
||||
<BaseLayer name="OpenStreetMap (Working)">
|
||||
<TileLayer
|
||||
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||||
maxZoom={19}
|
||||
/>
|
||||
</BaseLayer>
|
||||
|
||||
{/* Different Polish Geoportal attempts */}
|
||||
<BaseLayer name="Polish Ortho - Option 1 (REST Standard)">
|
||||
<PolishOrthophotoOption1 />
|
||||
</BaseLayer>
|
||||
|
||||
<BaseLayer name="Polish Ortho - Option 2 (XYZ Direct)">
|
||||
<PolishOrthophotoOption2 />
|
||||
</BaseLayer>
|
||||
|
||||
<BaseLayer name="Polish Ortho - Option 3 (WMTS)">
|
||||
<PolishOrthophotoOption3 />
|
||||
</BaseLayer>
|
||||
|
||||
<BaseLayer name="Polish Ortho - Option 4 (Alt REST)">
|
||||
<PolishOrthophotoOption4 />
|
||||
</BaseLayer>
|
||||
</LayersControl>
|
||||
|
||||
{markers.map((marker, index) => (
|
||||
<Marker key={index} position={marker.position}>
|
||||
{marker.popup && <Popup>{marker.popup}</Popup>}
|
||||
</Marker>
|
||||
))}
|
||||
</MapContainer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { MapContainer, TileLayer, Marker, Popup, LayersControl } from 'react-leaflet';
|
||||
import { MapContainer, TileLayer, WMSTileLayer, Marker, Popup, LayersControl } from 'react-leaflet';
|
||||
import 'leaflet/dist/leaflet.css';
|
||||
import { useEffect } from 'react';
|
||||
import { mapLayers } from './mapLayers';
|
||||
@@ -29,8 +29,7 @@ export default function EnhancedLeafletMap({
|
||||
useEffect(() => {
|
||||
fixLeafletIcons();
|
||||
}, []);
|
||||
|
||||
const { BaseLayer } = LayersControl;
|
||||
const { BaseLayer, Overlay } = LayersControl;
|
||||
|
||||
return (
|
||||
<MapContainer
|
||||
@@ -41,6 +40,7 @@ export default function EnhancedLeafletMap({
|
||||
>
|
||||
{showLayerControl ? (
|
||||
<LayersControl position="topright">
|
||||
{/* Base Layers */}
|
||||
{mapLayers.base.map((layer, index) => (
|
||||
<BaseLayer
|
||||
key={index}
|
||||
@@ -55,6 +55,32 @@ export default function EnhancedLeafletMap({
|
||||
/>
|
||||
</BaseLayer>
|
||||
))}
|
||||
{/* Overlay Layers */}
|
||||
{mapLayers.overlays && mapLayers.overlays.map((layer, index) => (
|
||||
<Overlay
|
||||
key={`overlay-${index}`}
|
||||
checked={layer.checked}
|
||||
name={layer.name}
|
||||
>
|
||||
{layer.type === "wms" ? (
|
||||
<WMSTileLayer
|
||||
attribution={layer.attribution}
|
||||
url={layer.url}
|
||||
params={layer.params}
|
||||
format={layer.params.format}
|
||||
transparent={layer.params.transparent}
|
||||
opacity={layer.opacity}
|
||||
/>
|
||||
) : (
|
||||
<TileLayer
|
||||
attribution={layer.attribution}
|
||||
url={layer.url}
|
||||
maxZoom={layer.maxZoom}
|
||||
opacity={layer.opacity}
|
||||
/>
|
||||
)}
|
||||
</Overlay>
|
||||
))}
|
||||
</LayersControl>
|
||||
) : (
|
||||
// Default layer when no layer control
|
||||
|
||||
167
src/components/ui/ImprovedPolishOrthophotoMap.js
Normal file
167
src/components/ui/ImprovedPolishOrthophotoMap.js
Normal file
@@ -0,0 +1,167 @@
|
||||
"use client";
|
||||
|
||||
import { MapContainer, TileLayer, Marker, Popup, LayersControl } from 'react-leaflet';
|
||||
import 'leaflet/dist/leaflet.css';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { WMTSLayer } from './WMTSLayer';
|
||||
|
||||
// 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',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Custom layer wrapper for WMTS
|
||||
function PolishWMTSLayer({ tilematrixSet = 'EPSG:3857', format = 'image/jpeg' }) {
|
||||
return (
|
||||
<WMTSLayer
|
||||
url="https://mapy.geoportal.gov.pl/wss/service/PZGIK/ORTO/WMTS/StandardResolution"
|
||||
layer="ORTO"
|
||||
style="default"
|
||||
tilematrixSet={tilematrixSet}
|
||||
format={format}
|
||||
attribution='© <a href="https://www.geoportal.gov.pl/">Geoportal</a>'
|
||||
maxZoom={19}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Working Google Maps layers for comparison
|
||||
function GoogleSatelliteLayer() {
|
||||
return (
|
||||
<TileLayer
|
||||
attribution='© Google'
|
||||
url="http://mt1.google.com/vt/lyrs=y&hl=pl&x={x}&y={y}&z={z}"
|
||||
maxZoom={20}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default function ImprovedPolishOrthophotoMap({
|
||||
center = [50.0647, 19.9450], // Krakow, Poland
|
||||
zoom = 13,
|
||||
markers = []
|
||||
}) {
|
||||
const [mapLoaded, setMapLoaded] = useState(false);
|
||||
const [debugInfo, setDebugInfo] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
fixLeafletIcons();
|
||||
setMapLoaded(true);
|
||||
|
||||
// Debug network requests
|
||||
const originalFetch = window.fetch;
|
||||
window.fetch = function(...args) {
|
||||
const url = args[0];
|
||||
if (typeof url === 'string' && url.includes('geoportal.gov.pl')) {
|
||||
console.log('Geoportal WMTS request:', url);
|
||||
setDebugInfo(prev => [...prev.slice(-5), `Request: ${url.split('?')[1]}`]);
|
||||
}
|
||||
return originalFetch.apply(this, args)
|
||||
.then(response => {
|
||||
if (typeof url === 'string' && url.includes('geoportal.gov.pl')) {
|
||||
console.log('Geoportal response:', response.status, response.statusText);
|
||||
setDebugInfo(prev => [...prev.slice(-5), `Response: ${response.status} ${response.statusText}`]);
|
||||
}
|
||||
return response;
|
||||
})
|
||||
.catch(error => {
|
||||
if (typeof url === 'string' && url.includes('geoportal.gov.pl')) {
|
||||
console.error('Geoportal error:', error);
|
||||
setDebugInfo(prev => [...prev.slice(-5), `Error: ${error.message}`]);
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
};
|
||||
|
||||
return () => {
|
||||
window.fetch = originalFetch;
|
||||
};
|
||||
}, []);
|
||||
|
||||
const { BaseLayer } = LayersControl;
|
||||
|
||||
if (!mapLoaded) {
|
||||
return <div>Loading improved map...</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ height: '100%', width: '100%' }}>
|
||||
{/* Debug Info Panel */}
|
||||
<div style={{
|
||||
position: 'absolute',
|
||||
top: '10px',
|
||||
left: '10px',
|
||||
background: 'rgba(255,255,255,0.95)',
|
||||
padding: '10px',
|
||||
maxWidth: '400px',
|
||||
maxHeight: '150px',
|
||||
overflow: 'auto',
|
||||
zIndex: 1000,
|
||||
fontSize: '11px',
|
||||
borderRadius: '5px',
|
||||
boxShadow: '0 2px 5px rgba(0,0,0,0.2)'
|
||||
}}>
|
||||
<strong>WMTS Debug Info:</strong>
|
||||
{debugInfo.map((info, index) => (
|
||||
<div key={index} style={{ marginTop: '2px', wordBreak: 'break-all' }}>
|
||||
{info}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<MapContainer
|
||||
center={center}
|
||||
zoom={zoom}
|
||||
style={{ height: '100%', width: '100%' }}
|
||||
scrollWheelZoom={true}
|
||||
>
|
||||
<LayersControl position="topright">
|
||||
{/* Working reference layer */}
|
||||
<BaseLayer checked name="Google Satellite (Working Reference)">
|
||||
<GoogleSatelliteLayer />
|
||||
</BaseLayer>
|
||||
|
||||
<BaseLayer name="OpenStreetMap">
|
||||
<TileLayer
|
||||
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||||
maxZoom={19}
|
||||
/>
|
||||
</BaseLayer>
|
||||
|
||||
{/* WMTS layers with custom implementation */}
|
||||
<BaseLayer name="Polish WMTS (EPSG:3857, JPEG)">
|
||||
<PolishWMTSLayer tilematrixSet="EPSG:3857" format="image/jpeg" />
|
||||
</BaseLayer>
|
||||
|
||||
<BaseLayer name="Polish WMTS (EPSG:3857, PNG)">
|
||||
<PolishWMTSLayer tilematrixSet="EPSG:3857" format="image/png" />
|
||||
</BaseLayer>
|
||||
|
||||
<BaseLayer name="Polish WMTS (EPSG:4326, JPEG)">
|
||||
<PolishWMTSLayer tilematrixSet="EPSG:4326" format="image/jpeg" />
|
||||
</BaseLayer>
|
||||
|
||||
<BaseLayer name="Polish WMTS (EPSG:2180, JPEG)">
|
||||
<PolishWMTSLayer tilematrixSet="EPSG:2180" format="image/jpeg" />
|
||||
</BaseLayer>
|
||||
</LayersControl>
|
||||
|
||||
{markers.map((marker, index) => (
|
||||
<Marker key={index} position={marker.position}>
|
||||
{marker.popup && <Popup>{marker.popup}</Popup>}
|
||||
</Marker>
|
||||
))}
|
||||
</MapContainer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
import {
|
||||
MapContainer,
|
||||
TileLayer,
|
||||
WMSTileLayer,
|
||||
Marker,
|
||||
Popup,
|
||||
LayersControl,
|
||||
@@ -80,8 +81,7 @@ export default function EnhancedLeafletMap({
|
||||
useEffect(() => {
|
||||
fixLeafletIcons();
|
||||
}, []);
|
||||
|
||||
const { BaseLayer } = LayersControl;
|
||||
const { BaseLayer, Overlay } = LayersControl;
|
||||
return (
|
||||
<MapContainer
|
||||
center={center}
|
||||
@@ -94,6 +94,7 @@ export default function EnhancedLeafletMap({
|
||||
|
||||
{showLayerControl ? (
|
||||
<LayersControl position="topright">
|
||||
{/* Base Layers */}
|
||||
{mapLayers.base.map((layer, index) => (
|
||||
<BaseLayer
|
||||
key={index}
|
||||
@@ -107,6 +108,32 @@ export default function EnhancedLeafletMap({
|
||||
tileSize={layer.tileSize || 256}
|
||||
/>
|
||||
</BaseLayer>
|
||||
))}
|
||||
{/* Overlay Layers */}
|
||||
{mapLayers.overlays && mapLayers.overlays.map((layer, index) => (
|
||||
<Overlay
|
||||
key={`overlay-${index}`}
|
||||
checked={layer.checked}
|
||||
name={layer.name}
|
||||
>
|
||||
{layer.type === "wms" ? (
|
||||
<WMSTileLayer
|
||||
attribution={layer.attribution}
|
||||
url={layer.url}
|
||||
params={layer.params}
|
||||
format={layer.params.format}
|
||||
transparent={layer.params.transparent}
|
||||
opacity={layer.opacity}
|
||||
/>
|
||||
) : (
|
||||
<TileLayer
|
||||
attribution={layer.attribution}
|
||||
url={layer.url}
|
||||
maxZoom={layer.maxZoom}
|
||||
opacity={layer.opacity}
|
||||
/>
|
||||
)}
|
||||
</Overlay>
|
||||
))}
|
||||
</LayersControl>
|
||||
) : (
|
||||
|
||||
271
src/components/ui/PolishGeoLayers.js
Normal file
271
src/components/ui/PolishGeoLayers.js
Normal file
@@ -0,0 +1,271 @@
|
||||
"use client";
|
||||
|
||||
import { WMSTileLayer, TileLayer } from 'react-leaflet';
|
||||
|
||||
// Collection of all Polish geospatial layers from your OpenLayers implementation
|
||||
// These can be imported individually and used in any map component
|
||||
|
||||
// 1. Polish Orthophoto Layers (WMTS)
|
||||
export function PolishOrthophotoStandard() {
|
||||
return (
|
||||
<TileLayer
|
||||
attribution='© <a href="https://www.geoportal.gov.pl/">Geoportal</a>'
|
||||
url="https://mapy.geoportal.gov.pl/wss/service/PZGIK/ORTO/WMTS/StandardResolution?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}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function PolishOrthophotoHighRes() {
|
||||
return (
|
||||
<TileLayer
|
||||
attribution='© <a href="https://www.geoportal.gov.pl/">Geoportal</a>'
|
||||
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}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// 2. Polish Government WMS Layers - All transparent overlays
|
||||
export function PolishCadastralData() {
|
||||
return (
|
||||
<WMSTileLayer
|
||||
attribution='© <a href="https://www.gugik.gov.pl/">GUGiK</a>'
|
||||
url="https://integracja01.gugik.gov.pl/cgi-bin/KrajowaIntegracjaEwidencjiGruntow"
|
||||
params={{
|
||||
service: 'WMS',
|
||||
request: 'GetMap',
|
||||
layers: 'powiaty,powiaty_obreby,zsin,obreby,dzialki,geoportal,numery_dzialek,budynki',
|
||||
styles: ',,,,,,,',
|
||||
format: 'image/png',
|
||||
transparent: true,
|
||||
version: '1.3.0',
|
||||
crs: 'EPSG:3857'
|
||||
}}
|
||||
format="image/png"
|
||||
transparent={true}
|
||||
opacity={0.8} // Semi-transparent overlay for property boundaries
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function PolishSpatialPlanning() {
|
||||
return (
|
||||
<WMSTileLayer
|
||||
attribution='© <a href="https://www.geoportal.gov.pl/">Geoportal</a>'
|
||||
url="https://mapy.geoportal.gov.pl/wss/ext/KrajowaIntegracjaMiejscowychPlanowZagospodarowaniaPrzestrzennego"
|
||||
params={{
|
||||
service: 'WMS',
|
||||
request: 'GetMap',
|
||||
layers: 'raster,wektor-str,wektor-lzb,wektor-pow,wektor-lin,wektor-pkt,granice',
|
||||
styles: ',,,,,,',
|
||||
format: 'image/png',
|
||||
transparent: true,
|
||||
version: '1.3.0',
|
||||
crs: 'EPSG:3857',
|
||||
tiled: true
|
||||
}}
|
||||
format="image/png"
|
||||
transparent={true}
|
||||
opacity={0.7} // Semi-transparent overlay for planning zones
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// 3. LP-Portal Municipal Layers - Transparent overlays with different opacity levels
|
||||
export function LPPortalRoads() {
|
||||
return (
|
||||
<WMSTileLayer
|
||||
attribution='© <a href="https://lp-portal.pl/">LP-Portal</a>'
|
||||
url="https://geoserver.lp-portal.pl/geoserver/pzdnowysacz/wms"
|
||||
params={{
|
||||
service: 'WMS',
|
||||
request: 'GetMap',
|
||||
layers: '00_6_mapainteraktywna_drogi',
|
||||
styles: '',
|
||||
format: 'image/png8',
|
||||
transparent: true,
|
||||
version: '1.3.0',
|
||||
crs: 'EPSG:3857',
|
||||
tiled: true
|
||||
}}
|
||||
format="image/png8"
|
||||
transparent={true}
|
||||
opacity={0.9} // Mostly opaque for road visibility
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function LPPortalStreetNames() {
|
||||
return (
|
||||
<WMSTileLayer
|
||||
attribution='© <a href="https://lp-portal.pl/">LP-Portal</a>'
|
||||
url="https://geoserver.lp-portal.pl/geoserver/pzdnowysacz/wms"
|
||||
params={{
|
||||
service: 'WMS',
|
||||
request: 'GetMap',
|
||||
layers: '00_5_mapainteraktywna_opisy_drog,00_3_mapainteraktywna_nazwy_ulic',
|
||||
styles: '',
|
||||
format: 'image/png8',
|
||||
transparent: true,
|
||||
version: '1.1.1',
|
||||
crs: 'EPSG:3857',
|
||||
tiled: true
|
||||
}}
|
||||
format="image/png8"
|
||||
transparent={true}
|
||||
opacity={1.0} // Fully opaque for text readability
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function LPPortalParcels() {
|
||||
return (
|
||||
<WMSTileLayer
|
||||
attribution='© <a href="https://lp-portal.pl/">LP-Portal</a>'
|
||||
url="https://geoserver.lp-portal.pl/geoserver/pzdnowysacz/wms"
|
||||
params={{
|
||||
service: 'WMS',
|
||||
request: 'GetMap',
|
||||
layers: 'dzialki',
|
||||
styles: '',
|
||||
format: 'image/png',
|
||||
transparent: true,
|
||||
version: '1.1.1',
|
||||
crs: 'EPSG:3857',
|
||||
tiled: true
|
||||
}}
|
||||
format="image/png"
|
||||
transparent={true}
|
||||
opacity={0.6} // Semi-transparent for parcel boundaries
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function LPPortalSurveyMarkers() {
|
||||
return (
|
||||
<WMSTileLayer
|
||||
attribution='© <a href="https://lp-portal.pl/">LP-Portal</a>'
|
||||
url="https://geoserver.lp-portal.pl/geoserver/pzdnowysacz/wms"
|
||||
params={{
|
||||
service: 'WMS',
|
||||
request: 'GetMap',
|
||||
layers: '00_2_view_geop_odcinek_pikietaz_glob_multi',
|
||||
styles: '',
|
||||
format: 'image/png8',
|
||||
transparent: true,
|
||||
version: '1.1.1',
|
||||
crs: 'EPSG:3857',
|
||||
tiled: true
|
||||
}}
|
||||
format="image/png8"
|
||||
transparent={true}
|
||||
opacity={0.8} // Semi-transparent for survey markers
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// 4. Utility Google Maps Layers for comparison
|
||||
export function GoogleSatellite() {
|
||||
return (
|
||||
<TileLayer
|
||||
attribution='© Google'
|
||||
url="http://mt1.google.com/vt/lyrs=y&hl=pl&x={x}&y={y}&z={z}"
|
||||
maxZoom={20}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function GoogleRoads() {
|
||||
return (
|
||||
<TileLayer
|
||||
attribution='© Google'
|
||||
url="http://mt1.google.com/vt/lyrs=h&hl=pl&x={x}&y={y}&z={z}"
|
||||
maxZoom={20}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Layer configuration for easy integration with transparency settings
|
||||
export const polishLayerConfigs = {
|
||||
base: [
|
||||
{
|
||||
name: "Polish Orthophoto (Standard)",
|
||||
component: PolishOrthophotoStandard,
|
||||
description: "High-quality aerial imagery from Polish Geoportal",
|
||||
opacity: 1.0,
|
||||
transparent: false
|
||||
},
|
||||
{
|
||||
name: "Polish Orthophoto (High Resolution)",
|
||||
component: PolishOrthophotoHighRes,
|
||||
description: "Ultra-high resolution aerial imagery",
|
||||
opacity: 1.0,
|
||||
transparent: false
|
||||
},
|
||||
{
|
||||
name: "Google Satellite",
|
||||
component: GoogleSatellite,
|
||||
description: "Google satellite imagery for comparison",
|
||||
opacity: 1.0,
|
||||
transparent: false
|
||||
},
|
||||
{
|
||||
name: "Google Roads",
|
||||
component: GoogleRoads,
|
||||
description: "Google road overlay",
|
||||
opacity: 1.0,
|
||||
transparent: false
|
||||
}
|
||||
],
|
||||
overlays: [
|
||||
{
|
||||
name: "📋 Polish Cadastral Data",
|
||||
component: PolishCadastralData,
|
||||
description: "Property boundaries and parcel information",
|
||||
opacity: 0.8,
|
||||
transparent: true,
|
||||
category: "government"
|
||||
},
|
||||
{
|
||||
name: "🏗️ Polish Spatial Planning",
|
||||
component: PolishSpatialPlanning,
|
||||
description: "Zoning and urban planning data",
|
||||
opacity: 0.7,
|
||||
transparent: true,
|
||||
category: "government"
|
||||
},
|
||||
{
|
||||
name: "🛣️ LP-Portal Roads",
|
||||
component: LPPortalRoads,
|
||||
description: "Detailed road network",
|
||||
opacity: 0.9,
|
||||
transparent: true,
|
||||
category: "municipal"
|
||||
},
|
||||
{
|
||||
name: "🏷️ LP-Portal Street Names",
|
||||
component: LPPortalStreetNames,
|
||||
description: "Street names and descriptions",
|
||||
opacity: 1.0,
|
||||
transparent: true,
|
||||
category: "municipal"
|
||||
},
|
||||
{
|
||||
name: "📐 LP-Portal Parcels",
|
||||
component: LPPortalParcels,
|
||||
description: "Municipal property parcels",
|
||||
opacity: 0.6,
|
||||
transparent: true,
|
||||
category: "municipal"
|
||||
},
|
||||
{
|
||||
name: "📍 LP-Portal Survey Markers",
|
||||
component: LPPortalSurveyMarkers,
|
||||
description: "Survey markers and reference points",
|
||||
opacity: 0.8,
|
||||
transparent: true,
|
||||
category: "municipal"
|
||||
}
|
||||
]
|
||||
};
|
||||
126
src/components/ui/PolishOrthophotoMap.js
Normal file
126
src/components/ui/PolishOrthophotoMap.js
Normal file
@@ -0,0 +1,126 @@
|
||||
"use client";
|
||||
|
||||
import { MapContainer, TileLayer, Marker, Popup, LayersControl } from 'react-leaflet';
|
||||
import 'leaflet/dist/leaflet.css';
|
||||
import { useEffect, useState } from 'react';
|
||||
import proj4 from 'proj4';
|
||||
|
||||
// Define Polish coordinate system EPSG:2180
|
||||
proj4.defs("EPSG:2180", "+proj=tmerc +lat_0=0 +lon_0=19 +k=0.9993 +x_0=500000 +y_0=-5300000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs +type=crs");
|
||||
|
||||
// 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',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Custom tile layer component for Polish Geoportal - WORKING VERSION
|
||||
function PolishOrthophotoLayer({ visible = true }) {
|
||||
return (
|
||||
<TileLayer
|
||||
attribution='© <a href="https://www.geoportal.gov.pl/">Geoportal</a>'
|
||||
url="https://mapy.geoportal.gov.pl/wss/service/PZGIK/ORTO/WMTS/StandardResolution?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}
|
||||
key="polish-orthophoto"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Google Maps layers as alternatives
|
||||
function GoogleSatelliteLayer() {
|
||||
return (
|
||||
<TileLayer
|
||||
attribution='© Google'
|
||||
url="http://mt1.google.com/vt/lyrs=y&hl=pl&x={x}&y={y}&z={z}"
|
||||
maxZoom={20}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function GoogleRoadsLayer() {
|
||||
return (
|
||||
<TileLayer
|
||||
attribution='© Google'
|
||||
url="http://mt1.google.com/vt/lyrs=h&hl=pl&x={x}&y={y}&z={z}"
|
||||
maxZoom={20}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default function PolishOrthophotoMap({
|
||||
center = [50.0647, 19.9450], // Default to Krakow, Poland
|
||||
zoom = 13,
|
||||
markers = [],
|
||||
showLayerControl = true
|
||||
}) {
|
||||
const [mapLoaded, setMapLoaded] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
fixLeafletIcons();
|
||||
setMapLoaded(true);
|
||||
}, []);
|
||||
|
||||
const { BaseLayer } = LayersControl;
|
||||
|
||||
if (!mapLoaded) {
|
||||
return <div>Loading map...</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<MapContainer
|
||||
center={center}
|
||||
zoom={zoom}
|
||||
style={{ height: '100%', width: '100%' }}
|
||||
scrollWheelZoom={true}
|
||||
>
|
||||
{showLayerControl ? (
|
||||
<LayersControl position="topright">
|
||||
<BaseLayer name="OpenStreetMap">
|
||||
<TileLayer
|
||||
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||||
maxZoom={19}
|
||||
/>
|
||||
</BaseLayer>
|
||||
|
||||
<BaseLayer checked name="Polish Geoportal Orthophoto">
|
||||
<PolishOrthophotoLayer />
|
||||
</BaseLayer>
|
||||
|
||||
<BaseLayer name="Google Satellite">
|
||||
<GoogleSatelliteLayer />
|
||||
</BaseLayer>
|
||||
|
||||
<BaseLayer name="Google Roads">
|
||||
<GoogleRoadsLayer />
|
||||
</BaseLayer>
|
||||
|
||||
<BaseLayer name="Esri Satellite">
|
||||
<TileLayer
|
||||
attribution='© <a href="https://www.esri.com/">Esri</a> — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
|
||||
url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"
|
||||
maxZoom={19}
|
||||
/>
|
||||
</BaseLayer>
|
||||
</LayersControl>
|
||||
) : (
|
||||
// Default to Polish orthophoto when no layer control
|
||||
<PolishOrthophotoLayer />
|
||||
)}
|
||||
|
||||
{markers.map((marker, index) => (
|
||||
<Marker key={index} position={marker.position}>
|
||||
{marker.popup && <Popup>{marker.popup}</Popup>}
|
||||
</Marker>
|
||||
))}
|
||||
</MapContainer>
|
||||
);
|
||||
}
|
||||
166
src/components/ui/TransparencyDemoMap.js
Normal file
166
src/components/ui/TransparencyDemoMap.js
Normal file
@@ -0,0 +1,166 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from 'react';
|
||||
import { MapContainer, TileLayer, LayersControl } from 'react-leaflet';
|
||||
import 'leaflet/dist/leaflet.css';
|
||||
import {
|
||||
PolishOrthophotoStandard,
|
||||
PolishCadastralData,
|
||||
PolishSpatialPlanning,
|
||||
LPPortalRoads,
|
||||
LPPortalStreetNames,
|
||||
LPPortalParcels
|
||||
} from './PolishGeoLayers';
|
||||
|
||||
// Custom layer with adjustable opacity
|
||||
function AdjustableOpacityLayer({ children, opacity = 1.0 }) {
|
||||
return React.cloneElement(children, { opacity });
|
||||
}
|
||||
|
||||
export default function TransparencyDemoMap({
|
||||
center = [50.0647, 19.9450],
|
||||
zoom = 15
|
||||
}) {
|
||||
const [opacitySettings, setOpacitySettings] = useState({
|
||||
cadastral: 0.8,
|
||||
planning: 0.7,
|
||||
roads: 0.9,
|
||||
streetNames: 1.0,
|
||||
parcels: 0.6
|
||||
});
|
||||
|
||||
const { BaseLayer, Overlay } = LayersControl;
|
||||
|
||||
const updateOpacity = (layer, value) => {
|
||||
setOpacitySettings(prev => ({
|
||||
...prev,
|
||||
[layer]: value / 100
|
||||
}));
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="h-full">
|
||||
{/* Opacity Controls */}
|
||||
<div className="absolute top-4 left-4 z-[1000] bg-white p-4 rounded-lg shadow-lg max-w-xs">
|
||||
<h3 className="font-semibold mb-3">🎨 Layer Transparency Controls</h3>
|
||||
<div className="space-y-3 text-sm">
|
||||
<div>
|
||||
<label className="block text-gray-700 mb-1">📋 Cadastral Data</label>
|
||||
<input
|
||||
type="range"
|
||||
min="0"
|
||||
max="100"
|
||||
value={opacitySettings.cadastral * 100}
|
||||
onChange={(e) => updateOpacity('cadastral', e.target.value)}
|
||||
className="w-full"
|
||||
/>
|
||||
<span className="text-xs text-gray-500">{Math.round(opacitySettings.cadastral * 100)}%</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-gray-700 mb-1">🏗️ Spatial Planning</label>
|
||||
<input
|
||||
type="range"
|
||||
min="0"
|
||||
max="100"
|
||||
value={opacitySettings.planning * 100}
|
||||
onChange={(e) => updateOpacity('planning', e.target.value)}
|
||||
className="w-full"
|
||||
/>
|
||||
<span className="text-xs text-gray-500">{Math.round(opacitySettings.planning * 100)}%</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-gray-700 mb-1">🛣️ Roads</label>
|
||||
<input
|
||||
type="range"
|
||||
min="0"
|
||||
max="100"
|
||||
value={opacitySettings.roads * 100}
|
||||
onChange={(e) => updateOpacity('roads', e.target.value)}
|
||||
className="w-full"
|
||||
/>
|
||||
<span className="text-xs text-gray-500">{Math.round(opacitySettings.roads * 100)}%</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-gray-700 mb-1">🏷️ Street Names</label>
|
||||
<input
|
||||
type="range"
|
||||
min="0"
|
||||
max="100"
|
||||
value={opacitySettings.streetNames * 100}
|
||||
onChange={(e) => updateOpacity('streetNames', e.target.value)}
|
||||
className="w-full"
|
||||
/>
|
||||
<span className="text-xs text-gray-500">{Math.round(opacitySettings.streetNames * 100)}%</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-gray-700 mb-1">📐 Parcels</label>
|
||||
<input
|
||||
type="range"
|
||||
min="0"
|
||||
max="100"
|
||||
value={opacitySettings.parcels * 100}
|
||||
onChange={(e) => updateOpacity('parcels', e.target.value)}
|
||||
className="w-full"
|
||||
/>
|
||||
<span className="text-xs text-gray-500">{Math.round(opacitySettings.parcels * 100)}%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<MapContainer
|
||||
center={center}
|
||||
zoom={zoom}
|
||||
style={{ height: '100%', width: '100%' }}
|
||||
scrollWheelZoom={true}
|
||||
>
|
||||
<LayersControl position="topright">
|
||||
<BaseLayer checked name="Polish Orthophoto">
|
||||
<PolishOrthophotoStandard />
|
||||
</BaseLayer>
|
||||
|
||||
<BaseLayer name="OpenStreetMap">
|
||||
<TileLayer
|
||||
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||||
maxZoom={19}
|
||||
/>
|
||||
</BaseLayer>
|
||||
|
||||
<Overlay name="📋 Cadastral Data (Adjustable)">
|
||||
<AdjustableOpacityLayer opacity={opacitySettings.cadastral}>
|
||||
<PolishCadastralData />
|
||||
</AdjustableOpacityLayer>
|
||||
</Overlay>
|
||||
|
||||
<Overlay name="🏗️ Spatial Planning (Adjustable)">
|
||||
<AdjustableOpacityLayer opacity={opacitySettings.planning}>
|
||||
<PolishSpatialPlanning />
|
||||
</AdjustableOpacityLayer>
|
||||
</Overlay>
|
||||
|
||||
<Overlay name="🛣️ Roads (Adjustable)">
|
||||
<AdjustableOpacityLayer opacity={opacitySettings.roads}>
|
||||
<LPPortalRoads />
|
||||
</AdjustableOpacityLayer>
|
||||
</Overlay>
|
||||
|
||||
<Overlay name="🏷️ Street Names (Adjustable)">
|
||||
<AdjustableOpacityLayer opacity={opacitySettings.streetNames}>
|
||||
<LPPortalStreetNames />
|
||||
</AdjustableOpacityLayer>
|
||||
</Overlay>
|
||||
|
||||
<Overlay name="📐 Parcels (Adjustable)">
|
||||
<AdjustableOpacityLayer opacity={opacitySettings.parcels}>
|
||||
<LPPortalParcels />
|
||||
</AdjustableOpacityLayer>
|
||||
</Overlay>
|
||||
</LayersControl>
|
||||
</MapContainer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
156
src/components/ui/WMTSLayer.js
Normal file
156
src/components/ui/WMTSLayer.js
Normal file
@@ -0,0 +1,156 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { useMap } from 'react-leaflet';
|
||||
|
||||
// Custom WMTS Layer for Polish Geoportal
|
||||
export function WMTSLayer({
|
||||
url,
|
||||
layer,
|
||||
style = 'default',
|
||||
tilematrixSet = 'EPSG:3857',
|
||||
format = 'image/jpeg',
|
||||
attribution = '',
|
||||
maxZoom = 19
|
||||
}) {
|
||||
const map = useMap();
|
||||
const layerRef = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
const L = require('leaflet');
|
||||
|
||||
// Custom WMTS layer that builds proper KVP URLs
|
||||
const WMTSTileLayer = L.TileLayer.extend({
|
||||
getTileUrl: function(coords) {
|
||||
const tilematrix = tilematrixSet === 'EPSG:2180' ? `EPSG:2180:${coords.z}` : coords.z;
|
||||
|
||||
const params = new URLSearchParams({
|
||||
SERVICE: 'WMTS',
|
||||
REQUEST: 'GetTile',
|
||||
VERSION: '1.0.0',
|
||||
LAYER: layer,
|
||||
STYLE: style,
|
||||
TILEMATRIXSET: tilematrixSet,
|
||||
TILEMATRIX: tilematrix,
|
||||
TILEROW: coords.y,
|
||||
TILECOL: coords.x,
|
||||
FORMAT: format
|
||||
});
|
||||
|
||||
return `${url}?${params.toString()}`;
|
||||
}
|
||||
});
|
||||
|
||||
// Create the layer
|
||||
layerRef.current = new WMTSTileLayer('', {
|
||||
attribution: attribution,
|
||||
maxZoom: maxZoom,
|
||||
tileSize: 256
|
||||
});
|
||||
|
||||
// Add to map
|
||||
map.addLayer(layerRef.current);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
return () => {
|
||||
if (layerRef.current && map) {
|
||||
map.removeLayer(layerRef.current);
|
||||
}
|
||||
};
|
||||
}, [map, url, layer, style, tilematrixSet, format, attribution, maxZoom]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Proj4Leaflet WMTS Layer for Polish projection
|
||||
export function Proj4WMTSLayer({
|
||||
url,
|
||||
layer,
|
||||
style = 'default',
|
||||
tilematrixSet = 'EPSG:2180',
|
||||
format = 'image/jpeg',
|
||||
attribution = '',
|
||||
maxZoom = 16
|
||||
}) {
|
||||
const map = useMap();
|
||||
const layerRef = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
const L = require('leaflet');
|
||||
const proj4 = require('proj4');
|
||||
require('proj4leaflet');
|
||||
|
||||
// Define Polish projection
|
||||
proj4.defs("EPSG:2180", "+proj=tmerc +lat_0=0 +lon_0=19 +k=0.9993 +x_0=500000 +y_0=-5300000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs +type=crs");
|
||||
|
||||
// Create CRS for EPSG:2180
|
||||
const crs2180 = new L.Proj.CRS('EPSG:2180', proj4.defs('EPSG:2180'), {
|
||||
resolutions: [
|
||||
2116.6709 * 4,
|
||||
2116.6709 * 2,
|
||||
2116.6709,
|
||||
1058.33545,
|
||||
529.167725,
|
||||
264.5838625,
|
||||
132.29193125,
|
||||
66.145965625,
|
||||
26.458386249999997,
|
||||
13.229193124999998,
|
||||
6.614596562499999,
|
||||
2.645838625,
|
||||
1.3229193125,
|
||||
0.529167725,
|
||||
0.2645838625,
|
||||
0.13229193125,
|
||||
0.13229193125 / 2,
|
||||
],
|
||||
origin: [100000, 850000],
|
||||
bounds: L.bounds([144907.16581514146, 129171.69217334315], [890379.1658151413, 812697.4119729949])
|
||||
});
|
||||
|
||||
// Custom WMTS layer
|
||||
const WMTSTileLayer = L.TileLayer.extend({
|
||||
getTileUrl: function(coords) {
|
||||
const tilematrix = `EPSG:2180:${coords.z}`;
|
||||
|
||||
const params = new URLSearchParams({
|
||||
SERVICE: 'WMTS',
|
||||
REQUEST: 'GetTile',
|
||||
VERSION: '1.0.0',
|
||||
LAYER: layer,
|
||||
STYLE: style,
|
||||
TILEMATRIXSET: tilematrixSet,
|
||||
TILEMATRIX: tilematrix,
|
||||
TILEROW: coords.y,
|
||||
TILECOL: coords.x,
|
||||
FORMAT: format
|
||||
});
|
||||
|
||||
return `${url}?${params.toString()}`;
|
||||
}
|
||||
});
|
||||
|
||||
// Create the layer
|
||||
layerRef.current = new WMTSTileLayer('', {
|
||||
attribution: attribution,
|
||||
maxZoom: maxZoom,
|
||||
tileSize: 512
|
||||
});
|
||||
|
||||
// Add to map (but this won't work properly with EPSG:3857 map)
|
||||
// This is more for demonstration - would need to change map CRS
|
||||
map.addLayer(layerRef.current);
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (layerRef.current && map) {
|
||||
map.removeLayer(layerRef.current);
|
||||
}
|
||||
};
|
||||
}, [map, url, layer, style, tilematrixSet, format, attribution, maxZoom]);
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -13,14 +13,32 @@ export const mapLayers = {
|
||||
url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
|
||||
maxZoom: 19
|
||||
},
|
||||
polishOrthophoto,
|
||||
{
|
||||
name: "Polish Land Records (WMS)",
|
||||
attribution: '© <a href="https://www.gugik.gov.pl/">GUGiK</a>',
|
||||
// This is actually a WMS service, not WMTS as discovered from GetCapabilities
|
||||
url: "https://integracja.gugik.gov.pl/cgi-bin/KrajowaIntegracjaEwidencjiGruntow?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&BBOX={bbox-epsg-3857}&CRS=EPSG:3857&WIDTH=256&HEIGHT=256&LAYERS=EGiB&STYLES=&FORMAT=image/png",
|
||||
name: "🇵🇱 Polish Orthophoto (Standard)",
|
||||
attribution: '© <a href="https://www.geoportal.gov.pl/">Geoportal</a>',
|
||||
url: "https://mapy.geoportal.gov.pl/wss/service/PZGIK/ORTO/WMTS/StandardResolution?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,
|
||||
tileSize: 256
|
||||
checked: false
|
||||
},
|
||||
{
|
||||
name: "🇵🇱 Polish Orthophoto (High Resolution)",
|
||||
attribution: '© <a href="https://www.geoportal.gov.pl/">Geoportal</a>',
|
||||
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,
|
||||
checked: false
|
||||
},
|
||||
{
|
||||
name: "🌍 Google Satellite",
|
||||
attribution: '© Google',
|
||||
url: "http://mt1.google.com/vt/lyrs=s&hl=pl&x={x}&y={y}&z={z}",
|
||||
maxZoom: 20,
|
||||
checked: false
|
||||
}, {
|
||||
name: "🌍 Google Hybrid",
|
||||
attribution: '© Google',
|
||||
url: "http://mt1.google.com/vt/lyrs=y&hl=pl&x={x}&y={y}&z={z}",
|
||||
maxZoom: 20,
|
||||
checked: false
|
||||
},
|
||||
{
|
||||
name: "Satellite (Esri)",
|
||||
@@ -34,7 +52,131 @@ export const mapLayers = {
|
||||
url: "https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png",
|
||||
maxZoom: 19
|
||||
}
|
||||
].filter(Boolean) // Remove any null entries
|
||||
].filter(Boolean), // Remove any null entries
|
||||
overlays: [
|
||||
{
|
||||
name: "🌍 Google Roads",
|
||||
type: "tile",
|
||||
attribution: '© Google',
|
||||
url: "http://mt1.google.com/vt/lyrs=h&hl=pl&x={x}&y={y}&z={z}",
|
||||
maxZoom: 20,
|
||||
opacity: 1.0,
|
||||
checked: false
|
||||
},
|
||||
{
|
||||
name: "📋 Polish Cadastral Data",
|
||||
type: "wms",
|
||||
attribution: '© <a href="https://www.gugik.gov.pl/">GUGiK</a>',
|
||||
url: "https://integracja01.gugik.gov.pl/cgi-bin/KrajowaIntegracjaEwidencjiGruntow",
|
||||
params: {
|
||||
service: 'WMS',
|
||||
request: 'GetMap',
|
||||
layers: 'powiaty,powiaty_obreby,zsin,obreby,dzialki,geoportal,numery_dzialek,budynki',
|
||||
styles: ',,,,,,,',
|
||||
format: 'image/png',
|
||||
transparent: true,
|
||||
version: '1.3.0',
|
||||
crs: 'EPSG:3857'
|
||||
},
|
||||
opacity: 0.8,
|
||||
checked: false
|
||||
},
|
||||
{
|
||||
name: "🏗️ Polish Spatial Planning",
|
||||
type: "wms",
|
||||
attribution: '© <a href="https://www.geoportal.gov.pl/">Geoportal</a>',
|
||||
url: "https://mapy.geoportal.gov.pl/wss/ext/KrajowaIntegracjaMiejscowychPlanowZagospodarowaniaPrzestrzennego",
|
||||
params: {
|
||||
service: 'WMS',
|
||||
request: 'GetMap',
|
||||
layers: 'raster,wektor-str,wektor-lzb,wektor-pow,wektor-lin,wektor-pkt,granice',
|
||||
styles: ',,,,,,',
|
||||
format: 'image/png',
|
||||
transparent: true,
|
||||
version: '1.3.0',
|
||||
crs: 'EPSG:3857',
|
||||
tiled: true
|
||||
},
|
||||
opacity: 0.7,
|
||||
checked: false
|
||||
},
|
||||
{
|
||||
name: "🛣️ LP-Portal Roads",
|
||||
type: "wms",
|
||||
attribution: '© <a href="https://lp-portal.pl/">LP-Portal</a>',
|
||||
url: "https://geoserver.lp-portal.pl/geoserver/pzdnowysacz/wms",
|
||||
params: {
|
||||
service: 'WMS',
|
||||
request: 'GetMap',
|
||||
layers: '00_6_mapainteraktywna_drogi',
|
||||
styles: '',
|
||||
format: 'image/png8',
|
||||
transparent: true,
|
||||
version: '1.3.0',
|
||||
crs: 'EPSG:3857',
|
||||
tiled: true
|
||||
},
|
||||
opacity: 0.9,
|
||||
checked: false
|
||||
},
|
||||
{
|
||||
name: "🏷️ LP-Portal Street Names",
|
||||
type: "wms",
|
||||
attribution: '© <a href="https://lp-portal.pl/">LP-Portal</a>',
|
||||
url: "https://geoserver.lp-portal.pl/geoserver/pzdnowysacz/wms",
|
||||
params: {
|
||||
service: 'WMS',
|
||||
request: 'GetMap',
|
||||
layers: '00_5_mapainteraktywna_opisy_drog,00_3_mapainteraktywna_nazwy_ulic',
|
||||
styles: '',
|
||||
format: 'image/png8',
|
||||
transparent: true,
|
||||
version: '1.1.1',
|
||||
crs: 'EPSG:3857',
|
||||
tiled: true
|
||||
},
|
||||
opacity: 1.0,
|
||||
checked: false
|
||||
},
|
||||
{
|
||||
name: "📐 LP-Portal Parcels",
|
||||
type: "wms",
|
||||
attribution: '© <a href="https://lp-portal.pl/">LP-Portal</a>',
|
||||
url: "https://geoserver.lp-portal.pl/geoserver/pzdnowysacz/wms",
|
||||
params: {
|
||||
service: 'WMS',
|
||||
request: 'GetMap',
|
||||
layers: 'dzialki',
|
||||
styles: '',
|
||||
format: 'image/png',
|
||||
transparent: true,
|
||||
version: '1.1.1',
|
||||
crs: 'EPSG:3857',
|
||||
tiled: true
|
||||
},
|
||||
opacity: 0.6,
|
||||
checked: false
|
||||
},
|
||||
{
|
||||
name: "📍 LP-Portal Survey Markers",
|
||||
type: "wms",
|
||||
attribution: '© <a href="https://lp-portal.pl/">LP-Portal</a>',
|
||||
url: "https://geoserver.lp-portal.pl/geoserver/pzdnowysacz/wms",
|
||||
params: {
|
||||
service: 'WMS',
|
||||
request: 'GetMap',
|
||||
layers: '00_2_view_geop_odcinek_pikietaz_glob_multi',
|
||||
styles: '',
|
||||
format: 'image/png8',
|
||||
transparent: true,
|
||||
version: '1.1.1',
|
||||
crs: 'EPSG:3857',
|
||||
tiled: true
|
||||
},
|
||||
opacity: 0.8,
|
||||
checked: false
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
// WMTS services configuration with GetCapabilities URLs
|
||||
|
||||
@@ -53,13 +53,15 @@ export function buildWMTSTileUrl(config) {
|
||||
export const polishWMTSServices = {
|
||||
orthophoto: {
|
||||
name: "Polish Geoportal Orthophoto",
|
||||
capabilitiesUrl: "https://mapy.geoportal.gov.pl/wss/service/PZGIK/ORTO/WMTS/StandardResolution",
|
||||
capabilitiesUrl: "https://mapy.geoportal.gov.pl/wss/service/PZGIK/ORTO/REST/StandardResolution",
|
||||
layer: "ORTO",
|
||||
style: "default",
|
||||
tilematrixSet: "EPSG:2180",
|
||||
format: "image/jpeg",
|
||||
tilematrixSet: "EPSG:3857", // Changed from EPSG:2180 to EPSG:3857 for better Leaflet compatibility
|
||||
format: "image/png", // Changed from jpeg to png
|
||||
attribution: '© <a href="https://www.geoportal.gov.pl/">Geoportal</a>',
|
||||
maxZoom: 19
|
||||
maxZoom: 19,
|
||||
tileSize: 512,
|
||||
zoomOffset: -1
|
||||
}
|
||||
};
|
||||
|
||||
@@ -75,14 +77,10 @@ export function generateLayerConfig(serviceName) {
|
||||
return {
|
||||
name: service.name,
|
||||
attribution: service.attribution,
|
||||
url: buildWMTSTileUrl({
|
||||
baseUrl: service.capabilitiesUrl,
|
||||
layer: service.layer,
|
||||
style: service.style,
|
||||
tilematrixSet: service.tilematrixSet,
|
||||
format: service.format
|
||||
}),
|
||||
// Use working WMTS KVP URL format
|
||||
url: "https://mapy.geoportal.gov.pl/wss/service/PZGIK/ORTO/WMTS/StandardResolution?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: service.maxZoom,
|
||||
tileSize: 256
|
||||
tileSize: 256, // Standard tile size for WMTS
|
||||
checked: false
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user