We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Read default of masked=None breaks for some nodatavals
Back in #71, there was some controversy over the decision to have RasterReader.read's default operation as `masked=None`, which is both the slowest and most complicated behavior, and also is _different_ from `masked=False`.

Here's one case that took a colleage and I hours to debug:  It's allowed have an image whose NoDataValue is outside the range of the dtype.  If I want to read one of these, the default `read` behavior throws an error.

```
import numpy as np
data = np.array([[0, 0, 1], [1, 2, 0]])
kwargs = {
    'driver': u'GTiff',
    'dtype': 'uint8',
    'nodata': -1.7e+308,
    'height': 3,
    'width': 3,
    'count': 1
}
with rasterio.drivers():
    with rasterio.open('foo.tif', 'w', **kwargs) as dst:
        dst.write_band(1, data.astype(rasterio.uint8))

    with rasterio.open('foo.tif') as src:
        mask = src.read_band(1)
# TypeError: Fill value -1.7e+308 overflows dtype uint8
```

Obviously it's impossible for any raster values to have been flagged as NoDataValues, so the workaround is to ignore the NoDataValue entirely by setting `masked=False` (the distinction was a bit lost at first).

We probably don't want to change the default now, but here's what we can do:
- at the very least, print a warning suggesting that you may want `masked=False`
- I prefer tweaking behavior so that `masked=None` returns a masked array if at least one of the bands has a NoDataValue that is within the `dtype` bounds. (currently it only checks `nodataval is not None`)

Finally we should clarify the docstring: "masked if any of the nodatavals are not `None`", but "nodatavals" is not defined or referenced elsewhere in the documentation.


