コード例 #1
0
ファイル: test_creation.py プロジェクト: mwtoews/pygeos
def test_polygons_not_enough_points_in_shell(shape):
    coords = np.ones(shape)
    with pytest.raises(pygeos.GEOSException):
        pygeos.polygons(coords)

    # make sure the first coordinate != second coordinate
    coords[..., 1] += 1
    with pytest.raises(pygeos.GEOSException):
        pygeos.polygons(coords)
コード例 #2
0
ファイル: test_creation.py プロジェクト: brendan-ward/pygeos
def test_polygons_not_enough_points_in_holes(shape):
    coords = np.ones(shape)
    with pytest.raises(ValueError):
        pygeos.polygons(np.ones((1, 4, 2)), coords)

    # make sure the first coordinate != second coordinate
    coords[..., 1] += 1
    with pytest.raises(ValueError):
        pygeos.polygons(np.ones((1, 4, 2)), coords)
コード例 #3
0
def default_filter(
    tile: mercantile.Tile,
    dataset: Sequence[Dict],
    geoms: Sequence[polygons],
    minimum_tile_cover=None,
    tile_cover_sort=False,
    maximum_items_per_tile: Optional[int] = None,
) -> List:
    """Filter and/or sort dataset per intersection coverage."""
    indices = list(range(len(dataset)))

    if minimum_tile_cover or tile_cover_sort:
        tile_geom = polygons(
            mercantile.feature(tile)["geometry"]["coordinates"][0])
        int_pcts = _intersect_percent(tile_geom, geoms)

        if minimum_tile_cover:
            indices = [
                ind for ind in indices if int_pcts[ind] > minimum_tile_cover
            ]

        if tile_cover_sort:
            # https://stackoverflow.com/a/9764364
            indices, _ = zip(*sorted(zip(indices, int_pcts), reverse=True))

    if maximum_items_per_tile:
        indices = indices[:maximum_items_per_tile]

    return [dataset[ind] for ind in indices]
コード例 #4
0
    def __init__(self, tessellation, edges, buildings, id_name, unique_id,
                 **kwargs):
        self.tessellation = tessellation
        self.edges = edges
        self.buildings = buildings
        self.id_name = id_name
        self.unique_id = unique_id

        if id_name in buildings.columns:
            raise ValueError(
                "'{}' column cannot be in the buildings GeoDataFrame".format(
                    id_name))

        cut = gpd.overlay(
            tessellation,
            gpd.GeoDataFrame(geometry=edges.buffer(0.001)),
            how="difference",
        ).explode()

        W = libpysal.weights.Queen.from_dataframe(cut, silence_warnings=True)
        cut["component"] = W.component_labels
        buildings_c = buildings.copy()
        buildings_c.geometry = buildings_c.representative_point(
        )  # make points
        centroids_tempID = gpd.sjoin(
            buildings_c,
            cut[[cut.geometry.name, "component"]],
            how="left",
            op="intersects",
        )
        cells_copy = tessellation[[
            unique_id, tessellation.geometry.name
        ]].merge(centroids_tempID[[unique_id, "component"]],
                 on=unique_id,
                 how="left")
        blocks = cells_copy.dissolve(by="component").explode().reset_index(
            drop=True)
        blocks[id_name] = range(len(blocks))
        blocks[blocks.geometry.name] = gpd.GeoSeries(pygeos.polygons(
            blocks.exterior.values.data),
                                                     crs=blocks.crs)
        blocks = blocks[[id_name, blocks.geometry.name]]

        centroids_w_bl_ID2 = gpd.sjoin(buildings_c,
                                       blocks,
                                       how="left",
                                       op="intersects")
        bl_ID_to_uID = centroids_w_bl_ID2[[unique_id, id_name]]

        buildings_m = buildings[[unique_id]].merge(bl_ID_to_uID,
                                                   on=unique_id,
                                                   how="left")
        self.buildings_id = buildings_m[id_name]

        cells_m = tessellation[[unique_id]].merge(bl_ID_to_uID,
                                                  on=unique_id,
                                                  how="left")
        self.tessellation_id = cells_m[id_name]

        self.blocks = blocks
