Example #1
0
    def create_final_od_grid(df,height_div):
        height = numpy.sqrt(pygeos.area(df.geometry)/height_div).values[0]
        grid = pd.DataFrame(create_grid(create_bbox(df),height),columns=['geometry'])

        #clip grid of bbox to grid of the actual spatial exterior of the country
        clip_grid = pygeos.intersection(grid,df.geometry)
        clip_grid = clip_grid.loc[~pygeos.is_empty(clip_grid.geometry)]

        # turn to shapely geometries again for zonal stats
        clip_grid.geometry = pygeos.to_wkb(clip_grid.geometry)
        clip_grid.geometry = clip_grid.geometry.apply(loads)
        clip_grid = gpd.GeoDataFrame(clip_grid)

        # get total population per grid cell
        clip_grid['tot_pop'] = clip_grid.geometry.apply(lambda x: zonal_stats(x,world_pop,stats="sum"))
        clip_grid['tot_pop'] = clip_grid['tot_pop'].apply(lambda x: x[0]['sum'])    

        # remove cells in the grid that have no population data
        clip_grid = clip_grid.loc[~pd.isna(clip_grid.tot_pop)]
        clip_grid = clip_grid.loc[clip_grid.tot_pop > 100]
        clip_grid.reset_index(inplace=True,drop=True)
        clip_grid.geometry = clip_grid.geometry.centroid
        clip_grid['GID_0'] = GID_0
        clip_grid['grid_height'] = height

        return clip_grid
Example #2
0
def test_simplify_nan():
    actual = pygeos.simplify(
        np.array([point, np.nan, np.nan, None, point]),
        np.array([np.nan, 1.0, np.nan, 1.0, 1.0]),
    )
    assert pygeos.equals(actual[-1], point)
    assert pygeos.is_empty(actual[:-1]).all()
Example #3
0
def test_intersection_nan():
    actual = pygeos.intersection(
        np.array([point, np.nan, np.nan, point, None, None, point]),
        np.array([np.nan, point, np.nan, None, point, None, point]),
    )
    assert pygeos.equals(actual[-1], point)
    assert pygeos.is_empty(actual[:-1]).all()
Example #4
0
def test_get_rings(geom):
    if (pygeos.get_type_id(geom) !=
            pygeos.GeometryType.POLYGON) or pygeos.is_empty(geom):
        rings = pygeos.get_rings(geom)
        assert len(rings) == 0
    else:
        rings = pygeos.get_rings(geom)
        assert len(rings) == 1
        assert rings[0] == pygeos.get_exterior_ring(geom)
Example #5
0
 def __init__(self, geometry):
     # set empty geometries to None to avoid segfault on GEOS <= 3.6
     # see:
     # https://github.com/pygeos/pygeos/issues/146
     # https://github.com/pygeos/pygeos/issues/147
     non_empty = geometry.copy()
     non_empty[pygeos.is_empty(non_empty)] = None
     # set empty geometries to None to mantain indexing
     super().__init__(non_empty)
     # store geometries, including empty geometries for user access
     self.geometries = geometry.copy()
Example #6
0
def _intersects_pyg(geom, gdf, sindex, tolerance=1e-9):
    buf = pygeos.buffer(geom, tolerance)
    if pygeos.is_empty(buf):
        # can have an empty buffer with too small a tolerance, fallback to original geom
        buf = geom
    try:
        return _intersects_gdf_pyg(buf, gdf, sindex)
    except shapely.errors.TopologicalError:  #this still needs to be changed
        # can exceptionally buffer to an invalid geometry, so try re-buffering
        buf = pygeos.buffer(geom, 0)
        return _intersects_gdf_pyg(buf, gdf, sindex)
    def trim_similarity_matrix(self,
                               similarity_matrix,
                               detections,
                               ground_truths,
                               label_mean_area=None):
        r"""Compute an array containing the indices in columns of similarity passing the first trimming.

        Here a detection/ground truth pair is kept if the detection
        :class:`~playground_metrics.utils.geometry_utils.geometry.Point` is within the ground truth
        :class:`~playground_metrics.utils.geometry_utils.geometry.BoundingBox` or
        :class:`~playground_metrics.utils.geometry_utils.geometry.Polygon`

        Args:
            similarity_matrix: The similarity matrix between detections and ground truths : dimension (#detection, #gt)
            detections (ndarray, list) : A ndarray of detections stored as:

                * Bounding boxes for a given class where each row is a detection stored as:
                  ``[BoundingBox, confidence]``
                * Polygons for a given class where each row is a detection stored as:
                  ``[Polygon, confidence]``
                * Points for a given class where each row is a detection stored as:
                  ``[Point, confidence]``

            ground_truths (ndarray,list) : A ndarray of ground truth stored as:

                * Bounding boxes for a given class where each row is a ground truth stored as:
                  ``[BoundingBox]``
                * Polygons for a given class where each row is a ground truth stored as:
                  ``[Polygon]``

            label_mean_area (float) : Optional, default to ``None``. The mean area for each label in the dataset.

        Returns:
            ndarray: An array of dimension (2, N) where each column is a tuple (detection, ground truth) describing
            a potential match. To be more precise, each match-tuple in the array corresponds to a position in the
            similarity matrix which will be used by the match algorithm to compute the final match.

        """
        potential = np.stack(np.nonzero(similarity_matrix != -np.Inf))
        potential = potential[:,
                              np.argsort(
                                  np.nonzero(similarity_matrix != -np.Inf)[0])]

        trim = []
        for i in range(potential.shape[1]):
            r, c = potential[:, i]
            if np.all(
                    is_empty(
                        intersection(detections[r, 0], ground_truths[c, 0]))):
                trim.append(i)

        return np.delete(potential, trim, axis=1)