--- 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/merge.py`
Content:
```
1 # Merge command.
2 
3 import logging
4 import math
5 import os.path
6 import sys
7 import warnings
8 
9 import click
10 from cligj import files_inout_arg, format_opt
11 
12 import rasterio
13 from rasterio.rio.cli import cli
14 from rasterio.transform import Affine
15 
16 
17 @cli.command(short_help="Merge a stack of raster datasets.")
18 @files_inout_arg
19 @format_opt
20 @click.option('--bounds', nargs=4, type=float, default=None,
21               help="Output bounds: left, bottom, right, top.")
22 @click.option('--res', nargs=2, type=float, default=None,
23               help="Output dataset resolution: pixel width, pixel height")
24 @click.option('--nodata', '-n', type=float, default=None,
25               help="Override nodata values defined in input datasets")
26 @click.pass_context
27 def merge(ctx, files, driver, bounds, res, nodata):
28     """Copy valid pixels from input files to an output file.
29 
30     All files must have the same number of bands, data type, and
31     coordinate reference system.
32 
33     Input files are merged in their listed order using the reverse
34     painter's algorithm. If the output file exists, its values will be
35     overwritten by input values.
36 
37     Geospatial bounds and resolution of a new output file in the
38     units of the input file coordinate reference system may be provided
39     and are otherwise taken from the first input file.
40     """
41     import numpy as np
42 
43     verbosity = (ctx.obj and ctx.obj.get('verbosity')) or 1
44     logger = logging.getLogger('rio')
45 
46     try:
47         with rasterio.drivers(CPL_DEBUG=verbosity>2):
48             output = files[-1]
49             files = files[:-1]
50 
51             with rasterio.open(files[0]) as first:
52                 first_res = first.res
53                 kwargs = first.meta
54                 kwargs.pop('affine')
55                 nodataval = first.nodatavals[0]
56                 dtype = first.dtypes[0]
57 
58             if os.path.exists(output):
59                 # TODO: prompt user to update existing file (-i option) like:
60                 # overwrite b.tif? (y/n [n]) n
61                 # not overwritten
62                 dst = rasterio.open(output, 'r+')
63                 nodataval = dst.nodatavals[0]
64                 dtype = dst.dtypes[0]
65                 dest = np.zeros((dst.count,) + dst.shape, dtype=dtype)
66             else:
67                 # Create new output file.
68                 # Extent from option or extent of all inputs.
69                 if not bounds:
70                     # scan input files.
71                     xs = []
72                     ys = []
73                     for f in files:
74                         with rasterio.open(f) as src:
75                             left, bottom, right, top = src.bounds
76                             xs.extend([left, right])
77                             ys.extend([bottom, top])
78                     bounds = min(xs), min(ys), max(xs), max(ys)
79                 output_transform = Affine.translation(bounds[0], bounds[3])
80 
81                 # Resolution/pixel size.
82                 if not res:
83                     res = first_res
84                 output_transform *= Affine.scale(res[0], -res[1])
85 
86                 # Dataset shape.
87                 output_width = int(math.ceil((bounds[2]-bounds[0])/res[0]))
88                 output_height = int(math.ceil((bounds[3]-bounds[1])/res[1]))
89 
90                 kwargs['driver'] == driver
91                 kwargs['transform'] = output_transform
92                 kwargs['width'] = output_width
93                 kwargs['height'] = output_height
94 
95                 dst = rasterio.open(output, 'w', **kwargs)
96                 dest = np.zeros((first.count, output_height, output_width),
97                         dtype=dtype)
98 
99             if nodata is not None:
100                 nodataval = nodata
101 
102             if nodataval is not None:
103                 # Only fill if the nodataval is within dtype's range.
104                 inrange = False
105                 if np.dtype(dtype).kind in ('i', 'u'):
106                     info = np.iinfo(dtype)
107                     inrange = (info.min <= nodataval <= info.max)
108                 elif np.dtype(dtype).kind == 'f':
109                     info = np.finfo(dtype)
110                     inrange = (info.min <= nodataval <= info.max)
111                 if inrange:
112                     dest.fill(nodataval)
113                 else:
114                     warnings.warn(
115                         "Input file's nodata value, %s, is beyond the valid "
116                         "range of its data type, %s. Consider overriding it "
117                         "using the --nodata option for better results." % (
118                             nodataval, dtype))
119             else:
120                 nodataval = 0
121 
122             for fname in reversed(files):
123                 with rasterio.open(fname) as src:
124                     # Real World (tm) use of boundless reads.
125                     # This approach uses the maximum amount of memory to solve
126                     # the problem. Making it more efficient is a TODO.
127                     window = src.window(*dst.bounds)
128                     data = np.zeros_like(dest)
129                     data = src.read(
130                             out=data,
131                             window=window,
132                             boundless=True,
133                             masked=True)
134                     np.copyto(dest, data,
135                         where=np.logical_and(
136                         dest==nodataval, data.mask==False))
137 
138             if dst.mode == 'r+':
139                 data = dst.read(masked=True)
140                 np.copyto(dest, data,
141                     where=np.logical_and(
142                     dest==nodataval, data.mask==False))
143 
144             dst.write(dest)
145             dst.close()
146 
147         sys.exit(0)
148     except Exception:
149         logger.exception("Failed. Exception caught")
150         sys.exit(1)
151
```
--- 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/merge.py b/rasterio/rio/merge.py
--- a/rasterio/rio/merge.py
+++ b/rasterio/rio/merge.py
@@ -92,10 +92,16 @@
                 kwargs['width'] = output_width
                 kwargs['height'] = output_height
 
+                logger.debug("Kwargs: %r", kwargs)
+                logger.debug("bounds: %r", bounds)
+                logger.debug("Res: %r", res)
+
                 dst = rasterio.open(output, 'w', **kwargs)
                 dest = np.zeros((first.count, output_height, output_width),
                         dtype=dtype)
 
+                logger.debug("In merge, dest shape: %r", dest.shape)
+
             if nodata is not None:
                 nodataval = nodata
 
@@ -119,27 +125,54 @@
             else:
                 nodataval = 0
 
+            dst_w, dst_s, dst_e, dst_n = dst.bounds
+
             for fname in reversed(files):
                 with rasterio.open(fname) as src:
                     # Real World (tm) use of boundless reads.
                     # This approach uses the maximum amount of memory to solve
                     # the problem. Making it more efficient is a TODO.
-                    window = src.window(*dst.bounds)
-                    data = np.zeros_like(dest)
-                    data = src.read(
-                            out=data,
-                            window=window,
-                            boundless=True,
+
+                    # 1. Compute spatial intersection of destination
+                    #    and source.
+                    src_w, src_s, src_e, src_n = src.bounds
+
+                    int_w = src_w if src_w > dst_w else dst_w
+                    int_s = src_s if src_s > dst_s else dst_s
+                    int_e = src_e if src_e < dst_e else dst_e
+                    int_n = src_n if src_n < dst_n else dst_n
+
+                    # 2. Compute the source window.
+                    src_window = src.window(int_w, int_s, int_e, int_n)
+
+                    # 3. Compute the destination window.
+                    dst_window = dst.window(int_w, int_s, int_e, int_n)
+
+                    # 4. Initialize temp array.
+                    temp = np.zeros(
+                            (first.count,) + tuple(b - a for a, b in dst_window),
+                            dtype=dtype)
+
+                    temp = src.read(
+                            out=temp,
+                            window=src_window,
+                            boundless=False,
                             masked=True)
-                    np.copyto(dest, data,
+
+                    # 5. Copy elements of temp into dest.
+                    roff, coff = dst.index(int_w, int_n)
+                    h, w = temp.shape[-2:]
+
+                    region = dest[:,roff:roff+h,coff:coff+w]
+                    np.copyto(region, temp,
                         where=np.logical_and(
-                        dest==nodataval, data.mask==False))
+                        region==nodataval, temp.mask==False))
 
             if dst.mode == 'r+':
-                data = dst.read(masked=True)
-                np.copyto(dest, data,
+                temp = dst.read(masked=True)
+                np.copyto(dest, temp,
                     where=np.logical_and(
-                    dest==nodataval, data.mask==False))
+                    dest==nodataval, temp.mask==False))
 
             dst.write(dest)
             dst.close()

{"golden_diff": "diff --git a/rasterio/rio/merge.py b/rasterio/rio/merge.py\n--- a/rasterio/rio/merge.py\n+++ b/rasterio/rio/merge.py\n@@ -92,10 +92,16 @@\n                 kwargs['width'] = output_width\n                 kwargs['height'] = output_height\n \n+                logger.debug(\"Kwargs: %r\", kwargs)\n+                logger.debug(\"bounds: %r\", bounds)\n+                logger.debug(\"Res: %r\", res)\n+\n                 dst = rasterio.open(output, 'w', **kwargs)\n                 dest = np.zeros((first.count, output_height, output_width),\n                         dtype=dtype)\n \n+                logger.debug(\"In merge, dest shape: %r\", dest.shape)\n+\n             if nodata is not None:\n                 nodataval = nodata\n \n@@ -119,27 +125,54 @@\n             else:\n                 nodataval = 0\n \n+            dst_w, dst_s, dst_e, dst_n = dst.bounds\n+\n             for fname in reversed(files):\n                 with rasterio.open(fname) as src:\n                     # Real World (tm) use of boundless reads.\n                     # This approach uses the maximum amount of memory to solve\n                     # the problem. Making it more efficient is a TODO.\n-                    window = src.window(*dst.bounds)\n-                    data = np.zeros_like(dest)\n-                    data = src.read(\n-                            out=data,\n-                            window=window,\n-                            boundless=True,\n+\n+                    # 1. Compute spatial intersection of destination\n+                    #    and source.\n+                    src_w, src_s, src_e, src_n = src.bounds\n+\n+                    int_w = src_w if src_w > dst_w else dst_w\n+                    int_s = src_s if src_s > dst_s else dst_s\n+                    int_e = src_e if src_e < dst_e else dst_e\n+                    int_n = src_n if src_n < dst_n else dst_n\n+\n+                    # 2. Compute the source window.\n+                    src_window = src.window(int_w, int_s, int_e, int_n)\n+\n+                    # 3. Compute the destination window.\n+                    dst_window = dst.window(int_w, int_s, int_e, int_n)\n+\n+                    # 4. Initialize temp array.\n+                    temp = np.zeros(\n+                            (first.count,) + tuple(b - a for a, b in dst_window),\n+                            dtype=dtype)\n+\n+                    temp = src.read(\n+                            out=temp,\n+                            window=src_window,\n+                            boundless=False,\n                             masked=True)\n-                    np.copyto(dest, data,\n+\n+                    # 5. Copy elements of temp into dest.\n+                    roff, coff = dst.index(int_w, int_n)\n+                    h, w = temp.shape[-2:]\n+\n+                    region = dest[:,roff:roff+h,coff:coff+w]\n+                    np.copyto(region, temp,\n                         where=np.logical_and(\n-                        dest==nodataval, data.mask==False))\n+                        region==nodataval, temp.mask==False))\n \n             if dst.mode == 'r+':\n-                data = dst.read(masked=True)\n-                np.copyto(dest, data,\n+                temp = dst.read(masked=True)\n+                np.copyto(dest, temp,\n                     where=np.logical_and(\n-                    dest==nodataval, data.mask==False))\n+                    dest==nodataval, temp.mask==False))\n \n             dst.write(dest)\n             dst.close()\n", "issue": "Read default of masked=None breaks for some nodatavals\nBack in #71, there was some controversy over the decision to have RasterReader.read's default operation as `masked=None`, which is both the slowest and most complicated behavior, and also is _different_ from `masked=False`.\n\nHere's one case that took a colleage and I hours to debug:  It's allowed have an image whose NoDataValue is outside the range of the dtype.  If I want to read one of these, the default `read` behavior throws an error.\n\n```\nimport numpy as np\ndata = np.array([[0, 0, 1], [1, 2, 0]])\nkwargs = {\n    'driver': u'GTiff',\n    'dtype': 'uint8',\n    'nodata': -1.7e+308,\n    'height': 3,\n    'width': 3,\n    'count': 1\n}\nwith rasterio.drivers():\n    with rasterio.open('foo.tif', 'w', **kwargs) as dst:\n        dst.write_band(1, data.astype(rasterio.uint8))\n\n    with rasterio.open('foo.tif') as src:\n        mask = src.read_band(1)\n# TypeError: Fill value -1.7e+308 overflows dtype uint8\n```\n\nObviously it's impossible for any raster values to have been flagged as NoDataValues, so the workaround is to ignore the NoDataValue entirely by setting `masked=False` (the distinction was a bit lost at first).\n\nWe probably don't want to change the default now, but here's what we can do:\n- at the very least, print a warning suggesting that you may want `masked=False`\n- I prefer tweaking behavior so that `masked=None` returns a masked array if at least one of the bands has a NoDataValue that is within the `dtype` bounds. (currently it only checks `nodataval is not None`)\n\nFinally we should clarify the docstring: \"masked if any of the nodatavals are not `None`\", but \"nodatavals\" is not defined or referenced elsewhere in the documentation.\n\n", "before_files": [{"content": "# Merge command.\n\nimport logging\nimport math\nimport os.path\nimport sys\nimport warnings\n\nimport click\nfrom cligj import files_inout_arg, format_opt\n\nimport rasterio\nfrom rasterio.rio.cli import cli\nfrom rasterio.transform import Affine\n\n\n@cli.command(short_help=\"Merge a stack of raster datasets.\")\n@files_inout_arg\n@format_opt\n@click.option('--bounds', nargs=4, type=float, default=None,\n              help=\"Output bounds: left, bottom, right, top.\")\n@click.option('--res', nargs=2, type=float, default=None,\n              help=\"Output dataset resolution: pixel width, pixel height\")\n@click.option('--nodata', '-n', type=float, default=None,\n              help=\"Override nodata values defined in input datasets\")\n@click.pass_context\ndef merge(ctx, files, driver, bounds, res, nodata):\n    \"\"\"Copy valid pixels from input files to an output file.\n\n    All files must have the same number of bands, data type, and\n    coordinate reference system.\n\n    Input files are merged in their listed order using the reverse\n    painter's algorithm. If the output file exists, its values will be\n    overwritten by input values.\n\n    Geospatial bounds and resolution of a new output file in the\n    units of the input file coordinate reference system may be provided\n    and are otherwise taken from the first input file.\n    \"\"\"\n    import numpy as np\n\n    verbosity = (ctx.obj and ctx.obj.get('verbosity')) or 1\n    logger = logging.getLogger('rio')\n\n    try:\n        with rasterio.drivers(CPL_DEBUG=verbosity>2):\n            output = files[-1]\n            files = files[:-1]\n\n            with rasterio.open(files[0]) as first:\n                first_res = first.res\n                kwargs = first.meta\n                kwargs.pop('affine')\n                nodataval = first.nodatavals[0]\n                dtype = first.dtypes[0]\n\n            if os.path.exists(output):\n                # TODO: prompt user to update existing file (-i option) like:\n                # overwrite b.tif? (y/n [n]) n\n                # not overwritten\n                dst = rasterio.open(output, 'r+')\n                nodataval = dst.nodatavals[0]\n                dtype = dst.dtypes[0]\n                dest = np.zeros((dst.count,) + dst.shape, dtype=dtype)\n            else:\n                # Create new output file.\n                # Extent from option or extent of all inputs.\n                if not bounds:\n                    # scan input files.\n                    xs = []\n                    ys = []\n                    for f in files:\n                        with rasterio.open(f) as src:\n                            left, bottom, right, top = src.bounds\n                            xs.extend([left, right])\n                            ys.extend([bottom, top])\n                    bounds = min(xs), min(ys), max(xs), max(ys)\n                output_transform = Affine.translation(bounds[0], bounds[3])\n\n                # Resolution/pixel size.\n                if not res:\n                    res = first_res\n                output_transform *= Affine.scale(res[0], -res[1])\n\n                # Dataset shape.\n                output_width = int(math.ceil((bounds[2]-bounds[0])/res[0]))\n                output_height = int(math.ceil((bounds[3]-bounds[1])/res[1]))\n\n                kwargs['driver'] == driver\n                kwargs['transform'] = output_transform\n                kwargs['width'] = output_width\n                kwargs['height'] = output_height\n\n                dst = rasterio.open(output, 'w', **kwargs)\n                dest = np.zeros((first.count, output_height, output_width),\n                        dtype=dtype)\n\n            if nodata is not None:\n                nodataval = nodata\n\n            if nodataval is not None:\n                # Only fill if the nodataval is within dtype's range.\n                inrange = False\n                if np.dtype(dtype).kind in ('i', 'u'):\n                    info = np.iinfo(dtype)\n                    inrange = (info.min <= nodataval <= info.max)\n                elif np.dtype(dtype).kind == 'f':\n                    info = np.finfo(dtype)\n                    inrange = (info.min <= nodataval <= info.max)\n                if inrange:\n                    dest.fill(nodataval)\n                else:\n                    warnings.warn(\n                        \"Input file's nodata value, %s, is beyond the valid \"\n                        \"range of its data type, %s. Consider overriding it \"\n                        \"using the --nodata option for better results.\" % (\n                            nodataval, dtype))\n            else:\n                nodataval = 0\n\n            for fname in reversed(files):\n                with rasterio.open(fname) as src:\n                    # Real World (tm) use of boundless reads.\n                    # This approach uses the maximum amount of memory to solve\n                    # the problem. Making it more efficient is a TODO.\n                    window = src.window(*dst.bounds)\n                    data = np.zeros_like(dest)\n                    data = src.read(\n                            out=data,\n                            window=window,\n                            boundless=True,\n                            masked=True)\n                    np.copyto(dest, data,\n                        where=np.logical_and(\n                        dest==nodataval, data.mask==False))\n\n            if dst.mode == 'r+':\n                data = dst.read(masked=True)\n                np.copyto(dest, data,\n                    where=np.logical_and(\n                    dest==nodataval, data.mask==False))\n\n            dst.write(dest)\n            dst.close()\n\n        sys.exit(0)\n    except Exception:\n        logger.exception(\"Failed. Exception caught\")\n        sys.exit(1)\n", "path": "rasterio/rio/merge.py"}], "after_files": [{"content": "# Merge command.\n\nimport logging\nimport math\nimport os.path\nimport sys\nimport warnings\n\nimport click\nfrom cligj import files_inout_arg, format_opt\n\nimport rasterio\nfrom rasterio.rio.cli import cli\nfrom rasterio.transform import Affine\n\n\n@cli.command(short_help=\"Merge a stack of raster datasets.\")\n@files_inout_arg\n@format_opt\n@click.option('--bounds', nargs=4, type=float, default=None,\n              help=\"Output bounds: left, bottom, right, top.\")\n@click.option('--res', nargs=2, type=float, default=None,\n              help=\"Output dataset resolution: pixel width, pixel height\")\n@click.option('--nodata', '-n', type=float, default=None,\n              help=\"Override nodata values defined in input datasets\")\n@click.pass_context\ndef merge(ctx, files, driver, bounds, res, nodata):\n    \"\"\"Copy valid pixels from input files to an output file.\n\n    All files must have the same number of bands, data type, and\n    coordinate reference system.\n\n    Input files are merged in their listed order using the reverse\n    painter's algorithm. If the output file exists, its values will be\n    overwritten by input values.\n\n    Geospatial bounds and resolution of a new output file in the\n    units of the input file coordinate reference system may be provided\n    and are otherwise taken from the first input file.\n    \"\"\"\n    import numpy as np\n\n    verbosity = (ctx.obj and ctx.obj.get('verbosity')) or 1\n    logger = logging.getLogger('rio')\n\n    try:\n        with rasterio.drivers(CPL_DEBUG=verbosity>2):\n            output = files[-1]\n            files = files[:-1]\n\n            with rasterio.open(files[0]) as first:\n                first_res = first.res\n                kwargs = first.meta\n                kwargs.pop('affine')\n                nodataval = first.nodatavals[0]\n                dtype = first.dtypes[0]\n\n            if os.path.exists(output):\n                # TODO: prompt user to update existing file (-i option) like:\n                # overwrite b.tif? (y/n [n]) n\n                # not overwritten\n                dst = rasterio.open(output, 'r+')\n                nodataval = dst.nodatavals[0]\n                dtype = dst.dtypes[0]\n                dest = np.zeros((dst.count,) + dst.shape, dtype=dtype)\n            else:\n                # Create new output file.\n                # Extent from option or extent of all inputs.\n                if not bounds:\n                    # scan input files.\n                    xs = []\n                    ys = []\n                    for f in files:\n                        with rasterio.open(f) as src:\n                            left, bottom, right, top = src.bounds\n                            xs.extend([left, right])\n                            ys.extend([bottom, top])\n                    bounds = min(xs), min(ys), max(xs), max(ys)\n                output_transform = Affine.translation(bounds[0], bounds[3])\n\n                # Resolution/pixel size.\n                if not res:\n                    res = first_res\n                output_transform *= Affine.scale(res[0], -res[1])\n\n                # Dataset shape.\n                output_width = int(math.ceil((bounds[2]-bounds[0])/res[0]))\n                output_height = int(math.ceil((bounds[3]-bounds[1])/res[1]))\n\n                kwargs['driver'] == driver\n                kwargs['transform'] = output_transform\n                kwargs['width'] = output_width\n                kwargs['height'] = output_height\n\n                logger.debug(\"Kwargs: %r\", kwargs)\n                logger.debug(\"bounds: %r\", bounds)\n                logger.debug(\"Res: %r\", res)\n\n                dst = rasterio.open(output, 'w', **kwargs)\n                dest = np.zeros((first.count, output_height, output_width),\n                        dtype=dtype)\n\n                logger.debug(\"In merge, dest shape: %r\", dest.shape)\n\n            if nodata is not None:\n                nodataval = nodata\n\n            if nodataval is not None:\n                # Only fill if the nodataval is within dtype's range.\n                inrange = False\n                if np.dtype(dtype).kind in ('i', 'u'):\n                    info = np.iinfo(dtype)\n                    inrange = (info.min <= nodataval <= info.max)\n                elif np.dtype(dtype).kind == 'f':\n                    info = np.finfo(dtype)\n                    inrange = (info.min <= nodataval <= info.max)\n                if inrange:\n                    dest.fill(nodataval)\n                else:\n                    warnings.warn(\n                        \"Input file's nodata value, %s, is beyond the valid \"\n                        \"range of its data type, %s. Consider overriding it \"\n                        \"using the --nodata option for better results.\" % (\n                            nodataval, dtype))\n            else:\n                nodataval = 0\n\n            dst_w, dst_s, dst_e, dst_n = dst.bounds\n\n            for fname in reversed(files):\n                with rasterio.open(fname) as src:\n                    # Real World (tm) use of boundless reads.\n                    # This approach uses the maximum amount of memory to solve\n                    # the problem. Making it more efficient is a TODO.\n\n                    # 1. Compute spatial intersection of destination\n                    #    and source.\n                    src_w, src_s, src_e, src_n = src.bounds\n\n                    int_w = src_w if src_w > dst_w else dst_w\n                    int_s = src_s if src_s > dst_s else dst_s\n                    int_e = src_e if src_e < dst_e else dst_e\n                    int_n = src_n if src_n < dst_n else dst_n\n\n                    # 2. Compute the source window.\n                    src_window = src.window(int_w, int_s, int_e, int_n)\n\n                    # 3. Compute the destination window.\n                    dst_window = dst.window(int_w, int_s, int_e, int_n)\n\n                    # 4. Initialize temp array.\n                    temp = np.zeros(\n                            (first.count,) + tuple(b - a for a, b in dst_window),\n                            dtype=dtype)\n\n                    temp = src.read(\n                            out=temp,\n                            window=src_window,\n                            boundless=False,\n                            masked=True)\n\n                    # 5. Copy elements of temp into dest.\n                    roff, coff = dst.index(int_w, int_n)\n                    h, w = temp.shape[-2:]\n\n                    region = dest[:,roff:roff+h,coff:coff+w]\n                    np.copyto(region, temp,\n                        where=np.logical_and(\n                        region==nodataval, temp.mask==False))\n\n            if dst.mode == 'r+':\n                temp = dst.read(masked=True)\n                np.copyto(dest, temp,\n                    where=np.logical_and(\n                    dest==nodataval, temp.mask==False))\n\n            dst.write(dest)\n            dst.close()\n\n        sys.exit(0)\n    except Exception:\n        logger.exception(\"Failed. Exception caught\")\n        sys.exit(1)\n", "path": "rasterio/rio/merge.py"}]}