コード例 #5
0
ファイル: conftest.py プロジェクト: brendan-ward/geofeather
def pg_polygons_wgs84():
    size = 1000
    x1, y1 = generate_lon_lat(size)
    x2, y2 = generate_lon_lat(size)

    # generate some fields in the data frame
    f = random.sample(size) * 360 - 180
    i = random.randint(-32767, 32767, size=size)
    ui = random.randint(0, 65535, size=size).astype("uint64")

    df = DataFrame(
        data={
            "x1": x1,
            "y1": y1,
            "x2": x2,
            "y2": y2,
            "f": f,
            "i": i,
            "ui": ui,
            "labels": i.astype("str"),
        })

    # Generate random triangles
    df["geometry"] = df[["x1", "y1", "x2", "y2"]].apply(
        lambda row: pg.polygons([[row.x1, row.y1], [row.x2, row.y1],
                                 [row.x2, row.y2], [row.x1, row.y1]]),
        axis=1,
    )

    return df
コード例 #6
0
    def transform_geometry(self, geom, rs, max_points=5):
        """Transforms a geometry embedding new points.

        In case geom is (multi)line or (multi)polygon, it adds points collinear to their neighbours, so that an equivalent geometry is generated. The number of extra points depends on the number of vertices in the geometry.

        Arguments:
            geom (pygeos.Geometry): Geometry
            rs (numpy.RandomState): Random State
            max_points (int): Maximum value of extra points.

        Returns:
            (pygeos.Geometry)

        Raises:
            ValueError: When geometry type is not supported.
        """
        type_ = pg.get_type_id(geom)
        if type_ == 1 or type_ == 3:
            # LINESTRING or POLYGON
            vertices = pg.get_coordinates(geom)
            size = min(max_points, math.ceil(len(vertices) / 6))
            vert_ids = rs.randint(1, len(vertices), size)
            vert_ids.sort()
            new = []
            for idx in vert_ids:
                xa, ya = vertices[idx - 1]
                xb, yb = vertices[idx]
                if xa == xb:
                    x = xa
                    y = self._random_float(rs, ya, yb)
                else:
                    x = self._random_float(rs, xa, xb)
                    y = (yb - ya) * (x - xa) / (xb - xa) + ya
                x = _round(x, [xa, xb])
                y = _round(y, [ya, yb])
                new.append((idx, [x, y]))
            offset = 0
            extended = []
            for idx, entry in new:
                extended.extend(vertices[offset:idx])
                extended.append(entry)
                offset = idx
            extended.extend(vertices[offset:])
            extended = np.array(extended)
            result = pg.linestrings(extended) if type_ == 1 else pg.polygons(
                extended)
        elif type_ == 5 or type_ == 6:
            # MULTILINESTRING or MULTIPOLYGON
            parts = pg.get_parts(geom)
            part_idx = rs.randint(0, len(parts))
            parts[part_idx] = self.transform_geometry(parts[part_idx], rs)
            result = pg.multilinestrings(
                parts) if type_ == 5 else pg.multipolygons(parts)
        else:
            raise ValueError(
                'geom should be linestring, polygon, multilinestring, or multipolygon.'
            )

        return result
コード例 #7
0
ファイル: benchmarks.py プロジェクト: 92kns/Shapely
 def setup(self):
     self.multipolygons = np.array(
         [
             pygeos.multipolygons(pygeos.polygons(np.random.random((2, 100, 2))))
             for i in range(10000)
         ],
         dtype=object,
     )
コード例 #8
0
ファイル: test_creation.py プロジェクト: mwtoews/pygeos
def test_polygon_with_none_hole():
    actual = pygeos.polygons(
        pygeos.linearrings(box_tpl(0, 0, 10, 10)),
        [
            pygeos.linearrings(box_tpl(1, 1, 2, 2)),
            None,
            pygeos.linearrings(box_tpl(3, 3, 4, 4)),
        ],
    )
    assert pygeos.area(actual) == 98.0
