We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
rio warp --like does not consider dtype
The rio warp help text says

```
  --like PATH                     Raster dataset to use as a template for
                                  obtaining affine transform (bounds and
                                  resolution), crs, data type, and driver used
                                  to create the output.
```

But the data type does not appear to be affected. 

```
$ rio info data1.l3a.vnir1.tif | jq .dtype
"uint8"
$ rio info data1.l3a.tir10.tif | jq .dtype
"uint16"
$ rio warp data1.l3a.tir10.tif /tmp/out.tif --like data1.l3a.vnir1.tif
$ rio info /tmp/out.tif | jq .dtype  # dtype is not "like" vnir1, should be uint8
"uint16"
```

This might just be a simple matter of changing the help text to reflect the actual behavior. Or it could be considered a bug. Not sure.


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

{"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@@ -48,7 +48,11 @@\n @files_inout_arg\n @options.output_opt\n @format_opt\n-@options.like_file_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", "issue": "rio warp --like does not consider dtype\nThe rio warp help text says\n\n```\n  --like PATH                     Raster dataset to use as a template for\n                                  obtaining affine transform (bounds and\n                                  resolution), crs, data type, and driver used\n                                  to create the output.\n```\n\nBut the data type does not appear to be affected. \n\n```\n$ rio info data1.l3a.vnir1.tif | jq .dtype\n\"uint8\"\n$ rio info data1.l3a.tir10.tif | jq .dtype\n\"uint16\"\n$ rio warp data1.l3a.tir10.tif /tmp/out.tif --like data1.l3a.vnir1.tif\n$ rio info /tmp/out.tif | jq .dtype  # dtype is not \"like\" vnir1, should be uint8\n\"uint16\"\n```\n\nThis might just be a simple matter of changing the help text to reflect the actual behavior. Or it could be considered a bug. Not sure.\n\n", "before_files": [{"content": "import logging\nfrom math import ceil\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 import crs\nfrom rasterio.env import Env\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\ndef bounds_handler(ctx, param, value):\n    \"\"\"Warn about future usage changes.\"\"\"\n    if value:\n        click.echo(\n            \"Future Warning: \"\n            \"the semantics of the `--bounds` option will change in Rasterio \"\n            \"version 1.0 from bounds of the source dataset to bounds of the \"\n            \"destination dataset.\", err=True)\n    return value\n\n\ndef x_dst_bounds_handler(ctx, param, value):\n    \"\"\"Warn about future usage changes.\"\"\"\n    if value:\n        click.echo(\n            \"Future Warning: \"\n            \"the `--x-dst-bounds` option will be removed in Rasterio version \"\n            \"1.0 in favor of `--bounds`.\", err=True)\n    return value\n\n\n@click.command(short_help='Warp a raster dataset.')\n@files_inout_arg\n@options.output_opt\n@format_opt\n@options.like_file_opt\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         \"(note: for future backwards compatibility in 1.0).\")\n@click.option(\n    '--x-dst-bounds',\n    nargs=4, type=float, default=None, callback=x_dst_bounds_handler,\n    help=\"Set output extent from bounding values: left bottom right top \"\n         \"(note: this option will be removed in 1.0).\")\n@click.option(\n    '--bounds',\n    nargs=4, type=float, default=None, callback=bounds_handler,\n    help=\"Determine output extent from source bounds: left bottom right top \"\n         \"(note: the semantics of this option will change to those of \"\n         \"`--x-dst-bounds` in version 1.0).\")\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('--threads', type=int, default=1,\n              help='Number of processing threads.')\n@click.option('--check-invert-proj', type=bool, 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         x_dst_bounds, bounds, res, resampling, threads, check_invert_proj,\n         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\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 Env(CPL_DEBUG=verbosity > 2,\n             CHECK_WITH_INVERT_PROJ=check_invert_proj) as env:\n        with rasterio.open(files[0]) as src:\n            l, b, r, t = src.bounds\n            out_kwargs = src.meta.copy()\n            out_kwargs['driver'] = driver\n\n            # Sort out the bounds options.\n            src_bounds = bounds or src_bounds\n            dst_bounds = x_dst_bounds\n            if src_bounds and dst_bounds:\n                raise click.BadParameter(\n                    \"Source 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            # 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            out_kwargs.update(**creation_options)\n\n            with rasterio.open(output, 'w', **out_kwargs) as dst:\n                for i in range(1, src.count + 1):\n\n                    reproject(\n                        source=rasterio.band(src, i),\n                        destination=rasterio.band(dst, i),\n                        src_transform=src.affine,\n                        src_crs=src.crs,\n                        # src_nodata=#TODO\n                        dst_transform=out_kwargs['transform'],\n                        dst_crs=out_kwargs['crs'],\n                        # dst_nodata=#TODO\n                        resampling=resampling,\n                        num_threads=threads)\n", "path": "rasterio/rio/warp.py"}], "after_files": [{"content": "import logging\nfrom math import ceil\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 import crs\nfrom rasterio.env import Env\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\ndef bounds_handler(ctx, param, value):\n    \"\"\"Warn about future usage changes.\"\"\"\n    if value:\n        click.echo(\n            \"Future Warning: \"\n            \"the semantics of the `--bounds` option will change in Rasterio \"\n            \"version 1.0 from bounds of the source dataset to bounds of the \"\n            \"destination dataset.\", err=True)\n    return value\n\n\ndef x_dst_bounds_handler(ctx, param, value):\n    \"\"\"Warn about future usage changes.\"\"\"\n    if value:\n        click.echo(\n            \"Future Warning: \"\n            \"the `--x-dst-bounds` option will be removed in Rasterio version \"\n            \"1.0 in favor of `--bounds`.\", err=True)\n    return value\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         \"(note: for future backwards compatibility in 1.0).\")\n@click.option(\n    '--x-dst-bounds',\n    nargs=4, type=float, default=None, callback=x_dst_bounds_handler,\n    help=\"Set output extent from bounding values: left bottom right top \"\n         \"(note: this option will be removed in 1.0).\")\n@click.option(\n    '--bounds',\n    nargs=4, type=float, default=None, callback=bounds_handler,\n    help=\"Determine output extent from source bounds: left bottom right top \"\n         \"(note: the semantics of this option will change to those of \"\n         \"`--x-dst-bounds` in version 1.0).\")\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('--threads', type=int, default=1,\n              help='Number of processing threads.')\n@click.option('--check-invert-proj', type=bool, 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         x_dst_bounds, bounds, res, resampling, threads, check_invert_proj,\n         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\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 Env(CPL_DEBUG=verbosity > 2,\n             CHECK_WITH_INVERT_PROJ=check_invert_proj) as env:\n        with rasterio.open(files[0]) as src:\n            l, b, r, t = src.bounds\n            out_kwargs = src.meta.copy()\n            out_kwargs['driver'] = driver\n\n            # Sort out the bounds options.\n            src_bounds = bounds or src_bounds\n            dst_bounds = x_dst_bounds\n            if src_bounds and dst_bounds:\n                raise click.BadParameter(\n                    \"Source 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            # 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            out_kwargs.update(**creation_options)\n\n            with rasterio.open(output, 'w', **out_kwargs) as dst:\n                for i in range(1, src.count + 1):\n\n                    reproject(\n                        source=rasterio.band(src, i),\n                        destination=rasterio.band(dst, i),\n                        src_transform=src.affine,\n                        src_crs=src.crs,\n                        # src_nodata=#TODO\n                        dst_transform=out_kwargs['transform'],\n                        dst_crs=out_kwargs['crs'],\n                        # dst_nodata=#TODO\n                        resampling=resampling,\n                        num_threads=threads)\n", "path": "rasterio/rio/warp.py"}]}