Example #1
0
def test_coverage_union_reduce_axis():
    # shape = (3, 2), all polygons - none of them overlapping
    data = [[pygeos.box(i, j, i + 1, j + 1) for i in range(2)]
            for j in range(3)]
    actual = pygeos.coverage_union_all(data)
    assert actual.shape == (2, )
    actual = pygeos.coverage_union_all(data, axis=0)  # default
    assert actual.shape == (2, )
    actual = pygeos.coverage_union_all(data, axis=1)
    assert actual.shape == (3, )
    actual = pygeos.coverage_union_all(data, axis=-1)
    assert actual.shape == (3, )
Example #2
0
def test_coverage_union_reduce_1dim(n):
    """
    This is tested seperately from other set operations as it differs in two ways:
      1. It expects only non-overlapping polygons
      2. It expects GEOS 3.8.0+
    """
    test_data = [
        pygeos.box(0, 0, 1, 1),
        pygeos.box(1, 0, 2, 1),
        pygeos.box(2, 0, 3, 1),
    ]
    actual = pygeos.coverage_union_all(test_data[:n])
    # perform the reduction in a python loop and compare
    expected = test_data[0]
    for i in range(1, n):
        expected = pygeos.coverage_union(expected, test_data[i])
    assert pygeos.equals(actual, expected)
def union_or_combine(geometries, grid_size=None, op="union"):
    """First does a check for overlap of geometries according to STRtree
    intersects.  If any overlap, then will use union_all on all of them;
    otherwise will return as a multipolygon.

    If only one polygon is present, it will be returned in a MultiPolygon.

    If coverage_union op is provided, geometries must be polygons and
    topologically related or this will produce bad output or fail outright.
    See docs for coverage_union in GEOS.

    Parameters
    ----------
    geometries : ndarray of single part polygons
    grid_size : [type], optional (default: None)
        provided to union_all; otherwise no effect
    op : str, one of {'union', 'coverage_union'}

    Returns
    -------
    MultiPolygon
    """

    if not (pg.get_type_id(geometries) == 3).all():
        print("Inputs to union or combine must be single-part geometries")

    if len(geometries) == 1:
        return pg.multipolygons(geometries)

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

    # no intersections, just combine parts
    if len(left) == 0:
        return pg.multipolygons(geometries)

    # find groups of contiguous geometries and union them together individually
    contiguous = np.sort(np.unique(np.concatenate([left, right])))
    discontiguous = np.setdiff1d(np.arange(len(geometries), dtype="uint"),
                                 contiguous)
    groups = find_adjacent_groups(left, right)

    parts = []

    if op == "coverage_union":
        for group in groups:
            parts.extend(
                pg.get_parts(pg.coverage_union_all(geometries[list(group)])))

    else:
        for group in groups:
            parts.extend(
                pg.get_parts(
                    pg.union_all(geometries[list(group)],
                                 grid_size=grid_size)))

    parts.extend(pg.get_parts(geometries[discontiguous]))

    return pg.multipolygons(parts)
# state outer boundaries, NOT analysis boundaries
bnd_df = gp.read_feather(out_dir / "region_boundary.feather")

bnd = bnd_df.loc[bnd_df.id == "total"].geometry.values.data[0]
sarp_bnd = bnd_df.loc[bnd_df.id == "se"].geometry.values.data[0]

state_df = gp.read_feather(out_dir / "region_states.feather",
                           columns=["STATEFIPS", "geometry"])
states = state_df.STATEFIPS.unique()

sarp_state_df = gp.read_feather(out_dir / "sarp_states.feather",
                                columns=["STATEFIPS", "geometry"])
sarp_states = sarp_state_df.STATEFIPS.unique()

# Clip HUC4 areas outside state boundaries; these are remainder
state_merged = pg.coverage_union_all(state_df.geometry.values.data)

# find all that intersect but are not contained
tree = pg.STRtree(huc4_df.geometry.values.data)
intersects_ix = tree.query(state_merged, predicate="intersects")
contains_ix = tree.query(state_merged, predicate="contains")
ix = np.setdiff1d(intersects_ix, contains_ix)

outer_huc4 = huc4_df.iloc[ix].copy()
outer_huc4["km2"] = pg.area(outer_huc4.geometry.values.data) / 1e6

# calculate geometric difference, explode, and keep non-slivers
outer_huc4["geometry"] = pg.difference(outer_huc4.geometry.values.data,
                                       state_merged)
outer_huc4 = explode(outer_huc4)
outer_huc4["clip_km2"] = pg.area(outer_huc4.geometry.values.data) / 1e6