コード例 #9
0
 def assets_for_tile(self, x: int, y: int, z: int) -> List[str]:
     """Retrieve assets for tile."""
     bbox = self.tms.bounds(x, y, z)
     geom = polygons(
         [
             [bbox[0], bbox[3]],
             [bbox[0], bbox[1]],
             [bbox[2], bbox[1]],
             [bbox[2], bbox[3]],
             [bbox[0], bbox[3]],
         ]
     )
     return self.get_assets(geom)
コード例 #10
0
ファイル: general_tree.py プロジェクト: dbstein/near_finder
 def __init__(self, bdy):
     """
     Construct rich "Boundary" type. Input "bdy" can either be:
         (1) GlobalSmoothBoundary type (from pybie2d)
         (2) complex form of (x, y) points of boundary
     """
     if type(bdy) == GSB:
         self.GSB = bdy
     else:
         self.GSB = GSB(c=bdy)
     self.c = self.GSB.c
     self.x = self.GSB.x
     self.y = self.GSB.y
     self.SH = pygeos.polygons([*zip(self.x, self.y)])
     pygeos.prepare(self.SH)
コード例 #11
0
ファイル: dimension.py プロジェクト: AtelierLibre/momepy
    def __init__(self, gdf, areas=None):
        self.gdf = gdf

        gdf = gdf.copy()
        if areas is None:
            areas = gdf.geometry.area

        if not isinstance(areas, str):
            gdf["mm_a"] = areas
            areas = "mm_a"
        self.areas = gdf[areas]

        exts = pygeos.area(pygeos.polygons(gdf.geometry.exterior.values.data))

        self.series = pd.Series(exts - gdf[areas], index=gdf.index)
コード例 #12
0
ファイル: population_OD.py プロジェクト: tomalrussell/trails
def create_grid(bbox,height):
    """Create a vector-based grid

    Args:
        bbox ([type]): [description]
        height ([type]): [description]

    Returns:
        [type]: [description]
    """    

    # set xmin,ymin,xmax,and ymax of the grid
    xmin, ymin = pygeos.total_bounds(bbox)[0],pygeos.total_bounds(bbox)[1]
    xmax, ymax = pygeos.total_bounds(bbox)[2],pygeos.total_bounds(bbox)[3]
    
    #estimate total rows and columns
    rows = int(numpy.ceil((ymax-ymin) / height))
    cols = int(numpy.ceil((xmax-xmin) / height))

    # set corner points
    x_left_origin = xmin
    x_right_origin = xmin + height
    y_top_origin = ymax
    y_bottom_origin = ymax - height

    # create actual grid
    res_geoms = []
    for countcols in range(cols):
        y_top = y_top_origin
        y_bottom = y_bottom_origin
        for countrows in range(rows):
            res_geoms.append((
                ((x_left_origin, y_top), (x_right_origin, y_top),
                (x_right_origin, y_bottom), (x_left_origin, y_bottom)
                )))
            y_top = y_top - height
            y_bottom = y_bottom - height
        x_left_origin = x_left_origin + height
        x_right_origin = x_right_origin + height

    return pygeos.polygons(res_geoms)
コード例 #13
0
    def _regions(self, voronoi_diagram, unique_id, ids, crs):
        """
        Generate GeoDataFrame of Voronoi regions from scipy.spatial.Voronoi.
        """
        vertices = pd.Series(voronoi_diagram.regions).take(
            voronoi_diagram.point_region)
        polygons = []
        for region in vertices:
            if -1 not in region:
                polygons.append(
                    pygeos.polygons(voronoi_diagram.vertices[region]))
            else:
                polygons.append(None)

        regions_gdf = gpd.GeoDataFrame({
            unique_id: ids
        },
                                       geometry=polygons,
                                       crs=crs).dropna()
        regions_gdf = regions_gdf.loc[regions_gdf[unique_id] !=
                                      -1]  # delete hull-based cells

        return regions_gdf
