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
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'
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