def connect_by_address(self, poi_node, address, streets, projection_threshold, address_threshold): """ Tries to connect a selected point of interest to a street with a given name @type poi_node: L{geo.osm_import.Node} @param poi_node: the OSM Node object that shall be connected with the street network @param address: The street name @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 @rtype: C{bool} """ connected = False named_streets = self.get_street_by_name(address, streets) if named_streets: address_street, address_distance, address_mode = get_nearest_street(poi_node, named_streets) nearest_street, nearest_distance, nearest_mode = get_nearest_street(poi_node, streets) # decide based on the address_threshold whether the poi is connected to the named street or the next street if address_distance - nearest_distance < address_threshold: connected = self.connect_with_nearest_street(poi_node, named_streets, projection_threshold) else: connected = self.connect_with_nearest_street(poi_node, streets, projection_threshold) # if no street with the given address is found connect to the nearest street else: connected = self.connect_with_nearest_street(poi_node, streets, projection_threshold) return connected
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_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