コード例 #14
0
ファイル: occult.py プロジェクト: vmario89/occult
def occult(lines: LineCollection, tolerance: float) -> LineCollection:
    """
    Remove occulted lines.

    The order of the geometries in 'lines' matters, see example below.

    'tolerance' controls the distance tolerance between the first and last points
    of a geometry to consider it closed.

    Examples:
        $ vpype line 0 0 5 5 rect 2 2 1 1 occult show  # line is occulted by rect

        $ vpype rect 2 2 1 1 line 0 0 5 5 occult show  # line is NOT occulted by rect,
        as the line is drawn after the rectangle.
    """

    line_arr = np.array(
        [pygeos.linestrings(list(zip(line.real, line.imag))) for line in lines]
    )

    for i, line in enumerate(line_arr):
        coords = pygeos.get_coordinates(line)

        if math.hypot(coords[-1, 0] - coords[0, 0], coords[-1, 1] - coords[0, 1]) < tolerance:
            tree = pygeos.STRtree(line_arr[:i])
            p = pygeos.polygons(coords)
            geom_idx = tree.query(p, predicate="intersects")
            line_arr[geom_idx] = pygeos.set_operations.difference(line_arr[geom_idx], p)

    new_lines = LineCollection()
    for geom in line_arr:
        for i in range(pygeos.get_num_geometries(geom)):
            coords = pygeos.get_coordinates(pygeos.get_geometry(geom, i))
            new_lines.append(coords[:, 0] + coords[:, 1] * 1j)

    return new_lines
コード例 #15
0
class _TestPolygons(_TestSimilarity):
    SIMILAR = [
        box(0, 0, 1, 1),
        polygons([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]),
        polygons([[0.5, 0], [1, 0], [1, 1], [0, 1], [0, 0.5], [0, 0]])
    ]
    DISSIMILAR = [
        box(10, 10, 11, 11),
        polygons([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]),
        polygons([[8, 8], [8, 13], [13, 13], [13, 8], [8, 8]],
                 holes=[[[9, 9], [9, 12], [12, 12], [12, 9], [9, 9]]]),
        polygons([[4.5, 4], [5, 4], [5, 5], [4, 5], [4, 4.5], [4, 4]]),
        points([0.5, 0.5])
    ]
    VALUE_GEOMETRIES = [[
        box(0, 0, 2, 2),
        polygons([[8, 8], [8, 13], [13, 13], [13, 8], [8, 8]],
                 holes=[[[9, 9], [9, 12], [12, 12], [12, 9], [9, 9]]])
    ], [box(-1, -1, 1, 1), box(8, 8, 13, 13)]]
    VALUE = [0.14285714285714285, 0.64]
コード例 #16
0
ファイル: test_creation.py プロジェクト: brendan-ward/pygeos
def test_polygon_from_linearring():
    actual = pygeos.polygons(pygeos.linearrings(box_tpl(0, 0, 1, 1)))
    assert str(actual) == "POLYGON ((1 0, 1 1, 0 1, 0 0, 1 0))"
コード例 #17
0
 def setup(self):
     self.points = pygeos.points(np.random.random((100000, 2)))
     self.polygon = pygeos.polygons(np.random.random((3, 2)))
コード例 #18
0
 def setup(self):
     self.to_write = pygeos.polygons(np.random.random((10000, 100, 2)))
     self.to_read_wkt = pygeos.to_wkt(self.to_write)
     self.to_read_wkb = pygeos.to_wkb(self.to_write)
コード例 #19
0
import numpy as np
import pygeos

