Compare commits
	
		
			2 Commits
		
	
	
		
			9002483036
			...
			84e5902436
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 84e5902436 | |||
| 81330e5eb3 | 
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -130,11 +130,12 @@ def new_trip(preferences: Preferences,
 | 
			
		||||
    logger.debug(f'First stage optimization\t: {round(t_first_stage,3)} seconds')
 | 
			
		||||
    logger.debug(f'Second stage optimization\t: {round(t_second_stage,3)} seconds')
 | 
			
		||||
    logger.info(f'Total computation time\t: {round(t_first_stage + t_second_stage,3)} seconds')
 | 
			
		||||
 | 
			
		||||
    linked_tour = LinkedLandmarks(refined_tour)
 | 
			
		||||
 | 
			
		||||
    # upon creation of the trip, persistence of both the trip and its landmarks is ensured.
 | 
			
		||||
    trip = Trip.from_linked_landmarks(linked_tour, cache_client)
 | 
			
		||||
    logger.info(f'Generated a trip of {trip.total_time} minutes with {len(refined_tour)} landmarks in {round(t_generate_landmarks + t_first_stage + t_second_stage,3)} seconds.')
 | 
			
		||||
    logger.debug('Detailed trip :\n\t' + '\n\t'.join(f'{landmark}' for landmark in refined_tour))
 | 
			
		||||
 | 
			
		||||
    background_tasks.add_task(fill_cache)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -594,7 +594,7 @@ class Optimizer:
 | 
			
		||||
        status = pl.LpStatus[prob.status]
 | 
			
		||||
        solution = [pl.value(var) for var in x]  # The values of the decision variables (will be 0 or 1)
 | 
			
		||||
 | 
			
		||||
        self.logger.debug("First results are out. Looking out for circles and correcting.")
 | 
			
		||||
        self.logger.debug("First results are out. Looking out for circles and correcting...")
 | 
			
		||||
 | 
			
		||||
        # Raise error if no solution is found. FIXME: for now this throws the internal server error
 | 
			
		||||
        if status != 'Optimal' :
 | 
			
		||||
 
 | 
			
		||||
@@ -52,7 +52,7 @@ class Overpass :
 | 
			
		||||
        # Retrieve cached data and identify missing cache entries
 | 
			
		||||
        cached_responses, non_cached_cells = self._retrieve_cached_data(overlapping_cells, osm_types, selector, conditions, out)
 | 
			
		||||
 | 
			
		||||
        self.logger.info(f'Cache hit for {len(overlapping_cells)-len(non_cached_cells)}/{len(overlapping_cells)} quadrants.')
 | 
			
		||||
        self.logger.debug(f'Cache hit for {len(overlapping_cells)-len(non_cached_cells)}/{len(overlapping_cells)} quadrants.')
 | 
			
		||||
 | 
			
		||||
        # If there is no missing data, return the cached responses after filtering.
 | 
			
		||||
        if not non_cached_cells :
 | 
			
		||||
@@ -61,6 +61,7 @@ class Overpass :
 | 
			
		||||
        # If there is no cached data, fetch all from Overpass.
 | 
			
		||||
        elif not cached_responses :
 | 
			
		||||
            query_str = Overpass.build_query(bbox, osm_types, selector, conditions, out)
 | 
			
		||||
            self.logger.debug(f'Query string: {query_str}')
 | 
			
		||||
            return self.fetch_data_from_api(query_str)
 | 
			
		||||
 | 
			
		||||
        # Hybrid cache: some data from Overpass, some data from cache.
 | 
			
		||||
@@ -68,6 +69,7 @@ class Overpass :
 | 
			
		||||
            # Resize the bbox for smaller search area and build new query string.
 | 
			
		||||
            non_cached_bbox = Overpass._get_non_cached_bbox(non_cached_cells, bbox)
 | 
			
		||||
            query_str = Overpass.build_query(non_cached_bbox, osm_types, selector, conditions, out)
 | 
			
		||||
            self.logger.debug(f'Query string: {query_str}')
 | 
			
		||||
            non_cached_responses = self.fetch_data_from_api(query_str)
 | 
			
		||||
            return Overpass._filter_landmarks(cached_responses, bbox) + non_cached_responses
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,11 @@
 | 
			
		||||
max_bbox_side: 4000   #m
 | 
			
		||||
radius_close_to: 50
 | 
			
		||||
church_coeff: 0.55
 | 
			
		||||
nature_coeff: 1.4
 | 
			
		||||
church_coeff: 0.75
 | 
			
		||||
nature_coeff: 1.6
 | 
			
		||||
overall_coeff: 10
 | 
			
		||||
tag_exponent: 1.15
 | 
			
		||||
image_bonus: 1.1
 | 
			
		||||
viewpoint_bonus: 5
 | 
			
		||||
viewpoint_bonus: 10
 | 
			
		||||
wikipedia_bonus: 1.25
 | 
			
		||||
name_bonus: 3
 | 
			
		||||
N_important: 60
 | 
			
		||||
pay_bonus: -1
 | 
			
		||||
 
 | 
			
		||||
@@ -5,5 +5,5 @@ max_landmarks: 10
 | 
			
		||||
max_landmarks_refiner: 20
 | 
			
		||||
overshoot: 0.0016
 | 
			
		||||
time_limit: 1
 | 
			
		||||
gap_rel: 0.05
 | 
			
		||||
gap_rel: 0.025
 | 
			
		||||
max_iter: 40
 | 
			
		||||
@@ -31,9 +31,9 @@ def test_turckheim(client, request):    # pylint: disable=redefined-outer-name
 | 
			
		||||
            "shopping": {"type": "shopping", "score": 0},
 | 
			
		||||
            "max_time_minute": duration_minutes,
 | 
			
		||||
            "detour_tolerance_minute": 0},
 | 
			
		||||
            # "start": [48.084588, 7.280405]
 | 
			
		||||
            "start": [48.084588, 7.280405]
 | 
			
		||||
            # "start": [45.74445023349939, 4.8222687890538865]
 | 
			
		||||
            "start": [45.75156398104873, 4.827154464827647]
 | 
			
		||||
            # "start": [45.75156398104873, 4.827154464827647]
 | 
			
		||||
            }
 | 
			
		||||
        )
 | 
			
		||||
    result = response.json()
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
"""Find clusters of interest to add more general areas of visit to the tour."""
 | 
			
		||||
