Jing997 commited on
Commit
944f6e3
·
1 Parent(s): 9fc0516

add utils src

Browse files
src/components/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+ # This file is intentionally left blank.
src/components/map_visualization.py ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ def load_data():
2
+ """
3
+ Load delivery and vehicle data from CSV files
4
+
5
+ Returns:
6
+ tuple: (delivery_data, vehicle_data)
7
+ """
8
+ # Get the project root directory
9
+ root_dir = Path(__file__).resolve().parent.parent.parent
10
+
11
+ # Define data paths
12
+ delivery_data_path = os.path.join(root_dir, 'data', 'delivery-data', 'delivery_data.csv')
13
+ vehicle_data_path = os.path.join(root_dir, 'data', 'vehicle-data', 'vehicle_data.csv')
14
+
15
+ # Load data
16
+ try:
17
+ delivery_data = pd.read_csv(delivery_data_path)
18
+ vehicle_data = pd.read_csv(vehicle_data_path)
19
+ return delivery_data, vehicle_data
20
+ except FileNotFoundError as e:
21
+ st.error(f"Could not load data: {e}")
22
+ st.info("Please generate the data first by running: python src/utils/generate_all_data.py")
23
+ return None, None
24
+
25
+ def create_delivery_map(delivery_data=None, vehicle_data=None, show_deliveries=True, show_depots=True,
26
+ date_filter=None, status_filter=None, priority_filter=None):
27
+ """
28
+ Create a Folium map with markers for deliveries and vehicle depots
29
+
30
+ Parameters:
31
+ delivery_data (pd.DataFrame): Delivery data
32
+ vehicle_data (pd.DataFrame): Vehicle data
33
+ show_deliveries (bool): Whether to show delivery markers
34
+ show_depots (bool): Whether to show depot markers
35
+ date_filter (str): Filter deliveries by date
36
+ status_filter (str): Filter deliveries by status
37
+ priority_filter (str): Filter deliveries by priority
38
+
39
+ Returns:
40
+ folium.Map: Folium map with markers
41
+ """
42
+ # If data not provided, load it
43
+ if delivery_data is None or vehicle_data is None:
44
+ delivery_data, vehicle_data = load_data()
45
+ if delivery_data is None or vehicle_data is None:
46
+ return None
47
+
48
+ # Apply filters to delivery data
49
+ if date_filter is not None:
50
+ delivery_data = delivery_data[delivery_data['delivery_date'] == date_filter]
51
+
52
+ if status_filter is not None:
53
+ delivery_data = delivery_data[delivery_data['status'] == status_filter]
54
+
55
+ if priority_filter is not None:
56
+ delivery_data = delivery_data[delivery_data['priority'] == priority_filter]
57
+
58
+ # Create map centered around Singapore
59
+ singapore_coords = [1.3521, 103.8198] # Center of Singapore
60
+ m = folium.Map(location=singapore_coords, zoom_start=12)
61
+
62
+ # Add delivery markers
63
+ if show_deliveries and not delivery_data.empty:
64
+ for _, row in delivery_data.iterrows():
65
+ # Create popup content with delivery information
66
+ popup_content = f"""
67
+ <b>Delivery ID:</b> {row['delivery_id']}<br>
68
+ <b>Customer:</b> {row['customer_name']}<br>
69
+ <b>Address:</b> {row['address']}<br>
70
+ <b>Time Window:</b> {row['time_window']}<br>
71
+ <b>Status:</b> {row['status']}<br>
72
+ <b>Priority:</b> {row['priority']}<br>
73
+ <b>Weight:</b> {row['weight_kg']} kg<br>
74
+ <b>Volume:</b> {row['volume_m3']} m³
75
+ """
76
+
77
+ # Set marker color based on priority
78
+ color_map = {'High': 'red', 'Medium': 'orange', 'Low': 'blue'}
79
+ color = color_map.get(row['priority'], 'blue')
80
+
81
+ # Add marker to map
82
+ folium.Marker(
83
+ location=[row['latitude'], row['longitude']],
84
+ popup=folium.Popup(popup_content, max_width=300),
85
+ tooltip=f"Delivery {row['delivery_id']}: {row['customer_name']}",
86
+ icon=folium.Icon(color=color, icon="package", prefix="fa")
87
+ ).add_to(m)
88
+
89
+ # Add depot markers
90
+ if show_depots and not vehicle_data.empty:
91
+ for _, row in vehicle_data.iterrows():
92
+ # Create popup content with vehicle information
93
+ popup_content = f"""
94
+ <b>Vehicle ID:</b> {row['vehicle_id']}<br>
95
+ <b>Type:</b> {row['vehicle_type']}<br>
96
+ <b>Driver:</b> {row['driver_name']}<br>
97
+ <b>Status:</b> {row['status']}<br>
98
+ <b>Capacity:</b> {row['max_weight_kg']} kg / {row['max_volume_m3']} m³<br>
99
+ <b>Working Hours:</b> {row['start_time']} - {row['end_time']}
100
+ """
101
+
102
+ # Add marker to map
103
+ folium.Marker(
104
+ location=[row['depot_latitude'], row['depot_longitude']],
105
+ popup=folium.Popup(popup_content, max_width=300),
106
+ tooltip=f"Depot: {row['vehicle_id']}",
107
+ icon=folium.Icon(color="green", icon="truck", prefix="fa")
108
+ ).add_to(m)
109
+
110
+ return m
111
+
112
+ def display_map_component():
113
+ """
114
+ Display the map visualization component in Streamlit
115
+ """
116
+ st.subheader("Delivery and Depot Locations")
117
+
118
+ # Load data
119
+ delivery_data, vehicle_data = load_data()
120
+ if delivery_data is None or vehicle_data is None:
121
+ return
122
+
123
+ # Create sidebar filters
124
+ with st.sidebar:
125
+ st.subheader("Map Filters")
126
+
127
+ # Show/hide options
128
+ show_deliveries = st.checkbox("Show Deliveries", value=True)
129
+ show_depots = st.checkbox("Show Depots", value=True)
130
+
131
+ # Delivery date filter
132
+ dates = sorted(delivery_data['delivery_date'].unique())
133
+ selected_date = st.selectbox(
134
+ "Filter by Date",
135
+ options=["All"] + list(dates),
136
+ index=0
137
+ )
138
+ date_filter = None if selected_date == "All" else selected_date
139
+
140
+ # Delivery status filter
141
+ statuses = sorted(delivery_data['status'].unique())
142
+ selected_status = st.selectbox(
143
+ "Filter by Status",
144
+ options=["All"] + list(statuses),
145
+ index=0
146
+ )
147
+ status_filter = None if selected_status == "All" else selected_status
148
+
149
+ # Delivery priority filter
150
+ priorities = sorted(delivery_data['priority'].unique())
151
+ selected_priority = st.selectbox(
152
+ "Filter by Priority",
153
+ options=["All"] + list(priorities),
154
+ index=0
155
+ )
156
+ priority_filter = None if selected_priority == "All" else selected_priority
157
+
158
+ # Display statistics
159
+ col1, col2, col3 = st.columns(3)
160
+
161
+ # Apply filters for stats calculation
162
+ filtered_delivery_data = delivery_data
163
+ if date_filter:
164
+ filtered_delivery_data = filtered_delivery_data[filtered_delivery_data['delivery_date'] == date_filter]
165
+ if status_filter:
166
+ filtered_delivery_data = filtered_delivery_data[filtered_delivery_data['status'] == status_filter]
167
+ if priority_filter:
168
+ filtered_delivery_data = filtered_delivery_data[filtered_delivery_data['priority'] == priority_filter]
169
+
170
+ with col1:
171
+ st.metric("Total Deliveries", filtered_delivery_data.shape[0])
172
+
173
+ with col2:
174
+ st.metric("Total Weight", f"{filtered_delivery_data['weight_kg'].sum():.2f} kg")
175
+
176
+ with col3:
177
+ st.metric("Available Vehicles", vehicle_data[vehicle_data['status'] == 'Available'].shape[0])
178
+
179
+ # Create and display the map
180
+ delivery_map = create_delivery_map(
181
+ delivery_data=delivery_data,
182
+ vehicle_data=vehicle_data,
183
+ show_deliveries=show_deliveries,
184
+ show_depots=show_depots,
185
+ date_filter=date_filter,
186
+ status_filter=status_filter,
187
+ priority_filter=priority_filter
188
+ )
189
+
190
+ if delivery_map:
191
+ folium_static(delivery_map, width=800, height=600)
192
+ else:
193
+ st.error("Could not create map. Please check that data is available.")
194
+
195
+ if __name__ == "__main__":
196
+ # Run the map visualization component
197
+ display_map_component()
src/streamlit_app.py DELETED
@@ -1,40 +0,0 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
- import streamlit as st
5
-
6
- """
7
- # Welcome to Streamlit!
8
-
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
-
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
15
-
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))