Example #8
0
 def __init__(self, geometry):
     # for compatibility with old RTree implementation, store ids/indexes
     original_indexes = geometry.index
     # set empty geometries to None to avoid segfault on GEOS <= 3.6
     # see:
     # https://github.com/pygeos/pygeos/issues/146
     # https://github.com/pygeos/pygeos/issues/147
     non_empty = geometry.values.data.copy()
     non_empty[pygeos.is_empty(non_empty)] = None
     # set empty geometries to None to mantain indexing
     self.objects = self.ids = original_indexes
     super().__init__(non_empty)
     # store geometries, including empty geometries for user access
     self.geometries = geometry.values.data.copy()
Example #9
0
def _pygeos_to_shapely(geom):
    if geom is None:
        return None

    if compat.PYGEOS_SHAPELY_COMPAT:
        geom = shapely.geos.lgeos.GEOSGeom_clone(geom._ptr)
        return shapely.geometry.base.geom_factory(geom)

    # fallback going through WKB
    if pygeos.is_empty(geom) and pygeos.get_type_id(geom) == 0:
        # empty point does not roundtrip through WKB
        return shapely.wkt.loads("POINT EMPTY")
    else:
        return shapely.wkb.loads(pygeos.to_wkb(geom))
Example #10
0
def country_grid_gdp_filled(trans_network,
                            country,
                            data_path,
                            rough_grid_split=100,
                            from_main_graph=False):
    """[summary]

    Args:
        trans_network ([type]): [description]
        rough_grid_split (int, optional): [description]. Defaults to 100.

    Returns:
        [type]: [description]
    """
    if from_main_graph == True:
        node_df = trans_network.copy()
        envelop = pygeos.envelope(
            pygeos.multilinestrings(node_df.geometry.values))
        height = np.sqrt(pygeos.area(envelop) / rough_grid_split)
    else:
        node_df = trans_network.nodes.copy()
        node_df.geometry, approximate_crs = convert_crs(node_df)
        envelop = pygeos.envelope(
            pygeos.multilinestrings(node_df.geometry.values))
        height = np.sqrt(pygeos.area(envelop) / rough_grid_split)

    gdf_admin = pd.DataFrame(create_grid(create_bbox(node_df), height),
                             columns=['geometry'])

    #load data and convert to pygeos
    country_shape = gpd.read_file(os.path.join(data_path, 'GADM',
                                               'gadm36_levels.gpkg'),
                                  layer=0)
    country_shape = pd.DataFrame(
        country_shape.loc[country_shape.GID_0 == country])
    country_shape.geometry = pygeos.from_shapely(country_shape.geometry)

    gdf_admin = pygeos.intersection(gdf_admin, country_shape.geometry)
    gdf_admin = gdf_admin.loc[~pygeos.is_empty(gdf_admin.geometry)]

    gdf_admin['centroid'] = pygeos.centroid(gdf_admin.geometry)
    gdf_admin['km2'] = area(gdf_admin)
    gdf_admin['gdp'] = get_gdp_values(gdf_admin, data_path)
    gdf_admin = gdf_admin.loc[gdf_admin.gdp > 0].reset_index()
    gdf_admin['gdp_area'] = gdf_admin.gdp / gdf_admin['km2']

    return gdf_admin
