linting
Some checks failed
Build and deploy the backend to staging / Build and push image (pull_request) Successful in 2m22s
Run linting on the backend code / Build (pull_request) Successful in 43s
Run testing on the backend code / Build (pull_request) Failing after 2m23s
Build and deploy the backend to staging / Deploy to staging (pull_request) Successful in 24s
Some checks failed
Build and deploy the backend to staging / Build and push image (pull_request) Successful in 2m22s
Run linting on the backend code / Build (pull_request) Successful in 43s
Run testing on the backend code / Build (pull_request) Failing after 2m23s
Build and deploy the backend to staging / Deploy to staging (pull_request) Successful in 24s
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
"""Find clusters of interest to add more general areas of visit to the tour."""
|
||||
import logging
|
||||
from typing import Literal
|
||||
|
||||
@@ -38,11 +39,24 @@ class Cluster(BaseModel):
|
||||
|
||||
|
||||
class ClusterManager:
|
||||
"""
|
||||
A manager responsible for clustering points of interest, such as shops or historic sites,
|
||||
to identify areas worth visiting. It uses the DBSCAN algorithm to detect clusters
|
||||
based on a set of points retrieved from OpenStreetMap (OSM).
|
||||
|
||||
Attributes:
|
||||
logger (logging.Logger): Logger for capturing relevant events and errors.
|
||||
valid (bool): Indicates whether clusters were successfully identified.
|
||||
all_points (list): All points retrieved from OSM, representing locations of interest.
|
||||
cluster_points (list): Points identified as part of a cluster.
|
||||
cluster_labels (list): Labels corresponding to the clusters each point belongs to.
|
||||
cluster_type (Literal['sightseeing', 'shopping']): Type of clustering, either for sightseeing
|
||||
landmarks or shopping areas.
|
||||
"""
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# NOTE: all points are in (lat, lon) format
|
||||
valid: bool # Ensure the manager is valid (ie there are some clusters to be found)
|
||||
valid: bool # Ensure the manager is valid (ie there are some clusters to be found)
|
||||
all_points: list
|
||||
cluster_points: list
|
||||
cluster_labels: list
|
||||
@@ -65,8 +79,6 @@ class ClusterManager:
|
||||
Args:
|
||||
bbox: The bounding box coordinates (around:radius, center_lat, center_lon).
|
||||
"""
|
||||
|
||||
# Initialize overpass and cache
|
||||
self.overpass = Overpass()
|
||||
CachingStrategy.use(JSON, cacheDir=OSM_CACHE_DIR)
|
||||
|
||||
@@ -96,7 +108,7 @@ class ClusterManager:
|
||||
|
||||
if len(result.elements()) == 0 :
|
||||
self.valid = False
|
||||
|
||||
|
||||
else :
|
||||
points = []
|
||||
for elem in result.elements() :
|
||||
@@ -126,8 +138,8 @@ class ClusterManager:
|
||||
self.filter_clusters() # ValueError here sometimes. I dont know why. # Filter the clusters to keep only the largest ones.
|
||||
self.valid = True
|
||||
|
||||
else :
|
||||
self.valid = False
|
||||
else :
|
||||
self.valid = False
|
||||
|
||||
|
||||
def generate_clusters(self) -> list[Landmark]:
|
||||
@@ -155,7 +167,7 @@ class ClusterManager:
|
||||
|
||||
# Extract points belonging to the current cluster
|
||||
current_cluster = self.cluster_points[self.cluster_labels == label]
|
||||
|
||||
|
||||
# Calculate the centroid as the mean of the points
|
||||
centroid = np.mean(current_cluster, axis=0)
|
||||
|
||||
@@ -205,7 +217,7 @@ class ClusterManager:
|
||||
selectors.append('"shop"="mall"')
|
||||
new_name = 'Shopping Area'
|
||||
t = 40
|
||||
else :
|
||||
else :
|
||||
new_name = 'Neighborhood'
|
||||
t = 15
|
||||
|
||||
@@ -214,7 +226,7 @@ class ClusterManager:
|
||||
osm_id = 0
|
||||
osm_type = 'node'
|
||||
|
||||
for sel in selectors :
|
||||
for sel in selectors :
|
||||
query = overpassQueryBuilder(
|
||||
bbox = bbox,
|
||||
elementType = ['node', 'way', 'relation'],
|
||||
@@ -233,11 +245,11 @@ class ClusterManager:
|
||||
location = (elem.centerLat(), elem.centerLon())
|
||||
|
||||
# Skip if element has neither name or location
|
||||
if elem.tag('name') is None :
|
||||
if elem.tag('name') is None :
|
||||
continue
|
||||
if location[0] is None :
|
||||
if location[0] is None :
|
||||
location = (elem.lat(), elem.lon())
|
||||
if location[0] is None :
|
||||
if location[0] is None :
|
||||
continue
|
||||
|
||||
d = get_distance(cluster.centroid, location)
|
||||
@@ -245,14 +257,14 @@ class ClusterManager:
|
||||
min_dist = d
|
||||
new_name = elem.tag('name')
|
||||
osm_type = elem.type() # Add type: 'way' or 'relation'
|
||||
osm_id = elem.id() # Add OSM id
|
||||
osm_id = elem.id() # Add OSM id
|
||||
|
||||
# Add english name if it exists
|
||||
try :
|
||||
new_name_en = elem.tag('name:en')
|
||||
except:
|
||||
pass
|
||||
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return Landmark(
|
||||
name=new_name,
|
||||
type=self.cluster_type,
|
||||
@@ -290,4 +302,3 @@ class ClusterManager:
|
||||
# update the cluster points and labels with the filtered data
|
||||
self.cluster_points = np.vstack(filtered_cluster_points) # ValueError here
|
||||
self.cluster_labels = np.concatenate(filtered_cluster_labels)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user