point_polygon_testdata = (
    pygeos.points(np.arange(6), np.arange(6)),
    pygeos.box(2, 2, 4, 4),
)
point = pygeos.points(2, 3)
line_string = pygeos.linestrings([(0, 0), (1, 0), (1, 1)])
linear_ring = pygeos.linearrings([(0, 0), (1, 0), (1, 1), (0, 1), (0, 0)])
polygon = pygeos.polygons([(0, 0), (2, 0), (2, 2), (0, 2), (0, 0)])
multi_point = pygeos.multipoints([(0, 0), (1, 2)])
multi_line_string = pygeos.multilinestrings([[(0, 0), (1, 2)]])
multi_polygon = pygeos.multipolygons([
    [(0, 0), (1, 0), (1, 1), (0, 1), (0, 0)],
    [(2.1, 2.1), (2.2, 2.1), (2.2, 2.2), (2.1, 2.2), (2.1, 2.1)],
])
geometry_collection = pygeos.geometrycollections(
    [pygeos.points(51, -1),
     pygeos.linestrings([(52, -1), (49, 2)])])
point_z = pygeos.points(1.0, 1.0, 1.0)
polygon_with_hole = pygeos.Geometry(
    "POLYGON((0 0, 0 10, 10 10, 10 0, 0 0), (2 2, 2 4, 4 4, 4 2, 2 2))")

