I'm trying to display the path found by the astar algorithm on a map using OSMnx, but I'm having a lot of issues displaying the nodes, edges & path on the graph. I'm pretty new to coding, I took a higher level university course this semester and I'm in way over my head, so if what I have looks like shit I apologise. Any help on how to get the nodes & that to show up would be appreciated.
visualisation.py
import osmnx as ox
import matplotlib.pyplot as plt
from coordinates import letter_to_coord
def visualise_map(graph, start, goal, path):
G = ox.graph_from_address('address', dist=800)
fig, ax = ox.plot_graph(G)
for node in graph:
coord = letter_to_coord.get(node, None)
if coord is not None and isinstance(coord, tuple):
ax.scatter(coord[1], coord[0], c='red')
ax.annotate(node, (coord[1], coord[0]), fontsize=12)
for u, v, *_ in G.edges:
u_coord = letter_to_coord.get(u, None)
v_coord = letter_to_coord.get(v, None)
if u_coord is not None and v_coord is not None and isinstance(u_coord, tuple) and isinstance(v_coord, tuple):
ax.plot([u_coord[1], v_coord[1]], [u_coord[0], v_coord[0]], c='k', linewidth=1, zorder=1)
path_coords = [letter_to_coord.get(node, None) for node in path]
path_coords = [coord for coord in path_coords if coord is not None and isinstance(coord, tuple)]
path_lons = [coord[1] for coord in path_coords]
path_lats = [coord[0] for coord in path_coords]
ax.plot(path_lons, path_lats, c='g', linewidth=3, zorder=2)
plt.show()
gui.py
import tkinter as tk
from tkinter import ttk
import matplotlib
matplotlib.use('TkAgg')
from astar import astar_search, graph
from visualisation import visualise_map
def display_path():
start = start_entry.get()
goal = end_entry.get()
path = astar_search(graph, start, goal)
if path:
path_text.delete('1.0', tk.END)
path_text.insert(tk.END, f"Path found: {', '.join(path)}")
visualise_map(graph, start, goal, path)
else:
path_text.delete('1.0', tk.END)
path_text.insert(tk.END, "No path found")
root = tk.Tk()
root.title("Wheelchair Navigation")
start_label = ttk.Label(root, text="Start:")
start_label.grid(row=0, column=0, padx=10, pady=10)
start_entry = ttk.Entry(root)
start_entry.grid(row=0, column=1, padx=10, pady=10)
end_label = ttk.Label(root, text="End:")
end_label.grid(row=1, column=0, padx=10, pady=10)
end_entry = ttk.Entry(root)
end_entry.grid(row=1, column=1, padx=10, pady=10)
display_button = ttk.Button(root, text="Find Path", command=display_path)
display_button.grid(row=2, column=0, columnspan=2, padx=10, pady=10)
path_text = tk.Text(root, height=5, width=50)
path_text.grid(row=3, column=0, columnspan=2, padx=10, pady=10)
root.mainloop()
letter_to_coord is just a basic dictionary mapping the letters I've assigned to each node to their real-world location using ESPG:4326.
astar
import heapq
from visualisation import visualise_map
from coordinates import letter_to_coord
class Node:
def __init__(self, position, cost, heuristic):
self.position = position
self.cost = cost
self.heuristic = heuristic
self.parent = None
def __lt__(self, other):
return (self.cost + self.heuristic) < (other.cost + other.heuristic)
def astar_search(graph, start, goal):
open_set = []
closed_set = set()
start_node = Node(start, 0, heuristic(start, goal))
heapq.heappush(open_set, start_node)
while open_set:
current_node = heapq.heappop(open_set)
if current_node.position == goal:
path = []
while current_node:
path.insert(0, current_node.position)
current_node = current_node.parent
return path
closed_set.add(current_node.position)
for neighbor in graph[current_node.position]:
if neighbor not in closed_set:
cost = current_node.cost + graph[current_node.position][neighbor]
heuristic_val = heuristic(neighbor, goal)
new_node = Node(neighbor, cost, heuristic_val)
new_node.parent = current_node
existing_node = next((node for node in open_set if node.position == neighbor), None)
if existing_node and existing_node.cost <= cost:
continue
heapq.heappush(open_set, new_node)
return None
def heuristic(start, goal):
node_coord = letter_to_coord.get(start)
goal_coord = letter_to_coord.get(goal)
if isinstance(node_coord, tuple) and isinstance(goal_coord, tuple):
return abs(node_coord[0] - goal_coord[0]) + abs(node_coord[1] - goal_coord[1])
else:
return 0
# Cost of each edge
graph = {
'A': {'B': 45.5},
'B': {'A': 45.5, 'C': 11.4, 'H': 23},
'C': {'B': 11.4, 'D': 10.2, 'I': 24.5},
'D': {'C': 10.2, 'E': 9.8, 'J': 24.8},
'E': {'D': 9.8, 'F': 21.4, 'K': 24.7},
'F': {'E': 21.4, 'G': 11.1},
'G': {'F': 11.1, 'L': 41.3},
'H': {'B': 23, 'I': 11},
'I': {'H': 11, 'C': 24.5, 'J': 10.3},
'J': {'I': 10.3, 'D': 24.8, 'K': 14.5},
'K': {'J': 14.5, 'E': 24.7, 'L': 17},
'L': {'K': 17, 'G': 41.3}
}
path = astar_search(graph, start, goal)