File size: 4,210 Bytes
faea948
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import streamlit as st
from transformers import pipeline
import folium
import numpy as np
from scipy.optimize import linear_sum_assignment
import pandas as pd

def calculate_distances(coordinates):
    """Calculate distances between all points using Haversine formula"""
    n = len(coordinates)
    distances = np.zeros((n, n))
    
    for i in range(n):
        for j in range(n):
            if i != j:
                # Haversine formula
                lat1, lon1 = coordinates[i]
                lat2, lon2 = coordinates[j]
                
                R = 6371  # Earth's radius in kilometers
                
                dlat = np.radians(lat2 - lat1)
                dlon = np.radians(lon2 - lon1)
                
                a = np.sin(dlat/2)**2 + np.cos(np.radians(lat1)) * np.cos(np.radians(lat2)) * np.sin(dlon/2)**2
                c = 2 * np.arctan2(np.sqrt(a), np.sqrt(1-a))
                distances[i,j] = R * c
                
    return distances

def optimize_route(coordinates):
    """Optimize route using Hungarian algorithm"""
    distances = calculate_distances(coordinates)
    row_ind, col_ind = linear_sum_assignment(distances)
    return col_ind

def get_place_coordinates(place_name):
    """Get coordinates using Nominatim geocoding"""
    try:
        from geopy.geocoders import Nominatim
        geolocator = Nominatim(user_agent="my_travel_app")
        location = geolocator.geocode(place_name)
        return (location.latitude, location.longitude) if location else None
    except:
        return None

def main():
    st.title("AI Travel Route Optimizer")
    
    # Sidebar for inputs
    st.sidebar.header("Travel Parameters")
    
    # Input for places
    places = []
    num_places = st.sidebar.number_input("Number of places to visit", min_value=2, max_value=10, value=3)
    
    for i in range(num_places):
        place = st.sidebar.text_input(f"Place {i+1}")
        if place:
            coordinates = get_place_coordinates(place)
            if coordinates:
                places.append((place, coordinates))
    
    # Only proceed if we have all places
    if len(places) == num_places and num_places >= 2:
        
        # Extract coordinates for optimization
        coordinates = [coord for _, coord in places]
        
        # Optimize route
        optimized_indices = optimize_route(coordinates)
        
        # Create map
        center_lat = sum(coord[0] for coord in coordinates) / len(coordinates)
        center_lon = sum(coord[1] for coord in coordinates) / len(coordinates)
        
        m = folium.Map(location=[center_lat, center_lon], zoom_start=4)
        
        # Add markers and route lines
        for i in range(len(optimized_indices)):
            current_idx = optimized_indices[i]
            next_idx = optimized_indices[(i + 1) % len(optimized_indices)]
            
            # Add marker
            place_name, (lat, lon) = places[current_idx]
            folium.Marker(
                [lat, lon],
                popup=f"Stop {i+1}: {place_name}",
                icon=folium.Icon(color='red', icon='info-sign')
            ).add_to(m)
            
            # Add line to next point
            next_lat, next_lon = coordinates[next_idx]
            folium.PolyLine(
                locations=[[lat, lon], [next_lat, next_lon]],
                weight=2,
                color='blue',
                opacity=0.8
            ).add_to(m)
        
        # Display map
        st.components.v1.html(m._repr_html_(), height=600)
        
        # Display itinerary
        st.header("Optimized Itinerary")
        for i in range(len(optimized_indices)):
            st.write(f"{i+1}. {places[optimized_indices[i]][0]}")
        
        # Calculate total distance
        total_distance = 0
        distances = calculate_distances(coordinates)
        for i in range(len(optimized_indices)):
            current_idx = optimized_indices[i]
            next_idx = optimized_indices[(i + 1) % len(optimized_indices)]
            total_distance += distances[current_idx][next_idx]
            
        st.write(f"\nTotal distance: {total_distance:.2f} km")

if __name__ == "__main__":
    main()