Exemple #1
0
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
Exemple #2
0
    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
Exemple #3
0
 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)
Exemple #4
0
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)
Exemple #6
0
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
Exemple #7
0
 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)
Exemple #8
0
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
Exemple #9
0
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
Exemple #10
0
    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
Exemple #12
0
    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)
Exemple #13
0
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
Exemple #14
0
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
Exemple #15
0
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
Exemple #16
0
 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 __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)
Exemple #18
0
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]
Exemple #19
0
 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)
Exemple #20
0
 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))
Exemple #21
0
	def __init__(self, state_polygon, population_polygons):
		self.finished_districts = 0
		speedups.enable()
		self.state_poly = state_polygon
		self.population_polygons = population_polygons
		self.total_pop = 0
		self.county_population_list = [] # keep track of each counties population
		self.county_polygon_list = [] # keep track of each counties polygon
		for i in population_polygons:
			self.county_polygon_list.append(i["poly"])
			self.county_population_list.append(i["population"])
		self.county_tree = STRtree(self.county_polygon_list) # STR trees for faster intersection detection
Exemple #22
0
def process_travel_edges(graph, fill_stitch_graph, shape, travel_edges):
    """Weight the interior edges and pre-calculate intersection with fill stitch rows."""

    # Set the weight equal to 5x the edge length, to encourage travel()
    # to avoid them.
    weight_edges_by_length(graph, 5)

    segments = get_segments(fill_stitch_graph)

    # The shapely documentation is pretty unclear on this.  An STRtree
    # allows for building a set of shapes and then efficiently testing
    # the set for intersection.  This allows us to do blazing-fast
    # queries of which line segments overlap each underpath edge.
    strtree = STRtree(segments)

    # This makes the distance calculations below a bit faster.  We're
    # not looking for high precision anyway.
    outline = shape.boundary.simplify(0.5 * PIXELS_PER_MM,
                                      preserve_topology=False)

    for ls in travel_edges:
        # In most cases, ls will be a simple line segment.  If we're
        # unlucky, in rare cases we can get a tiny little extra squiggle
        # at the end that can be ignored.
        points = [InkstitchPoint(*coord) for coord in ls.coords]
        p1, p2 = points[0], points[-1]

        edge = (p1.as_tuple(), p2.as_tuple(), 'travel')

        for segment in strtree.query(ls):
            # It seems like the STRTree only gives an approximate answer of
            # segments that _might_ intersect ls.  Refining the result is
            # necessary but the STRTree still saves us a ton of time.
            if segment.crosses(ls):
                start, end = segment.coords
                fill_stitch_graph[start][end]['segment'][
                    'underpath_edges'].append(edge)

        # The weight of a travel edge is the length of the line segment.
        weight = p1.distance(p2)

        # Give a bonus to edges that are far from the outline of the shape.
        # This includes the outer outline and the outlines of the holes.
        # The result is that travel stitching will tend to hug the center
        # of the shape.
        weight /= ls.distance(outline) + 0.1

        graph.add_edge(*edge, weight=weight)

    # without this, we sometimes get exceptions like this:
    # Exception AttributeError: "'NoneType' object has no attribute 'GEOSSTRtree_destroy'" in
    #   <bound method STRtree.__del__ of <shapely.strtree.STRtree instance at 0x0D2BFD50>> ignored
    del strtree
def get_features_inside_shape(geojson_data, border_shape):
    optimized_shapes = katana(border_shape, SPLIT_SIZE)
    tree = STRtree(optimized_shapes)

    inside_shape = []
    for feature in geojson_data['features']:
        shape = geometry.shape(feature['geometry'])
        for segment in tree.query(shape):
            if segment.contains(shape):
                inside_shape.append(feature)
    geojson_data['features'] = inside_shape
    return geojson_data
Exemple #24
0
def test_insert_empty_geometry():
    """
    Passing nothing but empty geometries results in an empty strtree.
    The query segfaults if the empty geometry was actually inserted.
    """
    empty = Polygon()
    geoms = [empty]
    with pytest.warns(ShapelyDeprecationWarning):
        tree = STRtree(geoms)
    assert tree._n_geoms == 0
    query = Polygon([(0, 0), (1, 1), (2, 0), (0, 0)])
    results = tree.query(query)
    assert len(results) == 0
