/** * Map initialization and GeoJSON visualization * This file handles the map creation and displaying GeoJSON data on it */ // Store the map object globally let map = null; let currentFeatureType = 'buildings'; // Initialize the map with default settings function initMap(initialCoords) { // If map already exists, remove it and create a new one if (map !== null) { map.remove(); } // Default center coordinates (will be overridden by GeoJSON data) let center = [0, 0]; let zoom = 2; // If coordinates are provided, use them if (initialCoords && initialCoords.lat !== undefined && initialCoords.lng !== undefined) { center = [initialCoords.lat, initialCoords.lng]; zoom = initialCoords.zoom || 13; } // Initialize the map with the center coordinates map = L.map('map').setView(center, zoom); // Define tile layers const osmLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors', maxZoom: 19 }); const satelliteLayer = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', { attribution: 'Imagery © Esri', maxZoom: 19 }); // Add OpenStreetMap layer by default osmLayer.addTo(map); // Add layer control const baseLayers = { "OpenStreetMap": osmLayer, "Satellite": satelliteLayer }; L.control.layers(baseLayers, null, {position: 'topright'}).addTo(map); // Add a scale control L.control.scale().addTo(map); return map; } // Display GeoJSON data on the map function displayGeoJSON(geojsonData) { // Log the GeoJSON data for debugging console.log('GeoJSON data received:', geojsonData); if (geojsonData && geojsonData.features && geojsonData.features.length > 0) { console.log('First feature:', geojsonData.features[0]); if (geojsonData.features[0].geometry && geojsonData.features[0].geometry.coordinates) { console.log('First feature coordinates:', geojsonData.features[0].geometry.type === 'Polygon' ? geojsonData.features[0].geometry.coordinates[0][0] : geojsonData.features[0].geometry.coordinates[0][0][0]); } } // Calculate center coordinates from GeoJSON data let initialCoords = calculateCenterFromGeoJSON(geojsonData); console.log('Calculated center coordinates:', initialCoords); if (!map) { initMap(initialCoords); } // Switch to satellite view for better context when viewing features if (geojsonData && geojsonData.features && geojsonData.features.length > 0) { // Switch to satellite view for better visualization try { document.querySelectorAll('.leaflet-control-layers-base input')[1].click(); } catch (e) { console.warn('Could not switch to satellite view:', e); } } // Update feature type if available in the data if (geojsonData && geojsonData.feature_type) { currentFeatureType = geojsonData.feature_type; } // Clear any existing GeoJSON layers map.eachLayer(function(layer) { if (layer instanceof L.GeoJSON) { map.removeLayer(layer); } }); // Add the GeoJSON data to the map with styling based on feature type const geojsonLayer = L.geoJSON(geojsonData, { style: function(feature) { // Different styling based on feature type switch(currentFeatureType) { case 'buildings': return { fillColor: '#e63946', weight: 1.5, opacity: 1, color: '#999', fillOpacity: 0.7 }; case 'trees': return { fillColor: '#2a9d8f', weight: 1, opacity: 0.9, color: '#006d4f', fillOpacity: 0.7 }; case 'water': return { fillColor: '#0077b6', weight: 1, opacity: 0.8, color: '#023e8a', fillOpacity: 0.6 }; case 'roads': return { fillColor: '#a8dadc', weight: 3, opacity: 1, color: '#457b9d', fillOpacity: 0.8 }; default: return { fillColor: getRandomColor(), weight: 2, opacity: 1, color: '#666', fillOpacity: 0.7 }; } }, pointToLayer: function(feature, latlng) { // Style points based on feature type let pointStyle = { radius: 8, color: "#000", weight: 1, opacity: 1, fillOpacity: 0.8 }; // Set color based on feature type switch(currentFeatureType) { case 'buildings': pointStyle.fillColor = '#e63946'; break; case 'trees': pointStyle.fillColor = '#2a9d8f'; break; case 'water': pointStyle.fillColor = '#0077b6'; break; case 'roads': pointStyle.fillColor = '#a8dadc'; break; default: pointStyle.fillColor = getRandomColor(); } return L.circleMarker(latlng, pointStyle); }, onEachFeature: function(feature, layer) { // Add popups to show feature properties if (feature.properties) { let popupContent = '