VIATEUR-AI commited on
Commit
932a171
·
verified ·
1 Parent(s): 97de2b1

import gradio as gr import folium import networkx as nx from folium import Map, Marker, PolyLine from math import radians, cos, sin, sqrt, atan2 import time from branca.element import MacroElement from jinja2 import Template # Uturere two mu Rwanda hamwe na coordinates (latitude, longitude) places = { "Nyarugenge": (-1.9577, 30.0619), "Gasabo": (-1.9400, 30.0861), "Kicukiro": (-1.9781, 30.0597), "Burera": (-1.4800, 29.7300), "Gakenke": (-1.5700, 29.7561), "Rulindo": (-1.8333, 30.0833), "Musanze": (-1.5014, 29.6344), "Gicumbi": (-1.5794, 30.0542), "Nyagatare": (-1.3100, 30.3000), "Gatsibo": (-1.6800, 30.3900), "Kayonza": (-2.0000, 30.5667), "Kirehe": (-2.3553, 30.7767), "Ngoma": (-2.1600, 30.4700), "Rwamagana": (-1.9491, 30.4349), "Bugesera": (-2.2083, 30.2576), "Kamonyi": (-2.0833, 29.9000), "Muhanga": (-2.1200, 29.7561), "Ruhango": (-2.2136, 29.7628), "Nyamagabe": (-2.4978, 29.4897), "Nyaruguru": (-2.5806, 29.4306), "Huye": (-2.5921, 29.7408), "Gisagara": (-2.6283, 29.6820), "Nyanza": (-2.3566, 29.7507), "Rutsiro": (-2.0986, 29.3269), "Karongi": (-2.0667, 29.4677), "Rubavu": (-1.7481, 29.2730), "Rusizi": (-2.5406, 29.3737), "Nyamasheke": (-2.4700, 29.3222), "Ngororero": (-1.8733, 29.5811) } # Haversine function (heuristic for A*) def haversine(coord1, coord2): R = 6371 # Earth radius in km lat1, lon1 = coord1 lat2, lon2 = coord2 dlat = radians(lat2 - lat1) dlon = radians(lon2 - lon1) a = sin(dlat/2)**2 + cos(radians(lat1))*cos(radians(lat2))*sin(dlon/2)**2 c = 2 * atan2(sqrt(a), sqrt(1-a)) return R * c # Build graph with edges and weights G = nx.Graph() edges = [ ("Nyarugenge", "Gasabo"), ("Gasabo", "Kicukiro"), ("Burera", "Gakenke"), ("Gakenke", "Rulindo"), ("Musanze", "Gicumbi"), ("Nyagatare", "Gatsibo"), ("Kayonza", "Kirehe"), ("Ngoma", "Rwamagana"), ("Bugesera", "Kamonyi"), ("Muhanga", "Ruhango"), ("Nyamagabe", "Nyaruguru"), ("Huye", "Gisagara"), ("Nyanza", "Ruhango"), ("Rutsiro", "Karongi"), ("Rubavu", "Rusizi"), ("Nyamasheke", "Ngororero"), ("Rulindo", "Gasabo"), ("Gicumbi", "Nyagatare"), ("Kicukiro", "Kamonyi"), ("Kamonyi", "Muhanga"), ("Ruhango", "Nyamagabe"), ("Karongi", "Rubavu"), ("Rusizi", "Nyamasheke"), ("Ngororero", "Rutsiro") ] for edge in edges: c1 = places[edge[0]] c2 = places[edge[1]] dist = haversine(c1, c2) G.add_edge(edge[0], edge[1], weight=dist) # Add nodes that might be missing for place in places.keys(): if place not in G: G.add_node(place) # Heuristic function for A* def heuristic(u, v): return haversine(places[u], places[v]) # Folium animation plugin for marker movement class AnimateMarker(MacroElement): _template = Template(""" {% macro script(this, kwargs) %} var marker = L.marker({{this.locations[0]}}).addTo({{this._parent.get_name()}}); var latlngs = {{this.locations}}; var index = 0; function moveMarker(){ index++; if(index >= latlngs.length){ return; } marker.setLatLng(latlngs[index]); setTimeout(moveMarker, 700); } moveMarker(); {% endmacro %} """) def __init__(self, locations): super().__init__() self._name = "AnimateMarker" self.locations = locations def generate_map(start, end): if start is None or end is None: return "Hitamo aho utangiriye n’aho ugiye neza.", "" if start not in G.nodes or end not in G.nodes: return "Hitamo aho utangiriye n’aho ugiye neza (ntiboneka mu rutonde).", "" m = Map(location=[-2.0, 30.0], zoom_start=8) for name, coord in places.items(): Marker(location=coord, popup=name).add_to(m) if start == end: return "Hitamo aho utangiriye n’aho ugiye bitandukanye.", m._repr_html_() if not nx.has_path(G, start, end): return f"Nta nzira ibaho hagati ya {start} na {end}.", m._repr_html_() try: path = nx.astar_path(G, start, end, heuristic=heuristic, weight='weight') coords = [places[p] for p in path] PolyLine(coords, color="blue", weight=5).add_to(m) # Add animated marker along the path m.add_child(AnimateMarker(coords)) return "Inzira ngufi ni: " + " ➔ ".join(path), m._repr_html_() except Exception as e: return f"Ntibishoboka kubona inzira: {str(e)}", m._repr_html_() iface = gr.Interface( fn=generate_map, inputs=[ gr.Dropdown(list(places.keys()), label="Hitamo aho uri", value=list(places.keys())[0]), gr.Dropdown(list(places.keys()), label="Hitamo aho ugiye", value=list(places.keys())[1]) ], outputs=[ gr.Textbox(label="Ubutumwa"), gr.HTML(label="Ikarita") ], title="🗺️ Rwanda Smart Route Planner with Animation" ) iface.launch()

