mirror of
https://github.com/rasterio/rasterio.git
synced 2026-02-01 14:34:43 +00:00
Align inputs/outputs with rio-merge
This means addition of `--output` option, use of the files_inout_arg decorator, and helpers. Additionally, turn _warp's RESAMPLING named tuple into an int enum, more useful in the CLI and other modules.
This commit is contained in:
parent
c9645b88db
commit
906b4ddc5b
@ -1,6 +1,7 @@
|
||||
# distutils: language = c++
|
||||
|
||||
from collections import namedtuple
|
||||
from enum import IntEnum
|
||||
|
||||
import logging
|
||||
|
||||
import numpy as np
|
||||
@ -39,14 +40,19 @@ cdef extern from "gdalwarper.h" nogil:
|
||||
double dfProgressScale=1.0)
|
||||
|
||||
|
||||
RESAMPLING = namedtuple('RESAMPLING', [
|
||||
'nearest',
|
||||
'bilinear',
|
||||
'cubic',
|
||||
'cubic_spline',
|
||||
'lanczos',
|
||||
'average',
|
||||
'mode'] )(*list(range(7)))
|
||||
class Resampling(IntEnum):
|
||||
nearest=0
|
||||
bilinear=1
|
||||
cubic=2
|
||||
cubic_spline=3
|
||||
lanczos=4
|
||||
average=5
|
||||
mode=6
|
||||
max=8
|
||||
min=9
|
||||
med=10
|
||||
q1=11
|
||||
q3=12
|
||||
|
||||
|
||||
cdef extern from "ogr_geometry.h" nogil:
|
||||
@ -56,9 +62,6 @@ cdef extern from "ogr_geometry.h" nogil:
|
||||
|
||||
cdef cppclass OGRGeometryFactory:
|
||||
void * transformWithOptions(void *geom, void *ct, char **options)
|
||||
# const OGRGeometry* poSrcGeom,
|
||||
# OGRCoordinateTransformation *poCT,
|
||||
# char** papszOptions
|
||||
|
||||
|
||||
cdef extern from "ogr_spatialref.h":
|
||||
@ -164,7 +167,7 @@ def _reproject(
|
||||
dst_transform=None,
|
||||
dst_crs=None,
|
||||
dst_nodata=None,
|
||||
resampling=RESAMPLING.nearest,
|
||||
resampling=Resampling.nearest,
|
||||
**kwargs):
|
||||
"""
|
||||
Reproject a source raster to a destination raster.
|
||||
@ -209,13 +212,13 @@ def _reproject(
|
||||
src_nodata, or 0 (gdal default).
|
||||
resampling: int
|
||||
Resampling method to use. One of the following:
|
||||
RESAMPLING.nearest,
|
||||
RESAMPLING.bilinear,
|
||||
RESAMPLING.cubic,
|
||||
RESAMPLING.cubic_spline,
|
||||
RESAMPLING.lanczos,
|
||||
RESAMPLING.average,
|
||||
RESAMPLING.mode
|
||||
Resampling.nearest,
|
||||
Resampling.bilinear,
|
||||
Resampling.cubic,
|
||||
Resampling.cubic_spline,
|
||||
Resampling.lanczos,
|
||||
Resampling.average,
|
||||
Resampling.mode
|
||||
kwargs: dict, optional
|
||||
Additional arguments passed to transformation function.
|
||||
|
||||
|
||||
@ -3,23 +3,26 @@ from math import ceil
|
||||
import warnings
|
||||
|
||||
import click
|
||||
from cligj import format_opt
|
||||
from cligj import files_inout_arg, format_opt
|
||||
|
||||
from .helpers import resolve_inout
|
||||
from . import options
|
||||
import rasterio
|
||||
from rasterio import crs
|
||||
from rasterio.transform import Affine
|
||||
from rasterio.warp import (reproject, RESAMPLING, calculate_default_transform,
|
||||
from rasterio.warp import (reproject, Resampling, calculate_default_transform,
|
||||
transform_bounds)
|
||||
|
||||
|
||||
MAX_OUTPUT_WIDTH = 50000
|
||||
MAX_OUTPUT_HEIGHT = 50000
|
||||
|
||||
logger = logging.getLogger('rio')
|
||||
# Improper usage of rio-warp can lead to accidental creation of
|
||||
# extremely large datasets. We'll put a hard limit on the size of
|
||||
# datasets and raise a usage error if the limits are exceeded.
|
||||
MAX_OUTPUT_WIDTH = 100000
|
||||
MAX_OUTPUT_HEIGHT = 100000
|
||||
|
||||
|
||||
def bounds_handler(ctx, param, value):
|
||||
"""Warn about future usage changes."""
|
||||
if value:
|
||||
click.echo("Future Warning: "
|
||||
"the semantics of the `--bounds` option will change in Rasterio "
|
||||
@ -29,6 +32,7 @@ def bounds_handler(ctx, param, value):
|
||||
|
||||
|
||||
def x_dst_bounds_handler(ctx, param, value):
|
||||
"""Warn about future usage changes."""
|
||||
if value:
|
||||
click.echo("Future Warning: "
|
||||
"the `--x-dst-bounds` option will be removed in Rasterio version "
|
||||
@ -37,8 +41,8 @@ def x_dst_bounds_handler(ctx, param, value):
|
||||
|
||||
|
||||
@click.command(short_help='Warp a raster dataset.')
|
||||
@options.file_in_arg
|
||||
@options.file_out_arg
|
||||
@files_inout_arg
|
||||
@options.output_opt
|
||||
@format_opt
|
||||
@options.like_file_opt
|
||||
@click.option('--dst-crs', default=None,
|
||||
@ -61,45 +65,30 @@ def x_dst_bounds_handler(ctx, param, value):
|
||||
"(note: the semantics of this option will change to those of "
|
||||
"`--x-dst-bounds` in version 1.0).")
|
||||
@options.resolution_opt
|
||||
@click.option('--resampling', type=click.Choice(['nearest', 'bilinear', 'cubic',
|
||||
'cubic_spline','lanczos', 'average', 'mode']),
|
||||
default='nearest', help='Resampling method (default: nearest).')
|
||||
@click.option('--resampling', type=click.Choice([r.name for r in Resampling]),
|
||||
default='nearest', help="Resampling method.",
|
||||
show_default=True)
|
||||
@click.option('--threads', type=int, default=2,
|
||||
help='Number of processing threads.')
|
||||
@options.force_overwrite_opt
|
||||
@options.creation_options
|
||||
@click.pass_context
|
||||
# TODO: add NODATA options and support for existing output rasters
|
||||
def warp(
|
||||
ctx,
|
||||
input,
|
||||
output,
|
||||
driver,
|
||||
like,
|
||||
dst_crs,
|
||||
dimensions,
|
||||
src_bounds,
|
||||
x_dst_bounds,
|
||||
bounds,
|
||||
res,
|
||||
resampling,
|
||||
threads,
|
||||
creation_options):
|
||||
def warp(ctx, files, output, driver, like, dst_crs, dimensions, src_bounds,
|
||||
x_dst_bounds, bounds, res, resampling, threads, force_overwrite,
|
||||
creation_options):
|
||||
"""
|
||||
Warp a raster dataset.
|
||||
|
||||
Currently, the output is always overwritten. This will be changed in a
|
||||
later version.
|
||||
|
||||
If a template raster is provided using the --like option, the coordinate
|
||||
reference system, affine transform, and dimensions of that raster will
|
||||
be used for the output. In this case --dst-crs, --bounds, --res, and
|
||||
--dimensions options are ignored.
|
||||
If a template raster is provided using the --like option, the
|
||||
coordinate reference system, affine transform, and dimensions of
|
||||
that raster will be used for the output. In this case --dst-crs,
|
||||
--bounds, --res, and --dimensions options are ignored.
|
||||
|
||||
\b
|
||||
$ rio warp input.tif output.tif --like template.tif
|
||||
|
||||
The output coordinate reference system may be either a PROJ.4 or EPSG:nnnn
|
||||
string,
|
||||
The output coordinate reference system may be either a PROJ.4 or
|
||||
EPSG:nnnn string,
|
||||
|
||||
\b
|
||||
--dst-crs EPSG:4326
|
||||
@ -110,13 +99,14 @@ def warp(
|
||||
\b
|
||||
--dst-crs '{"proj": "utm", "zone": 18, ...}'
|
||||
|
||||
If --dimensions are provided, --res and --bounds are ignored. Resolution
|
||||
is calculated based on the relationship between the raster bounds in the
|
||||
target coordinate system and the dimensions, and may produce rectangular
|
||||
rather than square pixels.
|
||||
If --dimensions are provided, --res and --bounds are ignored.
|
||||
Resolution is calculated based on the relationship between the
|
||||
raster bounds in the target coordinate system and the dimensions,
|
||||
and may produce rectangular rather than square pixels.
|
||||
|
||||
\b
|
||||
$ rio warp input.tif output.tif --dimensions 100 200 --dst-crs EPSG:4326
|
||||
$ rio warp input.tif output.tif --dimensions 100 200 \\
|
||||
> --dst-crs EPSG:4326
|
||||
|
||||
If --bounds are provided, --res is required if --dst-crs is provided
|
||||
(defaults to source raster resolution otherwise).
|
||||
@ -128,7 +118,12 @@ def warp(
|
||||
"""
|
||||
|
||||
verbosity = (ctx.obj and ctx.obj.get('verbosity')) or 1
|
||||
resampling = getattr(RESAMPLING, resampling) # get integer code for method
|
||||
logger = logging.getLogger('rio')
|
||||
|
||||
output, files = resolve_inout(
|
||||
files=files, output=output, force_overwrite=force_overwrite)
|
||||
|
||||
resampling = Resampling[resampling] # get integer code for method
|
||||
|
||||
if not len(res):
|
||||
# Click sets this as an empty tuple if not provided
|
||||
@ -138,7 +133,7 @@ def warp(
|
||||
res = (res[0], res[0]) if len(res) == 1 else res
|
||||
|
||||
with rasterio.drivers(CPL_DEBUG=verbosity > 2):
|
||||
with rasterio.open(input) as src:
|
||||
with rasterio.open(files[0]) as src:
|
||||
l, b, r, t = src.bounds
|
||||
out_kwargs = src.meta.copy()
|
||||
out_kwargs['driver'] = driver
|
||||
@ -166,7 +161,8 @@ def warp(
|
||||
param=dst_crs, param_hint=dst_crs)
|
||||
|
||||
if dimensions:
|
||||
# Calculate resolution appropriate for dimensions in target
|
||||
# Calculate resolution appropriate for dimensions
|
||||
# in target.
|
||||
dst_width, dst_height = dimensions
|
||||
xmin, ymin, xmax, ymax = transform_bounds(src.crs, dst_crs,
|
||||
*src.bounds)
|
||||
@ -179,7 +175,8 @@ def warp(
|
||||
|
||||
elif src_bounds or dst_bounds:
|
||||
if not res:
|
||||
raise click.BadParameter('Required when using --bounds',
|
||||
raise click.BadParameter(
|
||||
"Required when using --bounds.",
|
||||
param='res', param_hint='res')
|
||||
|
||||
if src_bounds:
|
||||
@ -198,7 +195,7 @@ def warp(
|
||||
resolution=res)
|
||||
|
||||
elif dimensions:
|
||||
# Same projection, different dimensions, calculate resolution
|
||||
# Same projection, different dimensions, calculate resolution.
|
||||
dst_crs = src.crs
|
||||
dst_width, dst_height = dimensions
|
||||
dst_transform = Affine(
|
||||
@ -209,8 +206,8 @@ def warp(
|
||||
)
|
||||
|
||||
elif src_bounds or dst_bounds:
|
||||
# Same projection, different dimensions and possibly different
|
||||
# resolution
|
||||
# Same projection, different dimensions and possibly
|
||||
# different resolution.
|
||||
if not res:
|
||||
res = (src.affine.a, -src.affine.e)
|
||||
|
||||
@ -221,7 +218,7 @@ def warp(
|
||||
dst_height = max(int(ceil((ymax - ymin) / res[1])), 1)
|
||||
|
||||
elif res:
|
||||
# Same projection, different resolution
|
||||
# Same projection, different resolution.
|
||||
dst_crs = src.crs
|
||||
dst_transform = Affine(res[0], 0, l, 0, -res[1], t)
|
||||
dst_width = max(int(ceil((r - l) / res[0])), 1)
|
||||
|
||||
@ -5,7 +5,7 @@ from math import ceil
|
||||
import numpy as np
|
||||
|
||||
from rasterio._base import _transform
|
||||
from rasterio._warp import _transform_geom, _reproject, RESAMPLING
|
||||
from rasterio._warp import _transform_geom, _reproject, Resampling
|
||||
from rasterio.transform import guard_transform
|
||||
|
||||
|
||||
@ -150,7 +150,7 @@ def reproject(
|
||||
dst_transform=None,
|
||||
dst_crs=None,
|
||||
dst_nodata=None,
|
||||
resampling=RESAMPLING.nearest,
|
||||
resampling=Resampling.nearest,
|
||||
**kwargs):
|
||||
"""
|
||||
Reproject a source raster to a destination raster.
|
||||
@ -195,13 +195,13 @@ def reproject(
|
||||
src_nodata, or 0 (GDAL default).
|
||||
resampling: int
|
||||
Resampling method to use. One of the following:
|
||||
RESAMPLING.nearest,
|
||||
RESAMPLING.bilinear,
|
||||
RESAMPLING.cubic,
|
||||
RESAMPLING.cubic_spline,
|
||||
RESAMPLING.lanczos,
|
||||
RESAMPLING.average,
|
||||
RESAMPLING.mode
|
||||
Resampling.nearest,
|
||||
Resampling.bilinear,
|
||||
Resampling.cubic,
|
||||
Resampling.cubic_spline,
|
||||
Resampling.lanczos,
|
||||
Resampling.average,
|
||||
Resampling.mode
|
||||
kwargs: dict, optional
|
||||
Additional arguments passed to transformation function.
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ import numpy
|
||||
|
||||
import rasterio
|
||||
from rasterio.warp import (
|
||||
reproject, RESAMPLING, transform_geom, transform, transform_bounds,
|
||||
reproject, Resampling, transform_geom, transform, transform_bounds,
|
||||
calculate_default_transform)
|
||||
|
||||
|
||||
@ -208,7 +208,7 @@ def test_reproject_ndarray():
|
||||
src_crs=src.crs,
|
||||
dst_transform=DST_TRANSFORM,
|
||||
dst_crs=dst_crs,
|
||||
resampling=RESAMPLING.nearest)
|
||||
resampling=Resampling.nearest)
|
||||
assert (out > 0).sum() == 438146
|
||||
|
||||
|
||||
@ -226,7 +226,7 @@ def test_reproject_epsg():
|
||||
src_crs=src.crs,
|
||||
dst_transform=DST_TRANSFORM,
|
||||
dst_crs=dst_crs,
|
||||
resampling=RESAMPLING.nearest)
|
||||
resampling=Resampling.nearest)
|
||||
assert (out > 0).sum() == 438146
|
||||
|
||||
|
||||
@ -245,7 +245,7 @@ def test_reproject_out_of_bounds():
|
||||
src_crs=src.crs,
|
||||
dst_transform=DST_TRANSFORM,
|
||||
dst_crs=dst_crs,
|
||||
resampling=RESAMPLING.nearest)
|
||||
resampling=Resampling.nearest)
|
||||
assert not out.any()
|
||||
|
||||
|
||||
@ -418,7 +418,7 @@ def test_reproject_multi():
|
||||
src_crs=src.crs,
|
||||
dst_transform=DST_TRANSFORM,
|
||||
dst_crs=dst_crs,
|
||||
resampling=RESAMPLING.nearest)
|
||||
resampling=Resampling.nearest)
|
||||
assert destin.any()
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user