123 lines
3.7 KiB
Python
123 lines
3.7 KiB
Python
from typing import Dict, List, Tuple
|
|
|
|
import matplotlib.pyplot as plt
|
|
import numpy as np
|
|
import numpy.typing as npt
|
|
from numpy._typing import NDArray
|
|
|
|
# Data given by the assignment
|
|
city_coords: Dict = {
|
|
"Barcelona": [2.154007, 41.390205],
|
|
"Belgrade": [20.46, 44.79],
|
|
"Berlin": [13.40, 52.52],
|
|
"Brussels": [4.35, 50.85],
|
|
"Bucharest": [26.10, 44.44],
|
|
"Budapest": [19.04, 47.50],
|
|
"Copenhagen": [12.57, 55.68],
|
|
"Dublin": [-6.27, 53.35],
|
|
"Hamburg": [9.99, 53.55],
|
|
"Istanbul": [28.98, 41.02],
|
|
"Kyiv": [30.52, 50.45],
|
|
"London": [-0.12, 51.51],
|
|
"Madrid": [-3.70, 40.42],
|
|
"Milan": [9.19, 45.46],
|
|
"Moscow": [37.62, 55.75],
|
|
"Munich": [11.58, 48.14],
|
|
"Paris": [2.35, 48.86],
|
|
"Prague": [14.42, 50.07],
|
|
"Rome": [12.50, 41.90],
|
|
"Saint Petersburg": [30.31, 59.94],
|
|
"Sofia": [23.32, 42.70],
|
|
"Stockholm": [18.06, 60.33],
|
|
"Vienna": [16.36, 48.21],
|
|
"Warsaw": [21.02, 52.24],
|
|
}
|
|
|
|
|
|
def plot_plan(city_order: List[str]) -> None:
|
|
"""A function that plots the circuit given by city_order.
|
|
|
|
This function was given in the assignment from 2024.
|
|
|
|
Args:
|
|
city_order (List[str]): A list of cities in the order to be plotted.
|
|
|
|
Returns:
|
|
None
|
|
"""
|
|
|
|
europe_map = plt.imread("map.png")
|
|
_, ax = plt.subplots(figsize=(10, 10))
|
|
ax.imshow(
|
|
europe_map, extent=[-14.56, 38.43, 37.697 + 0.3, 64.344 + 2.0], aspect="auto"
|
|
)
|
|
|
|
# Map (long, lat) to (x, y) for plotting
|
|
for index in range(len(city_order) - 1):
|
|
current_city_coords = city_coords[city_order[index]]
|
|
next_city_coords = city_coords[city_order[index + 1]]
|
|
x, y = current_city_coords[0], current_city_coords[1]
|
|
# Plotting a line to the next city
|
|
next_x, next_y = next_city_coords[0], next_city_coords[1]
|
|
plt.plot([x, next_x], [y, next_y])
|
|
|
|
plt.plot(x, y, "ok", markersize=5)
|
|
plt.text(x, y, str(index), fontsize=12)
|
|
# Finally, plotting from last to first city
|
|
first_city_coords = city_coords[city_order[0]]
|
|
first_x, first_y = first_city_coords[0], first_city_coords[1]
|
|
plt.plot([next_x, first_x], [next_y, first_y])
|
|
# Plotting a marker and index for the final city
|
|
plt.plot(next_x, next_y, "ok", markersize=5)
|
|
plt.text(next_x, next_y, str(index + 1), fontsize=12)
|
|
plt.show()
|
|
|
|
|
|
def index_to_city(indexes: npt.NDArray, cities: npt.NDArray) -> npt.NDArray:
|
|
"""Create an array of cities from indeces in a specific order.
|
|
|
|
Args:
|
|
indexes (npt.NDArray): An array of city indexes.
|
|
cities (npt.NDArray): An array of cities.
|
|
|
|
Returns:
|
|
npt.NDArray An array of cities in the same order as given in indexes.
|
|
"""
|
|
|
|
return np.array([cities[i] for i in indexes])
|
|
|
|
|
|
def read_data(file_path: str) -> Tuple[npt.NDArray, npt.NDArray]:
|
|
"""Read the city data from a file given and return 2 arrays.
|
|
|
|
The data being read should be separated by semicolons,
|
|
and the first line should be a list of cities while the
|
|
rest of the file should contain the data. The resulting
|
|
array for the data should be an NxN matrix.
|
|
|
|
Args:
|
|
file_path (str): The file path for the file containing the city data.
|
|
|
|
Returns:
|
|
Tuple[npt.NDArray, npt.NDArray] A tuple containing the list of cities
|
|
and the data associated with it.
|
|
|
|
"""
|
|
|
|
cities = None
|
|
data = []
|
|
with open(file_path, "r") as f:
|
|
cities = f.readline().strip().split(";")
|
|
lines = f.readlines()
|
|
for line in lines:
|
|
data.append(list(map(float, line.strip().split(";"))))
|
|
|
|
return (np.array(cities), np.array(data))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
# A test program to see that the file is read correctly.
|
|
cities, data = read_data("./european_cities.csv")
|
|
print(cities)
|
|
print(data)
|