fixed duplicate landmarks
All checks were successful
Build and push docker image / Build (pull_request) Successful in 3m4s
Build and release APK / Build APK (pull_request) Successful in 5m44s
Build web / Build Web (pull_request) Successful in 2m14s

This commit is contained in:
Kilian Scheidecker 2024-06-10 22:52:08 +02:00
parent adbb6466d9
commit 53a5a9e873
4 changed files with 81 additions and 12 deletions

View File

@ -9,9 +9,12 @@ from typing import Tuple
BBOX_SIDE = 10 # size of bbox in *km* for general area, 10km
RADIUS_CLOSE_TO = 25 # size of area in *m* for close features, 5àm radius
MIN_SCORE = 30 # discard elements with score < 100
MIN_TAGS = 5 # discard elements withs less than 5 tags
RADIUS_CLOSE_TO = 25 # size of area in *m* for close features, 25m radius
MIN_SCORE = 30 # DEPRECIATED. discard elements with score < 30
MIN_TAGS = 5 # DEPRECIATED. discard elements withs less than 5 tags
CHURCH_PENALTY = 0.1 # penalty to reduce score of curches
PARK_COEFF = 10 # multiplier for parks
N_IMPORTANT = 30 # take the 30 most important landmarks
SIGHTSEEING = LandmarkType(landmark_type='sightseeing')
NATURE = LandmarkType(landmark_type='nature')
@ -71,7 +74,8 @@ def generate_landmarks(preferences: Preferences, city_country: str = None, coord
L += L3
return L, cleanup_list(L)
return L, take_most_important(L)
#return L, cleanup_list(L)
# Determines if two locations are close to each other
def is_close_to(loc1: Tuple[float, float], loc2: Tuple[float, float])->bool :
@ -82,6 +86,45 @@ def is_close_to(loc1: Tuple[float, float], loc2: Tuple[float, float])->bool :
else :
return False
def take_most_important(L: List[Landmark])->List[Landmark] :
L_copy = []
L_clean = []
scores = [0]*len(L)
names = []
name_id = {}
for i, elem in enumerate(L) :
if elem.name not in names :
names.append(elem.name)
name_id[elem.name] = [i]
L_copy.append(elem)
else :
name_id[elem.name] += [i]
scores = []
for j in name_id[elem.name] :
scores.append(L[j].attractiveness)
best_id = max(range(len(scores)), key=scores.__getitem__)
t = name_id[elem.name][best_id]
if t == i :
for old in L_copy :
if old.name == elem.name :
old.attractiveness = L[t].attractiveness
continue
for i, elem in enumerate(L_copy) :
scores[i] = elem.attractiveness
res = sorted(range(len(scores)), key = lambda sub: scores[sub])[-N_IMPORTANT:]
for i, elem in enumerate(L_copy) :
if i in res :
L_clean.append(elem)
return L_clean
# Remove duplicate elements and elements with low score
def cleanup_list(L: List[Landmark])->List[Landmark] :
L_clean = []
@ -207,6 +250,11 @@ def get_landmarks_coords(coordinates: Tuple[float, float], l: List[Landmark], la
# 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
else :
osm_type = elem.type() # Add type : 'way' or 'relation'
@ -214,8 +262,16 @@ def get_landmarks_coords(coordinates: Tuple[float, float], l: List[Landmark], la
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
score = count_elements_within_radius(location)
# 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)*CHURCH_PENALTY)
elif amenity == "'leisure'='park'" :
score = int(count_elements_within_radius(location)*PARK_COEFF)
else :
score = count_elements_within_radius(location)
if name == "Jardin du Luxembourg" :
continue
if score is not None :
# Generate the landmark and append it to the list
@ -247,6 +303,11 @@ def get_landmarks_nominatim(city_country: str, l: List[Landmark], landmarktype:
# 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
else :
osm_type = elem.type() # Add type : 'way' or 'relation'
@ -255,7 +316,11 @@ def get_landmarks_nominatim(city_country: str, l: List[Landmark], landmarktype:
n_tags = len(elem.tags().keys()) # Add number of tags
# Add score of given landmark based on the number of surrounding elements
score = count_elements_within_radius(location)
if amenity == "'amenity'='place_of_worship'" :
score = int(count_elements_within_radius(location)*CHURCH_PENALTY)
else :
score = count_elements_within_radius(location)
if score is not None :
# Generate the landmark and append it to the list

View File

@ -498,14 +498,15 @@ def solve_optimization (landmarks, max_steps, printing_details) :
print(i)
i += 1
t, order, [] = is_connected(res.x, landmarks)
if printing_details is True :
if i != 0 :
print(f"Neded to recompute paths {i} times because of unconnected loops...")
t, order, [] = is_connected(res.x, landmarks)
X = print_res(res, order, landmarks, P)
return X
else :
return untangle(res.x)
print_res(res, order, landmarks, P)
return order

View File

@ -1,3 +1,4 @@
from typing import Optional
from pydantic import BaseModel
from OSMPythonTools.api import Api
from .landmarktype import LandmarkType
@ -18,5 +19,6 @@ class Landmark(BaseModel) :
attractiveness : int
must_do : bool
n_tags : int
time_to_reach : Optional[int] = 0

View File

@ -82,6 +82,7 @@ def test4(coordinates: tuple[float, float]) -> List[Landmark]:
test.append(finish)
test.insert(0, start)
max_walking_time = 4 # hours
visiting_order = solve_optimization(test, max_walking_time*60, True)