Exemple #25
0
def test_query_empty_geometry():
    """
    Empty geometries should be filtered out.
    The query segfaults if the empty geometry was actually inserted.
    """
    empty = Polygon()
    point = Point(1, 0.5)
    geoms = [empty, point]
    tree = STRtree(geoms)
    query = Polygon([(0, 0), (1, 1), (2, 0), (0, 0)])
    results = tree.query(query)
    assert len(results) == 1
    assert results[0] == point
def find_borders(polygons):
    str_tree = STRtree(polygons)

    for polygon in polygons:
        potentials = str_tree.query(polygon)

        for potential in potentials:
            if potential is polygon:
                continue
            intersect = potential.intersection(polygon)
            # if not intersect.is_empty and hasattr(intersect, 'exterior'):
            if not intersect.is_empty:
                yield intersect.convex_hull
    def filter_out_of_campus_points(self, whole_campus_x, whole_campus_y):
        """pre processing function to remove all the points that are not within campus. 

        Args:
            whole_campus_x (np.array): x "utm" coordinate in integer (east axis)
            whole_campus_y (np.array): y "utm" coordinate in integer (north axis)

        Returns:
            filtered_x, filtered_y: x, y array with out of campus points removed. 
        """
        if configure.getboolean("Configure", "debug"):
            print("filtering points that are not within campus...")

        # open the campus boundary geojson file and read it as a polygon
        file = open(configure.get("Constants", "boundary_geojson_file_path"))
        df = geopandas.read_file(file)

        # translate utm to geographic
        lat = (whole_campus_x / 100.0) + self.min_east * 100
        lon = (whole_campus_y / 100.0) + self.min_north * 100
        raw_geo = utm.to_latlon(lat, lon, 10, "U")

        # map 2d array to shapely points
        stacked = np.vstack((raw_geo[1], raw_geo[0])).T
        s = GeoSeries(map(Point, stacked))

        # query the points for faster processing.
        # according to https://stackoverflow.com/questions/62280398/checking-if-a-point-is-contained-in-a-polygon-multipolygon-for-many-points
        tree = STRtree(s)
        # we have to do a if check after query, according to the post
        res = [
            o for o in tree.query(df.geometry[0]) if df.geometry[0].contains(o)
        ]

        # translate from geographic to utm
        filtered_stacked = np.zeros((len(res), 2))
        count = 0
        for point in res:
            filtered_stacked[count, :] = np.asarray(point.xy).reshape(1, 2)
            count += 1
        raw_utm = utm.from_latlon(filtered_stacked[:, 1], filtered_stacked[:,
                                                                           0])
        filtered_x = (raw_utm[0] - self.min_east * 100) * 100
        filtered_y = (raw_utm[1] - self.min_north * 100) * 100
        filtered_x = filtered_x.astype(int)
        filtered_y = filtered_y.astype(int)

        if configure.getboolean("Configure", "debug"):
            print("filtering completed.")

        return filtered_x, filtered_y
