def str_tree(geometries): """Add ids to geometries and create a STR tree for spatial indexing. Use this for all spatial operations! """ for i in geometries.index: geometries[i].id = i try: tree = STRtree(geometries) except AttributeError: tree = STRtree(geometries) return tree
def get_STRtrees(network_file, talus_file): network = fiona.open(network_file, 'r') talus = fiona.open(talus_file, 'r') print("building tree for network of size", len(network)) nlines = [shape(l['geometry']) for l in network] ntree = STRtree(nlines) print("tree built --------------------------") network.close() print(f"building tree for {len(talus)} talus") tlines = [shape(t['geometry']) for t in talus] ttree = STRtree(tlines) print("tree built --------------------------") talus.close() return ntree, ttree
def get_road_rtree(shp_path): ''' 获得道路rtree,coord->feature字典 Parameters: ----------- shp_path : str 道路文件名 ''' c = fiona.open(shp_path) coord_feature_dict = {} geom_list = [] for feature in c: geometry = feature['geometry'] geom = shape(geometry) geom_list.append(geom) coord_key = geom.coords[0] + geom.coords[-1] assert(coord_key not in coord_feature_dict) coord_feature_dict[coord_key] = feature c.close() rtree = STRtree(geom_list) return rtree, coord_feature_dict
def _calculate_grid(self, cell_size, fake=False): key = "%.2f" % cell_size if fake: key = "fake_" + key # Get extent x_min, y_min, x_max, y_max = self.get_extent(cell_size, fake=fake) # Create the bins bins_y = np.arange(y_min, y_max, cell_size) bins_x = np.arange(x_min, x_max, cell_size) bin_area = cell_size * cell_size shape = (len(bins_y), len(bins_x)) # Create the grid self.rasterizations[key] = np.zeros(shape, dtype=object) for v, y in enumerate(bins_y): for u, x in enumerate(bins_x): b = box(y, x, y + cell_size, x + cell_size) b.u = u b.v = v b.patches = list() self.rasterizations[key][v, u] = b # Create a search tree of spatial boxes grid = STRtree(self.rasterizations[key].ravel().tolist()) return (grid, shape)
def find_sample_points_with_data(case_dir, sample_name, spacing, wind_directions, field='U', write=False): base_points = np.loadtxt(case_dir / "sample_points.txt") base_points = base_points[:, :2] buffered_base_points = [(p, Point(p).buffer(spacing * 0.45)) for p in base_points] filename = f"{sample_name}_{field}.xyz" kept_sample_points = [] for w in wind_directions: # case_data_points = np.loadtxt(case_dir/str(w)/filename) case_data_points = orient_sample_date(case_dir / str(w), sample_name, field) # case_data_points_2D = [Point(p) for p in case_data_points[:,:2]] case_data_points_2D = MultiPoint(case_data_points[:, :2]) rtree = STRtree(case_data_points_2D) kept_sample_index = [] for idx, (p, pt) in enumerate(buffered_base_points): res = rtree.query(pt) if len(res) == 0: continue else: kept_sample_points.append(p) kept_sample_index.append(idx) for i in kept_sample_index[::-1]: buffered_base_points.pop(i) kept_sample_points = np.array(kept_sample_points) if write: np.savetxt(case_dir / f"{sample_name}_sample_points.txt", kept_sample_points) return kept_sample_points
def test_query_items(geoms, items, query_geom, expected): """Store enumeration idx""" tree = STRtree(geoms, items) results = tree.query_items(query_geom) expected = [items[idx] for idx in expected] if items is not None else expected assert sorted(results) == sorted(expected)
def test_query(): points = [Point(i, i) for i in range(10)] tree = STRtree(points) results = tree.query(Point(2, 2).buffer(0.99)) assert len(results) == 1 results = tree.query(Point(2, 2).buffer(1.0)) assert len(results) == 3
def select_geoms_by_geometry(geoms, geometry): """Build a STRtree from geoms and returns intersection with geometry :param geoms: list of geometries you want to search from :param geometry: intersection geometry :return: list of geoms intersecting with geometry """ if shapely is None: raise_import_exception('shapely') if type(geometry) in (bytes, str): if isinstance(geometry, bytes): geometry = geometry.decode('utf-8') # assume wkt, try to load geometry = loads(geometry) tree = STRtree(geoms) # STRtree checks intersection based on bbox of the geometry only: # https://github.com/Toblerity/Shapely/issues/558 intersected_geoms = tree.query(geometry) # reverse loop because we pop elements based on index for i, intersected_geom in zip(reversed(range(len(intersected_geoms))), reversed(intersected_geoms)): if not intersected_geom.intersects(geometry): intersected_geoms.pop(i) return intersected_geoms
def infer_labels(geojson, extent, cell_sz, ioa_thresh, use_intersection_over_cell, pick_min_class_id, background_class_id): """Infer ChipClassificationLabels grid from GeoJSON containing polygons. Given GeoJSON with polygons associated with class_ids, infer a grid of cells and class_ids that best captures the contents of each cell. See infer_cell for info on the args. Args: geojson: dict in normalized GeoJSON format (see VectorSource) extent: Box representing the bounds of the grid Returns: ChipClassificationLabels """ labels = ChipClassificationLabels() cells = extent.get_windows(cell_sz, cell_sz) # We need to associate class_id with each geom. Monkey-patching it onto the geom # seems like a bad idea, but it's the only straightforward way of doing this # that I've been able to find. geoms = [] for f in geojson['features']: g = shape(f['geometry']) g.class_id = f['properties']['class_id'] geoms.append(g) str_tree = STRtree(geoms) for cell in cells: class_id = infer_cell(cell, str_tree, ioa_thresh, use_intersection_over_cell, background_class_id, pick_min_class_id) labels.set_cell(cell, class_id) return labels
def test_query(self): points = [Point(i, i) for i in range(10)] tree = STRtree(points) results = tree.query(Point(2, 2).buffer(0.99)) self.assertEqual(len(results), 1) results = tree.query(Point(2, 2).buffer(1.0)) self.assertEqual(len(results), 3)
def get_GandRtree(): G, edges = simple_G() coord_feature_dict = {} geom_list = [] for _, row in edges.iterrows(): xs, ys = row['geometry'].xy geometry = {'coordinates': list(zip(xs, ys)), 'type': 'LineString'} geom = row['geometry'] geom_list.append(geom) coord_key = geom.coords[0] + geom.coords[-1] assert (coord_key not in coord_feature_dict) coord_feature_dict[coord_key] = \ {'geometry': geometry, 'id': row['road_id'], 'properties': OrderedDict([('source', row['u_replace']), ('target', row['v_replace']), ('weight', row['length'])]), 'type': 'Feature'} rtree = STRtree(geom_list) G_copy = nx.MultiDiGraph() G_copy.graph = G.graph for _, data in G.nodes(data=True): G_copy.add_node(data['node_id'], **data) edges = [(data['u_replace'], data['v_replace'], data) for u, v, data in G.edges(data=True)] G_copy.add_edges_from(edges) return G_copy, rtree, coord_feature_dict
def load_map_data(dataroot, location): # Load the NuScenes map object nusc_map = NuScenesMap(dataroot, location) map_data = OrderedDict() for layer in nusc_utils.STATIC_CLASSES: # Retrieve all data associated with the current layer records = getattr(nusc_map, layer) polygons = list() # Drivable area records can contain multiple polygons if layer == 'drivable_area': for record in records: # Convert each entry in the record into a shapely object for token in record['polygon_tokens']: poly = nusc_map.extract_polygon(token) if poly.is_valid: polygons.append(poly) else: for record in records: # Convert each entry in the record into a shapely object poly = nusc_map.extract_polygon(record['polygon_token']) if poly.is_valid: polygons.append(poly) # Store as an R-Tree for fast intersection queries map_data[layer] = STRtree(polygons) return map_data
def tree_query(tree, queried): # tree: point, queried: polygon case_list = [] centroid_tree = STRtree(tree.geometry.representative_point()) for index, row in queried.iterrows(): if centroid_tree.query(Polygon(row['geometry'])) == []: case_list.append([]) else: point_input = [] point = centroid_tree.query(Polygon(row['geometry'])) for i in range(len(point)): if Polygon(row['geometry']).intersects(point[i]) == True: point_input.append(point[i]) case_list.append(point_input) tree['X'] = tree['geometry'].representative_point().x tree['Y'] = tree['geometry'].representative_point().y queried['Case'] = None # Initialized the attribute column for index, points in enumerate(case_list): tempID = [] for point in points: tempRow = tree.query('X == @point.x and Y == @point.y') tempID.append(tempRow['PID'].values) if tempID: queried.loc[index, 'Case'] = tempID return queried
def gen_path(path, alt, shapes, tif, proj, tif_proj, test_case, path_name, params_file, case_file): params = json.load(open(params_file)) tree = STRtree(shapes) case_name = basename(splitext(case_file)[0]) gen_path, lines = plan_path(path, tree, alt, params['be_buffer'], params['obs_buffer'], params['min_length'], params['climb_rate'], params['descent_rate'], params['max_speed'], params['min_speed']) lines_file = 'tests/lines/{0}.json'.format(case_name) json.dump(lines, open(lines_file, 'w')) test_case['lines'] = lines_file path_loc = 'tests/gen-paths/{0}.json'.format(path_name) save_path(path_loc, gen_path, proj) test_case['results'][path_name] = {} test_case['results'][path_name]['gen-path'] = path_loc test_case['results'][path_name]['params'] = params_file save_test_case(case_file, test_case) return gen_path
def setUp(self): self.crs_transformer = DoubleCRSTransformer() self.geojson = { 'type': 'FeatureCollection', 'features': [{ 'type': 'Feature', 'geometry': { 'type': 'MultiPolygon', 'coordinates': [[[[0., 0.], [0., 2.], [2., 2.], [2., 0.], [0., 0.]]]] }, 'properties': { 'class_name': 'car', 'class_id': 1, 'score': 0.0 } }, { 'type': 'Feature', 'geometry': { 'type': 'Polygon', 'coordinates': [[[2., 2.], [2., 4.], [4., 4.], [4., 2.], [2., 2.]]] }, 'properties': { 'score': 0.0, 'class_name': 'house', 'class_id': 2 } }] } self.class_map = ClassMap([ClassItem(1, 'car'), ClassItem(2, 'house')]) class MockTaskConfig(): def __init__(self, class_map): self.class_map = class_map self.task_config = MockTaskConfig(self.class_map) self.box1 = Box.make_square(0, 0, 4) self.box2 = Box.make_square(4, 4, 4) self.class_id1 = 1 self.class_id2 = 2 self.background_class_id = 3 geoms = [] for f in self.geojson['features']: g = shape(f['geometry']) g.class_id = f['properties']['class_id'] geoms.append(g) self.str_tree = STRtree(geoms) self.file_name = 'labels.json' self.temp_dir = RVConfig.get_tmp_dir() self.uri = os.path.join(self.temp_dir.name, self.file_name) json_to_file(self.geojson, self.uri)
def test_query(): points = [Point(i, i) for i in range(10)] with pytest.warns(ShapelyDeprecationWarning): tree = STRtree(points) results = tree.query(Point(2, 2).buffer(0.99)) assert len(results) == 1 results = tree.query(Point(2, 2).buffer(1.0)) assert len(results) == 3
def _occult_layer( layers: Dict[int, LineCollection], tolerance: float, keep_occulted: bool = False ) -> Tuple[Dict[int, LineCollection], LineCollection]: """ Perform occlusion on all provided layers. Optionally returns occulted lines in a separate LineCollection. Args: layers: dictionary of LineCollections to perform occlusion on, keyed by layer ID tolerance: Max distance between start and end point to consider a path closed keep_occulted: if True, save removed lines in removed_lines LineCollection. Otherwise, removed_lines is an empty LineCollection. Returns: a tuple with two items: - new_lines, a dictionary of LineCollections for each layer ID received - removed_lines, a LineCollection of removed lines """ removed_lines = LineCollection() new_lines = {l_id: LineCollection() for l_id in layers} line_arr = [] line_arr_lines = [] for l_id, lines in layers.items(): line_arr.extend([[l_id, line] for line in lines.as_mls().geoms]) line_arr_lines.extend([line for line in lines.as_mls().geoms]) # Build R-tree from previous geometries tree = STRtree(line_arr_lines) index_by_id = dict((id(pt), i) for i, pt in enumerate(line_arr_lines)) for i, (l_id, line) in enumerate(line_arr): coords = np.array(line.coords) if not (len(coords) > 3 and math.hypot(coords[-1, 0] - coords[0, 0], coords[-1, 1] - coords[0, 1]) < tolerance): continue p = Polygon(coords) geom_idx = [index_by_id[id(g)] for g in tree.query(p)] geom_idx = [idx for idx in geom_idx if idx < i] for gi in geom_idx: # Aggregate removed lines if keep_occulted: rl = p.intersection(line_arr_lines[gi]) add_to_linecollection(removed_lines, rl) # Update previous geometries line_arr[gi][1] = line_arr[gi][1].difference(p) for (l_id, line) in line_arr: add_to_linecollection(new_lines[l_id], line) return new_lines, removed_lines
def _activate(self): geojson = self.vector_source.get_geojson() geoms = [] for f in geojson['features']: geom = shape(f['geometry']) geom.class_id = f['properties']['class_id'] geoms.append(geom) self.str_tree = STRtree(geoms) self.activated = True
def __init__(self, polygons, stoppers): self._polygons = polygons self._stop = STRtree(stoppers) # we sometimes touch text regions which prevent merging, that's # why we erode a bit here to allow merging to allow touching # text regions. # -20 derived from tests on SNP2436020X-19100601-0-0-0-0.09. self._erosion = 20
def split_points_into_chunks(self, MP, boxes): tree = STRtree(MP) pt_chunks = [] for b in boxes: query_geom = b pts = [o.wkt for o in tree.query(query_geom)] pt_chunks.append(pts) return pt_chunks
def test_safe_delete(): tree = STRtree([]) _lgeos = strtree.lgeos strtree.lgeos = None del tree strtree.lgeos = _lgeos
def table_polygons(self, kernel=(6, 5)): # kernel = (6, 5) fixes missed left bottom " in SNP2436020X-19100601-0-0-0-0.13 # and fixes non-contiguous table regions in SNP2436020X-19100601-1-0-0-0.03 # and avoids spilling over v sep in SNP2436020X-19000601-0-0-0-0.09 #mini_regions = self._table_regions_at_iterations((3, 3), (1,))[0] micro_regions, macro_regions = self._table_regions_at_iterations( kernel, (2, 5)) # don't do more than 5 iterations here, otherwise tables will merge over text in # SNP2436020X-19100601-0-0-0-0.14 background0 = self.text_stopper(kernel=(7, 3), iterations=1) # iterations=1 tuned via SNP2436020X-19100601-0-0-0-0.13. # kernel, see SNP2436020X-19200601-1-0-0-0.03. labels, num = skimage.morphology.label(macro_regions.astype( numpy.bool), return_num=True) from .utils.geometry import contours, Simplifier, convex_hull, convex_contours simplify = Simplifier(simplify=0) # detect border cases like bottom table in 2436020X_1925-02-27_70_98_006. tree = STRtree( [s.path for s in self.segments if s.dominant_label == Label.V]) hulls = [] #tables = numpy.zeros(self._annotations.shape, dtype=numpy.bool) for i in range(1, num + 1): added = numpy.logical_and(labels == i, micro_regions) if not added.any(): continue added = skimage.morphology.convex_hull_image(added) added = numpy.logical_and(added, numpy.logical_not(background0)) hull = convex_hull(simplify(contours(added))) segment_by = None for s in tree.query(hull): if hull.buffer(-5).contains( shapely.geometry.Point(*s.centroid.coords)): segment_by = s break if segment_by: added = numpy.logical_and(labels == i, micro_regions) added = numpy.logical_and(added, numpy.logical_not(background0)) for c in convex_contours(added): hulls.append(c) else: hulls.append(hull) return _merge_convex_all(hulls)
def test_safe_delete(): with pytest.warns(ShapelyDeprecationWarning): tree = STRtree([]) _lgeos = strtree.lgeos strtree.lgeos = None del tree strtree.lgeos = _lgeos
def get_buffer_r_tree(): ''' 读入buffer文件, 并将geometry转化为shapely geometry然后构建rtree ''' buffers = read_shp('./shp/output/road_buffer.shp') shapely_buffers = [] for buffer in buffers: shapely_buffers.append(shape(buffer['geometry'])) buffer_rtree = STRtree(shapely_buffers) return buffer_rtree
def _contains(shapes, points): tree = STRtree(points) indices = dict((id(point), index) for index, point in enumerate(points)) mask = numpy.zeros(len(points), dtype=bool) for shape in shapes: pointsToCheck = tree.query(shape) indicesInShape = [indices[id(point)] for point in pointsToCheck if (shape.contains(point) or shape.intersects(point))] mask[indicesInShape] = True return mask
def _intersects(shape, polygons): tree = STRtree(polygons) indices = dict((id(polygon), index) for index, polygon in enumerate(polygons)) mask = numpy.zeros(len(polygons), dtype=bool) polygonsToCheck = tree.query(shape) indicesInShape = [indices[id(polygon)] for polygon in polygonsToCheck if shape.intersects(polygon)] mask[indicesInShape] = True return mask
def __init__(self, shape, center, angle, radius, holes, board, hole_offset, edge_offset): #self.optimiser = optimiser self.offset = center self.angle = angle self.shape = shape.buffer(hole_offset) self.board = Polygon(board).buffer(hole_offset).buffer(-edge_offset) self.shape_buffer = shape.buffer(radius/2) self.current_max = float('-inf') self.fail_counter = 0 self.tree = STRtree(holes)
def get_results(filename): print(filename) _dir, _, _file = filename.rpartition('/') _image, _, _ext = _file.rpartition('.') _annots, _, _im_ext = _image.rpartition('.') files.append(_image) # print _image # grab the train and test annotations trains = np.load(os.path.join(args.train_dir, _annots + _ + _ext)).item() tests = np.load(filename) #print filename, maps_dir+_image, args.train_dir+_annots+_+_ext # data structure for saving the IoU values IoU_vals = np.zeros((len(tests), len(trains.keys()))) # save the train anots train_polys = [] for i in trains.keys(): # print(trains[i]['vertices']) train_polys.append(Polygon(trains[i]['vertices'])) pass s = STRtree(train_polys) # save the test annots test_polys = [] for i in range(len(tests)): poly = tests[i] poly = poly.tolist() # poly.append(poly[0]) test_poly = Polygon(poly) if not test_poly.is_valid: continue try: results = s.query(test_poly) for j in range(len(results)): _id = train_polys.index(results[j]) _intersection = train_polys[_id].intersection(test_poly).area _union = train_polys[_id].union(test_poly).area IoU_vals[i, _id] = _intersection / _union test_polys.append(test_poly) except Exception: continue # do the linear sum assignment _row, _col = lsa(1 - IoU_vals) assignment_matrix = IoU_vals[_row, _col] # compute the numbers TP = (assignment_matrix >= IoU_thresh).sum() FP = (assignment_matrix < IoU_thresh).sum() FN = len(trains.keys()) - TP return [TP, FP, FN]
def test_insert_empty_geometry(self): """ Passing nothing but empty geometries results in an empty strtree. The query segfaults if the empty geometry was actually inserted. """ empty = Polygon() geoms = [empty] tree = STRtree(geoms) assert (tree._n_geoms == 0) query = Polygon([(0, 0), (1, 1), (2, 0), (0, 0)]) results = tree.query(query)
def test_nearest(self): tree = STRtree([ Polygon([(1,0),(2,0),(2,1),(1,1)]), Polygon([(0,2),(1,2),(1,3),(0,3)]), Point(0,0.5)]) result = tree.nearest(Point(0,0)) self.assertEqual(result, Point(0,0.5)) result = tree.nearest(Point(0,4)) self.assertEqual(result, Polygon([(0,2),(1,2),(1,3),(0,3)])) result = tree.nearest(Polygon([(-0.5,-0.5),(0.5,-0.5),(0.5,0.5),(-0.5,0.5)])) self.assertEqual(result, Point(0,0.5))