Browse files
Files changed (1) hide show
  1. app.py +54 -61
app.py CHANGED
@@ -1,11 +1,13 @@
1
  import gradio as gr
2
  import folium
3
  import networkx as nx
4
- from folium import Map, Marker, PolyLine, plugins
5
  from math import radians, cos, sin, sqrt, atan2
6
- import json
7
- from datetime import datetime, timedelta
 
8
 
 
9
  places = {
10
  "Nyarugenge": (-1.9577, 30.0619),
11
  "Gasabo": (-1.9400, 30.0861),
@@ -38,16 +40,18 @@ places = {
38
  "Ngororero": (-1.8733, 29.5811)
39
  }
40
 
 
41
  def haversine(coord1, coord2):
42
- R = 6371
43
  lat1, lon1 = coord1
44
  lat2, lon2 = coord2
45
  dlat = radians(lat2 - lat1)
46
  dlon = radians(lon2 - lon1)
47
- a = sin(dlat/2)**2 + cos(radians(lat1)) * cos(radians(lat2)) * sin(dlon/2)**2
48
- c = 2 * atan2(sqrt(a), sqrt(1 - a))
49
  return R * c
50
 
 
51
  G = nx.Graph()
52
  edges = [
53
  ("Nyarugenge", "Gasabo"),
@@ -75,20 +79,53 @@ edges = [
75
  ("Rusizi", "Nyamasheke"),
76
  ("Ngororero", "Rutsiro")
77
  ]
78
-
79
  for edge in edges:
80
- coord1 = places[edge[0]]
81
- coord2 = places[edge[1]]
82
- distance = haversine(coord1, coord2)
83
- G.add_edge(edge[0], edge[1], weight=distance)
 
 
 
 
 
84
 
 
85
  def heuristic(u, v):
86
  return haversine(places[u], places[v])
87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  def generate_map(start, end):
 
 
 
 
 
89
  m = Map(location=[-2.0, 30.0], zoom_start=8)
90
- for name, coords in places.items():
91
- Marker(location=coords, popup=name).add_to(m)
92
 
93
  if start == end:
94
  return "Hitamo aho utangiriye n’aho ugiye bitandukanye.", m._repr_html_()
@@ -98,64 +135,21 @@ def generate_map(start, end):
98
 
99
  try:
100
  path = nx.astar_path(G, start, end, heuristic=heuristic, weight='weight')
101
-
102
- # Coordinates for polyline and for animation points
103
  coords = [places[p] for p in path]
104
  PolyLine(coords, color="blue", weight=5).add_to(m)
105
 
106
- # Create features for TimestampedGeoJson
107
- features = []
108
- start_time = datetime.now()
109
- time_increment = timedelta(seconds=2) # 2 seconds between points
110
-
111
- for i, coord in enumerate(coords):
112
- feature = {
113
- "type": "Feature",
114
- "geometry": {
115
- "type": "Point",
116
- "coordinates": [coord[1], coord[0]] # GeoJSON uses [lon, lat]
117
- },
118
- "properties": {
119
- "time": (start_time + i * time_increment).isoformat(),
120
- "style": {"color": "red"},
121
- "icon": "circle",
122
- "iconstyle": {
123
- "fillColor": "red",
124
- "fillOpacity": 0.8,
125
- "stroke": "true",
126
- "radius": 7
127
- }
128
- }
129
- }
130
- features.append(feature)
131
-
132
- timestamped_geojson = {
133
- "type": "FeatureCollection",
134
- "features": features
135
- }
136
-
137
- plugins.TimestampedGeoJson(
138
- timestamped_geojson,
139
- period='PT2S',
140
- add_last_point=True,
141
- auto_play=True,
142
- loop=False,
143
- max_speed=1,
144
- loop_button=True,
145
- date_options='YYYY/MM/DD HH:mm:ss',
146
- time_slider_drag_update=True
147
- ).add_to(m)
148
 
149
  return "Inzira ngufi ni: " + " ➔ ".join(path), m._repr_html_()
150
-
151
  except Exception as e:
152
  return f"Ntibishoboka kubona inzira: {str(e)}", m._repr_html_()
153
 
154
  iface = gr.Interface(
155
  fn=generate_map,
156
  inputs=[
157
- gr.Dropdown(list(places.keys()), label="Hitamo aho uri"),
158
- gr.Dropdown(list(places.keys()), label="Hitamo aho ugiye")
159
  ],
160
  outputs=[
161
  gr.Textbox(label="Ubutumwa"),
@@ -166,4 +160,3 @@ iface = gr.Interface(
166
 
167
  iface.launch()
168
 
169
-
 
1
  import gradio as gr
2
  import folium
3
  import networkx as nx
4
+ from folium import Map, Marker, PolyLine
5
  from math import radians, cos, sin, sqrt, atan2
6
+ import time
7
+ from branca.element import MacroElement
8
+ from jinja2 import Template
9
 
10
+ # Uturere two mu Rwanda hamwe na coordinates (latitude, longitude)
11
  places = {
12
  "Nyarugenge": (-1.9577, 30.0619),
13
  "Gasabo": (-1.9400, 30.0861),
 
40
  "Ngororero": (-1.8733, 29.5811)
41
  }
42
 
43
+ # Haversine function (heuristic for A*)
44
  def haversine(coord1, coord2):
45
+ R = 6371 # Earth radius in km
46
  lat1, lon1 = coord1
47
  lat2, lon2 = coord2
48
  dlat = radians(lat2 - lat1)
49
  dlon = radians(lon2 - lon1)
50
+ a = sin(dlat/2)**2 + cos(radians(lat1))*cos(radians(lat2))*sin(dlon/2)**2
51
+ c = 2 * atan2(sqrt(a), sqrt(1-a))
52
  return R * c
53
 
54
+ # Build graph with edges and weights
55
  G = nx.Graph()
56
  edges = [
57
  ("Nyarugenge", "Gasabo"),
 
79
  ("Rusizi", "Nyamasheke"),
80
  ("Ngororero", "Rutsiro")
81
  ]
 
82
  for edge in edges:
83
+ c1 = places[edge[0]]
84
+ c2 = places[edge[1]]
85
+ dist = haversine(c1, c2)
86
+ G.add_edge(edge[0], edge[1], weight=dist)
87
+
88
+ # Add nodes that might be missing
89
+ for place in places.keys():
90
+ if place not in G:
91
+ G.add_node(place)
92
 
93
+ # Heuristic function for A*
94
  def heuristic(u, v):
95
  return haversine(places[u], places[v])
96
 
97
+ # Folium animation plugin for marker movement
98
+ class AnimateMarker(MacroElement):
99
+ _template = Template("""
100
+ {% macro script(this, kwargs) %}
101
+ var marker = L.marker({{this.locations[0]}}).addTo({{this._parent.get_name()}});
102
+ var latlngs = {{this.locations}};
103
+ var index = 0;
104
+ function moveMarker(){
105
+ index++;
106
+ if(index >= latlngs.length){
107
+ return;
108
+ }
109
+ marker.setLatLng(latlngs[index]);
110
+ setTimeout(moveMarker, 700);
111
+ }
112
+ moveMarker();
113
+ {% endmacro %}
114
+ """)
115
+ def __init__(self, locations):
116
+ super().__init__()
117
+ self._name = "AnimateMarker"
118
+ self.locations = locations
119
+
120
  def generate_map(start, end):
121
+ if start is None or end is None:
122
+ return "Hitamo aho utangiriye n’aho ugiye neza.", ""
123
+ if start not in G.nodes or end not in G.nodes:
124
+ return "Hitamo aho utangiriye n’aho ugiye neza (ntiboneka mu rutonde).", ""
125
+
126
  m = Map(location=[-2.0, 30.0], zoom_start=8)
127
+ for name, coord in places.items():
128
+ Marker(location=coord, popup=name).add_to(m)
129
 
130
  if start == end:
131
  return "Hitamo aho utangiriye n’aho ugiye bitandukanye.", m._repr_html_()
 
135
 
136
  try:
137
  path = nx.astar_path(G, start, end, heuristic=heuristic, weight='weight')
 
 
138
  coords = [places[p] for p in path]
139
  PolyLine(coords, color="blue", weight=5).add_to(m)
140
 
141
+ # Add animated marker along the path
142
+ m.add_child(AnimateMarker(coords))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
 
144
  return "Inzira ngufi ni: " + " ➔ ".join(path), m._repr_html_()
 
145
  except Exception as e:
146
  return f"Ntibishoboka kubona inzira: {str(e)}", m._repr_html_()
147
 
148
  iface = gr.Interface(
149
  fn=generate_map,
150
  inputs=[
151
+ gr.Dropdown(list(places.keys()), label="Hitamo aho uri", value=list(places.keys())[0]),
152
+ gr.Dropdown(list(places.keys()), label="Hitamo aho ugiye", value=list(places.keys())[1])
153
  ],
154
  outputs=[
155
  gr.Textbox(label="Ubutumwa"),
 
160
 
161
  iface.launch()
162