We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
rio warp like silently ignores res override
The obvious starting place is `rio warp --like` but this doesn't allow you to override the resolution. It silently ignores the `--res` option which could be considered a bug. 

```
$ rio warp --like b.tif --res 5  a.tif c.tif
$ rio info --res c.tif
1.0 1.0
```

In this case, warp should either a) override the resolution of the like raster or b) raise an exception saying that it's not supported


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `rasterio/rio/warp.py`
Content:
```
1 import logging
2 from math import ceil, floor, log
3 import warnings
4 
5 import click
6 from cligj import files_inout_arg, format_opt
7 
8 from .helpers import resolve_inout
9 from . import options
10 import rasterio
11 from rasterio.crs import CRS
12 from rasterio.errors import CRSError
13 from rasterio.transform import Affine
14 from rasterio.warp import (
15     reproject, Resampling, calculate_default_transform, transform_bounds)
16 
17 
18 # Improper usage of rio-warp can lead to accidental creation of
19 # extremely large datasets. We'll put a hard limit on the size of
20 # datasets and raise a usage error if the limits are exceeded.
21 MAX_OUTPUT_WIDTH = 100000
22 MAX_OUTPUT_HEIGHT = 100000
23 
24 
25 @click.command(short_help='Warp a raster dataset.')
26 @files_inout_arg
27 @options.output_opt
28 @format_opt
29 @click.option(
30     '--like',
31     type=click.Path(exists=True),
32     help='Raster dataset to use as a template for obtaining affine '
33          'transform (bounds and resolution), and crs.')
34 @click.option('--dst-crs', default=None,
35               help='Target coordinate reference system.')
36 @options.dimensions_opt
37 @click.option(
38     '--src-bounds',
39     nargs=4, type=float, default=None,
40     help="Determine output extent from source bounds: left bottom right top "
41          ". Cannot be used with destination --bounds")
42 @click.option(
43     '--bounds', '--dst-bounds', nargs=4, type=float, default=None,
44     help="Determine output extent from destination bounds: left bottom right top")
45 @options.resolution_opt
46 @click.option('--resampling', type=click.Choice([r.name for r in Resampling]),
47               default='nearest', help="Resampling method.",
48               show_default=True)
49 @click.option('--src-nodata', default=None, show_default=True,
50               type=float, help="Manually override source nodata")
51 @click.option('--dst-nodata', default=None, show_default=True,
52               type=float, help="Manually override destination nodata")
53 @click.option('--threads', type=int, default=1,
54               help='Number of processing threads.')
55 @click.option('--check-invert-proj', is_flag=True, default=True,
56               help='Constrain output to valid coordinate region in dst-crs')
57 @options.force_overwrite_opt
58 @options.creation_options
59 @click.pass_context
60 def warp(ctx, files, output, driver, like, dst_crs, dimensions, src_bounds,
61          dst_bounds, res, resampling, src_nodata, dst_nodata, threads,
62          check_invert_proj, force_overwrite, creation_options):
63     """
64     Warp a raster dataset.
65 
66     If a template raster is provided using the --like option, the
67     coordinate reference system, affine transform, and dimensions of
68     that raster will be used for the output.  In this case --dst-crs,
69     --bounds, --res, and --dimensions options are ignored.
70 
71     \b
72         $ rio warp input.tif output.tif --like template.tif
73 
74     The output coordinate reference system may be either a PROJ.4 or
75     EPSG:nnnn string,
76 
77     \b
78         --dst-crs EPSG:4326
79         --dst-crs '+proj=longlat +ellps=WGS84 +datum=WGS84'
80 
81     or a JSON text-encoded PROJ.4 object.
82 
83     \b
84         --dst-crs '{"proj": "utm", "zone": 18, ...}'
85 
86     If --dimensions are provided, --res and --bounds are ignored.
87     Resolution is calculated based on the relationship between the
88     raster bounds in the target coordinate system and the dimensions,
89     and may produce rectangular rather than square pixels.
90 
91     \b
92         $ rio warp input.tif output.tif --dimensions 100 200 \\
93         > --dst-crs EPSG:4326
94 
95     If --bounds are provided, --res is required if --dst-crs is provided
96     (defaults to source raster resolution otherwise).
97 
98     \b
99         $ rio warp input.tif output.tif \\
100         > --bounds -78 22 -76 24 --res 0.1 --dst-crs EPSG:4326
101 
102     """
103     verbosity = (ctx.obj and ctx.obj.get('verbosity')) or 1
104 
105     output, files = resolve_inout(
106         files=files, output=output, force_overwrite=force_overwrite)
107 
108     resampling = Resampling[resampling]  # get integer code for method
109 
110     if not len(res):
111         # Click sets this as an empty tuple if not provided
112         res = None
113     else:
114         # Expand one value to two if needed
115         res = (res[0], res[0]) if len(res) == 1 else res
116 
117     with rasterio.Env(CPL_DEBUG=verbosity > 2,
118                       CHECK_WITH_INVERT_PROJ=check_invert_proj):
119         with rasterio.open(files[0]) as src:
120             l, b, r, t = src.bounds
121             out_kwargs = src.profile.copy()
122             out_kwargs['driver'] = driver
123 
124             # Sort out the bounds options.
125             if src_bounds and dst_bounds:
126                 raise click.BadParameter(
127                     "--src-bounds and destination --bounds may not be specified "
128                     "simultaneously.")
129 
130             if like:
131                 with rasterio.open(like) as template_ds:
132                     dst_crs = template_ds.crs
133                     dst_transform = template_ds.affine
134                     dst_height = template_ds.height
135                     dst_width = template_ds.width
136 
137             elif dst_crs is not None:
138                 try:
139                     dst_crs = CRS.from_string(dst_crs)
140                 except ValueError as err:
141                     raise click.BadParameter(
142                         str(err), param='dst_crs', param_hint='dst_crs')
143 
144                 if dimensions:
145                     # Calculate resolution appropriate for dimensions
146                     # in target.
147                     dst_width, dst_height = dimensions
148                     try:
149                         xmin, ymin, xmax, ymax = transform_bounds(
150                             src.crs, dst_crs, *src.bounds)
151                     except CRSError as err:
152                         raise click.BadParameter(
153                             str(err), param='dst_crs', param_hint='dst_crs')
154                     dst_transform = Affine(
155                         (xmax - xmin) / float(dst_width),
156                         0, xmin, 0,
157                         (ymin - ymax) / float(dst_height),
158                         ymax
159                     )
160 
161                 elif src_bounds or dst_bounds:
162                     if not res:
163                         raise click.BadParameter(
164                             "Required when using --bounds.",
165                             param='res', param_hint='res')
166 
167                     if src_bounds:
168                         try:
169                             xmin, ymin, xmax, ymax = transform_bounds(
170                                 src.crs, dst_crs, *src_bounds)
171                         except CRSError as err:
172                             raise click.BadParameter(
173                                 str(err), param='dst_crs',
174                                 param_hint='dst_crs')
175                     else:
176                         xmin, ymin, xmax, ymax = dst_bounds
177 
178                     dst_transform = Affine(res[0], 0, xmin, 0, -res[1], ymax)
179                     dst_width = max(int(ceil((xmax - xmin) / res[0])), 1)
180                     dst_height = max(int(ceil((ymax - ymin) / res[1])), 1)
181 
182                 else:
183                     try:
184                         dst_transform, dst_width, dst_height = calculate_default_transform(
185                             src.crs, dst_crs, src.width, src.height,
186                             *src.bounds, resolution=res)
187                     except CRSError as err:
188                         raise click.BadParameter(
189                             str(err), param='dst_crs', param_hint='dst_crs')
190             elif dimensions:
191                 # Same projection, different dimensions, calculate resolution.
192                 dst_crs = src.crs
193                 dst_width, dst_height = dimensions
194                 dst_transform = Affine(
195                     (r - l) / float(dst_width),
196                     0, l, 0,
197                     (b - t) / float(dst_height),
198                     t
199                 )
200 
201             elif src_bounds or dst_bounds:
202                 # Same projection, different dimensions and possibly
203                 # different resolution.
204                 if not res:
205                     res = (src.affine.a, -src.affine.e)
206 
207                 dst_crs = src.crs
208                 xmin, ymin, xmax, ymax = (src_bounds or dst_bounds)
209                 dst_transform = Affine(res[0], 0, xmin, 0, -res[1], ymax)
210                 dst_width = max(int(ceil((xmax - xmin) / res[0])), 1)
211                 dst_height = max(int(ceil((ymax - ymin) / res[1])), 1)
212 
213             elif res:
214                 # Same projection, different resolution.
215                 dst_crs = src.crs
216                 dst_transform = Affine(res[0], 0, l, 0, -res[1], t)
217                 dst_width = max(int(ceil((r - l) / res[0])), 1)
218                 dst_height = max(int(ceil((t - b) / res[1])), 1)
219 
220             else:
221                 dst_crs = src.crs
222                 dst_transform = src.affine
223                 dst_width = src.width
224                 dst_height = src.height
225 
226             # If src_nodata is not None, update the dst metadata NODATA
227             # value to src_nodata (will be overridden by dst_nodata if it is not None
228             if src_nodata is not None:
229                 # Update the dst nodata value
230                 out_kwargs.update({
231                     'nodata': src_nodata
232                 })
233 
234             # Validate a manually set destination NODATA value
235             # against the input datatype.
236             if dst_nodata is not None:
237                 if src_nodata is None and src.meta['nodata'] is None:
238                     raise click.BadParameter(
239                         "--src-nodata must be provided because dst-nodata is not None")
240                 else:
241                     # Update the dst nodata value
242                     out_kwargs.update({'nodata': dst_nodata})
243 
244             # When the bounds option is misused, extreme values of
245             # destination width and height may result.
246             if (dst_width < 0 or dst_height < 0 or
247                     dst_width > MAX_OUTPUT_WIDTH or
248                     dst_height > MAX_OUTPUT_HEIGHT):
249                 raise click.BadParameter(
250                     "Invalid output dimensions: {0}.".format(
251                         (dst_width, dst_height)))
252 
253             out_kwargs.update({
254                 'crs': dst_crs,
255                 'transform': dst_transform,
256                 'affine': dst_transform,
257                 'width': dst_width,
258                 'height': dst_height
259             })
260 
261             # Adjust block size if necessary.
262             if ('blockxsize' in out_kwargs and
263                     dst_width < out_kwargs['blockxsize']):
264                 del out_kwargs['blockxsize']
265             if ('blockysize' in out_kwargs and
266                     dst_height < out_kwargs['blockysize']):
267                 del out_kwargs['blockysize']
268 
269             out_kwargs.update(**creation_options)
270 
271             with rasterio.open(output, 'w', **out_kwargs) as dst:
272                 reproject(
273                     source=rasterio.band(src, list(range(1, src.count + 1))),
274                     destination=rasterio.band(
275                         dst, list(range(1, src.count + 1))),
276                     src_transform=src.affine,
277                     src_crs=src.crs,
278                     src_nodata=src_nodata,
279                     dst_transform=out_kwargs['transform'],
280                     dst_crs=out_kwargs['crs'],
281                     dst_nodata=dst_nodata,
282                     resampling=resampling,
283                     num_threads=threads)
284
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/rasterio/rio/warp.py b/rasterio/rio/warp.py
--- a/rasterio/rio/warp.py
+++ b/rasterio/rio/warp.py
@@ -66,7 +66,8 @@
     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.
+    --bounds, --res, and --dimensions options are not applicable and
+    an exception will be raised.
 
     \b
         $ rio warp input.tif output.tif --like template.tif
@@ -83,7 +84,8 @@
     \b
         --dst-crs '{"proj": "utm", "zone": 18, ...}'
 
-    If --dimensions are provided, --res and --bounds are ignored.
+    If --dimensions are provided, --res and --bounds are not applicable and an
+    exception will be raised.
     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.
@@ -114,6 +116,20 @@
         # Expand one value to two if needed
         res = (res[0], res[0]) if len(res) == 1 else res
 
+    # Check invalid parameter combinations
+    if like:
+        invalid_combos = (dimensions, dst_bounds, dst_crs, res)
+        if any(p for p in invalid_combos if p is not None):
+            raise click.BadParameter(
+                "--like cannot be used with any of --dimensions, --bounds, "
+                "--dst-crs, or --res")
+
+    elif dimensions:
+        invalid_combos = (dst_bounds, res)
+        if any(p for p in invalid_combos if p is not None):
+            raise click.BadParameter(
+                "--dimensions cannot be used with --bounds or --res")
+
     with rasterio.Env(CPL_DEBUG=verbosity > 2,
                       CHECK_WITH_INVERT_PROJ=check_invert_proj):
         with rasterio.open(files[0]) as src:

{"golden_diff": "diff --git a/rasterio/rio/warp.py b/rasterio/rio/warp.py\n--- a/rasterio/rio/warp.py\n+++ b/rasterio/rio/warp.py\n@@ -66,7 +66,8 @@\n     If a template raster is provided using the --like option, the\n     coordinate reference system, affine transform, and dimensions of\n     that raster will be used for the output.  In this case --dst-crs,\n-    --bounds, --res, and --dimensions options are ignored.\n+    --bounds, --res, and --dimensions options are not applicable and\n+    an exception will be raised.\n \n     \\b\n         $ rio warp input.tif output.tif --like template.tif\n@@ -83,7 +84,8 @@\n     \\b\n         --dst-crs '{\"proj\": \"utm\", \"zone\": 18, ...}'\n \n-    If --dimensions are provided, --res and --bounds are ignored.\n+    If --dimensions are provided, --res and --bounds are not applicable and an\n+    exception will be raised.\n     Resolution is calculated based on the relationship between the\n     raster bounds in the target coordinate system and the dimensions,\n     and may produce rectangular rather than square pixels.\n@@ -114,6 +116,20 @@\n         # Expand one value to two if needed\n         res = (res[0], res[0]) if len(res) == 1 else res\n \n+    # Check invalid parameter combinations\n+    if like:\n+        invalid_combos = (dimensions, dst_bounds, dst_crs, res)\n+        if any(p for p in invalid_combos if p is not None):\n+            raise click.BadParameter(\n+                \"--like cannot be used with any of --dimensions, --bounds, \"\n+                \"--dst-crs, or --res\")\n+\n+    elif dimensions:\n+        invalid_combos = (dst_bounds, res)\n+        if any(p for p in invalid_combos if p is not None):\n+            raise click.BadParameter(\n+                \"--dimensions cannot be used with --bounds or --res\")\n+\n     with rasterio.Env(CPL_DEBUG=verbosity > 2,\n                       CHECK_WITH_INVERT_PROJ=check_invert_proj):\n         with rasterio.open(files[0]) as src:\n", "issue": "rio warp like silently ignores res override\nThe obvious starting place is `rio warp --like` but this doesn't allow you to override the resolution. It silently ignores the `--res` option which could be considered a bug. \n\n```\n$ rio warp --like b.tif --res 5  a.tif c.tif\n$ rio info --res c.tif\n1.0 1.0\n```\n\nIn this case, warp should either a) override the resolution of the like raster or b) raise an exception saying that it's not supported\n\n", "before_files": [{"content": "import logging\nfrom math import ceil, floor, log\nimport warnings\n\nimport click\nfrom cligj import files_inout_arg, format_opt\n\nfrom .helpers import resolve_inout\nfrom . import options\nimport rasterio\nfrom rasterio.crs import CRS\nfrom rasterio.errors import CRSError\nfrom rasterio.transform import Affine\nfrom rasterio.warp import (\n    reproject, Resampling, calculate_default_transform, transform_bounds)\n\n\n# Improper usage of rio-warp can lead to accidental creation of\n# extremely large datasets. We'll put a hard limit on the size of\n# datasets and raise a usage error if the limits are exceeded.\nMAX_OUTPUT_WIDTH = 100000\nMAX_OUTPUT_HEIGHT = 100000\n\n\n@click.command(short_help='Warp a raster dataset.')\n@files_inout_arg\n@options.output_opt\n@format_opt\n@click.option(\n    '--like',\n    type=click.Path(exists=True),\n    help='Raster dataset to use as a template for obtaining affine '\n         'transform (bounds and resolution), and crs.')\n@click.option('--dst-crs', default=None,\n              help='Target coordinate reference system.')\n@options.dimensions_opt\n@click.option(\n    '--src-bounds',\n    nargs=4, type=float, default=None,\n    help=\"Determine output extent from source bounds: left bottom right top \"\n         \". Cannot be used with destination --bounds\")\n@click.option(\n    '--bounds', '--dst-bounds', nargs=4, type=float, default=None,\n    help=\"Determine output extent from destination bounds: left bottom right top\")\n@options.resolution_opt\n@click.option('--resampling', type=click.Choice([r.name for r in Resampling]),\n              default='nearest', help=\"Resampling method.\",\n              show_default=True)\n@click.option('--src-nodata', default=None, show_default=True,\n              type=float, help=\"Manually override source nodata\")\n@click.option('--dst-nodata', default=None, show_default=True,\n              type=float, help=\"Manually override destination nodata\")\n@click.option('--threads', type=int, default=1,\n              help='Number of processing threads.')\n@click.option('--check-invert-proj', is_flag=True, default=True,\n              help='Constrain output to valid coordinate region in dst-crs')\n@options.force_overwrite_opt\n@options.creation_options\n@click.pass_context\ndef warp(ctx, files, output, driver, like, dst_crs, dimensions, src_bounds,\n         dst_bounds, res, resampling, src_nodata, dst_nodata, threads,\n         check_invert_proj, force_overwrite, creation_options):\n    \"\"\"\n    Warp a raster dataset.\n\n    If a template raster is provided using the --like option, the\n    coordinate reference system, affine transform, and dimensions of\n    that raster will be used for the output.  In this case --dst-crs,\n    --bounds, --res, and --dimensions options are ignored.\n\n    \\b\n        $ rio warp input.tif output.tif --like template.tif\n\n    The output coordinate reference system may be either a PROJ.4 or\n    EPSG:nnnn string,\n\n    \\b\n        --dst-crs EPSG:4326\n        --dst-crs '+proj=longlat +ellps=WGS84 +datum=WGS84'\n\n    or a JSON text-encoded PROJ.4 object.\n\n    \\b\n        --dst-crs '{\"proj\": \"utm\", \"zone\": 18, ...}'\n\n    If --dimensions are provided, --res and --bounds are ignored.\n    Resolution is calculated based on the relationship between the\n    raster bounds in the target coordinate system and the dimensions,\n    and may produce rectangular rather than square pixels.\n\n    \\b\n        $ rio warp input.tif output.tif --dimensions 100 200 \\\\\n        > --dst-crs EPSG:4326\n\n    If --bounds are provided, --res is required if --dst-crs is provided\n    (defaults to source raster resolution otherwise).\n\n    \\b\n        $ rio warp input.tif output.tif \\\\\n        > --bounds -78 22 -76 24 --res 0.1 --dst-crs EPSG:4326\n\n    \"\"\"\n    verbosity = (ctx.obj and ctx.obj.get('verbosity')) or 1\n\n    output, files = resolve_inout(\n        files=files, output=output, force_overwrite=force_overwrite)\n\n    resampling = Resampling[resampling]  # get integer code for method\n\n    if not len(res):\n        # Click sets this as an empty tuple if not provided\n        res = None\n    else:\n        # Expand one value to two if needed\n        res = (res[0], res[0]) if len(res) == 1 else res\n\n    with rasterio.Env(CPL_DEBUG=verbosity > 2,\n                      CHECK_WITH_INVERT_PROJ=check_invert_proj):\n        with rasterio.open(files[0]) as src:\n            l, b, r, t = src.bounds\n            out_kwargs = src.profile.copy()\n            out_kwargs['driver'] = driver\n\n            # Sort out the bounds options.\n            if src_bounds and dst_bounds:\n                raise click.BadParameter(\n                    \"--src-bounds and destination --bounds may not be specified \"\n                    \"simultaneously.\")\n\n            if like:\n                with rasterio.open(like) as template_ds:\n                    dst_crs = template_ds.crs\n                    dst_transform = template_ds.affine\n                    dst_height = template_ds.height\n                    dst_width = template_ds.width\n\n            elif dst_crs is not None:\n                try:\n                    dst_crs = CRS.from_string(dst_crs)\n                except ValueError as err:\n                    raise click.BadParameter(\n                        str(err), param='dst_crs', param_hint='dst_crs')\n\n                if dimensions:\n                    # Calculate resolution appropriate for dimensions\n                    # in target.\n                    dst_width, dst_height = dimensions\n                    try:\n                        xmin, ymin, xmax, ymax = transform_bounds(\n                            src.crs, dst_crs, *src.bounds)\n                    except CRSError as err:\n                        raise click.BadParameter(\n                            str(err), param='dst_crs', param_hint='dst_crs')\n                    dst_transform = Affine(\n                        (xmax - xmin) / float(dst_width),\n                        0, xmin, 0,\n                        (ymin - ymax) / float(dst_height),\n                        ymax\n                    )\n\n                elif src_bounds or dst_bounds:\n                    if not res:\n                        raise click.BadParameter(\n                            \"Required when using --bounds.\",\n                            param='res', param_hint='res')\n\n                    if src_bounds:\n                        try:\n                            xmin, ymin, xmax, ymax = transform_bounds(\n                                src.crs, dst_crs, *src_bounds)\n                        except CRSError as err:\n                            raise click.BadParameter(\n                                str(err), param='dst_crs',\n                                param_hint='dst_crs')\n                    else:\n                        xmin, ymin, xmax, ymax = dst_bounds\n\n                    dst_transform = Affine(res[0], 0, xmin, 0, -res[1], ymax)\n                    dst_width = max(int(ceil((xmax - xmin) / res[0])), 1)\n                    dst_height = max(int(ceil((ymax - ymin) / res[1])), 1)\n\n                else:\n                    try:\n                        dst_transform, dst_width, dst_height = calculate_default_transform(\n                            src.crs, dst_crs, src.width, src.height,\n                            *src.bounds, resolution=res)\n                    except CRSError as err:\n                        raise click.BadParameter(\n                            str(err), param='dst_crs', param_hint='dst_crs')\n            elif dimensions:\n                # Same projection, different dimensions, calculate resolution.\n                dst_crs = src.crs\n                dst_width, dst_height = dimensions\n                dst_transform = Affine(\n                    (r - l) / float(dst_width),\n                    0, l, 0,\n                    (b - t) / float(dst_height),\n                    t\n                )\n\n            elif src_bounds or dst_bounds:\n                # Same projection, different dimensions and possibly\n                # different resolution.\n                if not res:\n                    res = (src.affine.a, -src.affine.e)\n\n                dst_crs = src.crs\n                xmin, ymin, xmax, ymax = (src_bounds or dst_bounds)\n                dst_transform = Affine(res[0], 0, xmin, 0, -res[1], ymax)\n                dst_width = max(int(ceil((xmax - xmin) / res[0])), 1)\n                dst_height = max(int(ceil((ymax - ymin) / res[1])), 1)\n\n            elif res:\n                # Same projection, different resolution.\n                dst_crs = src.crs\n                dst_transform = Affine(res[0], 0, l, 0, -res[1], t)\n                dst_width = max(int(ceil((r - l) / res[0])), 1)\n                dst_height = max(int(ceil((t - b) / res[1])), 1)\n\n            else:\n                dst_crs = src.crs\n                dst_transform = src.affine\n                dst_width = src.width\n                dst_height = src.height\n\n            # If src_nodata is not None, update the dst metadata NODATA\n            # value to src_nodata (will be overridden by dst_nodata if it is not None\n            if src_nodata is not None:\n                # Update the dst nodata value\n                out_kwargs.update({\n                    'nodata': src_nodata\n                })\n\n            # Validate a manually set destination NODATA value\n            # against the input datatype.\n            if dst_nodata is not None:\n                if src_nodata is None and src.meta['nodata'] is None:\n                    raise click.BadParameter(\n                        \"--src-nodata must be provided because dst-nodata is not None\")\n                else:\n                    # Update the dst nodata value\n                    out_kwargs.update({'nodata': dst_nodata})\n\n            # When the bounds option is misused, extreme values of\n            # destination width and height may result.\n            if (dst_width < 0 or dst_height < 0 or\n                    dst_width > MAX_OUTPUT_WIDTH or\n                    dst_height > MAX_OUTPUT_HEIGHT):\n                raise click.BadParameter(\n                    \"Invalid output dimensions: {0}.\".format(\n                        (dst_width, dst_height)))\n\n            out_kwargs.update({\n                'crs': dst_crs,\n                'transform': dst_transform,\n                'affine': dst_transform,\n                'width': dst_width,\n                'height': dst_height\n            })\n\n            # Adjust block size if necessary.\n            if ('blockxsize' in out_kwargs and\n                    dst_width < out_kwargs['blockxsize']):\n                del out_kwargs['blockxsize']\n            if ('blockysize' in out_kwargs and\n                    dst_height < out_kwargs['blockysize']):\n                del out_kwargs['blockysize']\n\n            out_kwargs.update(**creation_options)\n\n            with rasterio.open(output, 'w', **out_kwargs) as dst:\n                reproject(\n                    source=rasterio.band(src, list(range(1, src.count + 1))),\n                    destination=rasterio.band(\n                        dst, list(range(1, src.count + 1))),\n                    src_transform=src.affine,\n                    src_crs=src.crs,\n                    src_nodata=src_nodata,\n                    dst_transform=out_kwargs['transform'],\n                    dst_crs=out_kwargs['crs'],\n                    dst_nodata=dst_nodata,\n                    resampling=resampling,\n                    num_threads=threads)\n", "path": "rasterio/rio/warp.py"}], "after_files": [{"content": "import logging\nfrom math import ceil, floor, log\nimport warnings\n\nimport click\nfrom cligj import files_inout_arg, format_opt\n\nfrom .helpers import resolve_inout\nfrom . import options\nimport rasterio\nfrom rasterio.crs import CRS\nfrom rasterio.errors import CRSError\nfrom rasterio.transform import Affine\nfrom rasterio.warp import (\n    reproject, Resampling, calculate_default_transform, transform_bounds)\n\n\n# Improper usage of rio-warp can lead to accidental creation of\n# extremely large datasets. We'll put a hard limit on the size of\n# datasets and raise a usage error if the limits are exceeded.\nMAX_OUTPUT_WIDTH = 100000\nMAX_OUTPUT_HEIGHT = 100000\n\n\n@click.command(short_help='Warp a raster dataset.')\n@files_inout_arg\n@options.output_opt\n@format_opt\n@click.option(\n    '--like',\n    type=click.Path(exists=True),\n    help='Raster dataset to use as a template for obtaining affine '\n         'transform (bounds and resolution), and crs.')\n@click.option('--dst-crs', default=None,\n              help='Target coordinate reference system.')\n@options.dimensions_opt\n@click.option(\n    '--src-bounds',\n    nargs=4, type=float, default=None,\n    help=\"Determine output extent from source bounds: left bottom right top \"\n         \". Cannot be used with destination --bounds\")\n@click.option(\n    '--bounds', '--dst-bounds', nargs=4, type=float, default=None,\n    help=\"Determine output extent from destination bounds: left bottom right top\")\n@options.resolution_opt\n@click.option('--resampling', type=click.Choice([r.name for r in Resampling]),\n              default='nearest', help=\"Resampling method.\",\n              show_default=True)\n@click.option('--src-nodata', default=None, show_default=True,\n              type=float, help=\"Manually override source nodata\")\n@click.option('--dst-nodata', default=None, show_default=True,\n              type=float, help=\"Manually override destination nodata\")\n@click.option('--threads', type=int, default=1,\n              help='Number of processing threads.')\n@click.option('--check-invert-proj', is_flag=True, default=True,\n              help='Constrain output to valid coordinate region in dst-crs')\n@options.force_overwrite_opt\n@options.creation_options\n@click.pass_context\ndef warp(ctx, files, output, driver, like, dst_crs, dimensions, src_bounds,\n         dst_bounds, res, resampling, src_nodata, dst_nodata, threads,\n         check_invert_proj, force_overwrite, creation_options):\n    \"\"\"\n    Warp a raster dataset.\n\n    If a template raster is provided using the --like option, the\n    coordinate reference system, affine transform, and dimensions of\n    that raster will be used for the output.  In this case --dst-crs,\n    --bounds, --res, and --dimensions options are not applicable and\n    an exception will be raised.\n\n    \\b\n        $ rio warp input.tif output.tif --like template.tif\n\n    The output coordinate reference system may be either a PROJ.4 or\n    EPSG:nnnn string,\n\n    \\b\n        --dst-crs EPSG:4326\n        --dst-crs '+proj=longlat +ellps=WGS84 +datum=WGS84'\n\n    or a JSON text-encoded PROJ.4 object.\n\n    \\b\n        --dst-crs '{\"proj\": \"utm\", \"zone\": 18, ...}'\n\n    If --dimensions are provided, --res and --bounds are not applicable and an\n    exception will be raised.\n    Resolution is calculated based on the relationship between the\n    raster bounds in the target coordinate system and the dimensions,\n    and may produce rectangular rather than square pixels.\n\n    \\b\n        $ rio warp input.tif output.tif --dimensions 100 200 \\\\\n        > --dst-crs EPSG:4326\n\n    If --bounds are provided, --res is required if --dst-crs is provided\n    (defaults to source raster resolution otherwise).\n\n    \\b\n        $ rio warp input.tif output.tif \\\\\n        > --bounds -78 22 -76 24 --res 0.1 --dst-crs EPSG:4326\n\n    \"\"\"\n    verbosity = (ctx.obj and ctx.obj.get('verbosity')) or 1\n\n    output, files = resolve_inout(\n        files=files, output=output, force_overwrite=force_overwrite)\n\n    resampling = Resampling[resampling]  # get integer code for method\n\n    if not len(res):\n        # Click sets this as an empty tuple if not provided\n        res = None\n    else:\n        # Expand one value to two if needed\n        res = (res[0], res[0]) if len(res) == 1 else res\n\n    # Check invalid parameter combinations\n    if like:\n        invalid_combos = (dimensions, dst_bounds, dst_crs, res)\n        if any(p for p in invalid_combos if p is not None):\n            raise click.BadParameter(\n                \"--like cannot be used with any of --dimensions, --bounds, \"\n                \"--dst-crs, or --res\")\n\n    elif dimensions:\n        invalid_combos = (dst_bounds, res)\n        if any(p for p in invalid_combos if p is not None):\n            raise click.BadParameter(\n                \"--dimensions cannot be used with --bounds or --res\")\n\n    with rasterio.Env(CPL_DEBUG=verbosity > 2,\n                      CHECK_WITH_INVERT_PROJ=check_invert_proj):\n        with rasterio.open(files[0]) as src:\n            l, b, r, t = src.bounds\n            out_kwargs = src.profile.copy()\n            out_kwargs['driver'] = driver\n\n            # Sort out the bounds options.\n            if src_bounds and dst_bounds:\n                raise click.BadParameter(\n                    \"--src-bounds and destination --bounds may not be specified \"\n                    \"simultaneously.\")\n\n            if like:\n                with rasterio.open(like) as template_ds:\n                    dst_crs = template_ds.crs\n                    dst_transform = template_ds.affine\n                    dst_height = template_ds.height\n                    dst_width = template_ds.width\n\n            elif dst_crs is not None:\n                try:\n                    dst_crs = CRS.from_string(dst_crs)\n                except ValueError as err:\n                    raise click.BadParameter(\n                        str(err), param='dst_crs', param_hint='dst_crs')\n\n                if dimensions:\n                    # Calculate resolution appropriate for dimensions\n                    # in target.\n                    dst_width, dst_height = dimensions\n                    try:\n                        xmin, ymin, xmax, ymax = transform_bounds(\n                            src.crs, dst_crs, *src.bounds)\n                    except CRSError as err:\n                        raise click.BadParameter(\n                            str(err), param='dst_crs', param_hint='dst_crs')\n                    dst_transform = Affine(\n                        (xmax - xmin) / float(dst_width),\n                        0, xmin, 0,\n                        (ymin - ymax) / float(dst_height),\n                        ymax\n                    )\n\n                elif src_bounds or dst_bounds:\n                    if not res:\n                        raise click.BadParameter(\n                            \"Required when using --bounds.\",\n                            param='res', param_hint='res')\n\n                    if src_bounds:\n                        try:\n                            xmin, ymin, xmax, ymax = transform_bounds(\n                                src.crs, dst_crs, *src_bounds)\n                        except CRSError as err:\n                            raise click.BadParameter(\n                                str(err), param='dst_crs',\n                                param_hint='dst_crs')\n                    else:\n                        xmin, ymin, xmax, ymax = dst_bounds\n\n                    dst_transform = Affine(res[0], 0, xmin, 0, -res[1], ymax)\n                    dst_width = max(int(ceil((xmax - xmin) / res[0])), 1)\n                    dst_height = max(int(ceil((ymax - ymin) / res[1])), 1)\n\n                else:\n                    try:\n                        dst_transform, dst_width, dst_height = calculate_default_transform(\n                            src.crs, dst_crs, src.width, src.height,\n                            *src.bounds, resolution=res)\n                    except CRSError as err:\n                        raise click.BadParameter(\n                            str(err), param='dst_crs', param_hint='dst_crs')\n            elif dimensions:\n                # Same projection, different dimensions, calculate resolution.\n                dst_crs = src.crs\n                dst_width, dst_height = dimensions\n                dst_transform = Affine(\n                    (r - l) / float(dst_width),\n                    0, l, 0,\n                    (b - t) / float(dst_height),\n                    t\n                )\n\n            elif src_bounds or dst_bounds:\n                # Same projection, different dimensions and possibly\n                # different resolution.\n                if not res:\n                    res = (src.affine.a, -src.affine.e)\n\n                dst_crs = src.crs\n                xmin, ymin, xmax, ymax = (src_bounds or dst_bounds)\n                dst_transform = Affine(res[0], 0, xmin, 0, -res[1], ymax)\n                dst_width = max(int(ceil((xmax - xmin) / res[0])), 1)\n                dst_height = max(int(ceil((ymax - ymin) / res[1])), 1)\n\n            elif res:\n                # Same projection, different resolution.\n                dst_crs = src.crs\n                dst_transform = Affine(res[0], 0, l, 0, -res[1], t)\n                dst_width = max(int(ceil((r - l) / res[0])), 1)\n                dst_height = max(int(ceil((t - b) / res[1])), 1)\n\n            else:\n                dst_crs = src.crs\n                dst_transform = src.affine\n                dst_width = src.width\n                dst_height = src.height\n\n            # If src_nodata is not None, update the dst metadata NODATA\n            # value to src_nodata (will be overridden by dst_nodata if it is not None\n            if src_nodata is not None:\n                # Update the dst nodata value\n                out_kwargs.update({\n                    'nodata': src_nodata\n                })\n\n            # Validate a manually set destination NODATA value\n            # against the input datatype.\n            if dst_nodata is not None:\n                if src_nodata is None and src.meta['nodata'] is None:\n                    raise click.BadParameter(\n                        \"--src-nodata must be provided because dst-nodata is not None\")\n                else:\n                    # Update the dst nodata value\n                    out_kwargs.update({'nodata': dst_nodata})\n\n            # When the bounds option is misused, extreme values of\n            # destination width and height may result.\n            if (dst_width < 0 or dst_height < 0 or\n                    dst_width > MAX_OUTPUT_WIDTH or\n                    dst_height > MAX_OUTPUT_HEIGHT):\n                raise click.BadParameter(\n                    \"Invalid output dimensions: {0}.\".format(\n                        (dst_width, dst_height)))\n\n            out_kwargs.update({\n                'crs': dst_crs,\n                'transform': dst_transform,\n                'affine': dst_transform,\n                'width': dst_width,\n                'height': dst_height\n            })\n\n            # Adjust block size if necessary.\n            if ('blockxsize' in out_kwargs and\n                    dst_width < out_kwargs['blockxsize']):\n                del out_kwargs['blockxsize']\n            if ('blockysize' in out_kwargs and\n                    dst_height < out_kwargs['blockysize']):\n                del out_kwargs['blockysize']\n\n            out_kwargs.update(**creation_options)\n\n            with rasterio.open(output, 'w', **out_kwargs) as dst:\n                reproject(\n                    source=rasterio.band(src, list(range(1, src.count + 1))),\n                    destination=rasterio.band(\n                        dst, list(range(1, src.count + 1))),\n                    src_transform=src.affine,\n                    src_crs=src.crs,\n                    src_nodata=src_nodata,\n                    dst_transform=out_kwargs['transform'],\n                    dst_crs=out_kwargs['crs'],\n                    dst_nodata=dst_nodata,\n                    resampling=resampling,\n                    num_threads=threads)\n", "path": "rasterio/rio/warp.py"}]}