ErzhanAb commited on
Commit
6ad0c75
·
verified ·
1 Parent(s): 013a5f0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +37 -15
app.py CHANGED
@@ -70,23 +70,43 @@ def find_fastest_route(G, start_node, end_node, weight='travel_time'):
70
  except nx.NetworkXNoPath:
71
  return None, None
72
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  def plot_route_on_map(G, route, start_point, end_point):
74
  """Отрисовывает один маршрут на большой цветной карте со стильными маркерами."""
75
- # Возвращаем цветную карту OpenStreetMap
76
  m = folium.Map(tiles="OpenStreetMap")
77
 
78
  if route:
79
  points = [(G.nodes[node]['y'], G.nodes[node]['x']) for node in route]
80
-
81
- # Белая "подложка" для контраста и лучшей видимости
82
  folium.PolyLine(points, color="white", weight=10, opacity=0.8).add_to(m)
83
- # Основная линия маршрута - яркий, приятный синий цвет
84
  main_line = folium.PolyLine(points, color="#3b82f6", weight=5, opacity=1, tooltip="Оптимальный маршрут")
85
  main_line.add_to(m)
86
-
87
  m.fit_bounds(main_line.get_bounds(), padding=(30, 30))
88
 
89
- # Новые, более стильные маркеры с использованием иконок Font Awesome
90
  folium.Marker(
91
  location=start_point, popup="<b>Точка А (Старт)</b>",
92
  icon=folium.Icon(color="blue", icon="play-circle", prefix='fa')
@@ -105,7 +125,7 @@ print("✅ Вспомогательные функции готовы.")
105
  # ==============================================================================
106
  print("\n🚀 Шаг 5: Настройка и запуск веб-интерфейса Gradio...")
107
 
108
- geolocator = Nominatim(user_agent="bishkek_navigator_app_v5")
109
  geocode = RateLimiter(geolocator.geocode, min_delay_seconds=1)
110
 
111
  def find_and_plot_route_by_address(start_address, end_address, day_of_week, hour, minute):
@@ -124,7 +144,10 @@ def find_and_plot_route_by_address(start_address, end_address, day_of_week, hour
124
  start_node = ox.nearest_nodes(G, Y=start_point[0], X=start_point[1])
125
  end_node = ox.nearest_nodes(G, Y=end_point[0], X=end_point[1])
126
 
127
- selected_time = datetime.datetime(2023, 1, 2 + day_of_week, int(hour), int(minute))
 
 
 
128
  travel_times = predict_graph_weights(gdf_edges, model, selected_time)
129
  nx.set_edge_attributes(G, values=pd.Series(travel_times, index=gdf_edges.index).to_dict(), name='travel_time')
130
 
@@ -132,7 +155,9 @@ def find_and_plot_route_by_address(start_address, end_address, day_of_week, hour
132
  if route is None:
133
  return None, "### ❌ Ошибка\nНе удалось построить маршрут. Возможно, точки находятся в несвязанных частях города."
134
 
135
- SIGNAL_DELAY_SECONDS = 30
 
 
136
  signals_on_route = sum(1 for node in route if node in signal_nodes_set)
137
  total_time_sec = travel_time + signals_on_route * SIGNAL_DELAY_SECONDS
138
  total_time_min = total_time_sec / 60
@@ -140,12 +165,12 @@ def find_and_plot_route_by_address(start_address, end_address, day_of_week, hour
140
 
141
  final_map = plot_route_on_map(G, route, start_point, end_point)
142
 
143
- # Форматирование вывода в Markdown с новой цветовой схемой
144
  output_md = f"""
145
  ### ✅ Маршрут построен!
146
  - **Время в пути:** <span style="font-size: 1.1em; color: #3b82f6;">**~{total_time_min:.1f} мин.**</span>
147
  - **Расстояние:** **{distance_km:.2f} км**
148
- - **Светофоров на пути:** **{signals_on_route}**
 
149
  """
150
  return final_map._repr_html_(), output_md
151
 
@@ -156,7 +181,6 @@ def find_and_plot_route_by_address(start_address, end_address, day_of_week, hour
156
  css = """
157
  body { font-family: 'Inter', sans-serif; }
158
  .gradio-container { max-width: 100% !important; }
159
- /* Кнопка */
160
  .gr-button-primary {
161
  background: linear-gradient(to right, #60a5fa, #3b82f6);
162
  color: white; font-weight: bold; border: none; transition: all 0.3s ease;
@@ -166,7 +190,6 @@ body { font-family: 'Inter', sans-serif; }
166
  background: linear-gradient(to right, #3b82f6, #2563eb);
167
  box-shadow: 0 6px 20px 0 rgba(59, 130, 246, 0.45); transform: translateY(-1px);
168
  }
169
- /* Информационный блок */
170
  #info-box { background-color: #f9fafb; padding: 1.5rem !important; border-radius: 0.75rem; border: 1px solid #e5e7eb;}
171
  """
172
 
@@ -185,7 +208,6 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="blue", fo
185
  start_address_input = gr.Textbox(label="Откуда?", placeholder="Например, ЦУМ")
186
  end_address_input = gr.Textbox(label="Куда?", placeholder="Например, парк Ата-Тюрк")
187
 
188
- # Убрали Accordion, теперь настройки времени всегда видны
189
  gr.Markdown("#### 🗓️ Укажите время и дату")
190
  day_dropdown = gr.Dropdown(label="День недели", choices=["Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота", "Воскресенье"], value="Понедельник", type="index")
191
  current_time = datetime.datetime.now()
@@ -195,7 +217,7 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="blue", fo
195
  build_btn = gr.Button("🚀 Найти лучший маршрут", variant="primary")
196
  output_info = gr.Markdown(label="Информация о маршруте", elem_id="info-box")
197
 
198
- with gr.Column(scale=3): # Увеличили масштаб для карты, чтобы она была больше
199
  output_map_html = gr.HTML(label="Карта с маршрутом", elem_id="map-output")
200
 
201
  build_btn.click(
 
70
  except nx.NetworkXNoPath:
71
  return None, None
72
 
73
+ # --- ИЗМЕНЕНИЕ ЛОГИКИ ЗДЕСЬ ---
74
+ def get_signal_delay(day_of_week, hour):
75
+ """Определяет задержку на светофоре согласно новым правилам."""
76
+ is_weekday = 0 <= day_of_week <= 4 # Понедельник (0) - Пятница (4)
77
+
78
+ # Правило 1: Часы-пик в будние дни (высший приоритет)
79
+ is_morning_rush = 8 <= hour <= 10
80
+ is_evening_rush = 17 <= hour <= 20
81
+ if is_weekday and (is_morning_rush or is_evening_rush):
82
+ return 35
83
+
84
+ # Правило 2: Ночное время, любой день (второй приоритет)
85
+ # "до 8 часов утра" означает до 7:59, поэтому "hour <= 7"
86
+ is_night_time = hour >= 23 or hour <= 7
87
+ if is_night_time:
88
+ return 15
89
+
90
+ # Правило 3: Дневное время в будни (не час-пик и не ночь)
91
+ if is_weekday:
92
+ return 25
93
+
94
+ # Правило 4: Дневное время в выходные (не ночь)
95
+ # Если код дошел до сюда, значит это выходной день (is_weekday = False)
96
+ else:
97
+ return 15
98
+
99
  def plot_route_on_map(G, route, start_point, end_point):
100
  """Отрисовывает один маршрут на большой цветной карте со стильными маркерами."""
 
101
  m = folium.Map(tiles="OpenStreetMap")
102
 
103
  if route:
104
  points = [(G.nodes[node]['y'], G.nodes[node]['x']) for node in route]
 
 
105
  folium.PolyLine(points, color="white", weight=10, opacity=0.8).add_to(m)
 
106
  main_line = folium.PolyLine(points, color="#3b82f6", weight=5, opacity=1, tooltip="Оптимальный маршрут")
107
  main_line.add_to(m)
 
108
  m.fit_bounds(main_line.get_bounds(), padding=(30, 30))
109
 
 
110
  folium.Marker(
111
  location=start_point, popup="<b>Точка А (Старт)</b>",
112
  icon=folium.Icon(color="blue", icon="play-circle", prefix='fa')
 
125
  # ==============================================================================
126
  print("\n🚀 Шаг 5: Настройка и запуск веб-интерфейса Gradio...")
127
 
128
+ geolocator = Nominatim(user_agent="bishkek_navigator_app_v7")
129
  geocode = RateLimiter(geolocator.geocode, min_delay_seconds=1)
130
 
131
  def find_and_plot_route_by_address(start_address, end_address, day_of_week, hour, minute):
 
144
  start_node = ox.nearest_nodes(G, Y=start_point[0], X=start_point[1])
145
  end_node = ox.nearest_nodes(G, Y=end_point[0], X=end_point[1])
146
 
147
+ current_hour = int(hour)
148
+ current_minute = int(minute)
149
+
150
+ selected_time = datetime.datetime(2023, 1, 2 + day_of_week, current_hour, current_minute)
151
  travel_times = predict_graph_weights(gdf_edges, model, selected_time)
152
  nx.set_edge_attributes(G, values=pd.Series(travel_times, index=gdf_edges.index).to_dict(), name='travel_time')
153
 
 
155
  if route is None:
156
  return None, "### ❌ Ошибка\nНе удалось построить маршрут. Возможно, точки находятся в несвязанных частях города."
157
 
158
+ # Получаем динамическую задержку на светофоре согласно новым правилам
159
+ SIGNAL_DELAY_SECONDS = get_signal_delay(day_of_week, current_hour)
160
+
161
  signals_on_route = sum(1 for node in route if node in signal_nodes_set)
162
  total_time_sec = travel_time + signals_on_route * SIGNAL_DELAY_SECONDS
163
  total_time_min = total_time_sec / 60
 
165
 
166
  final_map = plot_route_on_map(G, route, start_point, end_point)
167
 
 
168
  output_md = f"""
169
  ### ✅ Маршрут построен!
170
  - **Время в пути:** <span style="font-size: 1.1em; color: #3b82f6;">**~{total_time_min:.1f} мин.**</span>
171
  - **Расстояние:** **{distance_km:.2f} км**
172
+ - **Светофоров на пути:** **{signals_on_route}**
173
+ <p style="font-size: 0.8em; color: #6b7280;">(задержка на светофор: {SIGNAL_DELAY_SECONDS} сек.)</p>
174
  """
175
  return final_map._repr_html_(), output_md
176
 
 
181
  css = """
182
  body { font-family: 'Inter', sans-serif; }
183
  .gradio-container { max-width: 100% !important; }
 
184
  .gr-button-primary {
185
  background: linear-gradient(to right, #60a5fa, #3b82f6);
186
  color: white; font-weight: bold; border: none; transition: all 0.3s ease;
 
190
  background: linear-gradient(to right, #3b82f6, #2563eb);
191
  box-shadow: 0 6px 20px 0 rgba(59, 130, 246, 0.45); transform: translateY(-1px);
192
  }
 
193
  #info-box { background-color: #f9fafb; padding: 1.5rem !important; border-radius: 0.75rem; border: 1px solid #e5e7eb;}
194
  """
195
 
 
208
  start_address_input = gr.Textbox(label="Откуда?", placeholder="Например, ЦУМ")
209
  end_address_input = gr.Textbox(label="Куда?", placeholder="Например, парк Ата-Тюрк")
210
 
 
211
  gr.Markdown("#### 🗓️ Укажите время и дату")
212
  day_dropdown = gr.Dropdown(label="День недели", choices=["Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота", "Воскресенье"], value="Понедельник", type="index")
213
  current_time = datetime.datetime.now()
 
217
  build_btn = gr.Button("🚀 Найти лучший маршрут", variant="primary")
218
  output_info = gr.Markdown(label="Информация о маршруте", elem_id="info-box")
219
 
220
+ with gr.Column(scale=3):
221
  output_map_html = gr.HTML(label="Карта с маршрутом", elem_id="map-output")
222
 
223
  build_btn.click(