mapgen / app.py
aaron.xavier
Changes
dd769a5
Raw
History Blame Contribute Delete
6.88 kB
import gradio as gr
from PIL import Image
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import itertools
import sys
import math
from tqdm import tqdm
# Define maps
maps = {
"Map 1": [
('A', 0, 'LO'), ('B', 1, 'HI'),
('C', 1, 'LO'), ('D', 2, 'HI'),
('C', 3, 'LO'), ('B', 3, 'HI'),
('A', 4, 'HI'), ('B', 2, 'LO'),
('C', 0, 'HI'), ('D', 4, 'LO')
],
"Map 2": [
('B', 0, 'LO'), ('C', 0, 'HI'),
('A', 1, 'HI'), ('D', 1, 'LO'),
('C', 2, 'LO'), ('B', 2, 'HI'),
('A', 3, 'LO'), ('D', 3, 'HI'),
('B', 4, 'HI'), ('C', 4, 'LO')
],
"Map 3": [
('A', 0, 'HI'), ('D', 0, 'LO'),
('B', 1, 'LO'), ('C', 1, 'HI'),
('A', 2, 'LO'), ('D', 2, 'HI'),
('B', 3, 'HI'), ('C', 3, 'LO'),
('A', 4, 'LO'), ('D', 4, 'HI')
],
"Map Easy": [
('B', 0, 'LO'), ('C', 0, 'LO'),
('C', 1, 'LO'), ('B', 1, 'LO'),
('B', 2, 'LO'), ('C', 2, 'LO'),
('C', 3, 'LO'), ('B', 3, 'LO'),
('B', 4, 'LO'), ('C', 4, 'LO')
]
}
def make_map(map1):
# Load base image
img_path = "map.png"
base_img = mpimg.imread(img_path)
# Mapping from Aisle to image X-coordinates (estimated from image)
aisle_x_map = {
'A': 145, 'B': 185, 'C': 320, 'D': 355
}
# Mapping from Row to image Y-coordinates (0-4 mapped top to bottom)
row_y_map = {
0: 120, 1: 185, 2: 255, 3: 325, 4: 385
}
# Prepare coordinates and colors
x_coords = [aisle_x_map[a] for (a, r, h) in map1]
y_coords = [row_y_map[r] for (a, r, h) in map1]
colors = ['green' if h == 'LO' else 'red' for (a, r, h) in map1]
# Plot on top of base image
fig, ax = plt.subplots(figsize=(6, 6))
ax.imshow(base_img)
# Plot points with different colors
for i in range(len(x_coords)):
ax.plot(x_coords[i], y_coords[i], marker='o', color=colors[i])
# Label each point
for i, (x, y) in enumerate(zip(x_coords, y_coords)):
ax.text(x, y, str(i + 1), color='black', fontsize=10, ha='center', va='bottom')
# Add legend
from matplotlib.lines import Line2D
legend_elements = [Line2D([0], [0], marker='o', color='w', label='LO',
markerfacecolor='green', markersize=10),
Line2D([0], [0], marker='o', color='w', label='HI',
markerfacecolor='red', markersize=10)]
ax.legend(handles=legend_elements, loc='upper right')
# Set axis ticks and labels
ax.set_xticks(list(aisle_x_map.values()))
ax.set_xticklabels(list(aisle_x_map.keys()))
ax.set_yticks(list(row_y_map.values()))
ax.set_yticklabels(list(row_y_map.keys()))
ax.axis('on')
plt.show()
def calculate_shortest_path(map_coords):
"""
Calculates the shortest path to visit all points in a map using permutations.
Args:
map_coords: A list of tuples, where each tuple represents a point
in the map as (aisle, row, height). Aisle is a string
('A', 'B', 'C', 'D'), row is an integer (0-4), and
height is a string ('LO', 'HI').
Returns:
A tuple containing the shortest length found and the corresponding path (list of indices).
"""
min_length = float('inf')
best_path = None
num_points = len(map_coords)
# Iterate through all possible permutations of visiting the points with a progress bar
for path_indices in tqdm(itertools.permutations(range(num_points)), total=math.factorial(num_points), desc="Calculating Shortest Path"):
current_length = 0.0
# Calculate the length for the current permutation
for i in range(num_points - 1):
p1_index = path_indices[i]
p2_index = path_indices[i+1]
# Convert map coordinates to 3D space (aisle, row, height)
x1 = aisle_map[map_coords[p1_index][0]]
y1 = map_coords[p1_index][1]
z1 = height_map[map_coords[p1_index][2]]
x2 = aisle_map[map_coords[p2_index][0]]
y2 = map_coords[p2_index][1]
z2 = height_map[map_coords[p2_index][2]]
# Calculate Euclidean distance between consecutive points
distance = math.sqrt((x2 - x1)**2 + (y2 - y1)**2 + (z2 - z1)**2)
current_length += distance
# Update minimum length and best path if current path is shorter
if current_length < min_length:
min_length = current_length
best_path = list(path_indices)
return min_length, best_path
def run_app(coord_text):
# Parse the input text into a list of tuples (Aisle, Row, Height)
coords = []
for line in coord_text.strip().split('\n'):
parts = line.strip().split(',')
if len(parts) == 3:
aisle = parts[0].strip().upper()
try:
row = int(parts[1].strip())
except ValueError:
continue
height = parts[2].strip().upper()
coords.append((aisle, row, height))
if not coords:
return None
# Generate and save the map image
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import io
from PIL import Image
# Use the same logic as make_map, but output to a buffer
img_path = "/content/map.png" # You may want to update this path
base_img = mpimg.imread(img_path)
aisle_x_map = {'A': 145, 'B': 185, 'C': 320, 'D': 355}
row_y_map = {0: 120, 1: 185, 2: 255, 3: 325, 4: 385}
x_coords = [aisle_x_map.get(a, 0) for (a, r, h) in coords]
y_coords = [row_y_map.get(r, 0) for (a, r, h) in coords]
colors = ['green' if h == 'LO' else 'red' for (a, r, h) in coords]
fig, ax = plt.subplots(figsize=(6, 6))
ax.imshow(base_img)
for i in range(len(x_coords)):
ax.plot(x_coords[i], y_coords[i], marker='o', color=colors[i])
for i, (x, y) in enumerate(zip(x_coords, y_coords)):
ax.text(x, y, str(i + 1), color='black', fontsize=10, ha='center', va='bottom')
from matplotlib.lines import Line2D
legend_elements = [Line2D([0], [0], marker='o', color='w', label='LO', markerfacecolor='green', markersize=10),
Line2D([0], [0], marker='o', color='w', label='HI', markerfacecolor='red', markersize=10)]
ax.legend(handles=legend_elements, loc='upper right')
ax.set_xticks(list(aisle_x_map.values()))
ax.set_xticklabels(list(aisle_x_map.keys()))
ax.set_yticks(list(row_y_map.values()))
ax.set_yticklabels(list(row_y_map.keys()))
ax.axis('on')
buf = io.BytesIO()
plt.savefig(buf, format='png')
plt.close(fig)
buf.seek(0)
img = Image.open(buf)
return img
# Update Gradio interface to accept multiline text and output image
demo = gr.Interface(fn=run_app, inputs=gr.Textbox(lines=10, label="Enter coordinates (Aisle,Row,Height per line)"), outputs="image", title="Shortest Path Finder",)
demo.launch()