Exemple #28
0
def detector_counts_time(gdf_d, gdf_s, buff, source, mu=[0], polys=None):
    '''
    This function tallies the total counts each detector sees at each point
    in time. It does so by finding all detectors with the same timestep as
    the source, and then finding all detectors within range. 
    Parameters
    ----------
    gdf_d: GeoDataFrame
        The geodataframe containing the information for the mobile and 
        or stationary detectors. 
    gdf_s: GeoDataFrame
        The geodataframe containing the information for the mobile and 
        or stationary sources. 
    buff: float
        The maximum detection distance
    source: float
        The strength of the mobile source
    Returns
    -------
    gdf_d: GeoDataFrame
        The geodataframe containing the information for the mobile and 
        or stationary detectors updated with counts. 
    '''
    for index_s in range(len(gdf_s)):
        cols = ['detID', 'sourceID', 'counts', 'dist', 'dist2']
        interaction_array = []
        spoint = gdf_s.at[index_s, 'geometry']
        time = gdf_s.at[index_s, 'time']
        gdf_t=gdf_d[gdf_d['time'] == time]
        geometries = np.append(gdf_t.geometry.values, gdf_s.geometry.values)
        tree=STRtree(geometries)
        buff1 = buff/111180
        d_list = tree.query(spoint.buffer(buff1))
        for d in d_list:
            if d in gdf_t['geometry']:
                index = gdf_t[gdf_t['geometry']==d].index
                for index_d in index:
                    if polys is None:
                        dist = spoint.distance(d)*111180
                        val = tally_counts(dist, mu[0], source)
                        gdf_d.at[index_d, 'count'] += val
                        gdf_s.at[index_s, 'count'] += val
                        interaction_array.append([index_d, index_s, val, dist, 0.0])
                    else:
                        dist = attenu_lengths(gdf_d, gdf_s, index_d, index_s, polys)
                        val = tally_counts_buildings(dist, mu, source)
                        gdf_d.at[index_d, 'count'] += val
                        gdf_s.at[index_s, 'count'] += val
                        interaction_array.append([index_d, index_s, val, dist[0], dist[1]])
        pd1 = pd.DataFrame(interaction_array, columns=cols)
    return pd1
Exemple #29
0
def find_adjacent_polygons(in_polygon,
                           polygon_list,
                           buffer_size=None,
                           Rtree=None):
    # find adjacent polygons
    # in_polygon is the center polygon
    # polygon_list is a polygon list without in_polygon

    if buffer_size is not None:
        center_poly = in_polygon.buffer(buffer_size)
    else:
        center_poly = in_polygon

    if len(polygon_list) < 1:
        return [], []

    # https://shapely.readthedocs.io/en/stable/manual.html#str-packed-r-tree
    if Rtree is None:
        tree = STRtree(polygon_list)
    else:
        tree = Rtree
    # query: Returns a list of all geometries in the strtree whose extents intersect the extent of geom.
    # This means that a subsequent search through the returned subset using the desired binary predicate
    # (eg. intersects, crosses, contains, overlaps) may be necessary to further filter the results according
    # to their specific spatial relationships.

    # https://www.geeksforgeeks.org/introduction-to-r-tree/
    # R-trees are faster than Quad-trees for Nearest Neighbour queries while for window queries, Quad-trees are faster than R-trees

    # quicker than check one by one
    # adjacent_polygons = [item for item in tree.query(center_poly) if item.intersection(center_poly) ]
    # t0= time.time()
    adjacent_polygons = [
        item for item in tree.query(center_poly)
        if item.intersects(center_poly)
    ]
    adjacent_poly_idx = [
        polygon_list.index(item) for item in adjacent_polygons
    ]
    # print('cost %f seconds'%(time.time() - t0))

    # adjacent_polygons = []
    # adjacent_poly_idx = []
    # for idx, poly in enumerate(polygon_list):
    #     if is_two_polygons_connected(poly, center_poly):
    #         adjacent_polygons.append(poly)
    #         adjacent_poly_idx.append(idx)

    # print(datetime.now(), 'find %d adjacent polygons' % len(adjacent_polygons))

    return adjacent_polygons, adjacent_poly_idx
Exemple #30
0
 def test_query_empty_geometry(self):
     """
     Empty geometries should be filtered out.
     The query segfaults if the empty geometry was actually inserted.
     """
     empty = Polygon()
     point = Point(1, 0.5)
     geoms = [empty, point]
     tree = STRtree(geoms)
     assert (tree._n_geoms == 1)
     query = Polygon([(0, 0), (1, 1), (2, 0), (0, 0)])
     results = tree.query(query)
     self.assertEqual(len(results), 1)
     self.assertEqual(results[0], point)
Exemple #31
0
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
Exemple #32
0
 def test_query_empty_geometry(self):
     """
     Empty geometries should be filtered out.
     The query segfaults if the empty geometry was actually inserted.
     """
     empty = Polygon()
     point = Point(1, 0.5)
     geoms = [empty, point]
     tree = STRtree(geoms)
     assert(tree._n_geoms == 1)
     query = Polygon([(0,0),(1,1),(2,0),(0,0)])
     results = tree.query(query)
     self.assertEqual(len(results), 1)
     self.assertEqual(results[0], point)
