Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -122,155 +122,188 @@ If you encounter any issues or need assistance, feel free to [Contact Support on
|
|
122 |
st.write("### Interactive Map of Dhaka Metro Stations")
|
123 |
map_html = """
|
124 |
<!DOCTYPE html>
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
#map {
|
133 |
-
height:
|
134 |
-
width: 100%;
|
135 |
}
|
|
|
136 |
#controls {
|
137 |
-
|
138 |
-
padding: 10px;
|
139 |
-
display: flex;
|
140 |
-
justify-content: center;
|
141 |
-
align-items: center;
|
142 |
-
gap: 10px;
|
143 |
-
background-color: #D8C4B6;
|
144 |
}
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
<select id="source">
|
150 |
-
<option value="">Select Source</option>
|
151 |
-
</select>
|
152 |
-
<select id="destination">
|
153 |
-
<option value="">Select Destination</option>
|
154 |
-
</select>
|
155 |
-
<button onclick="startRouteAnimation()">Animate Route</button>
|
156 |
-
<button onclick="animateAllLocations()">Animate All Locations</button>
|
157 |
-
<button onclick="stopAnimation()">Stop Animation</button>
|
158 |
-
</div>
|
159 |
-
<div id="map"></div>
|
160 |
-
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
|
161 |
-
<script>
|
162 |
-
const coordinates = {
|
163 |
-
"Uttara North": [23.869066, 90.367445],
|
164 |
-
"Uttara Center": [23.860118, 90.365106],
|
165 |
-
"Uttara South": [23.845934, 90.363175],
|
166 |
-
"Pallabi": [23.82619516961383, 90.36481554252525],
|
167 |
-
"Mirpur 11": [23.819438208310213, 90.36528532902963],
|
168 |
-
"Mirpur 10": [23.808582994847285, 90.36821595330717],
|
169 |
-
"Kazipara": [23.800017952100532, 90.37178261495391],
|
170 |
-
"Shewrapara": [23.79070140857881, 90.37564622631841],
|
171 |
-
"Agargaon": [23.778385546736345, 90.3800557456356],
|
172 |
-
"Bijoy Sarani": [23.766638127271825, 90.38307537134754],
|
173 |
-
"Farmgate": [23.75923604938459, 90.38694218434738],
|
174 |
-
"Kawran Bazar": [23.751392319539104, 90.39275707447003],
|
175 |
-
"Shahbagh": [23.740324209546923, 90.39600784811131],
|
176 |
-
"Dhaka University": [23.732091083122114, 90.39659408796354],
|
177 |
-
"Bangladesh Secretariat": [23.73004754106779, 90.40764881366906],
|
178 |
-
"Motijheel": [23.72816566933198, 90.41923497972823],
|
179 |
-
"Kamalapur": [23.732367758919807, 90.42547378971085]
|
180 |
-
};
|
181 |
-
const map = L.map('map').setView([23.8103, 90.4125], 12); // Centered on Dhaka
|
182 |
-
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
183 |
-
maxZoom: 19,
|
184 |
-
attribution: '© OpenStreetMap contributors'
|
185 |
-
}).addTo(map);
|
186 |
-
// Populate source and destination dropdowns
|
187 |
-
const sourceSelect = document.getElementById('source');
|
188 |
-
const destinationSelect = document.getElementById('destination');
|
189 |
-
for (const location in coordinates) {
|
190 |
-
const option = document.createElement('option');
|
191 |
-
option.value = location;
|
192 |
-
option.textContent = location;
|
193 |
-
sourceSelect.appendChild(option);
|
194 |
-
destinationSelect.appendChild(option.cloneNode(true));
|
195 |
-
}
|
196 |
-
const markers = {};
|
197 |
-
for (const [name, coord] of Object.entries(coordinates)) {
|
198 |
-
const marker = L.marker(coord).addTo(map).bindPopup(`<b>${name}</b>`);
|
199 |
-
markers[name] = marker;
|
200 |
}
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
217 |
}
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
function animateRoute() {
|
228 |
-
if (routeIndex >= route.length) {
|
229 |
-
return; // Animation completed
|
230 |
-
}
|
231 |
-
const currentLocation = route[routeIndex];
|
232 |
-
const marker = markers[currentLocation];
|
233 |
-
if (routeIndex === 0) {
|
234 |
-
map.flyTo(marker.getLatLng(), 14, { duration: 2 });
|
235 |
-
marker.openPopup();
|
236 |
-
} else {
|
237 |
-
setTimeout(() => {
|
238 |
-
map.flyTo(marker.getLatLng(), 14, { duration: 2 });
|
239 |
-
marker.openPopup();
|
240 |
-
}, 3000);
|
241 |
-
}
|
242 |
-
routeIndex++;
|
243 |
-
animationTimeout = setTimeout(animateRoute, 3000); // Wait before moving to the next
|
244 |
-
}
|
245 |
-
animateRoute();
|
246 |
}
|
247 |
-
|
248 |
-
|
249 |
-
|
|
|
|
|
|
|
250 |
}
|
251 |
-
|
252 |
-
|
|
|
253 |
map.flyTo(marker.getLatLng(), 14, { duration: 2 });
|
254 |
marker.openPopup();
|
255 |
-
currentIndex++;
|
256 |
-
animationTimeout = setTimeout(animateAllLocations, 3000); // Wait 3 seconds before next
|
257 |
} else {
|
258 |
-
|
|
|
|
|
|
|
259 |
}
|
|
|
|
|
260 |
}
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
271 |
}
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
|
|
|
|
|
|
|
|
276 |
components.html(map_html, height=600)
|
|
|
122 |
st.write("### Interactive Map of Dhaka Metro Stations")
|
123 |
map_html = """
|
124 |
<!DOCTYPE html>
|
125 |
+
<html lang="en">
|
126 |
+
<head>
|
127 |
+
<meta charset="UTF-8">
|
128 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
129 |
+
<title>Interactive Map</title>
|
130 |
+
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
|
131 |
+
<style>
|
132 |
+
/* Make map container responsive */
|
133 |
+
#map {
|
134 |
+
height: 70vh; /* Default height is 70% of the viewport height */
|
135 |
+
width: 100%; /* Full width */
|
136 |
+
}
|
137 |
+
|
138 |
+
/* Controls container: Flex layout for larger screens, column layout for smaller screens */
|
139 |
+
#controls {
|
140 |
+
padding: 10px;
|
141 |
+
display: flex;
|
142 |
+
justify-content: center;
|
143 |
+
align-items: center;
|
144 |
+
gap: 10px;
|
145 |
+
background-color: #D8C4B6;
|
146 |
+
flex-wrap: wrap; /* Allows wrapping of elements on small screens */
|
147 |
+
}
|
148 |
+
|
149 |
+
#controls select, #controls button {
|
150 |
+
margin: 5px;
|
151 |
+
font-size: 14px;
|
152 |
+
}
|
153 |
+
|
154 |
+
@media (max-width: 600px) {
|
155 |
#map {
|
156 |
+
height: 50vh; /* For mobile screens, reduce map height */
|
|
|
157 |
}
|
158 |
+
|
159 |
#controls {
|
160 |
+
flex-direction: column; /* Stack controls vertically on smaller screens */
|
|
|
|
|
|
|
|
|
|
|
|
|
161 |
}
|
162 |
+
|
163 |
+
#controls select, #controls button {
|
164 |
+
width: 100%; /* Make controls fill the available width */
|
165 |
+
margin: 8px 0; /* Add vertical margin for better spacing */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
166 |
}
|
167 |
+
}
|
168 |
+
</style>
|
169 |
+
</head>
|
170 |
+
<body>
|
171 |
+
<div id="controls">
|
172 |
+
<select id="source">
|
173 |
+
<option value="">Select Source</option>
|
174 |
+
</select>
|
175 |
+
<select id="destination">
|
176 |
+
<option value="">Select Destination</option>
|
177 |
+
</select>
|
178 |
+
<button onclick="startRouteAnimation()">Animate Route</button>
|
179 |
+
<button onclick="animateAllLocations()">Animate All Locations</button>
|
180 |
+
<button onclick="stopAnimation()">Stop Animation</button>
|
181 |
+
</div>
|
182 |
+
|
183 |
+
<div id="map"></div>
|
184 |
+
|
185 |
+
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
|
186 |
+
<script>
|
187 |
+
const coordinates = {
|
188 |
+
"Uttara North": [23.869066, 90.367445],
|
189 |
+
"Uttara Center": [23.860118, 90.365106],
|
190 |
+
"Uttara South": [23.845934, 90.363175],
|
191 |
+
"Pallabi": [23.82619516961383, 90.36481554252525],
|
192 |
+
"Mirpur 11": [23.819438208310213, 90.36528532902963],
|
193 |
+
"Mirpur 10": [23.808582994847285, 90.36821595330717],
|
194 |
+
"Kazipara": [23.800017952100532, 90.37178261495391],
|
195 |
+
"Shewrapara": [23.79070140857881, 90.37564622631841],
|
196 |
+
"Agargaon": [23.778385546736345, 90.3800557456356],
|
197 |
+
"Bijoy Sarani": [23.766638127271825, 90.38307537134754],
|
198 |
+
"Farmgate": [23.75923604938459, 90.38694218434738],
|
199 |
+
"Kawran Bazar": [23.751392319539104, 90.39275707447003],
|
200 |
+
"Shahbagh": [23.740324209546923, 90.39600784811131],
|
201 |
+
"Dhaka University": [23.732091083122114, 90.39659408796354],
|
202 |
+
"Bangladesh Secretariat": [23.73004754106779, 90.40764881366906],
|
203 |
+
"Motijheel": [23.72816566933198, 90.41923497972823],
|
204 |
+
"Kamalapur": [23.732367758919807, 90.42547378971085]
|
205 |
+
};
|
206 |
+
|
207 |
+
const map = L.map('map').setView([23.8103, 90.4125], 12); // Centered on Dhaka
|
208 |
+
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
209 |
+
maxZoom: 19,
|
210 |
+
attribution: '© OpenStreetMap contributors'
|
211 |
+
}).addTo(map);
|
212 |
+
|
213 |
+
// Populate source and destination dropdowns
|
214 |
+
const sourceSelect = document.getElementById('source');
|
215 |
+
const destinationSelect = document.getElementById('destination');
|
216 |
+
for (const location in coordinates) {
|
217 |
+
const option = document.createElement('option');
|
218 |
+
option.value = location;
|
219 |
+
option.textContent = location;
|
220 |
+
sourceSelect.appendChild(option);
|
221 |
+
destinationSelect.appendChild(option.cloneNode(true));
|
222 |
+
}
|
223 |
+
|
224 |
+
const markers = {};
|
225 |
+
for (const [name, coord] of Object.entries(coordinates)) {
|
226 |
+
const marker = L.marker(coord).addTo(map).bindPopup(`<b>${name}</b>`);
|
227 |
+
markers[name] = marker;
|
228 |
+
}
|
229 |
+
|
230 |
+
let currentIndex = 0;
|
231 |
+
const markerArray = Object.values(markers);
|
232 |
+
let animationTimeout; // Store the timeout ID to cancel animation
|
233 |
+
|
234 |
+
function getIntermediateNodes(source, destination) {
|
235 |
+
const allLocations = Object.keys(coordinates);
|
236 |
+
const sourceIndex = allLocations.indexOf(source);
|
237 |
+
const destinationIndex = allLocations.indexOf(destination);
|
238 |
+
const route = [];
|
239 |
+
if (sourceIndex < destinationIndex) {
|
240 |
+
// Forward direction (source to destination)
|
241 |
+
route.push(...allLocations.slice(sourceIndex, destinationIndex + 1));
|
242 |
+
} else {
|
243 |
+
// Reverse direction (destination to source)
|
244 |
+
route.push(...allLocations.slice(destinationIndex, sourceIndex + 1).reverse());
|
245 |
}
|
246 |
+
return route;
|
247 |
+
}
|
248 |
+
|
249 |
+
function startRouteAnimation() {
|
250 |
+
const source = sourceSelect.value;
|
251 |
+
const destination = destinationSelect.value;
|
252 |
+
if (!source || !destination) {
|
253 |
+
alert('Please select both source and destination locations.');
|
254 |
+
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
255 |
}
|
256 |
+
const route = getIntermediateNodes(source, destination);
|
257 |
+
let routeIndex = 0;
|
258 |
+
|
259 |
+
function animateRoute() {
|
260 |
+
if (routeIndex >= route.length) {
|
261 |
+
return; // Animation completed
|
262 |
}
|
263 |
+
const currentLocation = route[routeIndex];
|
264 |
+
const marker = markers[currentLocation];
|
265 |
+
if (routeIndex === 0) {
|
266 |
map.flyTo(marker.getLatLng(), 14, { duration: 2 });
|
267 |
marker.openPopup();
|
|
|
|
|
268 |
} else {
|
269 |
+
setTimeout(() => {
|
270 |
+
map.flyTo(marker.getLatLng(), 14, { duration: 2 });
|
271 |
+
marker.openPopup();
|
272 |
+
}, 3000);
|
273 |
}
|
274 |
+
routeIndex++;
|
275 |
+
animationTimeout = setTimeout(animateRoute, 3000); // Wait before moving to the next
|
276 |
}
|
277 |
+
animateRoute();
|
278 |
+
}
|
279 |
+
|
280 |
+
function animateAllLocations() {
|
281 |
+
if (currentIndex > 0) {
|
282 |
+
markerArray[currentIndex - 1].closePopup();
|
283 |
+
}
|
284 |
+
if (currentIndex < markerArray.length) {
|
285 |
+
const marker = markerArray[currentIndex];
|
286 |
+
map.flyTo(marker.getLatLng(), 14, { duration: 2 });
|
287 |
+
marker.openPopup();
|
288 |
+
currentIndex++;
|
289 |
+
animationTimeout = setTimeout(animateAllLocations, 3000); // Wait 3 seconds before next
|
290 |
+
} else {
|
291 |
+
currentIndex = 0; // Restart animation
|
292 |
+
}
|
293 |
+
}
|
294 |
+
|
295 |
+
function stopAnimation() {
|
296 |
+
clearTimeout(animationTimeout); // Stop the timeout for animation
|
297 |
+
currentIndex = 0; // Reset index
|
298 |
+
for (const marker of markerArray) {
|
299 |
+
marker.closePopup(); // Close all popups
|
300 |
}
|
301 |
+
map.setView([23.8103, 90.4125], 12); // Reset map to initial view
|
302 |
+
sourceSelect.value = ''; // Clear source dropdown
|
303 |
+
destinationSelect.value = ''; // Clear destination dropdown
|
304 |
+
}
|
305 |
+
</script>
|
306 |
+
</body>
|
307 |
+
</html>
|
308 |
+
"""
|
309 |
components.html(map_html, height=600)
|