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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +45 -90
app.py CHANGED
@@ -3,98 +3,58 @@ 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),
14
- "Kicukiro": (-1.9781, 30.0597),
15
- "Burera": (-1.4800, 29.7300),
16
- "Gakenke": (-1.5700, 29.7561),
17
- "Rulindo": (-1.8333, 30.0833),
18
- "Musanze": (-1.5014, 29.6344),
19
- "Gicumbi": (-1.5794, 30.0542),
20
- "Nyagatare": (-1.3100, 30.3000),
21
- "Gatsibo": (-1.6800, 30.3900),
22
- "Kayonza": (-2.0000, 30.5667),
23
- "Kirehe": (-2.3553, 30.7767),
24
- "Ngoma": (-2.1600, 30.4700),
25
- "Rwamagana": (-1.9491, 30.4349),
26
- "Bugesera": (-2.2083, 30.2576),
27
- "Kamonyi": (-2.0833, 29.9000),
28
- "Muhanga": (-2.1200, 29.7561),
29
- "Ruhango": (-2.2136, 29.7628),
30
- "Nyamagabe": (-2.4978, 29.4897),
31
- "Nyaruguru": (-2.5806, 29.4306),
32
- "Huye": (-2.5921, 29.7408),
33
- "Gisagara": (-2.6283, 29.6820),
34
- "Nyanza": (-2.3566, 29.7507),
35
- "Rutsiro": (-2.0986, 29.3269),
36
- "Karongi": (-2.0667, 29.4677),
37
- "Rubavu": (-1.7481, 29.2730),
38
- "Rusizi": (-2.5406, 29.3737),
39
- "Nyamasheke": (-2.4700, 29.3222),
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"),
58
- ("Gasabo", "Kicukiro"),
59
- ("Burera", "Gakenke"),
60
- ("Gakenke", "Rulindo"),
61
- ("Musanze", "Gicumbi"),
62
- ("Nyagatare", "Gatsibo"),
63
- ("Kayonza", "Kirehe"),
64
- ("Ngoma", "Rwamagana"),
65
- ("Bugesera", "Kamonyi"),
66
- ("Muhanga", "Ruhango"),
67
- ("Nyamagabe", "Nyaruguru"),
68
- ("Huye", "Gisagara"),
69
- ("Nyanza", "Ruhango"),
70
- ("Rutsiro", "Karongi"),
71
- ("Rubavu", "Rusizi"),
72
- ("Nyamasheke", "Ngororero"),
73
- ("Rulindo", "Gasabo"),
74
- ("Gicumbi", "Nyagatare"),
75
- ("Kicukiro", "Kamonyi"),
76
- ("Kamonyi", "Muhanga"),
77
- ("Ruhango", "Nyamagabe"),
78
- ("Karongi", "Rubavu"),
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) %}
@@ -117,46 +77,41 @@ class AnimateMarker(MacroElement):
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_()
132
 
133
  if not nx.has_path(G, start, end):
134
- return f"Nta nzira ibaho hagati ya {start} na {end}.", 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"),
156
  gr.HTML(label="Ikarita")
157
  ],
158
- title="🗺️ Rwanda Smart Route Planner with Animation"
159
  )
160
 
161
  iface.launch()
162
-
 
3
  import networkx as nx
4
  from folium import Map, Marker, PolyLine
5
  from math import radians, cos, sin, sqrt, atan2
 
6
  from branca.element import MacroElement
7
  from jinja2 import Template
8
 
9
+ # 1. Districts of Rwanda with coordinates
10
  places = {
11
+ "Nyarugenge": (-1.9577, 30.0619), "Gasabo": (-1.9400, 30.0861), "Kicukiro": (-1.9781, 30.0597),
12
+ "Burera": (-1.4800, 29.7300), "Gakenke": (-1.5700, 29.7561), "Rulindo": (-1.8333, 30.0833),
13
+ "Musanze": (-1.5014, 29.6344), "Gicumbi": (-1.5794, 30.0542), "Nyagatare": (-1.3100, 30.3000),
14
+ "Gatsibo": (-1.6800, 30.3900), "Kayonza": (-2.0000, 30.5667), "Kirehe": (-2.3553, 30.7767),
15
+ "Ngoma": (-2.1600, 30.4700), "Rwamagana": (-1.9491, 30.4349), "Bugesera": (-2.2083, 30.2576),
16
+ "Kamonyi": (-2.0833, 29.9000), "Muhanga": (-2.1200, 29.7561), "Ruhango": (-2.2136, 29.7628),
17
+ "Nyamagabe": (-2.4978, 29.4897), "Nyaruguru": (-2.5806, 29.4306), "Huye": (-2.5921, 29.7408),
18
+ "Gisagara": (-2.6283, 29.6820), "Nyanza": (-2.3566, 29.7507), "Rutsiro": (-2.0986, 29.3269),
19
+ "Karongi": (-2.0667, 29.4677), "Rubavu": (-1.7481, 29.2730), "Rusizi": (-2.5406, 29.3737),
20
+ "Nyamasheke": (-2.4700, 29.3222), "Ngororero": (-1.8733, 29.5811)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  }
22
 