def intersect(mglist, shp, shptype="POLYGON", length_area_greater_than=0.0):
    intersect_dict = {}

    s = STRtree(mglist)

    result = s.query(shp)

    isectshp = []
    cellids = []
    vertices = []
    areas = []
    lengths = []

    for i, r in enumerate(result):
        intersect = shp.intersection(r)

        if shptype == "POLYGON":
            if intersect.area > length_area_greater_than:
                #cellids.append(mglist.index(r))  # this is extremely slow
                cellids.append(r.index)  # vincent post
                isectshp.append(intersect)
                areas.append(intersect.area)
                vertices.append(intersect.__geo_interface__["coordinates"])
        elif shptype == "POLYLINE":
            try:
                isect_iter = iter(intersect)
            except TypeError:
                isect_iter = [intersect]

            for isect in isect_iter:
                if isect.length > length_area_greater_than:
                    #cellids.append(mglist.index(r))  # this is extremely slow
                    cellids.append(r.index)  # vincent post
                    isectshp.append(isect)
                    lengths.append(isect.length)
                    vertices.append(isect.__geo_interface__["coordinates"])
        else:
            raise NotImplementedError(
                "shptype '{}' is not supported!".format(shptype))

    intersect_dict["intersect"] = isectshp
    intersect_dict["cellids"] = cellids
    intersect_dict["vertices"] = vertices
    if shptype == "POLYGON":
        intersect_dict["areas"] = areas
    elif shptype == "POLYLINE":
        intersect_dict["lengths"] = lengths

    return intersect_dict
Exemple #34
0
    def _process(self, element, key=None):
        # Compute view port
        x0, x1 = self.p.x_range or element.range(0)
        y0, y1 = self.p.y_range or element.range(1)
        bounds = bounds_to_poly((x0, y0, x1, y1))

        # Initialize or lookup cache with STRTree 
        if element._plot_id in self._cache:
            cache = self._cache[element._plot_id]
            domain, tree, geom_dicts, geom_cache, area_cache = cache
        else:
            if isinstance(element, Polygons):
                geom_dicts = polygons_to_geom_dicts(element)
            elif isinstance(element, Path):
                geom_dicts = path_to_geom_dicts(element)
            geoms = [g['geometry'] for g in geom_dicts]
            tree = STRtree(geoms)
            domain = bounds
            geom_cache, area_cache = {}, {}
            self._cache.clear()
            cache = (domain, tree, geom_dicts, geom_cache, area_cache)
            self._cache[element._plot_id] = cache

        area = bounds.area
        current_zoom = compute_zoom_level(bounds, domain, self.p.zoom_levels)
        tol = np.sqrt(bounds.area) * self.p.tolerance_factor

        # Query RTree, then cull and simplify polygons
        new_geoms, gdict = [], {}
        for g in tree.query(bounds):
            garea = area_cache.get(id(g))
            if garea is None:
                is_poly = 'Polygon' in g.geom_type
                garea = g.area if is_poly else bounds_to_poly(g.bounds).area
                area_cache[id(g)] = garea

            # Skip if geometry area is below display threshold or
            # does not intersect with viewport
            if ((self.p.display_threshold is not None and
                 (garea/area) < self.p.display_threshold)
                or not g.intersects(bounds)):
                continue

            # Try to look up geometry in cache by zoom level
            cache_id = (id(g), current_zoom)
            if cache_id in geom_cache and not self.p.clip:
                geom_dict = geom_cache[cache_id]
            else:
                if element.vdims:
                    gidx = find_geom(tree._geoms, g)
                    gdict = geom_dicts[gidx]

                g = g.simplify(tol, self.p.preserve_topology)
                if not g:
                    continue # Skip if geometry empty

                geom_dict = dict(gdict, geometry=g)
                if self.p.cache:
                    geom_cache[cache_id] = geom_dict
                if self.p.clip:
                    geom_dict = dict(geom_dict, geometry=g.intersection(bounds))
            new_geoms.append(geom_dict)
        return element.clone(new_geoms)