Is there a way to crop by image coordinates? #428
-
Hello! If I understand correctly, the current /crop endpoint only allows cropping by geocoordinates (lat/lon)? Is there another endpoint that allows cropping by image x,y (lines,sample)? |
Beta Was this translation helpful? Give feedback.
Answered by
vincentsarago
Jan 31, 2022
Replies: 1 comment 1 reply
-
👋 @rbudhu Good question! No there is not but here is how you could add one: from fastapi import FastAPI, Path, Query, Depends
from titiler.core.factory import TilerFactory, img_endpoint_params
from titiler.core.utils import Timer
from titiler.core.resources.enums import ImageType
from rasterio import windows
app = FastAPI(description="A lightweight Cloud Optimized GeoTIFF tile server")
# Create a Default set of endpoint using the TilerFactory
cog = TilerFactory()
# Register a custom `/window` endpoint
@cog.router.get(
# https://rasterio.readthedocs.io/en/latest/topics/windowed-rw.html?highlight=window#windows
# simple path parameters to define a rasterio window
r"/window/{col_off},{row_off},{width},{height}.{format}",
**img_endpoint_params,
)
def window(
col_off: int = Path(..., description="Column offset"),
row_off: int = Path(..., description="Row offset"),
width: int = Path(..., description="Width"),
height: int = Path(..., description="Height"),
format: ImageType = Query(..., description="Output image type."),
src_path=Depends(cog.path_dependency),
layer_params=Depends(cog.layer_dependency),
dataset_params=Depends(cog.dataset_dependency),
postprocess_params=Depends(cog.process_dependency),
colormap=Depends(cog.colormap_dependency),
render_params=Depends(cog.render_dependency),
):
"""Read a window."""
timings = []
headers: Dict[str, str] = {}
with Timer() as t:
with rasterio.Env(**self.gdal_config):
with self.reader(src_path) as src_dst:
# https://github.com/cogeotiff/rio-tiler/blob/master/rio_tiler/io/cogeo.py#L600-L605
data = src_dst.read(
window=windows.Window(col_off, row_off, width, height),
**dataset_params,
)
dst_colormap = getattr(src_dst, "colormap", None)
timings.append(("dataread", round(t.elapsed * 1000, 2)))
with Timer() as t:
image = data.post_process(**postprocess_params)
timings.append(("postprocess", round(t.elapsed * 1000, 2)))
with Timer() as t:
content = image.render(
img_format=format.driver,
colormap=colormap or dst_colormap,
**format.profile,
**render_params,
)
timings.append(("format", round(t.elapsed * 1000, 2)))
if OptionalHeader.server_timing in self.optional_headers:
headers["Server-Timing"] = ", ".join(
[f"{name};dur={time}" for (name, time) in timings]
)
return Response(content, media_type=format.mediatype, headers=headers)
app.include_router(cog.router, tags=["Cloud Optimized GeoTIFF"]) |
Beta Was this translation helpful? Give feedback.
1 reply
Answer selected by
vincentsarago
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
👋 @rbudhu
Good question! No there is not but here is how you could add one: