Skip to content

Commit

Permalink
edit PR
Browse files Browse the repository at this point in the history
  • Loading branch information
vincentsarago committed Oct 28, 2024
1 parent e09b596 commit 380f20e
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 43 deletions.
4 changes: 0 additions & 4 deletions rio_tiler/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,3 @@ class MissingCRS(RioTilerError):

class InvalidGeographicBounds(RioTilerError):
"""Invalid Geographic bounds."""


class InvalidRowColOperator(RioTilerError):
"""The rasterio rowcol 'op' parameter must be one of: math.floor, math.ceil, or round."""
17 changes: 6 additions & 11 deletions rio_tiler/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

from rio_tiler.colormap import apply_cmap
from rio_tiler.constants import WEB_MERCATOR_CRS, WGS84_CRS
from rio_tiler.errors import InvalidRowColOperator, RioTilerError
from rio_tiler.errors import RioTilerError
from rio_tiler.types import BBox, ColorMapType, IntervalTuple, RIOResampling


Expand Down Expand Up @@ -652,13 +652,15 @@ def _calculateRatio(
def _convert_to_raster_space(
src_dst: Union[DatasetReader, DatasetWriter, WarpedVRT],
poly_coordinates: List,
op: Callable[[float], int],
op: Optional[Callable[[float], Union[int, float]]] = None,
) -> List[str]:
# NOTE: we could remove this once we have rasterio >= 1.4.2
op = op or numpy.floor
polygons = []
for point in poly_coordinates:
xs, ys = zip(*coords(point))
src_y, src_x = rowcol(src_dst.transform, xs, ys, op=op)
polygon = ", ".join([f"{x} {y}" for x, y in list(zip(src_x, src_y))])
polygon = ", ".join([f"{int(x)} {int(y)}" for x, y in list(zip(src_x, src_y))])
polygons.append(f"({polygon})")

return polygons
Expand All @@ -668,7 +670,7 @@ def create_cutline(
src_dst: Union[DatasetReader, DatasetWriter, WarpedVRT],
geometry: Dict,
geometry_crs: CRS = None,
op: Callable[[float], int] = math.floor,
op: Optional[Callable[[float], Union[int, float]]] = None,
) -> str:
"""
Create WKT Polygon Cutline for GDALWarpOptions.
Expand All @@ -683,13 +685,6 @@ def create_cutline(
str: WKT geometry in form of `POLYGON ((x y, x y, ...)))
"""

# Validate that the function provided is one of the allowed methods
if op not in {math.floor, math.ceil, round}:
raise InvalidRowColOperator(
"The rasterio rowcol 'op' parameter must be one of: math.floor, math.ceil, or round."
)

geometry = _validate_shape_input(geometry)
geom_type = geometry["type"]

Expand Down
9 changes: 2 additions & 7 deletions tests/test_io_rasterio.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""tests rio_tiler.io.rasterio.Reader"""

import math
import os
from io import BytesIO
from typing import Any, Dict
Expand Down Expand Up @@ -752,9 +751,7 @@ def test_equality_part_feature():
}
img_feat = src.feature(feat)

cutline = create_cutline(
src.dataset, feat, geometry_crs="epsg:4326", op=math.floor
)
cutline = create_cutline(src.dataset, feat, geometry_crs="epsg:4326")
bbox = featureBounds(feat)
img_part = src.part(bbox, vrt_options={"cutline": cutline})

Expand All @@ -770,9 +767,7 @@ def test_equality_part_feature():
# Re-Projection
img_feat = src.feature(feat, dst_crs="epsg:3857")

cutline = create_cutline(
src.dataset, feat, geometry_crs="epsg:4326", op=math.floor
)
cutline = create_cutline(src.dataset, feat, geometry_crs="epsg:4326")
bbox = featureBounds(feat)
img_part = src.part(bbox, vrt_options={"cutline": cutline}, dst_crs="epsg:3857")

Expand Down
81 changes: 60 additions & 21 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

from rio_tiler import colormap, utils
from rio_tiler.constants import WEB_MERCATOR_TMS, WGS84_CRS
from rio_tiler.errors import InvalidRowColOperator, RioTilerError
from rio_tiler.errors import RioTilerError
from rio_tiler.expression import parse_expression
from rio_tiler.io import Reader

Expand Down Expand Up @@ -289,14 +289,12 @@ def test_cutline():
feature_bounds = featureBounds(feat)

with Reader(COGEO) as src:
cutline = utils.create_cutline(
src.dataset, feat, geometry_crs="epsg:4326", op=math.floor
)
cutline = utils.create_cutline(src.dataset, feat, geometry_crs="epsg:4326")
data, mask = src.part(feature_bounds, vrt_options={"cutline": cutline})
assert not mask.all()

cutline = utils.create_cutline(
src.dataset, feat["geometry"], geometry_crs="epsg:4326", op=math.floor
src.dataset, feat["geometry"], geometry_crs="epsg:4326"
)
data, mask = src.part(feature_bounds, vrt_options={"cutline": cutline})
assert not mask.all()
Expand All @@ -317,9 +315,7 @@ def test_cutline():

with Reader(COGEO) as src:
with pytest.raises(RioTilerError):
utils.create_cutline(
src.dataset, feat_line, geometry_crs="epsg:4326", op=math.floor
)
utils.create_cutline(src.dataset, feat_line, geometry_crs="epsg:4326")

feat_mp = {
"type": "MultiPolygon",
Expand All @@ -346,9 +342,7 @@ def test_cutline():
}

with Reader(COGEO) as src:
c = utils.create_cutline(
src.dataset, feat_mp, geometry_crs="epsg:4326", op=math.floor
)
c = utils.create_cutline(src.dataset, feat_mp, geometry_crs="epsg:4326")
assert "MULTIPOLYGON" in c

bad_poly = {
Expand All @@ -368,9 +362,7 @@ def test_cutline():

with Reader(COGEO) as src:
with pytest.raises(RioTilerError):
utils.create_cutline(
src.dataset, bad_poly, geometry_crs="epsg:4326", op=math.floor
)
utils.create_cutline(src.dataset, bad_poly, geometry_crs="epsg:4326")

triangle_over_image_edge = {
"type": "Polygon",
Expand All @@ -389,20 +381,67 @@ def test_cutline():
triangle_bounds = featureBounds(triangle_over_image_edge)
with Reader(COG_RGB) as src:
cutline = utils.create_cutline(
src.dataset, triangle_over_image_edge, geometry_crs="epsg:4326", op=math.floor
src.dataset, triangle_over_image_edge, geometry_crs="epsg:4326"
)
data, mask = src.part(triangle_bounds, vrt_options={"cutline": cutline})
assert sum(mask[:, 0]) == 0 # first column
assert sum(mask[0, :]) == 0 # first line
assert sum(mask[-1, :]) == 0 # last line

# Check create_cutline operator callable is one of rasterio rowcol accepted method
with Reader(COGEO) as src:
invalid_op = abs
with pytest.raises(InvalidRowColOperator):
utils.create_cutline(
src.dataset, bad_poly, geometry_crs="epsg:4326", op=invalid_op

def test_cutline_operator(dataset_fixture):
"""Test rio_tiler.utils.create_cutline with operators."""
with MemoryFile(
dataset_fixture(
crs=CRS.from_epsg(4326),
bounds=(-175.0, -85, 175.0, 85.0),
dtype="uint8",
nodata_type="nodata",
width=720,
height=360,
)
) as memfile:
with memfile.open() as src_dst:
feat = {
"type": "Polygon",
"coordinates": [
[
[-163.0, -83.0],
[163.0, -83.0],
[163.0, 83.0],
[-163.0, 83.0],
[-163.0, -83.0],
]
],
}
cutline = utils.create_cutline(
src_dst,
feat,
geometry_crs="epsg:4326",
)
cutline_mathfloor = utils.create_cutline(
src_dst,
feat,
geometry_crs="epsg:4326",
op=math.floor,
)
assert cutline == cutline_mathfloor

cutline_npfloor = utils.create_cutline(
src_dst,
feat,
geometry_crs="epsg:4326",
op=np.floor,
)
assert cutline_npfloor == cutline_mathfloor

cutline_npceil = utils.create_cutline(
src_dst,
feat,
geometry_crs="epsg:4326",
op=np.ceil,
)
assert cutline_npceil != cutline_npfloor


def test_parse_expression():
Expand Down

0 comments on commit 380f20e

Please sign in to comment.