Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,14 +1,11 @@
|
|
| 1 |
import streamlit as st
|
| 2 |
import folium
|
| 3 |
import numpy as np
|
| 4 |
-
from scipy.optimize import linear_sum_assignment
|
| 5 |
-
from folium import plugins
|
| 6 |
-
import requests
|
| 7 |
-
from datetime import datetime
|
| 8 |
-
from geopy.geocoders import Nominatim
|
| 9 |
-
import polyline
|
| 10 |
from typing import List, Tuple, Dict, Optional
|
| 11 |
import time
|
|
|
|
|
|
|
|
|
|
| 12 |
|
| 13 |
# Utility Functions
|
| 14 |
def create_numbered_marker(number: int) -> folium.features.DivIcon:
|
|
@@ -76,8 +73,8 @@ def get_route_from_osrm(coord1: Tuple[float, float], coord2: Tuple[float, float]
|
|
| 76 |
st.warning(f"Error getting route: {str(e)}")
|
| 77 |
return None
|
| 78 |
|
| 79 |
-
def
|
| 80 |
-
"""Calculate
|
| 81 |
n = len(places)
|
| 82 |
distances = np.zeros((n, n))
|
| 83 |
routing_info = {}
|
|
@@ -108,17 +105,37 @@ def calculate_real_distances(places: List[Tuple[str, Tuple[float, float]]]) -> T
|
|
| 108 |
|
| 109 |
return distances, routing_info
|
| 110 |
|
| 111 |
-
def
|
| 112 |
-
"""
|
| 113 |
n = len(distances)
|
| 114 |
-
|
|
|
|
|
|
|
| 115 |
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 120 |
|
| 121 |
-
return
|
| 122 |
|
| 123 |
def add_markers_and_route(m: folium.Map, places: List[Tuple[str, Tuple[float, float]]], optimal_order: List[int], routing_info: Dict):
|
| 124 |
"""Add markers and route lines to the map"""
|
|
@@ -237,16 +254,16 @@ def main():
|
|
| 237 |
col1, col2 = st.columns([2, 1])
|
| 238 |
with col1:
|
| 239 |
with st.spinner("🚗 Calculating optimal route..."):
|
| 240 |
-
# Calculate
|
| 241 |
-
distances, routing_info =
|
| 242 |
|
| 243 |
-
# Get optimized route order
|
| 244 |
-
optimal_order =
|
| 245 |
|
| 246 |
# Update the route if the user changes the input
|
| 247 |
if st.button("Recalculate Route"):
|
| 248 |
-
distances, routing_info =
|
| 249 |
-
optimal_order =
|
| 250 |
|
| 251 |
# Create map and display
|
| 252 |
m = folium.Map()
|
|
|
|
| 1 |
import streamlit as st
|
| 2 |
import folium
|
| 3 |
import numpy as np
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
from typing import List, Tuple, Dict, Optional
|
| 5 |
import time
|
| 6 |
+
from collections import deque
|
| 7 |
+
import requests
|
| 8 |
+
import polyline
|
| 9 |
|
| 10 |
# Utility Functions
|
| 11 |
def create_numbered_marker(number: int) -> folium.features.DivIcon:
|
|
|
|
| 73 |
st.warning(f"Error getting route: {str(e)}")
|
| 74 |
return None
|
| 75 |
|
| 76 |
+
def calculate_distance_matrix(places: List[Tuple[str, Tuple[float, float]]]) -> Tuple[np.ndarray, Dict]:
|
| 77 |
+
"""Calculate distance matrix and routing information using OSRM"""
|
| 78 |
n = len(places)
|
| 79 |
distances = np.zeros((n, n))
|
| 80 |
routing_info = {}
|
|
|
|
| 105 |
|
| 106 |
return distances, routing_info
|
| 107 |
|
| 108 |
+
def dijkstra(distances: np.ndarray, start_idx: int) -> Tuple[List[int], Dict[int, float]]:
|
| 109 |
+
"""Implement Dijkstra's algorithm to find the optimal route"""
|
| 110 |
n = len(distances)
|
| 111 |
+
visited = [False] * n
|
| 112 |
+
distances_to = [float('inf')] * n
|
| 113 |
+
prev_node = [-1] * n
|
| 114 |
|
| 115 |
+
distances_to[start_idx] = 0
|
| 116 |
+
queue = deque([start_idx])
|
| 117 |
+
|
| 118 |
+
while queue:
|
| 119 |
+
current_node = queue.popleft()
|
| 120 |
+
visited[current_node] = True
|
| 121 |
+
|
| 122 |
+
for neighbor in range(n):
|
| 123 |
+
if not visited[neighbor] and distances[current_node, neighbor] > 0:
|
| 124 |
+
new_distance = distances_to[current_node] + distances[current_node, neighbor]
|
| 125 |
+
if new_distance < distances_to[neighbor]:
|
| 126 |
+
distances_to[neighbor] = new_distance
|
| 127 |
+
prev_node[neighbor] = current_node
|
| 128 |
+
queue.append(neighbor)
|
| 129 |
+
|
| 130 |
+
# Reconstruct the optimal route
|
| 131 |
+
optimal_order = []
|
| 132 |
+
node = n - 1
|
| 133 |
+
while prev_node[node] != -1:
|
| 134 |
+
optimal_order.insert(0, node)
|
| 135 |
+
node = prev_node[node]
|
| 136 |
+
optimal_order.insert(0, start_idx)
|
| 137 |
|
| 138 |
+
return optimal_order, distances_to
|
| 139 |
|
| 140 |
def add_markers_and_route(m: folium.Map, places: List[Tuple[str, Tuple[float, float]]], optimal_order: List[int], routing_info: Dict):
|
| 141 |
"""Add markers and route lines to the map"""
|
|
|
|
| 254 |
col1, col2 = st.columns([2, 1])
|
| 255 |
with col1:
|
| 256 |
with st.spinner("🚗 Calculating optimal route..."):
|
| 257 |
+
# Calculate distance matrix
|
| 258 |
+
distances, routing_info = calculate_distance_matrix(places)
|
| 259 |
|
| 260 |
+
# Get optimized route order using Dijkstra's algorithm
|
| 261 |
+
optimal_order, _ = dijkstra(distances, 0)
|
| 262 |
|
| 263 |
# Update the route if the user changes the input
|
| 264 |
if st.button("Recalculate Route"):
|
| 265 |
+
distances, routing_info = calculate_distance_matrix(places)
|
| 266 |
+
optimal_order, _ = dijkstra(distances, 0)
|
| 267 |
|
| 268 |
# Create map and display
|
| 269 |
m = folium.Map()
|