Example #11
0
def test_get_rings_return_index():
    geom = np.array([polygon, None, empty_polygon, polygon_with_hole])
    expected_parts = []
    expected_index = []
    for i, g in enumerate(geom):
        if g is None or pygeos.is_empty(g):
            continue
        expected_parts.append(pygeos.get_exterior_ring(g))
        expected_index.append(i)
        for j in range(0, pygeos.get_num_interior_rings(g)):
            expected_parts.append(pygeos.get_interior_ring(g, j))
            expected_index.append(i)

    parts, index = pygeos.get_rings(geom, return_index=True)
    assert len(parts) == len(expected_parts)
    assert np.all(pygeos.equals_exact(parts, expected_parts))
    assert np.array_equal(index, expected_index)
Example #12
0
def naive_compute_point_in_box_distance_similarity_matrix(sorted_detections, ground_truths):
    """Computes a similarity based on euclidean distance between all pairs of geometries in a naive fashion.

    Args:
        sorted_detections (ndarray, list) : A ndarray of detections stored as:

                * Bounding boxes for a given class where each row is a detection stored as:
                  ``[BoundingBox, confidence]``
                * Polygons for a given class where each row is a detection stored as:
                  ``[Polygon, confidence]``
                * Points for a given class where each row is a detection stored as:
                  ``[Point, confidence]``

        ground_truths (ndarray,list) : A ndarray of ground truth stored as:

            * Bounding boxes for a given class where each row is a ground truth stored as:
              ``[BoundingBox]``
            * Polygons for a given class where each row is a ground truth stored as:
              ``[Polygon]``
            * Points for a given class where each row is a ground truth stored as:
              ``[Point]``

    Returns:
        ndarray : An similarity matrix (#detections, #ground truth)
    """

    # We prepare the distance matrix (#detection, #gt)
    distance_matrix = np.zeros((sorted_detections.shape[0], len(ground_truths)))

    # Naive iterative distance matrix construction (Note: we iterate over the sorted detections)
    for k, ground_truth in enumerate(ground_truths):
        for m, detection in enumerate(sorted_detections):
            distance_matrix[m, k] = distance(centroid(detection[0]), centroid(ground_truth[0]))

    for i in range(distance_matrix.shape[0]):
        for j in range(distance_matrix.shape[1]):
            if is_empty(intersection(centroid(sorted_detections[i, 0]), ground_truths[j, 0])):
                distance_matrix[i, j] = np.inf

    return 1 - distance_matrix
Example #13
0
def test_get_geometry_simple(geom):
    actual = pygeos.get_geometry(geom, [0, -1, 1, -2])
    assert pygeos.equals(actual[0], actual[1]).all()
    assert pygeos.is_empty(actual[2:4]).all()
Example #14
0
def test_from_wkt_empty(wkt):
    geom = pygeos.from_wkt(wkt)
    assert pygeos.is_geometry(geom).all()
    assert pygeos.is_empty(geom).all()
    assert pygeos.to_wkt(geom) == wkt
Example #15
0
 def is_empty(self):
     return pygeos.is_empty(self.g)
Example #16
0
def test_clone_nan():
    actual = pygeos.clone(np.array([point, np.nan, None]))
    assert pygeos.equals(actual[0], point)
    assert pygeos.is_empty(actual[1])
    assert pygeos.is_empty(actual[2])
Example #17
0
def test_get_geometry_collection(geom):
    n = pygeos.get_num_geometries(geom)
    actual = pygeos.get_geometry(geom, [0, -n, n, -(n + 1)])
    assert pygeos.equals(actual[0], actual[1]).all()
    assert pygeos.is_empty(actual[2:4]).all()
Example #18
0
    (pygeos.intersection_all, pygeos.intersection),
    (pygeos.symmetric_difference_all, pygeos.symmetric_difference),
    (pygeos.union_all, pygeos.union),
    # (pygeos.coverage_union_all, pygeos.coverage_union) is tested seperately
)

reduce_test_data = [
    pygeos.box(0, 0, 5, 5),
    pygeos.box(2, 2, 7, 7),
    pygeos.box(4, 4, 9, 9),
    pygeos.box(5, 5, 10, 10),
]

non_polygon_types = [
    geom for geom in all_types
    if (not pygeos.is_empty(geom) and geom not in (polygon, multi_polygon))
]


@pytest.mark.parametrize("a", all_types)
@pytest.mark.parametrize("func", SET_OPERATIONS)
def test_set_operation_array(a, func):
    actual = func([a, a], point)
    assert actual.shape == (2, )
    assert isinstance(actual[0], Geometry)


@pytest.mark.parametrize("n", range(1, 5))
@pytest.mark.parametrize("func, related_func", REDUCE_SET_OPERATIONS)
def test_set_operation_reduce_1dim(n, func, related_func):
    actual = func(reduce_test_data[:n])
