We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Switch sense of rio-warp's --bounds from src to dst
For 1.0, let's harmonize rio-warp's `--dimensions`, `--res`, `--bounds`, and `--like` options so they all specify the output/destination raster. This will mean a breaking change for `--bounds`. I apologize for not catching the interface discrepancy earlier, everyone.

Plan: 
- raise a [FutureWarning](https://docs.python.org/2/library/exceptions.html#exceptions.FutureWarning) starting with the next release explaining the upcoming change to rio-warp's `--bounds` option.
- add a `--x-dst-bounds` option to impl the corrected feature.
- add a `--src-bounds` option to preserve the existing feature.
- prevent the GDAL faults (crashes and non-returning calls) that are possible when bad destination bounds are passed.

Sound good, @brendan-ward @perrygeo?


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

{"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@@ -22,27 +22,6 @@\n MAX_OUTPUT_HEIGHT = 100000\n \n \n-def 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-\n-def 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@@ -59,18 +38,10 @@\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+         \". Cannot be used with destination --bounds\")\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+    '--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@@ -87,7 +58,7 @@\n @options.creation_options\n @click.pass_context\n def warp(ctx, files, output, driver, like, dst_crs, dimensions, src_bounds,\n-         x_dst_bounds, bounds, res, resampling, src_nodata, dst_nodata, threads, check_invert_proj,\n+         dst_bounds, res, resampling, src_nodata, dst_nodata, threads, check_invert_proj,\n          force_overwrite, creation_options):\n     \"\"\"\n     Warp a raster dataset.\n@@ -151,11 +122,9 @@\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+                    \"--src-bounds and destination --bounds may not be specified \"\n                     \"simultaneously.\")\n \n             if like:\n", "issue": "Switch sense of rio-warp's --bounds from src to dst\nFor 1.0, let's harmonize rio-warp's `--dimensions`, `--res`, `--bounds`, and `--like` options so they all specify the output/destination raster. This will mean a breaking change for `--bounds`. I apologize for not catching the interface discrepancy earlier, everyone.\n\nPlan: \n- raise a [FutureWarning](https://docs.python.org/2/library/exceptions.html#exceptions.FutureWarning) starting with the next release explaining the upcoming change to rio-warp's `--bounds` option.\n- add a `--x-dst-bounds` option to impl the corrected feature.\n- add a `--src-bounds` option to preserve the existing feature.\n- prevent the GDAL faults (crashes and non-returning calls) that are possible when bad destination bounds are passed.\n\nSound good, @brendan-ward @perrygeo?\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.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\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('--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', 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, src_nodata, dst_nodata, 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    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.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            # 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({\n                        'nodata': dst_nodata\n                        })\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=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\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', 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         dst_bounds, res, resampling, src_nodata, dst_nodata, 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    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.meta.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({\n                        'nodata': dst_nodata\n                        })\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=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"}]}