Exemple #1
0
 def connect_with_nearest_street(self, poi_node, streets, projection_threshold):
     """ Tries to connect a selected point of interest with the nearest streets
     
     The method looks in a list of streets for the neareast street and connects the poi and this street.
     
     @type poi_node: L{geo.osm_import.Node}
     @param poi_node: the OSM Node object that shall be connected with the street network
     @param streets: list of L{geo.osm_import.Way} objects that are streets
     @param projection_threshold: distance in meters that a connection to the next node may be longer than a direct connection by projection
     @returns: True if the connection was successful, False otherwise
     @rtype: C{bool}
     """
     connected = False
     
     # connection fails if the street list is empty or None
     if not streets:
         return False
     
     nearest_street, street_distance, nearest_mode = get_nearest_street(poi_node, streets)
     
     
     # for explanation of the distance_mode see geo.geo_utils.__distance_point_to_line
     # connect to nearest node if no projection is possible
     if len(nearest_mode) == 1:
         connected = connect_by_node(self.__osm_object, poi_node, nearest_mode[0])
     else:
         nearest_node, node_distance = get_nearest_street_node(poi_node, [nearest_street])
         if node_distance - street_distance < projection_threshold:
             connected = connect_by_node(self.__osm_object, poi_node, nearest_node)
         else:
             connected = connect_by_projection(self.__osm_object, poi_node, nearest_street, nearest_mode)
     return connected        
Exemple #2
0
    def connect_by_building(self, poi_node, building, streets, projection_threshold, address_threshold):
        """ Tries to connect a selected point of interest via a building with the street network
        
        The method checks if the given node lies within a building. It extracts several properties of the building like entrances or the address and tries to connect the node with these parameters to the street network
        
        @type poi_node: L{geo.osm_import.Node}
        @param poi_node: the OSM Node object that shall be connected with the street network
        @type building: L{geo.osm_import.Way}
        @param building: OSM Way object that is a building
        @param streets: list of L{geo.osm_import.Way} objects that are streets
        @param projection_threshold: distance in meters that a connection to the next node may be longer than a direct connection by projection
        @param address_threshold: distance in meters that a connection to a street with a given name may be longer than a direct connection to the next street
        @returns: True if the connection was successful, False otherwise (i. e. the node doesn't lie within the building at all)
        @rtype: C{bool}
        """

        connected = False

        # do nothing if the 'building' isn't a building at all
        # or if the POI isn't inside the building
        if not (is_building(building) and is_inside_polygon(poi_node, building)):
            return False
        
        building_address = building.getTags().get('addr:street')
        building_entrance = get_building_entrance(building)
        poi_address = poi_node.getTags().get('addr:street')
       
        # connect the POI with the entrance if the building has an entrance
        if building_entrance:
            for entrance in building_entrance:
                connect_by_node(self.__osm_object, poi_node, entrance)
                entrance_address = entrance.getTags().get('addr:street')
                # choose the possible connection:
                #connect by entrance address or poi address or building address or directly with the next street 
                if entrance_address:
                    connected = self.connect_by_address(entrance, entrance_address, streets, projection_threshold, address_threshold)
                elif poi_address:
                    connected = self.connect_by_address(entrance, poi_address, streets, projection_threshold, address_threshold)
                elif building_address:
                    connected = self.connect_by_address(entrance, building_address, streets, projection_threshold, address_threshold)
                else:
                    connected = self.connect_with_nearest_street(entrance, streets, projection_threshold)
        
        # if no entrance was found choose the possible connection:
        # connect by poi address or building address or directly with the next street 
        elif poi_address:
            connected = self.connect_by_address(poi_node, poi_address, streets, projection_threshold, address_threshold)
        elif building_address:
            connected = self.connect_by_address(poi_node, building_address, streets, projection_threshold, address_threshold)
        else:
            connected = self.connect_with_nearest_street(poi_node, streets, projection_threshold)
        return connected
