diff --git a/web/static/map.js b/web/static/map.js index 25da2fb..bfa69ee 100644 --- a/web/static/map.js +++ b/web/static/map.js @@ -77,7 +77,7 @@ function calculateBounds() { } } -// Style functions +// Style functions for lines function osmStyle(feature) { return { color: '#4a4a4a', @@ -86,10 +86,17 @@ function osmStyle(feature) { }; } -// const leafIcon = new L.icon({ -// iconUrl: "https://docs.maptiler.com/sdk-js/examples/custom-points-icon-png/underground.png", //your custom pin -// iconSize: [24, 26], -// }); +// Style functions for point markers (addresses) +function osmMarkerStyle(feature) { + return { + radius: 6, + fillColor: '#4a4a4a', + color: '#333', + weight: 1, + opacity: 0.8, + fillOpacity: 0.6 + }; +} function diffStyle(feature) { // Check if feature is accepted or rejected @@ -117,6 +124,41 @@ function diffStyle(feature) { }; } +function diffMarkerStyle(feature) { + // Check if feature is accepted or rejected + if (acceptedFeatures.has(feature)) { + return { + radius: 6, + fillColor: '#007bff', + color: '#0056b3', + weight: 1, + opacity: 0.8, + fillOpacity: 0.7 + }; + } + + if (rejectedFeatures.has(feature)) { + return { + radius: 6, + fillColor: '#ff8c00', + color: '#d47200', + weight: 1, + opacity: 0.8, + fillOpacity: 0.7 + }; + } + + const isRemoved = feature.properties && (feature.properties.removed === true || feature.properties.removed === 'True'); + return { + radius: 6, + fillColor: isRemoved ? '#ff0000' : '#00ff00', + color: isRemoved ? '#cc0000' : '#00cc00', + weight: 1, + opacity: 0.8, + fillOpacity: 0.7 + }; +} + function countyStyle(feature) { return { color: '#ff00ff', @@ -125,6 +167,17 @@ function countyStyle(feature) { }; } +function countyMarkerStyle(feature) { + return { + radius: 6, + fillColor: '#ff00ff', + color: '#cc00cc', + weight: 1, + opacity: 0.8, + fillOpacity: 0.6 + }; +} + // Filter function for OSM features function shouldShowOsmFeature(feature) { const props = feature.properties || {}; @@ -147,7 +200,12 @@ function createOsmLayer() { style: osmStyle, filter: shouldShowOsmFeature, pane: 'osmPane', + pointToLayer: function(feature, latlng) { + return L.circleMarker(latlng, osmMarkerStyle(feature)); + }, onEachFeature: function(feature, layer) { + const isPoint = feature.geometry.type === 'Point'; + layer.on('click', function(e) { L.DomEvent.stopPropagation(e); selectFeature(feature, layer, e, 'osm'); @@ -155,16 +213,27 @@ function createOsmLayer() { layer.on('mouseover', function(e) { if (selectedLayer !== layer) { - layer.setStyle({ - weight: 5, - opacity: 1 - }); + if (isPoint) { + layer.setStyle({ + radius: 8, + fillOpacity: 1 + }); + } else { + layer.setStyle({ + weight: 5, + opacity: 1 + }); + } } }); layer.on('mouseout', function(e) { if (selectedLayer !== layer) { - layer.setStyle(osmStyle(feature)); + if (isPoint) { + layer.setStyle(osmMarkerStyle(feature)); + } else { + layer.setStyle(osmStyle(feature)); + } } }); } @@ -203,12 +272,14 @@ function createDiffLayer() { diffLayer = L.geoJSON(diffData, { style: diffStyle, - // pointToLayer: function (geoJsonPoint, latlng) { - // return L.marker(latlng, {icon: leafIcon}); - // } filter: shouldShowFeature, pane: 'diffPane', + pointToLayer: function(feature, latlng) { + return L.circleMarker(latlng, diffMarkerStyle(feature)); + }, onEachFeature: function(feature, layer) { + const isPoint = feature.geometry.type === 'Point'; + layer.on('click', function(e) { L.DomEvent.stopPropagation(e); selectFeature(feature, layer, e, 'diff'); @@ -216,16 +287,27 @@ function createDiffLayer() { layer.on('mouseover', function(e) { if (selectedLayer !== layer) { - layer.setStyle({ - weight: 5, - opacity: 1 - }); + if (isPoint) { + layer.setStyle({ + radius: 8, + fillOpacity: 1 + }); + } else { + layer.setStyle({ + weight: 5, + opacity: 1 + }); + } } }); layer.on('mouseout', function(e) { if (selectedLayer !== layer) { - layer.setStyle(diffStyle(feature)); + if (isPoint) { + layer.setStyle(diffMarkerStyle(feature)); + } else { + layer.setStyle(diffStyle(feature)); + } } }); } @@ -256,7 +338,12 @@ function createCountyLayer() { style: countyStyle, filter: shouldShowCountyFeature, pane: 'countyPane', + pointToLayer: function(feature, latlng) { + return L.circleMarker(latlng, countyMarkerStyle(feature)); + }, onEachFeature: function(feature, layer) { + const isPoint = feature.geometry.type === 'Point'; + layer.on('click', function(e) { L.DomEvent.stopPropagation(e); selectFeature(feature, layer, e, 'county'); @@ -264,16 +351,27 @@ function createCountyLayer() { layer.on('mouseover', function(e) { if (selectedLayer !== layer) { - layer.setStyle({ - weight: 5, - opacity: 1 - }); + if (isPoint) { + layer.setStyle({ + radius: 8, + fillOpacity: 1 + }); + } else { + layer.setStyle({ + weight: 5, + opacity: 1 + }); + } } }); layer.on('mouseout', function(e) { if (selectedLayer !== layer) { - layer.setStyle(countyStyle(feature)); + if (isPoint) { + layer.setStyle(countyMarkerStyle(feature)); + } else { + layer.setStyle(countyStyle(feature)); + } } }); } @@ -291,20 +389,40 @@ function createCountyLayer() { function selectFeature(feature, layer, e, layerType = 'diff') { // Deselect previous feature if (selectedLayer) { + const isPoint = selectedLayer.feature.geometry.type === 'Point'; // Get the appropriate style function based on previous layer type - const styleFunc = selectedLayer._layerType === 'diff' ? diffStyle : - selectedLayer._layerType === 'osm' ? osmStyle : countyStyle; - selectedLayer.setStyle(styleFunc(selectedLayer.feature)); + if (isPoint) { + const markerStyleFunc = selectedLayer._layerType === 'diff' ? diffMarkerStyle : + selectedLayer._layerType === 'osm' ? osmMarkerStyle : countyMarkerStyle; + selectedLayer.setStyle(markerStyleFunc(selectedLayer.feature)); + } else { + const styleFunc = selectedLayer._layerType === 'diff' ? diffStyle : + selectedLayer._layerType === 'osm' ? osmStyle : countyStyle; + selectedLayer.setStyle(styleFunc(selectedLayer.feature)); + } } selectedFeature = feature; selectedLayer = layer; selectedLayer._layerType = layerType; // Store layer type for later - layer.setStyle({ - weight: 6, - opacity: 1, - color: '#ffc107' - }); + + const isPoint = feature.geometry.type === 'Point'; + if (isPoint) { + layer.setStyle({ + radius: 9, + fillColor: '#ffc107', + color: '#ff9800', + weight: 2, + opacity: 1, + fillOpacity: 1 + }); + } else { + layer.setStyle({ + weight: 6, + opacity: 1, + color: '#ffc107' + }); + } // Create popup near the clicked location const props = feature.properties || {}; @@ -326,8 +444,17 @@ function selectFeature(feature, layer, e, layerType = 'diff') { const displayProps = Object.entries(props) .filter(([key, value]) => value !== null && value !== undefined && key !== 'removed') .sort(([a], [b]) => { - // Priority order: name, highway, then alphabetical - const priorityOrder = { 'name': 0, 'highway': 1 }; + // Priority order: address fields first, then name/highway, then alphabetical + const priorityOrder = { + 'addr:housenumber': 0, + 'addr:street': 1, + 'addr:unit': 2, + 'addr:city': 3, + 'addr:postcode': 4, + 'addr:state': 5, + 'name': 10, + 'highway': 11 + }; const aPriority = priorityOrder[a] ?? 999; const bPriority = priorityOrder[b] ?? 999; @@ -380,7 +507,16 @@ function selectFeature(feature, layer, e, layerType = 'diff') { // Handle popup close featurePopup.on('remove', function() { if (selectedLayer) { - selectedLayer.setStyle(diffStyle(selectedLayer.feature)); + const isPoint = selectedLayer.feature.geometry.type === 'Point'; + if (isPoint) { + const markerStyleFunc = selectedLayer._layerType === 'diff' ? diffMarkerStyle : + selectedLayer._layerType === 'osm' ? osmMarkerStyle : countyMarkerStyle; + selectedLayer.setStyle(markerStyleFunc(selectedLayer.feature)); + } else { + const styleFunc = selectedLayer._layerType === 'diff' ? diffStyle : + selectedLayer._layerType === 'osm' ? osmStyle : countyStyle; + selectedLayer.setStyle(styleFunc(selectedLayer.feature)); + } selectedLayer = null; selectedFeature = null; } @@ -399,7 +535,12 @@ function acceptFeature() { // Update layer style if (selectedLayer) { - selectedLayer.setStyle(diffStyle(selectedFeature)); + const isPoint = selectedFeature.geometry.type === 'Point'; + if (isPoint) { + selectedLayer.setStyle(diffMarkerStyle(selectedFeature)); + } else { + selectedLayer.setStyle(diffStyle(selectedFeature)); + } } // Close popup @@ -425,7 +566,12 @@ function rejectFeature() { // Update layer style if (selectedLayer) { - selectedLayer.setStyle(diffStyle(selectedFeature)); + const isPoint = selectedFeature.geometry.type === 'Point'; + if (isPoint) { + selectedLayer.setStyle(diffMarkerStyle(selectedFeature)); + } else { + selectedLayer.setStyle(diffStyle(selectedFeature)); + } } // Close popup @@ -481,9 +627,9 @@ async function loadFiles() { diffFile = `latest/${county}/diff-paths.geojson`; countyFile = `latest/${county}/county-paths.geojson`; } else if (dataType === 'addresses') { - osmFile = null; //`latest/${county}/addresses-existing.geojson`; + osmFile = `osm_cache/osm_addresses_${county}_20251207.geojson`; diffFile = `latest/${county}/addresses-to-add.geojson`; - countyFile = null; + countyFile = `latest/${county}/addresses.shp_converted.geojson`; } // Load files from server