Spaces:
Sleeping
Sleeping
thedynamicpacif
commited on
Commit
·
b96ab7a
1
Parent(s):
5cf313a
Improves map visualization
Browse filesUpdated the map to display different feature types (buildings, trees, water, roads) with distinct colors and styles. Added a feature type selection to the upload form and updated the displayResults function to handle and display the feature type. Changes made to `static/js/map.js` and `static/js/upload.js`.
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: c7b687d7-8856-49d8-87a3-9d7f3f6499f6
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d7727d0d-3b25-49de-9476-c76c61abfa65/e5f084ec-b0de-4b77-93ae-2162e40cb521.jpg
- static/js/map.js +93 -15
- static/js/upload.js +16 -0
static/js/map.js
CHANGED
@@ -5,6 +5,7 @@
|
|
5 |
|
6 |
// Store the map object globally
|
7 |
let map = null;
|
|
|
8 |
|
9 |
// Initialize the map with default settings
|
10 |
function initMap() {
|
@@ -14,7 +15,8 @@ function initMap() {
|
|
14 |
}
|
15 |
|
16 |
// Create a new map centered on a default location
|
17 |
-
|
|
|
18 |
|
19 |
// Add the base tile layer (OpenStreetMap)
|
20 |
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
@@ -34,6 +36,11 @@ function displayGeoJSON(geojsonData) {
|
|
34 |
initMap();
|
35 |
}
|
36 |
|
|
|
|
|
|
|
|
|
|
|
37 |
// Clear any existing GeoJSON layers
|
38 |
map.eachLayer(function(layer) {
|
39 |
if (layer instanceof L.GeoJSON) {
|
@@ -41,35 +48,106 @@ function displayGeoJSON(geojsonData) {
|
|
41 |
}
|
42 |
});
|
43 |
|
44 |
-
// Add the GeoJSON data to the map with styling
|
45 |
const geojsonLayer = L.geoJSON(geojsonData, {
|
46 |
style: function(feature) {
|
47 |
-
//
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
},
|
56 |
pointToLayer: function(feature, latlng) {
|
57 |
-
// Style points
|
58 |
-
|
59 |
radius: 8,
|
60 |
-
fillColor: getRandomColor(),
|
61 |
color: "#000",
|
62 |
weight: 1,
|
63 |
opacity: 1,
|
64 |
fillOpacity: 0.8
|
65 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
},
|
67 |
onEachFeature: function(feature, layer) {
|
68 |
// Add popups to show feature properties
|
69 |
if (feature.properties) {
|
70 |
let popupContent = '<div class="feature-popup">';
|
71 |
|
72 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
|
74 |
for (const [key, value] of Object.entries(feature.properties)) {
|
75 |
popupContent += `<strong>${key}:</strong> ${value}<br>`;
|
|
|
5 |
|
6 |
// Store the map object globally
|
7 |
let map = null;
|
8 |
+
let currentFeatureType = 'buildings';
|
9 |
|
10 |
// Initialize the map with default settings
|
11 |
function initMap() {
|
|
|
15 |
}
|
16 |
|
17 |
// Create a new map centered on a default location
|
18 |
+
// Use a location outside of Manhattan
|
19 |
+
map = L.map('map').setView([41.0, -74.5], 10);
|
20 |
|
21 |
// Add the base tile layer (OpenStreetMap)
|
22 |
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
|
|
36 |
initMap();
|
37 |
}
|
38 |
|
39 |
+
// Update feature type if available in the data
|
40 |
+
if (geojsonData && geojsonData.feature_type) {
|
41 |
+
currentFeatureType = geojsonData.feature_type;
|
42 |
+
}
|
43 |
+
|
44 |
// Clear any existing GeoJSON layers
|
45 |
map.eachLayer(function(layer) {
|
46 |
if (layer instanceof L.GeoJSON) {
|
|
|
48 |
}
|
49 |
});
|
50 |
|
51 |
+
// Add the GeoJSON data to the map with styling based on feature type
|
52 |
const geojsonLayer = L.geoJSON(geojsonData, {
|
53 |
style: function(feature) {
|
54 |
+
// Different styling based on feature type
|
55 |
+
switch(currentFeatureType) {
|
56 |
+
case 'buildings':
|
57 |
+
return {
|
58 |
+
fillColor: '#e63946',
|
59 |
+
weight: 1.5,
|
60 |
+
opacity: 1,
|
61 |
+
color: '#999',
|
62 |
+
fillOpacity: 0.7
|
63 |
+
};
|
64 |
+
case 'trees':
|
65 |
+
return {
|
66 |
+
fillColor: '#2a9d8f',
|
67 |
+
weight: 1,
|
68 |
+
opacity: 0.9,
|
69 |
+
color: '#006d4f',
|
70 |
+
fillOpacity: 0.7
|
71 |
+
};
|
72 |
+
case 'water':
|
73 |
+
return {
|
74 |
+
fillColor: '#0077b6',
|
75 |
+
weight: 1,
|
76 |
+
opacity: 0.8,
|
77 |
+
color: '#023e8a',
|
78 |
+
fillOpacity: 0.6
|
79 |
+
};
|
80 |
+
case 'roads':
|
81 |
+
return {
|
82 |
+
fillColor: '#a8dadc',
|
83 |
+
weight: 3,
|
84 |
+
opacity: 1,
|
85 |
+
color: '#457b9d',
|
86 |
+
fillOpacity: 0.8
|
87 |
+
};
|
88 |
+
default:
|
89 |
+
return {
|
90 |
+
fillColor: getRandomColor(),
|
91 |
+
weight: 2,
|
92 |
+
opacity: 1,
|
93 |
+
color: '#666',
|
94 |
+
fillOpacity: 0.7
|
95 |
+
};
|
96 |
+
}
|
97 |
},
|
98 |
pointToLayer: function(feature, latlng) {
|
99 |
+
// Style points based on feature type
|
100 |
+
let pointStyle = {
|
101 |
radius: 8,
|
|
|
102 |
color: "#000",
|
103 |
weight: 1,
|
104 |
opacity: 1,
|
105 |
fillOpacity: 0.8
|
106 |
+
};
|
107 |
+
|
108 |
+
// Set color based on feature type
|
109 |
+
switch(currentFeatureType) {
|
110 |
+
case 'buildings':
|
111 |
+
pointStyle.fillColor = '#e63946';
|
112 |
+
break;
|
113 |
+
case 'trees':
|
114 |
+
pointStyle.fillColor = '#2a9d8f';
|
115 |
+
break;
|
116 |
+
case 'water':
|
117 |
+
pointStyle.fillColor = '#0077b6';
|
118 |
+
break;
|
119 |
+
case 'roads':
|
120 |
+
pointStyle.fillColor = '#a8dadc';
|
121 |
+
break;
|
122 |
+
default:
|
123 |
+
pointStyle.fillColor = getRandomColor();
|
124 |
+
}
|
125 |
+
|
126 |
+
return L.circleMarker(latlng, pointStyle);
|
127 |
},
|
128 |
onEachFeature: function(feature, layer) {
|
129 |
// Add popups to show feature properties
|
130 |
if (feature.properties) {
|
131 |
let popupContent = '<div class="feature-popup">';
|
132 |
|
133 |
+
// Set title based on feature type
|
134 |
+
let title = 'Feature';
|
135 |
+
switch(currentFeatureType) {
|
136 |
+
case 'buildings':
|
137 |
+
title = 'Building';
|
138 |
+
break;
|
139 |
+
case 'trees':
|
140 |
+
title = 'Tree/Vegetation';
|
141 |
+
break;
|
142 |
+
case 'water':
|
143 |
+
title = 'Water Body';
|
144 |
+
break;
|
145 |
+
case 'roads':
|
146 |
+
title = 'Road';
|
147 |
+
break;
|
148 |
+
}
|
149 |
+
|
150 |
+
popupContent += `<h5>${title} Properties</h5>`;
|
151 |
|
152 |
for (const [key, value] of Object.entries(feature.properties)) {
|
153 |
popupContent += `<strong>${key}:</strong> ${value}<br>`;
|
static/js/upload.js
CHANGED
@@ -44,6 +44,7 @@ uploadForm.addEventListener('submit', function(event) {
|
|
44 |
// Create FormData object for file upload
|
45 |
const formData = new FormData();
|
46 |
formData.append('file', file);
|
|
|
47 |
|
48 |
// Upload the file
|
49 |
fetch('/upload', {
|
@@ -85,6 +86,21 @@ function displayResults(data) {
|
|
85 |
initMap();
|
86 |
}
|
87 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
// Display the GeoJSON on the map
|
89 |
displayGeoJSON(data.geojson);
|
90 |
|
|
|
44 |
// Create FormData object for file upload
|
45 |
const formData = new FormData();
|
46 |
formData.append('file', file);
|
47 |
+
formData.append('feature_type', featureTypeSelect.value);
|
48 |
|
49 |
// Upload the file
|
50 |
fetch('/upload', {
|
|
|
86 |
initMap();
|
87 |
}
|
88 |
|
89 |
+
// Update the header to show the feature type
|
90 |
+
const featureType = data.feature_type || 'buildings';
|
91 |
+
const featureTypeName = {
|
92 |
+
'buildings': 'Buildings',
|
93 |
+
'trees': 'Trees/Vegetation',
|
94 |
+
'water': 'Water Bodies',
|
95 |
+
'roads': 'Roads'
|
96 |
+
}[featureType] || 'Features';
|
97 |
+
|
98 |
+
// Update the card header text
|
99 |
+
const resultsHeader = document.querySelector('#resultsSection .card-header h3');
|
100 |
+
if (resultsHeader) {
|
101 |
+
resultsHeader.innerHTML = `<i class="fas fa-map"></i> ${featureTypeName} Extraction Results`;
|
102 |
+
}
|
103 |
+
|
104 |
// Display the GeoJSON on the map
|
105 |
displayGeoJSON(data.geojson);
|
106 |
|