Example #19
0
def test_get_interior_ring():
    actual = pygeos.get_interior_ring(polygon_with_hole, [0, -1, 1, -2])
    assert pygeos.equals(actual[0], actual[1]).all()
    assert pygeos.is_empty(actual[2:4]).all()
Example #20
0
def test_get_point_non_linestring(geom):
    actual = pygeos.get_point(geom, [0, 2, -1])
    assert pygeos.is_empty(actual).all()
Example #21
0
def is_empty(data):
    if compat.USE_PYGEOS:
        return pygeos.is_empty(data)
    else:
        return _unary_op("is_empty", data, null_value=False)
Example #22
0
def test_from_wkb_point_empty(wkb, expected_type):
    geom = pygeos.from_wkb(wkb)
    # POINT (nan nan) transforms to an empty point
    # Note that the dimensionality (2D/3D) is GEOS-version dependent
    assert pygeos.is_empty(geom)
    assert pygeos.get_type_id(geom) == expected_type
Example #23
0
def test_from_wkb_empty(wkt):
    wkb = pygeos.to_wkb(pygeos.Geometry(wkt))
    geom = pygeos.from_wkb(wkb)
    assert pygeos.is_geometry(geom).all()
    assert pygeos.is_empty(geom).all()
    assert pygeos.to_wkb(geom) == wkb
Example #24
0
def find_nhd_waterbody_breaks(geometries, nhd_lines):
    """Some large waterbody complexes are divided by dams; these breaks
    need to be preserved.  This is done by finding the shared edges between
    adjacent waterbodies that fall near NHD lines (which include dams) and
    buffering them by 10 meters (arbitrary, from trial and error).

    This should be skipped if nhd_lines is empty.

    Parameters
    ----------
    df : GeoDataFrame
    nhd_lines : GeoDataFrame

    Returns
    -------
    MultiPolygon containing all buffered lines between waterbodies that are near
        NHD lines.  Returns None if no adjacent waterbodies meet these criteria
    """

    # find all nhd lines that intersect waterbodies
    # first, buffer them slightly
    nhd_lines = pg.get_parts(pg.union_all(pg.buffer(nhd_lines, 0.1)))
    tree = pg.STRtree(geometries)
    left, right = tree.query_bulk(nhd_lines, predicate="intersects")

    # add these to the return
    keep_nhd_lines = nhd_lines[np.unique(left)]

    # find connected boundaries
    boundaries = pg.polygons(pg.get_exterior_ring(geometries))
    tree = pg.STRtree(boundaries)
    left, right = tree.query_bulk(boundaries, predicate="intersects")
    # drop self intersections
    ix = left != right
    left = left[ix]
    right = right[ix]

    # extract unique pairs (dedup symmetric pairs)
    pairs = np.array([left, right]).T
    pairs = (
        pd.DataFrame({"left": pairs.min(axis=1), "right": pairs.max(axis=1)})
        .groupby(["left", "right"])
        .first()
        .reset_index()
    )

    # calculate geometric intersection
    i = pg.intersection(
        geometries.take(pairs.left.values), geometries.take(pairs.right.values)
    )

    # extract individual parts (may be geom collections)
    parts = pg.get_parts(pg.get_parts(pg.get_parts(i)))

    # extract only the lines or polygons
    t = pg.get_type_id(parts)
    parts = parts[((t == 1) | (t == 3)) & (~pg.is_empty(parts))].copy()

    # buffer and merge
    split_lines = pg.get_parts(pg.union_all(pg.buffer(parts, 10)))

    # now find the ones that are within 100m of nhd lines
    nhd_lines = pg.get_parts(nhd_lines)
    tree = pg.STRtree(nhd_lines)
    left, right = tree.nearest_all(split_lines, max_distance=100)

    split_lines = split_lines[np.unique(left)]

    if len(split_lines) or len(keep_nhd_lines):
        return pg.union_all(np.append(split_lines, keep_nhd_lines))

    return None
Example #25
0
def test_get_point(geom):
    n = pygeos.get_num_points(geom)
    actual = pygeos.get_point(geom, [0, -n, n, -(n + 1)])
    assert pygeos.equals(actual[0], actual[1]).all()
    assert pygeos.is_empty(actual[2:4]).all()
Example #26
0
def test_offset_curve_empty():
    actual = pygeos.offset_curve(empty_line_string, 2.0)
    assert pygeos.is_empty(actual)
Example #27
0
def test_get_interior_ring_non_polygon(geom):
    actual = pygeos.get_interior_ring(geom, [0, 2, -1])
    assert pygeos.is_empty(actual).all()