Exemple #3
0
    def connect_poi(self, poi_thresholds):
        """ Initializes the connection of the points of interests with the street network
        
        @param poi_thresholds: a dictionary containing search distance, projection threshold and address threshold { 'search':svalue, 'projection':pvalue, 'address':avalue }
        """
        search_threshold = int(poi_thresholds.get('search'))
        projection_threshold = int(poi_thresholds.get('projection'))
        address_threshold = int(poi_thresholds.get('address'))
        for poi_node in self.__poi_nodes:
            

            # do nothing if the poi is already part of the street network
            if self.is_street_node(poi_node):
                poi_node.set_poi(POI_CONNECTED)
                continue
            
            connected = False
            
            # extract the streets within the search distance
            streets = self.__osm_object.get_adjacent_streets(poi_node, search_threshold)
            
            if streets:
            
                # get the poi address
                poi_address = poi_node.getTags().get('addr:street')
                
                # extract the buildings within the search distance
                buildings = self.get_adjacent_buildings(poi_node, search_threshold)
                
                nearest_building, building_distance = self.get_nearest_building(poi_node, buildings)
                nearest_node, node_distance = get_nearest_street_node(poi_node, streets)
                
                # connect to the nearest node if there is already a street node with the same coordinates
                if have_same_coords(poi_node, nearest_node):
                    connected = connect_by_node(self.__osm_object, poi_node, nearest_node)
                
                # try to conenct in the following order:
                # by building, by street name, with the nearest street
                if not connected:
                    connected = self.connect_by_building(poi_node, nearest_building, streets, projection_threshold, address_threshold)
                if not connected and poi_address:
                    connected = self.connect_by_address(poi_node, poi_address, streets, projection_threshold, address_threshold)
                if not connected:
                    connected = self.connect_with_nearest_street(poi_node, streets, projection_threshold)
            
            # mark a successfully connected poi as connected
            if connected:
                poi_node.set_poi(POI_CONNECTED)
            if not connected:
                print 'nothing found'
                poi_node.set_poi(POI_NOT_CONNECTED)
        # TODO: remove debug message
        if DEBUG:
            print 'ende'
Exemple #4
0
    def connect_partition(self, partition_id, thresholds):
        """ Initializes the connection of a single partition given by its partition id with the street network
        
        @type partition_id: C{int}
        @param partition_id: partition id
        @param thresholds: a dictionary containing search distance, projection threshold, size threshold, connection threshold and distance threshold { 'search':svalue, 'projection':pvalue, 'size':sivalue, 'connection':cvalue, 'distance':dvalue }
        @returns: True if the partition was successfully connected with the street network
        @rtype: C{bool}
        """
        search_threshold = int(thresholds.get('search'))
        projection_threshold = int(thresholds.get('projection'))
        size_threshold = int(thresholds.get('size'))
        connection_threshold = int(thresholds.get('connection'))
        distance_threshold = int(thresholds.get('distance'))
        
        partition = self.__partitions.get(partition_id)
        
        if partition.partition_size_by_nodes() < size_threshold:
            self.remove_partition(partition)
            return True
        
        #nearest_street = None
        min_distance = 1e400
        #min_mode = None
        nearest_part_node = None
        
        nodes_and_distances = []
        
        new_partition_id = 0

        # saves the nodes that have already been connected to another partition
        connected_nodes = []
        
        for node in partition.nodes:
            streets = self.__osm_object.get_adjacent_streets(node, search_threshold)
            streets = self.filter_streets_by_partition(streets, partition_id)
            
            # TODO: remove debug message
            #if DEBUG:
            #    print node, get_nearest_street(node, streets)
            street, distance, mode = get_nearest_street(node, streets)
            
            if street:
                nodes_and_distances.append((distance, node, street))
                
        sorted_nodes_by_distances = sorted(nodes_and_distances)

        partition_connected = False

        connection_count = 0
        index = 0
        while connection_count < connection_threshold:
            
            if index >= len(sorted_nodes_by_distances):
                break
            
            connected = False
            min_distance, nearest_part_node, nearest_street = sorted_nodes_by_distances[index]
            index += 1
            
            ignore = False
            for connected_node in connected_nodes:
                az_f, az_b, distance = distance_points(nearest_part_node, connected_node)
                if distance < distance_threshold:
                    ignore = True
  
            if not ignore:
                
                nearest_street, dist, min_mode = get_nearest_street(nearest_part_node, [nearest_street])
                
                if len(min_mode) == 1:
                    connected = connect_by_node(self.__osm_object, nearest_part_node, min_mode[0])
                    if connected:
                        new_partition_id = min_mode[0].partition_id
                        partition.add_street(connected)
                else:
                    nearest_street_node, node_distance = get_nearest_street_node(nearest_part_node, [nearest_street])
                    if node_distance - min_distance < projection_threshold:
                        connected = connect_by_node(self.__osm_object, nearest_part_node, nearest_street_node)
                        if connected:
                            new_partition_id = nearest_street_node.partition_id
                            partition.add_street(connected)
                    else:
                        connected = connect_by_projection(self.__osm_object, nearest_part_node, nearest_street, min_mode)
                        if connected:
                            new_partition_id = nearest_street.partition_id
                            partition.add_street(connected)
                
                if connected:
                    connected_nodes.append(nearest_part_node)
                    connection_count += 1
                
                partition_connected = partition_connected or connected
            
        # merge the joined partitions to one partition
        if partition_connected:
            new_partition = self.__partitions.get(new_partition_id)
            # TODO: remove debug message
            if DEBUG:
                if new_partition == None:
                    print new_partition_id
                    print thresholds
            new_partition.append_partition(partition)
            del self.__partitions[partition_id]
            del partition
        return partition_connected