all_types = (
    point,
    line_string,
    linear_ring,
    polygon,
    multi_point,
    multi_line_string,
コード例 #20
0
def test_polygons_invalid_indices(indices):
    with pytest.raises((TypeError, ValueError)):
        pygeos.polygons([linear_ring], [linear_ring], indices=indices)
コード例 #21
0
ファイル: verify.py プロジェクト: brey/pyPoseidon
def verify(g, shp, thorough=False):
    #---------------------------------------------------------------------
    logger.info(' Verify grid against coastline\n')
    #---------------------------------------------------------------------

    lon_min = g.Dataset.SCHISM_hgrid_node_x.values.min()
    lon_max = g.Dataset.SCHISM_hgrid_node_x.values.max()
    lat_min = g.Dataset.SCHISM_hgrid_node_y.values.min()
    lat_max = g.Dataset.SCHISM_hgrid_node_y.values.max()

    c = shp.cx[lon_min:lon_max, lat_min:lat_max]

    # ## Test polygons

    d = g.Dataset

    x = d.SCHISM_hgrid_node_x.values
    y = d.SCHISM_hgrid_node_y.values
    tri = d.SCHISM_hgrid_face_nodes.values

    nodes = pd.DataFrame({'lon': x, 'lat': y})

    elems = pd.DataFrame(tri, columns=['a', 'b', 'c'])

    bnodes = g.Dataset[['node', 'id', 'type']].to_dataframe()

    # ### Find the invalid nodes (that cross the coasts)
    cos = pygeos.from_shapely(c.geometry)
    cos_ = pygeos.set_operations.union_all(cos)

    gps = pygeos.points(list(nodes.values))

    gtree = pygeos.STRtree(gps)

    invs = gtree.query(cos_, predicate='contains').tolist()

    #---------------------------------------------------------------------
    logger.info('Number of nodes within the coastlines {}\n'.format(len(invs)))
    #---------------------------------------------------------------------

    nps = len(invs)

    nels = 1

    if thorough:

        # ### Find invalid elements (that cross land)

        # cells to polygons
        ap = nodes.loc[elems.a]
        bp = nodes.loc[elems.b]
        cp = nodes.loc[elems.c]

        elems['ap'] = ap.values.tolist()
        elems['bp'] = bp.values.tolist()
        elems['cp'] = cp.values.tolist()

        n = 2
        al = elems.ap + elems.bp + elems.cp + elems.ap
        coords = [[l[i:i + n] for i in range(0, len(l), n)] for l in al]
        elems['coordinates'] = coords

        jig = pygeos.polygons(coords)

        jtree = pygeos.STRtree(jig)

        jig_ = pygeos.set_operations.union_all(jig)

        cross = pygeos.set_operations.intersection(jig_, cos_)

        # #### convert to dataframe

        fd = pd.DataFrame({'overlap': pygeos.to_wkt(cross)}, index=[0])

        fd['overlap'] = fd['overlap'].apply(shapely.wkt.loads)

        gover = gp.GeoDataFrame(fd, geometry='overlap')

        # #### Reject small injuctions
        ipols = gover.explode().loc[0]

        ipols.columns = ['geometry']

        mask = ipols.area.values == 0.

        ipols = ipols[~mask].reset_index(drop=True)
        ipols = gp.GeoDataFrame(ipols)

        #---------------------------------------------------------------------
        logger.info(
            'Number of elements intersecting the coastlines {}\n'.format(
                ipols.shape[0]))
        #---------------------------------------------------------------------

        nels = ipols.shape[0]

    if nps == 0 and nels == 0:
        #---------------------------------------------------------------------
        logger.info('Grid is verified against the coastline')
        #---------------------------------------------------------------------
        return True
    elif nps == 0:
        #---------------------------------------------------------------------
        logger.info('Grid is node verified against the coastline')
        #---------------------------------------------------------------------
        return True
    else:
        #---------------------------------------------------------------------
        logger.warning('Grid is not verified against the coastline')
        #---------------------------------------------------------------------
        return False
コード例 #22
0
ファイル: test_creation.py プロジェクト: brendan-ward/pygeos
def test_2_polygons_with_2_same_holes():
    actual = pygeos.polygons(
        [box_tpl(0, 0, 10, 10), box_tpl(0, 0, 5, 5)],
        [box_tpl(1, 1, 2, 2), box_tpl(3, 3, 4, 4)],
    )
    assert pygeos.area(actual).tolist() == [98.0, 23.0]
コード例 #23
0
ファイル: test_creation.py プロジェクト: brendan-ward/pygeos
def test_2_polygons_with_different_holes():
    actual = pygeos.polygons(
        [box_tpl(0, 0, 10, 10), box_tpl(0, 0, 5, 5)],
        [[box_tpl(1, 1, 3, 3)], [box_tpl(1, 1, 2, 2)]],
    )
    assert pygeos.area(actual).tolist() == [96.0, 24.0]
コード例 #24
0
ファイル: test_creation.py プロジェクト: brendan-ward/pygeos
def test_polygon_with_2_holes():
    actual = pygeos.polygons(
        box_tpl(0, 0, 10, 10), [box_tpl(1, 1, 2, 2), box_tpl(3, 3, 4, 4)]
    )
    assert pygeos.area(actual) == 98.0
コード例 #25
0
ファイル: test_creation.py プロジェクト: brendan-ward/pygeos
def test_2_polygons_with_same_hole():
    actual = pygeos.polygons(
        [box_tpl(0, 0, 10, 10), box_tpl(0, 0, 5, 5)], [box_tpl(1, 1, 2, 2)]
    )
    assert pygeos.area(actual).tolist() == [99.0, 24.0]
コード例 #26
0
ファイル: test_creation.py プロジェクト: brendan-ward/pygeos
def test_polygon_with_1_hole():
    actual = pygeos.polygons(box_tpl(0, 0, 10, 10), [box_tpl(1, 1, 2, 2)])
    assert pygeos.area(actual) == 99.0
コード例 #27
0
ファイル: test_creation.py プロジェクト: brendan-ward/pygeos
def test_polygon_no_hole_list_raises():
    with pytest.raises(ValueError):
        pygeos.polygons(box_tpl(0, 0, 10, 10), box_tpl(1, 1, 2, 2))
コード例 #28
0
ファイル: test_creation.py プロジェクト: brendan-ward/pygeos
def test_polygons():
    actual = pygeos.polygons(box_tpl(0, 0, 1, 1))
    assert str(actual) == "POLYGON ((1 0, 1 1, 0 1, 0 0, 1 0))"
コード例 #29
0
def test_polygons(holes, indices, expected):
    actual = pygeos.polygons([linear_ring, linear_ring],
                             holes,
                             indices=indices)
    assert_geometries_equal(actual, expected)
コード例 #30
0
def test_polygons_missing_shell():
    actual = pygeos.polygons([None, linear_ring], [hole_1, hole_2],
                             indices=[0, 1])
    assert_geometries_equal(actual, [None, poly_hole_2])