Upgraded refiner
This commit is contained in:
parent
813c83a81d
commit
8d068c80a7
@ -15,7 +15,33 @@ SHOPPING = LandmarkType(landmark_type='shopping')
|
||||
|
||||
# Include the json here
|
||||
# Create a list of all things to visit given some preferences and a city. Ready for the optimizer
|
||||
def generate_landmarks(preferences: Preferences, city_country: str = None, coordinates: Tuple[float, float] = None) -> Tuple[List[Landmark], List[Landmark]] :
|
||||
def generate_landmarks(preferences: Preferences, coordinates: Tuple[float, float]) :
|
||||
|
||||
l_sights, l_nature, l_shop = get_amenities()
|
||||
L = []
|
||||
|
||||
# List for sightseeing
|
||||
if preferences.sightseeing.score != 0 :
|
||||
L1 = get_landmarks(l_sights, SIGHTSEEING, coordinates=coordinates)
|
||||
correct_score(L1, preferences.sightseeing)
|
||||
L += L1
|
||||
|
||||
# List for nature
|
||||
if preferences.nature.score != 0 :
|
||||
L2 = get_landmarks(l_nature, NATURE, coordinates=coordinates)
|
||||
correct_score(L2, preferences.nature)
|
||||
L += L2
|
||||
|
||||
# List for shopping
|
||||
if preferences.shopping.score != 0 :
|
||||
L3 = get_landmarks(l_shop, SHOPPING, coordinates=coordinates)
|
||||
correct_score(L3, preferences.shopping)
|
||||
L += L3
|
||||
|
||||
return remove_duplicates(L), take_most_important(L)
|
||||
|
||||
|
||||
"""def generate_landmarks(preferences: Preferences, city_country: str = None, coordinates: Tuple[float, float] = None) -> Tuple[List[Landmark], List[Landmark]] :
|
||||
|
||||
l_sights, l_nature, l_shop = get_amenities()
|
||||
L = []
|
||||
@ -39,8 +65,7 @@ def generate_landmarks(preferences: Preferences, city_country: str = None, coord
|
||||
L += L3
|
||||
|
||||
return remove_duplicates(L), take_most_important(L)
|
||||
|
||||
|
||||
"""
|
||||
# Helper function to gather the amenities list
|
||||
def get_amenities() -> List[List[str]] :
|
||||
|
||||
@ -199,7 +224,71 @@ def create_bbox(coordinates: Tuple[float, float], side_length: int) -> Tuple[flo
|
||||
return min_lat, min_lon, max_lat, max_lon
|
||||
|
||||
|
||||
def get_landmarks(list_amenity: list, landmarktype: LandmarkType, city_country: str = None, coordinates: Tuple[float, float] = None) -> List[Landmark] :
|
||||
def get_landmarks(list_amenity: list, landmarktype: LandmarkType, coordinates: Tuple[float, float]) -> List[Landmark] :
|
||||
|
||||
# Read the parameters from the file
|
||||
with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/landmarks_manager.params', "r") as f :
|
||||
parameters = json.loads(f.read())
|
||||
tag_coeff = parameters['tag coeff']
|
||||
park_coeff = parameters['park coeff']
|
||||
church_coeff = parameters['church coeff']
|
||||
radius = parameters['radius close to']
|
||||
bbox_side = parameters['city bbox side']
|
||||
|
||||
# Create bbox around start location
|
||||
bbox = create_bbox(coordinates, bbox_side)
|
||||
|
||||
# Initialize some variables
|
||||
N = 0
|
||||
L = []
|
||||
overpass = Overpass()
|
||||
|
||||
for amenity in list_amenity :
|
||||
query = overpassQueryBuilder(bbox=bbox, elementType=['way', 'relation'], selector=amenity, includeCenter=True, out='body')
|
||||
result = overpass.query(query)
|
||||
N += result.countElements()
|
||||
|
||||
for elem in result.elements():
|
||||
|
||||
name = elem.tag('name') # Add name
|
||||
location = (elem.centerLat(), elem.centerLon()) # Add coordinates (lat, lon)
|
||||
|
||||
# skip if unprecise location
|
||||
if name is None or location[0] is None:
|
||||
continue
|
||||
|
||||
# skip if unused
|
||||
if 'disused:leisure' in elem.tags().keys():
|
||||
continue
|
||||
|
||||
# skip if part of another building
|
||||
if 'building:part' in elem.tags().keys() and elem.tag('building:part') == 'yes':
|
||||
continue
|
||||
|
||||
else :
|
||||
osm_type = elem.type() # Add type : 'way' or 'relation'
|
||||
osm_id = elem.id() # Add OSM id
|
||||
elem_type = landmarktype # Add the landmark type as 'sightseeing
|
||||
n_tags = len(elem.tags().keys()) # Add number of tags
|
||||
|
||||
# Add score of given landmark based on the number of surrounding elements. Penalty for churches as there are A LOT
|
||||
if amenity == "'amenity'='place_of_worship'" :
|
||||
score = int((count_elements_within_radius(location, radius) + n_tags*tag_coeff )*church_coeff)
|
||||
elif amenity == "'leisure'='park'" :
|
||||
score = int((count_elements_within_radius(location, radius) + n_tags*tag_coeff )*park_coeff)
|
||||
else :
|
||||
score = count_elements_within_radius(location, radius) + n_tags*tag_coeff
|
||||
|
||||
if score is not None :
|
||||
# Generate the landmark and append it to the list
|
||||
landmark = Landmark(name=name, type=elem_type, location=location, osm_type=osm_type, osm_id=osm_id, attractiveness=score, must_do=False, n_tags=n_tags)
|
||||
L.append(landmark)
|
||||
|
||||
return L
|
||||
|
||||
|
||||
|
||||
"""def get_landmarks(list_amenity: list, landmarktype: LandmarkType, city_country: str = None, coordinates: Tuple[float, float] = None) -> List[Landmark] :
|
||||
|
||||
if city_country is None and coordinates is None :
|
||||
raise ValueError("Either one of 'city_country' and 'coordinates' arguments must be specified")
|
||||
@ -277,3 +366,4 @@ def get_landmarks(list_amenity: list, landmarktype: LandmarkType, city_country:
|
||||
L.append(landmark)
|
||||
|
||||
return L
|
||||
"""
|
@ -1,6 +1,6 @@
|
||||
from optimizer import solve_optimization
|
||||
from refiner import refine_optimization
|
||||
from landmarks_manager import generate_landmarks
|
||||
from structs.landmarks import LandmarkTest
|
||||
from structs.landmarks import Landmark
|
||||
from structs.landmarktype import LandmarkType
|
||||
from structs.preferences import Preferences, Preference
|
||||
@ -12,35 +12,45 @@ app = FastAPI()
|
||||
|
||||
# Assuming frontend is calling like this :
|
||||
#"http://127.0.0.1:8000/process?param1={param1}¶m2={param2}"
|
||||
@app.post("/optimizer_coords/{latitude}/{longitude}/{city_country}")
|
||||
def main1(preferences: Preferences = Body(...), latitude: float = None, longitude: float = None, city_country: str = None) -> List[Landmark]:
|
||||
@app.post("/optimizer_coords/{start_lat}/{start_lon}/{finish_lat}/{finish_lon}")
|
||||
def main1(start_lat: float, start_lon: float, preferences: Preferences = Body(...), finish_lat: float = None, finish_lon: float = None) -> List[Landmark]:
|
||||
|
||||
if preferences is None :
|
||||
raise ValueError("Please provide preferences in the form of a 'Preference' BaseModel class.")
|
||||
elif latitude is None and longitude is None and city_country is None :
|
||||
raise ValueError("Please provide GPS coordinates or a 'city_country' string.")
|
||||
elif latitude is not None and longitude is not None and city_country is not None :
|
||||
raise ValueError("Please provide EITHER GPS coordinates or a 'city_country' string.")
|
||||
if bool(start_lat) ^ bool(start_lon) :
|
||||
raise ValueError("Please provide both latitude and longitude for the starting point")
|
||||
if bool(finish_lat) ^ bool(finish_lon) :
|
||||
raise ValueError("Please provide both latitude and longitude for the finish point")
|
||||
|
||||
start = Landmark(name='start', type=LandmarkType(landmark_type='start'), location=(start_lat, start_lon), osm_type='start', osm_id=0, attractiveness=0, must_do=True, n_tags = 0)
|
||||
|
||||
# From frontend get longitude, latitude and prefence list
|
||||
if city_country is None :
|
||||
coordinates = tuple((latitude, longitude))
|
||||
if bool(finish_lat) and bool(finish_lon) :
|
||||
finish = Landmark(name='finish', type=LandmarkType(landmark_type='finish'), location=(finish_lat, finish_lon), osm_type='finish', osm_id=0, attractiveness=0, must_do=True, n_tags = 0)
|
||||
else :
|
||||
finish = Landmark(name='finish', type=LandmarkType(landmark_type='finish'), location=(start_lat, start_lon), osm_type='finish', osm_id=0, attractiveness=0, must_do=True, n_tags = 0)
|
||||
|
||||
|
||||
[], landmarks_short = generate_landmarks(preferences=preferences, city_country=city_country, coordinates=coordinates)
|
||||
|
||||
start = Landmark(name='start', type=LandmarkType(landmark_type='start'), location=(48.8375946, 2.2949904), osm_type='start', osm_id=0, attractiveness=0, must_do=True, n_tags = 0)
|
||||
finish = Landmark(name='finish', type=LandmarkType(landmark_type='finish'), location=(48.8375946, 2.2949904), osm_type='finish', osm_id=0, attractiveness=0, must_do=True, n_tags = 0)
|
||||
|
||||
# Generate the landmarks from the start location
|
||||
landmarks, landmarks_short = generate_landmarks(preferences=preferences, coordinates=start.location)
|
||||
|
||||
# insert start and finish to the landmarks list
|
||||
landmarks_short.insert(0, start)
|
||||
landmarks_short.append(finish)
|
||||
|
||||
# TODO use these parameters in another way
|
||||
max_walking_time = 4 # hours
|
||||
detour = 30 # minutes
|
||||
|
||||
visiting_list = solve_optimization(landmarks_short, max_walking_time*60, True)
|
||||
# First stage optimization
|
||||
base_tour = solve_optimization(landmarks_short, max_walking_time*60, True)
|
||||
|
||||
return visiting_list
|
||||
# Second stage optimization
|
||||
refined_tour = refine_optimization(landmarks, base_tour, max_walking_time*60+detour, True)
|
||||
|
||||
return refined_tour
|
||||
|
||||
|
||||
|
||||
|
@ -141,19 +141,19 @@ def get_distance(p1: Tuple[float, float], p2: Tuple[float, float], detour: float
|
||||
else:
|
||||
dist = 6371.01 * acos(sin(radians(p1[0]))*sin(radians(p2[0])) + cos(radians(p1[0]))*cos(radians(p2[0]))*cos(radians(p1[1]) - radians(p2[1])))
|
||||
|
||||
# Consider the detour factor for average city
|
||||
wdist = dist*detour
|
||||
# Consider the detour factor for average cityto deterline walking distance (in km)
|
||||
walk_dist = dist*detour
|
||||
|
||||
# Time to walk this distance (in minutes)
|
||||
wtime = wdist/speed*60
|
||||
walk_time = walk_dist/speed*60
|
||||
|
||||
if wtime > 15 :
|
||||
wtime = 5*round(wtime/5)
|
||||
if walk_time > 15 :
|
||||
walk_time = 5*round(walk_time/5)
|
||||
else :
|
||||
wtime = round(wtime)
|
||||
walk_time = round(walk_time)
|
||||
|
||||
|
||||
return round(wdist, 1), wtime
|
||||
return round(walk_dist, 1), walk_time
|
||||
|
||||
|
||||
# Initialize A and c. Compute the distances from all landmarks to each other and store attractiveness
|
||||
@ -291,23 +291,23 @@ def respect_order(N: int, A_eq, b_eq):
|
||||
|
||||
|
||||
# Computes the path length given path matrix (dist_table) and a result
|
||||
def add_time_to_reach(order: List[Landmark], landmarks: List[Landmark])->List[Landmark] :
|
||||
|
||||
j = 0
|
||||
L = []
|
||||
def add_time_to_reach(order: List[int], landmarks: List[Landmark])->List[Landmark] :
|
||||
|
||||
# Read the parameters from the file
|
||||
with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/optimizer.params', "r") as f :
|
||||
parameters = json.loads(f.read())
|
||||
detour = parameters['detour factor']
|
||||
detour_factor = parameters['detour factor']
|
||||
speed = parameters['average walking speed']
|
||||
|
||||
j = 0
|
||||
L = []
|
||||
prev = landmarks[0]
|
||||
|
||||
while(len(L) != len(order)) :
|
||||
|
||||
elem = landmarks[order[j]]
|
||||
if elem != prev :
|
||||
elem.time_to_reach = get_distance(elem.location, prev.location, detour, speed)[1]
|
||||
elem.time_to_reach = get_distance(elem.location, prev.location, detour_factor, speed)[1]
|
||||
elem.must_do = True
|
||||
L.append(elem)
|
||||
prev = elem
|
||||
@ -315,6 +315,26 @@ def add_time_to_reach(order: List[Landmark], landmarks: List[Landmark])->List[La
|
||||
|
||||
return L
|
||||
|
||||
def add_time_to_reach_simple(ordered_visit: List[Landmark])-> List[Landmark] :
|
||||
|
||||
# Read the parameters from the file
|
||||
with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/optimizer.params', "r") as f :
|
||||
parameters = json.loads(f.read())
|
||||
detour_factor = parameters['detour factor']
|
||||
speed = parameters['average walking speed']
|
||||
|
||||
L = []
|
||||
prev = ordered_visit[0]
|
||||
L.append(prev)
|
||||
|
||||
for elem in ordered_visit[1:] :
|
||||
elem.time_to_reach = get_distance(elem.location, prev.location, detour_factor, speed)[1]
|
||||
elem.must_do = True
|
||||
L.append(elem)
|
||||
prev = elem
|
||||
|
||||
return L
|
||||
|
||||
|
||||
# Main optimization pipeline
|
||||
def solve_optimization (landmarks :List[Landmark], max_steps: int, printing_details: bool) :
|
||||
@ -356,7 +376,7 @@ def solve_optimization (landmarks :List[Landmark], max_steps: int, printing_deta
|
||||
# Add the times to reach and stop optimizing
|
||||
L = add_time_to_reach(order, landmarks)
|
||||
break
|
||||
print(i)
|
||||
#print(i)
|
||||
i += 1
|
||||
|
||||
if i == timeout :
|
||||
|
@ -1,4 +1,4 @@
|
||||
{
|
||||
"detour factor" : 10,
|
||||
"average walking speed" : 27.5
|
||||
"detour factor" : 1.4,
|
||||
"average walking speed" : 4.8
|
||||
}
|
@ -1,9 +1,10 @@
|
||||
from shapely import buffer, LineString, Point, Polygon
|
||||
from shapely import buffer, LineString, Point, Polygon, MultiPoint, convex_hull, concave_hull, LinearRing
|
||||
from typing import List
|
||||
from math import pi
|
||||
|
||||
from structs.landmarks import Landmark
|
||||
from landmarks_manager import take_most_important
|
||||
from optimizer import solve_optimization, add_time_to_reach_simple, print_res
|
||||
|
||||
|
||||
def create_corridor(landmarks: List[Landmark], width: float) :
|
||||
@ -34,10 +35,78 @@ def is_in_area(area: Polygon, coordinates) -> bool :
|
||||
def get_minor_landmarks(all_landmarks: List[Landmark], visited_landmarks: List[Landmark], width: float) -> List[Landmark] :
|
||||
|
||||
second_order_landmarks = []
|
||||
visited_names = []
|
||||
area = create_corridor(visited_landmarks, width)
|
||||
|
||||
for visited in visited_landmarks :
|
||||
visited_names.append(visited.name)
|
||||
|
||||
for landmark in all_landmarks :
|
||||
if is_in_area(area, landmark.location) and landmark not in visited_landmarks:
|
||||
if is_in_area(area, landmark.location) and landmark.name not in visited_names:
|
||||
second_order_landmarks.append(landmark)
|
||||
|
||||
return take_most_important(second_order_landmarks)
|
||||
|
||||
|
||||
|
||||
"""def refine_optimization(landmarks: List[Landmark], base_tour: List[Landmark], max_time: int, print_infos: bool) -> List[Landmark] :
|
||||
|
||||
minor_landmarks = get_minor_landmarks(landmarks, base_tour, 200)
|
||||
|
||||
if print_infos : print("There are " + str(len(minor_landmarks)) + " minor landmarks around the predicted path")
|
||||
|
||||
full_set = base_tour[:-1] + minor_landmarks # create full set of possible landmarks (without finish)
|
||||
full_set.append(base_tour[-1]) # add finish back
|
||||
|
||||
new_route = solve_optimization(full_set, max_time, print_infos)
|
||||
|
||||
return new_route"""
|
||||
|
||||
|
||||
def refine_optimization(landmarks: List[Landmark], base_tour: List[Landmark], max_time: int, print_infos: bool) -> List[Landmark] :
|
||||
|
||||
minor_landmarks = get_minor_landmarks(landmarks, base_tour, 200)
|
||||
|
||||
if print_infos : print("There are " + str(len(minor_landmarks)) + " minor landmarks around the predicted path")
|
||||
|
||||
# full set of visitable landmarks
|
||||
full_set = base_tour[:-1] + minor_landmarks # create full set of possible landmarks (without finish)
|
||||
full_set.append(base_tour[-1]) # add finish back
|
||||
|
||||
# get a new route
|
||||
new_route = solve_optimization(full_set, max_time, False)
|
||||
|
||||
coords = [] # Coordinates of the new route
|
||||
coords_dict = {} # maps the location of an element to the element itself. Used to access the elements back once we get the geometry
|
||||
|
||||
# Iterate through the new route without finish
|
||||
for elem in new_route[:-1] :
|
||||
coords.append(Point(elem.location))
|
||||
coords_dict[elem.location] = elem # if start = goal, only finish remains
|
||||
|
||||
# Create a concave polygon using the coordinates
|
||||
better_route_poly = concave_hull(MultiPoint(coords)) # Create concave hull with "core" of route leaving out start and finish
|
||||
xs, ys = better_route_poly.exterior.xy
|
||||
|
||||
better_route = [] # List of ordered visit
|
||||
name_index = {} # Maps the name of a landmark to its index in the concave polygon
|
||||
|
||||
# Loop through the polygon and generate the better (ordered) route
|
||||
for i,x in enumerate(xs[:-1]) :
|
||||
better_route.append(coords_dict[tuple((x,ys[i]))])
|
||||
name_index[coords_dict[tuple((x,ys[i]))].name] = i
|
||||
|
||||
|
||||
# Scroll the list to have start in front again
|
||||
start_index = name_index['start']
|
||||
better_route = better_route[start_index:] + better_route[:start_index]
|
||||
|
||||
# Append the finish back and correct the time to reach
|
||||
better_route.append(new_route[-1])
|
||||
better_route = add_time_to_reach_simple(better_route)
|
||||
|
||||
if print_infos :
|
||||
print("\nRefined tour (result of second stage optimization): ")
|
||||
print_res(better_route, len(better_route))
|
||||
|
||||
return better_route
|
||||
|
@ -5,7 +5,7 @@ from landmarks_manager import generate_landmarks
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
|
||||
from optimizer import solve_optimization
|
||||
from refiner import get_minor_landmarks
|
||||
from refiner import refine_optimization
|
||||
from structs.landmarks import Landmark
|
||||
from structs.landmarktype import LandmarkType
|
||||
from structs.preferences import Preferences, Preference
|
||||
@ -80,38 +80,32 @@ def test4(coordinates: tuple[float, float]) -> List[Landmark]:
|
||||
type=LandmarkType(landmark_type='shopping'),
|
||||
score = 5))
|
||||
|
||||
city_country = None
|
||||
|
||||
landmarks, landmarks_short = generate_landmarks(preferences=preferences, city_country=city_country, coordinates=coordinates)
|
||||
# Create start and finish
|
||||
start = Landmark(name='start', type=LandmarkType(landmark_type='start'), location=coordinates, osm_type='start', osm_id=0, attractiveness=0, must_do=True, n_tags = 0)
|
||||
finish = Landmark(name='finish', type=LandmarkType(landmark_type='finish'), location=coordinates, osm_type='finish', osm_id=0, attractiveness=0, must_do=True, n_tags = 0)
|
||||
|
||||
# Generate the landmarks from the start location
|
||||
landmarks, landmarks_short = generate_landmarks(preferences=preferences, coordinates=start.location)
|
||||
#write_data(landmarks, "landmarks.txt")
|
||||
|
||||
# Insert start and finish to the landmarks list
|
||||
landmarks_short.insert(0, start)
|
||||
landmarks_short.append(finish)
|
||||
|
||||
start = Landmark(name='start', type=LandmarkType(landmark_type='start'), location=(48.8375946, 2.2949904), osm_type='start', osm_id=0, attractiveness=0, must_do=True, n_tags = 0)
|
||||
finish = Landmark(name='finish', type=LandmarkType(landmark_type='finish'), location=(48.8375946, 2.2949904), osm_type='finish', osm_id=0, attractiveness=0, must_do=True, n_tags = 0)
|
||||
|
||||
test = landmarks_short
|
||||
|
||||
test.insert(0, start)
|
||||
test.append(finish)
|
||||
|
||||
# TODO use these parameters in another way
|
||||
max_walking_time = 4 # hours
|
||||
detour = 30 # minutes
|
||||
|
||||
visited_list = solve_optimization(test, max_walking_time*60, True)
|
||||
#visited_list = [Landmark(name='start', type=LandmarkType(landmark_type='start'), location=(48.8375946, 2.2949904), osm_type='start', osm_id=0, attractiveness=0, must_do=True, n_tags=0, time_to_reach=0), Landmark(name='Palais du Louvre', type=LandmarkType(landmark_type='sightseeing'), location=(48.8614768, 2.3351677), osm_type='relation', osm_id=3262297, attractiveness=32, must_do=False, n_tags=32, time_to_reach=85), Landmark(name='Musée du Louvre', type=LandmarkType(landmark_type='sightseeing'), location=(48.8611474, 2.3358637), osm_type='relation', osm_id=7515426, attractiveness=34, must_do=False, n_tags=33, time_to_reach=1), Landmark(name='Bourse de Commerce — Pinault Collection', type=LandmarkType(landmark_type='sightseeing'), location=(48.8628167, 2.3428183), osm_type='way', osm_id=19856722, attractiveness=32, must_do=False, n_tags=32, time_to_reach=12), Landmark(name='Centre Georges Pompidou', type=LandmarkType(landmark_type='sightseeing'), location=(48.8605235, 2.3524395), osm_type='way', osm_id=55503397, attractiveness=43, must_do=False, n_tags=43, time_to_reach=15), Landmark(name='Tour Saint-Jacques', type=LandmarkType(landmark_type='sightseeing'), location=(48.8579983, 2.3489178), osm_type='way', osm_id=20326709, attractiveness=33, must_do=False, n_tags=31, time_to_reach=8), Landmark(name='Hôtel de Ville', type=LandmarkType(landmark_type='sightseeing'), location=(48.8564265, 2.352527), osm_type='relation', osm_id=284089, attractiveness=34, must_do=False, n_tags=32, time_to_reach=7), Landmark(name='Cathédrale Notre-Dame de Paris', type=LandmarkType(landmark_type='sightseeing'), location=(48.8529372, 2.3498701), osm_type='way', osm_id=201611261, attractiveness=55, must_do=False, n_tags=54, time_to_reach=9), Landmark(name='Sainte-Chapelle', type=LandmarkType(landmark_type='sightseeing'), location=(48.8553966, 2.3450136), osm_type='relation', osm_id=3344870, attractiveness=57, must_do=False, n_tags=54, time_to_reach=10), Landmark(name='finish', type=LandmarkType(landmark_type='finish'), location=(48.8375946, 2.2949904), osm_type='finish', osm_id=0, attractiveness=0, must_do=True, n_tags=0, time_to_reach=90)]
|
||||
# First stage optimization
|
||||
base_tour = solve_optimization(landmarks_short, max_walking_time*60, True)
|
||||
|
||||
# Second stage optimization
|
||||
refined_tour = refine_optimization(landmarks, base_tour, max_walking_time*60+detour, True)
|
||||
|
||||
return refined_tour
|
||||
|
||||
|
||||
minor_landmarks = get_minor_landmarks(landmarks, visited_list, 200)
|
||||
#write_data(minor_landmarks, 'minor_landmarks.txt')
|
||||
print("There are " + str(len(minor_landmarks)) + " minor landmarks around the predicted path")
|
||||
|
||||
full_set = visited_list[:-1] + minor_landmarks[:30]
|
||||
full_set.append(finish)
|
||||
|
||||
new_route = solve_optimization(full_set, max_walking_time*60+detour, True)
|
||||
|
||||
return new_route
|
||||
|
||||
|
||||
test4(tuple((48.8795156, 2.3660204)))
|
||||
#test4(tuple((48.8344400, 2.3220540))) # Café Chez César
|
||||
test4(tuple((48.8375946, 2.2949904))) # Point random
|
||||
#test3('Vienna, Austria')
|
1438
landmarks.txt
1438
landmarks.txt
File diff suppressed because it is too large
Load Diff
@ -16,86 +16,198 @@
|
||||
"time_to_reach":0
|
||||
},
|
||||
"1":{
|
||||
"name":"Musée d'art et d'histoire du Judaïsme",
|
||||
"name":"Musée de Cluny",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8612656,
|
||||
2.355418
|
||||
48.8506604,
|
||||
2.3437398
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":56687783,
|
||||
"attractiveness":9,
|
||||
"must_do":false,
|
||||
"n_tags":8,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"2":{
|
||||
"name":"Musée Ernest-Hébert (en travaux)",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8473326,
|
||||
2.3227159
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":64314872,
|
||||
"attractiveness":10,
|
||||
"must_do":false,
|
||||
"n_tags":9,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"3":{
|
||||
"name":"Crypte Archéologique du Parvis Notre-Dame",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8535851,
|
||||
2.3480846
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":159896046,
|
||||
"osm_id":56640163,
|
||||
"attractiveness":18,
|
||||
"must_do":false,
|
||||
"n_tags":18,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"4":{
|
||||
"name":"Jardin Catherine Labouré",
|
||||
"2":{
|
||||
"name":"Musée du Luxembourg",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8510562,
|
||||
2.320532
|
||||
48.8485965,
|
||||
2.3340156
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":148481812,
|
||||
"attractiveness":8,
|
||||
"osm_id":170226810,
|
||||
"attractiveness":15,
|
||||
"must_do":false,
|
||||
"n_tags":8,
|
||||
"n_tags":15,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"3":{
|
||||
"name":"Musée national Eugène Delacroix",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8546662,
|
||||
2.3353836
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":395785603,
|
||||
"attractiveness":15,
|
||||
"must_do":false,
|
||||
"n_tags":15,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"4":{
|
||||
"name":"Hôtel de Sully",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.854635,
|
||||
2.3638126
|
||||
],
|
||||
"osm_type":"relation",
|
||||
"osm_id":403146,
|
||||
"attractiveness":14,
|
||||
"must_do":false,
|
||||
"n_tags":13,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"5":{
|
||||
"name":"Arc de Triomphe du Carrousel",
|
||||
"name":"Hôtel de la Monnaie",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8617276,
|
||||
2.3329082
|
||||
48.856403,
|
||||
2.3388625
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":227483542,
|
||||
"attractiveness":16,
|
||||
"osm_type":"relation",
|
||||
"osm_id":967664,
|
||||
"attractiveness":11,
|
||||
"must_do":false,
|
||||
"n_tags":11,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"6":{
|
||||
"name":"Musée Bourdelle",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8432078,
|
||||
2.3186583
|
||||
],
|
||||
"osm_type":"relation",
|
||||
"osm_id":1212876,
|
||||
"attractiveness":23,
|
||||
"must_do":false,
|
||||
"n_tags":23,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"7":{
|
||||
"name":"Musée Carnavalet",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8576819,
|
||||
2.3627147
|
||||
],
|
||||
"osm_type":"relation",
|
||||
"osm_id":2405955,
|
||||
"attractiveness":25,
|
||||
"must_do":false,
|
||||
"n_tags":25,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"8":{
|
||||
"name":"Pont Neuf",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8565248,
|
||||
2.3408132
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":53574149,
|
||||
"attractiveness":16,
|
||||
"must_do":false,
|
||||
"n_tags":15,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"9":{
|
||||
"name":"Jardin du Luxembourg",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8467137,
|
||||
2.3363649
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":128206209,
|
||||
"attractiveness":35,
|
||||
"must_do":false,
|
||||
"n_tags":23,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"10":{
|
||||
"name":"Cathédrale Notre-Dame de Paris",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8529372,
|
||||
2.3498701
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":201611261,
|
||||
"attractiveness":55,
|
||||
"must_do":false,
|
||||
"n_tags":54,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"11":{
|
||||
"name":"Maison à l'enseigne du Faucheur",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8558553,
|
||||
2.3568266
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":1123456865,
|
||||
"attractiveness":13,
|
||||
"must_do":false,
|
||||
"n_tags":11,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"12":{
|
||||
"name":"Maison à l'enseigne du Mouton",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8558431,
|
||||
2.3568914
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":1123456866,
|
||||
"attractiveness":13,
|
||||
"must_do":false,
|
||||
"n_tags":11,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"13":{
|
||||
"name":"Palais de Justice de Paris",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
@ -111,7 +223,23 @@
|
||||
"n_tags":24,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"7":{
|
||||
"14":{
|
||||
"name":"Mémorial des Martyrs de la Déportation",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8517365,
|
||||
2.3524734
|
||||
],
|
||||
"osm_type":"relation",
|
||||
"osm_id":9396191,
|
||||
"attractiveness":21,
|
||||
"must_do":false,
|
||||
"n_tags":21,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"15":{
|
||||
"name":"Fontaine des Innocents",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
@ -127,7 +255,39 @@
|
||||
"n_tags":15,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"8":{
|
||||
"16":{
|
||||
"name":"Hôtel de Sens",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8535257,
|
||||
2.3588733
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":55541122,
|
||||
"attractiveness":21,
|
||||
"must_do":false,
|
||||
"n_tags":20,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"17":{
|
||||
"name":"Hôtel d'Ourscamp",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8555465,
|
||||
2.3571206
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":55620201,
|
||||
"attractiveness":10,
|
||||
"must_do":false,
|
||||
"n_tags":9,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"18":{
|
||||
"name":"Hôtel de Choiseul-Praslin",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
@ -143,23 +303,7 @@
|
||||
"n_tags":12,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"9":{
|
||||
"name":"Hôtel de Cassini",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8519819,
|
||||
2.3209847
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":68571376,
|
||||
"attractiveness":13,
|
||||
"must_do":false,
|
||||
"n_tags":13,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"10":{
|
||||
"19":{
|
||||
"name":"Chapelle Notre-Dame-des-Anges",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
@ -175,7 +319,7 @@
|
||||
"n_tags":16,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"11":{
|
||||
"20":{
|
||||
"name":"Fontaine du Palmier",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
@ -191,103 +335,39 @@
|
||||
"n_tags":14,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"12":{
|
||||
"name":"Colonne Médicis",
|
||||
"21":{
|
||||
"name":"Église Saint-Séverin",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8625255,
|
||||
2.3429926
|
||||
48.8520913,
|
||||
2.3457237
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":942543401,
|
||||
"osm_id":19740659,
|
||||
"attractiveness":15,
|
||||
"must_do":false,
|
||||
"n_tags":13,
|
||||
"n_tags":25,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"13":{
|
||||
"name":"Noviciat des Dominicains",
|
||||
"22":{
|
||||
"name":"Église Orthodoxe Roumaine des Saints Archanges",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8561352,
|
||||
2.3284496
|
||||
],
|
||||
"osm_type":"relation",
|
||||
"osm_id":1002118,
|
||||
"attractiveness":8,
|
||||
"must_do":false,
|
||||
"n_tags":8,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"14":{
|
||||
"name":"Hôtel de Matignon",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8544393,
|
||||
2.320661
|
||||
],
|
||||
"osm_type":"relation",
|
||||
"osm_id":1076880,
|
||||
"attractiveness":13,
|
||||
"must_do":false,
|
||||
"n_tags":13,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"15":{
|
||||
"name":"Ligne de Petite Ceinture",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8597838,
|
||||
2.3341775
|
||||
],
|
||||
"osm_type":"relation",
|
||||
"osm_id":1536589,
|
||||
"attractiveness":8,
|
||||
"must_do":false,
|
||||
"n_tags":8,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"16":{
|
||||
"name":"Bateau Daphné",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8520929,
|
||||
2.3494633
|
||||
48.849488,
|
||||
2.3471975
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":618750321,
|
||||
"attractiveness":6,
|
||||
"osm_id":55366403,
|
||||
"attractiveness":10,
|
||||
"must_do":false,
|
||||
"n_tags":6,
|
||||
"n_tags":16,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"17":{
|
||||
"name":"Église Saint-Leu - Saint-Gilles",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8628813,
|
||||
2.3500683
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":53933240,
|
||||
"attractiveness":14,
|
||||
"must_do":false,
|
||||
"n_tags":23,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"18":{
|
||||
"23":{
|
||||
"name":"Église Saint-Merri",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
@ -303,87 +383,23 @@
|
||||
"n_tags":26,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"19":{
|
||||
"name":"Église Saint-Joseph des Carmes",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8485199,
|
||||
2.3302805
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":63370983,
|
||||
"attractiveness":7,
|
||||
"must_do":false,
|
||||
"n_tags":11,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"20":{
|
||||
"name":"Église Orthodoxe Saint-Séraphin de Sarov",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8426176,
|
||||
2.3045363
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":80237345,
|
||||
"attractiveness":7,
|
||||
"must_do":false,
|
||||
"n_tags":11,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"21":{
|
||||
"name":"Fontaine des quatre évêques",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.85087,
|
||||
2.3332776
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":40068036,
|
||||
"attractiveness":8,
|
||||
"must_do":false,
|
||||
"n_tags":8,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"22":{
|
||||
"name":"La fontaine de la Vierge",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8525605,
|
||||
2.3513841
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":948654101,
|
||||
"attractiveness":6,
|
||||
"must_do":false,
|
||||
"n_tags":6,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"23":{
|
||||
"name":"Square Jean Chérioux",
|
||||
"type":{
|
||||
"landmark_type":"nature"
|
||||
},
|
||||
"location":[
|
||||
48.8401918,
|
||||
2.3006179
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":14334838,
|
||||
"attractiveness":9,
|
||||
"must_do":false,
|
||||
"n_tags":5,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"24":{
|
||||
"name":"Église Saint-Germain des Prés",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8539667,
|
||||
2.334463
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":62287173,
|
||||
"attractiveness":12,
|
||||
"must_do":false,
|
||||
"n_tags":21,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"25":{
|
||||
"name":"Square de la Tour Saint-Jacques",
|
||||
"type":{
|
||||
"landmark_type":"nature"
|
||||
@ -399,7 +415,7 @@
|
||||
"n_tags":12,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"25":{
|
||||
"26":{
|
||||
"name":"Square Jean XXIII",
|
||||
"type":{
|
||||
"landmark_type":"nature"
|
||||
@ -415,52 +431,36 @@
|
||||
"n_tags":15,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"26":{
|
||||
"name":"Jardinet place du lieutenant Henri-Karcher",
|
||||
"type":{
|
||||
"landmark_type":"nature"
|
||||
},
|
||||
"location":[
|
||||
48.8632971,
|
||||
2.3399434
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":53826866,
|
||||
"attractiveness":8,
|
||||
"must_do":false,
|
||||
"n_tags":5,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"27":{
|
||||
"name":"Square de l'Abbé Esquerré",
|
||||
"name":"Square Félix Desruelles",
|
||||
"type":{
|
||||
"landmark_type":"nature"
|
||||
},
|
||||
"location":[
|
||||
48.8503173,
|
||||
2.3136601
|
||||
48.8536974,
|
||||
2.3345069
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":103344111,
|
||||
"attractiveness":11,
|
||||
"osm_id":62287123,
|
||||
"attractiveness":12,
|
||||
"must_do":false,
|
||||
"n_tags":7,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"28":{
|
||||
"name":"Jardin Nelson Mandela",
|
||||
"name":"Jardin des Rosiers – Joseph-Migneret",
|
||||
"type":{
|
||||
"landmark_type":"nature"
|
||||
},
|
||||
"location":[
|
||||
48.8626235,
|
||||
2.344487
|
||||
48.8572946,
|
||||
2.3602516
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":159103475,
|
||||
"attractiveness":23,
|
||||
"osm_id":365878540,
|
||||
"attractiveness":14,
|
||||
"must_do":false,
|
||||
"n_tags":15,
|
||||
"n_tags":8,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"29":{
|
||||
|
Loading…
x
Reference in New Issue
Block a user