def __init__(self, gis_polygon_list=None, grow_regions=False, neighbor_method='coordinates'): self.__grow_regions = grow_regions self.__point2polygon = np.zeros(0, dtype=np.uint16) self.__polygon2points = [] self.__polygon2gis = [] self.__all_points = np.zeros([0, 2]) self.__next_polygon_id_to_add = 0 self.__tree_synced = False self.__polygons = [] self.__polygon2region = {} self.__centroids = [] if gis_polygon_list is not None: timer = Stopwatch() print("\n==== CREATING POLYGON TREE OF {} POLYGONS ===".format( len(gis_polygon_list))) timer.start("Extracting all points from all polygons") for polygon in gis_polygon_list: self.add_polygon(polygon) timer.stop_latest() self.create_necessary_datastructures()
def find_intersecting(self, polygon: Polygon, overlap_thresh=0.9, rectangle_mode=True, output_crossers=False): MIN_HOUSE_DISTANCE = 0.2 POLYGON_OVERLAP_THRESH = overlap_thresh #returns all ids of polygons that in someway intersects input polygon timer = Stopwatch() if not self.__tree_synced: self.create_necessary_datastructures() self.__tree_synced = True print("\n==== FIND INTERSECTION ===") timer.start("Finding smallest enclosing circle") #Circle C around P circle = sec.make_circle(list(polygon.exterior.coords)) center = circle[0:2] radius = circle[2] timer.stop_latest() timer.start("Searching points within circle in kd-tree") #FInd points in C point_ids = np.array(self.__tree.query_ball_point(center, radius)) points = self.__all_points[point_ids] timer.stop_latest() print("Points found: {}".format(len(points))) #Exlude points not in P timer.start("Determining which points are inside polygon") if rectangle_mode: mask = ulpy.points_in_rectangle(points, polygon) else: mask = np.array([polygon.intersects(Point(x)) for x in points]) point_ids_in = point_ids[mask] timer.stop_latest() print("Points remaining {} ".format(len(points))) #Find polygons belonging to points polygon_ids, counts = np.unique(self.__point2polygon[point_ids_in], return_counts=True) #Only choose polygons that are very much inside the search polygon polygon_id_relevance = self.polygon_coverage(polygon_ids, polygon) top_dog_polygon_ids = polygon_ids[ polygon_id_relevance > POLYGON_OVERLAP_THRESH] questionable_polygon_ids = polygon_ids[ polygon_id_relevance <= POLYGON_OVERLAP_THRESH] if output_crossers: return top_dog_polygon_ids, questionable_polygon_ids else: return top_dog_polygon_ids
def create_necessary_datastructures(self): N_NEIGHBOURS = 12 timer = Stopwatch() timer.start("Creating kd-tree") self.__tree = cKDTree(self.__all_points) self.__tree_synced = True timer.stop_latest() timer.start("Creating neighbour tree") self.__nbr_tree = NearestNeighbors(n_neighbors=N_NEIGHBOURS, algorithm='ball_tree').fit( self.__all_points) self.__nbr_distances, self.__nbr_indices = self.__nbr_tree.kneighbors( self.__all_points) timer.stop_latest() if self.__grow_regions: self.__regions = self.grow_regions()
def get_points_from_polygon(self, polygon: Polygon, rectangle_mode=False): timer = Stopwatch() if type(polygon) != type(Polygon): TypeError("polygon has to be shapely Polygon") point_temp = np.array(list(polygon.exterior.coords)) print("\n==== SEARCHING FOR POINTS IN POLYGON ({} POINTS) ===".format( point_temp.shape[0])) timer.start("Finding smallest enclosing circle") circle = sec.make_circle(list(polygon.exterior.coords)) center = circle[0:2] radius = circle[2] timer.stop_latest() str = "Finding points in {} sub-trees".format(len(self.__trees)) timer.start(str) points = np.zeros([0, 3]) for i in range(0, len(self.__trees)): ids = self.__trees[i].query_ball_point(center, radius + 5) points_temp = [self.__point_data[i][k] for k in ids] points = np.vstack([points, self.__point_data[i][ids]]) timer.stop_latest() print("Found {} points".format(len(points))) z_range = (points[:, 2].min(), points[:, 2].max()) timer.start("Determining which points are inside polygon") #points[:] = [x for x in points if polygon.intersects(Point(x))] if rectangle_mode: mask = ulpy.points_in_rectangle(points[:, 0:2], polygon) else: mask = np.array([polygon.intersects(Point(x)) for x in points]) points_in = points[mask] points_out = points[mask == False] timer.stop_latest() print("Now only {} points remain".format(len(points_in))) #print(np.array(points)) return points_in, points_out, z_range
def main(): for path in sys.path: path = path.encode('UTF-8') print(path) plotter = PlotAnimator() timer = Stopwatch() a_polygon = generateLetterPolygon('A') points = generateTestDataFromPolygon(a_polygon) plotter.add_point_data(points) plotter.show() plotter.draw_all_points() timer.start("Santos fixar hull") hull = csh.concaveHull(points, 20) timer.stop_latest() plotter.draw_extra_edges(np.array(hull)) print(hull) x = 0
def intersects(self, polygon: Polygon): MIN_HOUSE_DISTANCE = 0.2 POLYGON_OVERLAP_THRESH = 0.9 #returns all ids of polygons that in someway intersects input polygon timer = Stopwatch() if not self.__tree_synced: self.create_necessary_datastructures() self.__tree_synced = True print("\n==== SEARCHING POLYGON INTERSECTION ===") timer.start("Finding smallest enclosing circle") #Circle C around P circle = sec.make_circle(list(polygon.exterior.coords)) center = circle[0:2] radius = circle[2] timer.stop_latest() timer.start("Searching points within circle in kd-tree") #FInd points in C point_ids = np.array(self.__tree.query_ball_point(center, radius)) points = self.__all_points[point_ids] timer.stop_latest() print("Found {} points".format(len(points))) timer.start("Determining which points are inside polygon") #Exlude points not in P mask = np.array([polygon.intersects(Point(x)) for x in points]) point_ids_in = point_ids[mask] print("\npoint ids in:") print(point_ids_in) timer.stop_latest() print("\npolygon ids in:") print(self.__point2polygon[point_ids_in]) #Find polygons belonging to points polygon_ids, counts = np.unique(self.__point2polygon[point_ids_in], return_counts=True) print("\nunique ids :") print(polygon_ids) print("\ncounts :") print(counts) #Circle around those points circle = sec.make_circle(self.get_polygon_points(polygon_ids)) center = circle[0:2] radius = circle[2] point_ids_2 = np.array(self.__tree.query_ball_point(center, radius)) polygon_ids_2, counts_2 = np.unique(self.__point2polygon[point_ids_2], return_counts=True) print("\npolygon ids 2:") print(self.__point2polygon[point_ids_2]) print("\nunique ids 2 :") print(polygon_ids_2) print("\ncounts 2 :") print(counts_2) #points = self.__all_points[point_ids_2] polygon_id_relevance = self.polygon_coverage(polygon_ids_2, polygon) print("\ninsideness :") print(polygon_id_relevance) top_dog_polygon_ids = polygon_ids_2[ polygon_id_relevance > POLYGON_OVERLAP_THRESH] print("\ntop polygon ids :") print(top_dog_polygon_ids) other_dog_polygon_ids = np.setdiff1d(polygon_ids_2, top_dog_polygon_ids) final_polygon_ids = top_dog_polygon_ids print("\nother polygon ids :") print(other_dog_polygon_ids) for tp in top_dog_polygon_ids: top_polygon = self.get_polygon(tp) for op in other_dog_polygon_ids: other_polygon = self.get_polygon(op) intersects = top_polygon.intersects( other_polygon.buffer(MIN_HOUSE_DISTANCE)) print("{} intersects {}: \t{}".format(tp, op, intersects)) if intersects: final_polygon_ids = np.append(final_polygon_ids, op) print("\nfinal polygon ids :") final_polygon_ids = np.unique(final_polygon_ids) print(final_polygon_ids) return final_polygon_ids
def algorithm(point_data): timer = Stopwatch() plotter = PlotAnimator() #1. PARAMETERS THRESHOLD = 3 SAMPLE_DIST = 2 N_NEIGHBOURS = 14 #2. INITIALIZE #2.1 Convex Hull & Edge Neighbors & kdTree n_points = point_data.shape[0] hull = ConvexHull(point_data) convex_list = make_convex_list(hull.vertices) #contains point pairs concave_list = list(convex_list) nrbs = EdgeNeighbors(convex_list) kd_tree = cKDTree(point_data) point_ids = set(np.arange(point_data.shape[0])) inner_point_ids = point_ids - set(np.array(convex_list).flatten()) plotter.add_point_data(point_data) plotter.draw_all_points() #plotter.draw_extra_points(sample_points,PointStyle.LOWLIGHT) plotter.show() plotter.edge_multi(convex_list, EdgeStyle.NORMAL) DEBUG = False print("\nPoint data: ") for i, point in enumerate(point_data): print("{}: {}".format(i, point)) print("\nConvex list:\n {}".format(convex_list)) #1. Digging convex #input("FFS") n_starting_edges = hull.simplices.shape[0] print("Nr of starting edges: {}".format(n_starting_edges)) stopwatch = AdvancedStopWatch(7, [ 'Nearest inne point', 'Calculations', 'Split and remove', 'Remove deleted' ]) stopwatch.start_total() counter = 0 current_egde_id = 0 while current_egde_id < len(concave_list) and counter < 100000: counter = counter + 1 edge_point_ids = concave_list[ current_egde_id] #get point ids of current edge edge_points = point_data[edge_point_ids] # the actual coordinates #DEBUG if current_egde_id == 6: #DEBUG = False pass print('Round {}/{}: [{} & {}]'.format(current_egde_id, len(concave_list), edge_point_ids[0], edge_point_ids[1])) sample_points = sample_edge(edge_points[0, :], edge_points[1, :], SAMPLE_DIST) nbr_ids = set() for p in sample_points: nbr_ids.update(set(kd_tree.query_ball_point(p, SAMPLE_DIST * 2))) if DEBUG: #plotter.draw_extra_points(sample_points,PointStyle.LOWLIGHT) plotter.edge_multi(concave_list, EdgeStyle.DEACTIVATED) plotter.point_multi(nbr_ids, PointStyle.HIGHLIGHT) nbr_ids.discard(edge_point_ids[0]) nbr_ids.discard(edge_point_ids[1]) nbr_ids.intersection_update(inner_point_ids) print("\tPotential pk: {}".format(nbr_ids)) #find the nearest inner point from the current edge neighbor_edge_1 = concave_list[nrbs.get_predecessor(current_egde_id)] neighbor_edge_2 = concave_list[nrbs.get_successor(current_egde_id)] stopwatch.start_lap('Nearest inne point') pk_id, pk_dist = find_nearest_inner_point_not_closer_to_neighbor_edges( point_data, nbr_ids, edge_points, neighbor_edge_1, neighbor_edge_2) stopwatch.stop_lap('Nearest inne point') if pk_id == -1: print("\t => TRUE NEIGHBOR TROUBLE! Done with this edge") current_egde_id = current_egde_id + 1 if DEBUG: plotter.reset_all_points() plotter.delete_all_edges() continue pk = point_data[pk_id] stopwatch.start_lap('Calculations') edge_length = np.linalg.norm(edge_points[0] - edge_points[1]) dd = decision_distance(pk, edge_points) #distance_pk_edge = point_to_edge_distance(point value_to_compare = edge_length / dd stopwatch.stop_lap('Calculations') if DEBUG: print("\tDistance to pk: {}".format(pk_dist)) print("\tEdge length (eh): {}".format(edge_length)) print("\tDecision distance (dd): {}".format(dd)) print("\tValue to compare: {}".format(value_to_compare)) plotter.edge(edge_point_ids, EdgeStyle.CHOSEN) plotter.edge(neighbor_edge_1, EdgeStyle.LOWLIGHT) plotter.edge(neighbor_edge_2, EdgeStyle.LOWLIGHT) plotter.point(pk_id, PointStyle.CHOSEN) input("\t...enter to proceed....") if value_to_compare > THRESHOLD: stopwatch.start_lap('Split and remove') #Split and remove concave_list.append( np.array([edge_point_ids[0], pk_id], dtype=np.int32)) concave_list.append( np.array([pk_id, edge_point_ids[1]], dtype=np.int32)) nrbs.replace_edge_with_two_new(current_egde_id, len(concave_list) - 2, len(concave_list) - 1) concave_list[current_egde_id] = np.array([-1, -1]) inner_point_ids.remove(pk_id) stopwatch.stop_lap('Split and remove') if DEBUG: print("\t => Split and remove!") #plotter.delete_edge(edge_point_ids) #plotter.edge(concave_list[-1],EdgeStyle.NORMAL) #plotter.edge(concave_list[-2],EdgeStyle.NORMAL) else: #Save edge and move on print("\t => Done with this edge") #pass if DEBUG: #plotter.delete_edge(neighbor_edge_1) #plotter.delete_edge(neighbor_edge_2) plotter.reset_all_points() plotter.delete_all_edges() current_egde_id = current_egde_id + 1 stopwatch.start_lap('Remove deleted') concave_list_2 = [pair for pair in concave_list if pair[0] != -1] stopwatch.stop_lap('Remove deleted') stopwatch.stop_total() stopwatch.print_timers() plotter.edge_multi(concave_list_2, EdgeStyle.LOWLIGHT) return concave_list_2
def make_kdtree(self, ids, current_lod, n_trees): timer = Stopwatch() point_data = None n_iterations = len(ids) dataset_file_name = "{}_{}_{}_{}{}.npy".format( self.__file_creation_year, self.__file_creation_day_of_year, self.__nr_of_point_records, n_trees, current_lod) my_file = Path(dataset_file_name) if my_file.is_file(): #file exists! Praise the lauwd!!!! timer.start("Reading point data from file") point_data = np.load(dataset_file_name) timer.stop_latest() else: #file does not exist #Open file and discard header f = open(self.__file_path, "rb") f.seek(self.__offset_to_point_data) #Read points from file timer.start("Reading all {} points from file".format( self.__nr_of_point_records)) all_data = array.array('i') all_data.fromfile(f, self.__nr_of_point_records * 7) timer.stop_latest() #Move to list (version 3) timer.start("Moving {} data points to a list".format(n_iterations)) offset = np.array([ self.__XYZ_offset[0], self.__XYZ_offset[1], self.__XYZ_offset[2] ]) scale_factor = np.array([ self.__XYZ_scale_factor[0], self.__XYZ_scale_factor[1], self.__XYZ_scale_factor[2] ]) raw_points = np.array([(all_data[id], all_data[id + 1], all_data[id + 2]) for id in ids]) print("Scale factor: {}".format(scale_factor)) print("Offset: {}".format(offset)) point_data = raw_points[:, :] * scale_factor + offset timer.stop_latest() #Save points to file timer.start("Saving point data to file") np.save(dataset_file_name, point_data) timer.stop_latest() xy_point_data = point_data[:, 0:2] #Create KDTree timer.start("Creating kd-tree with {} points".format(n_iterations)) tree = cKDTree(xy_point_data, leafsize=24, compact_nodes=False, balanced_tree=False) timer.stop_latest() #timer.start("Re-arranging data") #for i in range(n_iterations): # point_data[i].append(z_vals[i]) #timer.stop_latest() #print("Nr of points in tree: ",tree.n) return tree, point_data