23
+ # 2. Haversine function for distance (used in graph and heuristic)
24
  def haversine(coord1, coord2):
25
+ R = 6371
26
  lat1, lon1 = coord1
27
  lat2, lon2 = coord2
28
  dlat = radians(lat2 - lat1)
29
  dlon = radians(lon2 - lon1)
30
+ a = sin(dlat / 2)**2 + cos(radians(lat1)) * cos(radians(lat2)) * sin(dlon / 2)**2
31
+ c = 2 * atan2(sqrt(a), sqrt(1 - a))
32
  return R * c
33
 
34
+ # 3. Graph structure with real connections between neighboring districts
 
35
  edges = [
36
+ ("Nyarugenge", "Gasabo"), ("Gasabo", "Kicukiro"), ("Kicukiro", "Bugesera"), ("Bugesera", "Rwamagana"),
37
+ ("Rwamagana", "Kayonza"), ("Kayonza", "Kirehe"), ("Kirehe", "Ngoma"), ("Ngoma", "Gatsibo"),
38
+ ("Gatsibo", "Nyagatare"), ("Gatsibo", "Gicumbi"), ("Gicumbi", "Rulindo"), ("Rulindo", "Gakenke"),
39
+ ("Gakenke", "Burera"), ("Burera", "Musanze"), ("Musanze", "Rubavu"), ("Rubavu", "Rutsiro"),
40
+ ("Rutsiro", "Karongi"), ("Karongi", "Nyamasheke"), ("Nyamasheke", "Rusizi"), ("Rutsiro", "Ngororero"),
41
+ ("Ngororero", "Muhanga"), ("Muhanga", "Kamonyi"), ("Kamonyi", "Nyarugenge"), ("Muhanga", "Ruhango"),
42
+ ("Ruhango", "Nyanza"), ("Nyanza", "Huye"), ("Huye", "Gisagara"), ("Gisagara", "Nyaruguru"),
43
+ ("Nyaruguru", "Nyamagabe"), ("Nyamagabe", "Karongi"), ("Ngororero", "Ruhango"),
44
+ ("Gicumbi", "Gasabo"), ("Bugesera", "Ngoma")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  ]
 
 
 
 
 
46
 
47
+ # 4. Build the weighted graph
48
+ G = nx.Graph()
49
+ for u, v in edges:
50
+ dist = haversine(places[u], places[v])
51
+ G.add_edge(u, v, weight=dist)
52
 
53
+ # 5. A* heuristic function
54
  def heuristic(u, v):
55
  return haversine(places[u], places[v])
56
 
57
+ # 6. Folium animation class
58
  class AnimateMarker(MacroElement):
59
  _template = Template("""
60
  {% macro script(this, kwargs) %}
 
77
  self._name = "AnimateMarker"
78
  self.locations = locations
79
 
80
+ # 7. Core route generation function
81
  def generate_map(start, end):
 
 
 
 
 
 
 
 
 
82
  if start == end:
83
+ return "Hitamo aho utangiriye n’aho ugiye bitandukanye.", ""
84
 
85
  if not nx.has_path(G, start, end):
86
+ return f"Nta nzira ibaho hagati ya {start} na {end}.", ""
87
 
88
  try:
89
  path = nx.astar_path(G, start, end, heuristic=heuristic, weight='weight')
90
  coords = [places[p] for p in path]
 
91
 
92
+ m = Map(location=[-2.0, 30.0], zoom_start=8)
93
+ for name, coord in places.items():
94
+ Marker(location=coord, popup=name).add_to(m)
95
+
96
+ PolyLine(coords, color="blue", weight=5).add_to(m)
97
  m.add_child(AnimateMarker(coords))
98
 
99
  return "Inzira ngufi ni: " + " ➔ ".join(path), m._repr_html_()
100
  except Exception as e:
101
+ return f"Ntibishoboka kubona inzira: {str(e)}", ""
102
 
103
+ # 8. Gradio Interface
104
  iface = gr.Interface(
105
  fn=generate_map,
106
  inputs=[
107
+ gr.Dropdown(list(places.keys()), label="Hitamo aho uri"),
108
+ gr.Dropdown(list(places.keys()), label="Hitamo aho ugiye")
109
  ],
110
  outputs=[
111
  gr.Textbox(label="Ubutumwa"),
112
  gr.HTML(label="Ikarita")
113
  ],
114
+ title="🗺️ VIATEUR AI Rwanda Smart Route Planner "
115
  )
116
 
117
  iface.launch()