import logging
 | 
			
		||||
from typing import Literal
 | 
			
		||||
from typing import Literal, Tuple
 | 
			
		||||
 | 
			
		||||
import numpy as np
 | 
			
		||||
from sklearn.cluster import DBSCAN
 | 
			
		||||
@@ -33,7 +33,7 @@ class Cluster(BaseModel):
 | 
			
		||||
    """
 | 
			
		||||
    type: Literal['street', 'area']
 | 
			
		||||
    importance: int
 | 
			
		||||
    centroid: tuple
 | 
			
		||||
    centroid: Tuple[float, float]
 | 
			
		||||
    # start: Optional[list] = None      # for later use if we want to have streets as well
 | 
			
		||||
    # end: Optional[list] = None
 | 
			
		||||
 | 
			
		||||
@@ -178,11 +178,12 @@ class ClusterManager:
 | 
			
		||||
 | 
			
		||||
            # Calculate the centroid as the mean of the points
 | 
			
		||||
            centroid = np.mean(current_cluster, axis=0)
 | 
			
		||||
            centroid = tuple((round(centroid[0], 7), round(centroid[1], 7)))
 | 
			
		||||
 | 
			
		||||
            if self.cluster_type == 'shopping' :
 | 
			
		||||
                score = len(current_cluster)*2
 | 
			
		||||
                score = len(current_cluster)*3
 | 
			
		||||
            else :
 | 
			
		||||
                score = len(current_cluster)*8
 | 
			
		||||
                score = len(current_cluster)*15
 | 
			
		||||
            locations.append(Cluster(
 | 
			
		||||
                type='area',
 | 
			
		||||
                centroid=centroid,
 | 
			
		||||
@@ -215,7 +216,7 @@ class ClusterManager:
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        # Define the bounding box for a given radius around the coordinates
 | 
			
		||||
        bbox = create_bbox(cluster.centroid, 1000)
 | 
			
		||||
        bbox = create_bbox(cluster.centroid, 300)
 | 
			
		||||
        
 | 
			
		||||
        # Query neighborhoods and shopping malls
 | 
			
		||||
        selectors = ['"place"~"^(suburb|neighborhood|neighbourhood|quarter|city_block)$"']
 | 
			
		||||
@@ -223,10 +224,10 @@ class ClusterManager:
 | 
			
		||||
        if self.cluster_type == 'shopping' :
 | 
			
		||||
            selectors.append('"shop"="mall"')
 | 
			
		||||
            new_name = 'Shopping Area'
 | 
			
		||||
            t = 40
 | 
			
		||||
            t = 30
 | 
			
		||||
        else :
 | 
			
		||||
            new_name = 'Neighborhood'
 | 
			
		||||
            t = 15
 | 
			
		||||
            t = 20
 | 
			
		||||
 | 
			
		||||
        min_dist = float('inf')
 | 
			
		||||
        osm_id = 0
 | 
			
		||||
@@ -238,7 +239,7 @@ class ClusterManager:
 | 
			
		||||
                result = self.overpass.send_query(bbox = bbox,
 | 
			
		||||
                                                  osm_types = osm_types,
 | 
			
		||||
                                                  selector = sel,
 | 
			
		||||
                                                  out = 'ids center'
 | 
			
		||||
                                                  out = 'ids center tags'
 | 
			
		||||
                                                  )
 | 
			
		||||
            except Exception as e:
 | 
			
		||||
                self.logger.error(f"Error fetching clusters: {e}")
 | 
			
		||||
@@ -259,9 +260,9 @@ class ClusterManager:
 | 
			
		||||
                d = get_distance(cluster.centroid, coords)
 | 
			
		||||
                if  d < min_dist :
 | 
			
		||||
                    min_dist = d
 | 
			
		||||
                    new_name = name
 | 
			
		||||
                    osm_type = osm_type     # Add type: 'way' or 'relation'
 | 
			
		||||
                    osm_id = id             # Add OSM id
 | 
			
		||||
                    new_name = name         # add name
 | 
			
		||||
                    osm_type = osm_type     # add type: 'way' or 'relation'
 | 
			
		||||
                    osm_id = id             # add OSM id
 | 
			
		||||
 | 
			
		||||
        return Landmark(
 | 
			
		||||
            name=new_name,
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,6 @@ class LandmarkManager:
 | 
			
		||||
            self.overall_coeff = parameters['overall_coeff']
 | 
			
		||||
            self.tag_exponent = parameters['tag_exponent']
 | 
			
		||||
            self.image_bonus = parameters['image_bonus']
 | 
			
		||||
            self.name_bonus = parameters['name_bonus']
 | 
			
		||||
            self.wikipedia_bonus = parameters['wikipedia_bonus']
 | 
			
		||||
            self.viewpoint_bonus = parameters['viewpoint_bonus']
 | 
			
		||||
            self.pay_bonus = parameters['pay_bonus']
 | 
			
		||||
@@ -147,6 +146,8 @@ class LandmarkManager:
 | 
			
		||||
            score *= self.wikipedia_bonus
 | 
			
		||||
        if landmark.is_place_of_worship :
 | 
			
		||||
            score *= self.church_coeff
 | 
			
		||||
        if landmark.is_viewpoint :
 | 
			
		||||
            score *= self.viewpoint_bonus
 | 
			
		||||
        if landmarktype == 'nature' :
 | 
			
		||||
            score *= self.nature_coeff
 | 
			
		||||
 | 
			
		||||
@@ -201,7 +202,7 @@ class LandmarkManager:
 | 
			
		||||
 | 
			
		||||
            return_list += self._to_landmarks(result, landmarktype, preference_level)
 | 
			
		||||
 | 
			
		||||
        self.logger.debug(f"Fetched {len(return_list)} landmarks of type {landmarktype} in {bbox}")
 | 
			
		||||
        # self.logger.debug(f"Fetched {len(return_list)} landmarks of type {landmarktype} in {bbox}")
 | 
			
		||||
 | 
			
		||||
        return return_list
 | 
			
		||||
 | 
			
		||||
@@ -267,7 +268,7 @@ class LandmarkManager:
 | 
			
		||||
                    landmark.image_url = value
 | 
			
		||||
                if key == 'website' :
 | 
			
		||||
                    landmark.website_url = value
 | 
			
		||||
                if key == 'place_of_worship' :
 | 
			
		||||
                if value == 'place_of_worship' :
 | 
			
		||||
                    landmark.is_place_of_worship = True
 | 
			
		||||
                if key == 'wikipedia' :
 | 
			
		||||
                    landmark.wiki_url = value
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user