shukdevdatta123 commited on
Commit
4b581f6
·
verified ·
1 Parent(s): 3ed15d0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +160 -0
app.py CHANGED
@@ -1,5 +1,6 @@
1
  import streamlit as st
2
  import pandas as pd
 
3
 
4
  # Load the Excel file
5
  file_path = 'Dhaka Metro Rail Fare 2.XLSX' # Ensure the correct file path
@@ -101,3 +102,162 @@ else:
101
  st.write("No fare data available for the selected origin and destinations.")
102
  else:
103
  st.write("Please select both an origin and at least one destination.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
  import pandas as pd
3
+ import streamlit.components.v1 as components
4
 
5
  # Load the Excel file
6
  file_path = 'Dhaka Metro Rail Fare 2.XLSX' # Ensure the correct file path
 
102
  st.write("No fare data available for the selected origin and destinations.")
103
  else:
104
  st.write("Please select both an origin and at least one destination.")
105
+
106
+ # Embedding the interactive map
107
+ st.write("### Interactive Map of Dhaka Metro Stations")
108
+ map_html = """
109
+ <!DOCTYPE html>
110
+ <html lang="en">
111
+ <head>
112
+ <meta charset="UTF-8">
113
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
114
+ <title>Interactive Map</title>
115
+ <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
116
+ <style>
117
+ #map {
118
+ height: 90vh;
119
+ width: 100%;
120
+ }
121
+ #controls {
122
+ height: 10vh;
123
+ padding: 10px;
124
+ display: flex;
125
+ justify-content: center;
126
+ align-items: center;
127
+ gap: 10px;
128
+ background-color: #f0f0f0;
129
+ }
130
+ </style>
131
+ </head>
132
+ <body>
133
+ <div id="controls">
134
+ <select id="source">
135
+ <option value="">Select Source</option>
136
+ </select>
137
+ <select id="destination">
138
+ <option value="">Select Destination</option>
139
+ </select>
140
+ <button onclick="startRouteAnimation()">Animate Route</button>
141
+ <button onclick="animateAllLocations()">Animate All Locations</button>
142
+ <button onclick="stopAnimation()">Stop Animation</button>
143
+ </div>
144
+ <div id="map"></div>
145
+
146
+ <script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
147
+ <script>
148
+ const coordinates = {
149
+ "Uttara North": [23.869066, 90.367445],
150
+ "Uttara Center": [23.860118, 90.365106],
151
+ "Uttara South": [23.845934, 90.363175],
152
+ "Pallabi": [23.82619516961383, 90.36481554252525],
153
+ "Mirpur 11": [23.819438208310213, 90.36528532902963],
154
+ "Mirpur 10": [23.808582994847285, 90.36821595330717],
155
+ "Kazipara": [23.800017952100532, 90.37178261495391],
156
+ "Shewrapara": [23.79070140857881, 90.37564622631841],
157
+ "Agargaon": [23.778385546736345, 90.3800557456356],
158
+ "Bijoy Sarani": [23.766638127271825, 90.38307537134754],
159
+ "Farmgate": [23.75923604938459, 90.38694218434738],
160
+ "Kawran Bazar": [23.751392319539104, 90.39275707447003],
161
+ "Shahbagh": [23.740324209546923, 90.39600784811131],
162
+ "Dhaka University": [23.732091083122114, 90.39659408796354],
163
+ "Bangladesh Secretariat": [23.73004754106779, 90.40764881366906],
164
+ "Motijheel": [23.72816566933198, 90.41923497972823],
165
+ "Kamalapur": [23.732367758919807, 90.42547378971085]
166
+ };
167
+ const map = L.map('map').setView([23.8103, 90.4125], 12); // Centered on Dhaka
168
+ L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
169
+ maxZoom: 19,
170
+ attribution: '© OpenStreetMap contributors'
171
+ }).addTo(map);
172
+ // Populate source and destination dropdowns
173
+ const sourceSelect = document.getElementById('source');
174
+ const destinationSelect = document.getElementById('destination');
175
+ for (const location in coordinates) {
176
+ const option = document.createElement('option');
177
+ option.value = location;
178
+ option.textContent = location;
179
+ sourceSelect.appendChild(option);
180
+ destinationSelect.appendChild(option.cloneNode(true));
181
+ }
182
+ const markers = {};
183
+ for (const [name, coord] of Object.entries(coordinates)) {
184
+ const marker = L.marker(coord).addTo(map).bindPopup(`<b>${name}</b>`);
185
+ markers[name] = marker;
186
+ }
187
+ let currentIndex = 0;
188
+ const markerArray = Object.values(markers);
189
+ let animationTimeout; // Store the timeout ID to cancel animation
190
+ function getIntermediateNodes(source, destination) {
191
+ const allLocations = Object.keys(coordinates);
192
+ const sourceIndex = allLocations.indexOf(source);
193
+ const destinationIndex = allLocations.indexOf(destination);
194
+ const route = [];
195
+ if (sourceIndex < destinationIndex) {
196
+ // Forward direction (source to destination)
197
+ route.push(...allLocations.slice(sourceIndex, destinationIndex + 1));
198
+ } else {
199
+ // Reverse direction (destination to source)
200
+ route.push(...allLocations.slice(destinationIndex, sourceIndex + 1).reverse());
201
+ }
202
+ return route;
203
+ }
204
+ function startRouteAnimation() {
205
+ const source = sourceSelect.value;
206
+ const destination = destinationSelect.value;
207
+ if (!source || !destination) {
208
+ alert('Please select both source and destination locations.');
209
+ return;
210
+ }
211
+ const route = getIntermediateNodes(source, destination);
212
+ let routeIndex = 0;
213
+ function animateRoute() {
214
+ if (routeIndex >= route.length) {
215
+ return; // Animation completed
216
+ }
217
+ const currentLocation = route[routeIndex];
218
+ const marker = markers[currentLocation];
219
+ if (routeIndex === 0) {
220
+ map.flyTo(marker.getLatLng(), 14, { duration: 2 });
221
+ marker.openPopup();
222
+ } else {
223
+ setTimeout(() => {
224
+ map.flyTo(marker.getLatLng(), 14, { duration: 2 });
225
+ marker.openPopup();
226
+ }, 3000);
227
+ }
228
+ routeIndex++;
229
+ animationTimeout = setTimeout(animateRoute, 3000); // Wait before moving to the next
230
+ }
231
+ animateRoute();
232
+ }
233
+ function animateAllLocations() {
234
+ if (currentIndex > 0) {
235
+ markerArray[currentIndex - 1].closePopup();
236
+ }
237
+ if (currentIndex < markerArray.length) {
238
+ const marker = markerArray[currentIndex];
239
+ map.flyTo(marker.getLatLng(), 14, { duration: 2 });
240
+ marker.openPopup();
241
+ currentIndex++;
242
+ animationTimeout = setTimeout(animateAllLocations, 3000); // Wait 3 seconds before next
243
+ } else {
244
+ currentIndex = 0; // Restart animation
245
+ }
246
+ }
247
+ // Stop animation and reset everything
248
+ function stopAnimation() {
249
+ clearTimeout(animationTimeout); // Stop the timeout for animation
250
+ currentIndex = 0; // Reset index
251
+ for (const marker of markerArray) {
252
+ marker.closePopup(); // Close all popups
253
+ }
254
+ map.setView([23.8103, 90.4125], 12); // Reset map to initial view
255
+ sourceSelect.value = ''; // Clear source dropdown
256
+ destinationSelect.value = ''; // Clear destination dropdown
257
+ }
258
+ </script>
259
+ </body>
260
+ </html>
261
+ """
262
+ components.html(map_html, height=600)
263
+