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