53 lines
2.1 KiB
Python
53 lines
2.1 KiB
Python
from typing import Optional, Literal
|
|
from pydantic import BaseModel, Field
|
|
|
|
from uuid import uuid4
|
|
|
|
# Output to frontend
|
|
class Landmark(BaseModel) :
|
|
|
|
# Properties of the landmark
|
|
name : str
|
|
type: Literal['sightseeing', 'nature', 'shopping', 'start', 'finish']
|
|
location : tuple
|
|
osm_type : str
|
|
osm_id : int
|
|
attractiveness : int
|
|
n_tags : int
|
|
image_url : Optional[str] = None
|
|
website_url : Optional[str] = None
|
|
description : Optional[str] = None # TODO future
|
|
duration : Optional[int] = 0
|
|
name_en : Optional[str] = None
|
|
|
|
# Unique ID of a given landmark
|
|
uuid: str = Field(default_factory=uuid4)
|
|
|
|
# Additional properties depending on specific tour
|
|
must_do : Optional[bool] = False
|
|
must_avoid : Optional[bool] = False
|
|
is_secondary : Optional[bool] = False # TODO future
|
|
|
|
time_to_reach_next : Optional[int] = 0
|
|
next_uuid : Optional[str] = None
|
|
|
|
def __str__(self) -> str:
|
|
time_to_next_str = f", time_to_next={self.time_to_reach_next}" if self.time_to_reach_next else ""
|
|
is_secondary_str = f", secondary" if self.is_secondary else ""
|
|
type_str = '(' + self.type + ')'
|
|
if self.type in ["start", "finish", "nature", "shopping"] : type_str += '\t '
|
|
return f'Landmark{type_str}: [{self.name} @{self.location}, score={self.attractiveness}{time_to_next_str}{is_secondary_str}]'
|
|
|
|
def distance(self, value: 'Landmark') -> float:
|
|
return (self.location[0] - value.location[0])**2 + (self.location[1] - value.location[1])**2
|
|
|
|
def __hash__(self) -> int:
|
|
return hash(self.name)
|
|
|
|
def __eq__(self, value: 'Landmark') -> bool:
|
|
# eq and hash must be consistent
|
|
# in particular, if two objects are equal, their hash must be equal
|
|
# uuid and osm_id are just shortcuts to avoid comparing all the properties
|
|
# if they are equal, we know that the name is also equal and in turn the hash is equal
|
|
return self.uuid == value.uuid or self.osm_id == value.osm_id or (self.name == value.name and self.distance(value) < 0.001)
|