Repository: rasterio/rasterio

Issue:
OVERVIEW_LEVEL open option doesn't work for Slippy Map dataset
I'm looking for a way to translate to rasterio this GDAL CLI command:

```
gdal_translate -oo OVERVIEW_LEVEL=1 -projwin 10817977.2 3650863.4 10818322.7 3650646.5 /vsicurl/https://raw.githubusercontent.com/satellogic/telluric/master/tests/data/google.xml out.tif
```

I wrote the following snippet:

```
import rasterio

with rasterio.open(
    "/vsicurl/https://raw.githubusercontent.com/satellogic/telluric/master/tests/data/google.xml"
) as src:
    bounds = (10817977.2, 3650646.5, 10818322.7, 3650863.4)
    bounds_window = src.window(*bounds)
    out_window = bounds_window.round_lengths(op="ceil")

    height = int(out_window.height)
    width = int(out_window.width)

    out_kwargs = src.profile
    out_kwargs.update(
        {
            "driver": "GTiff",
            "height": height,
            "width": width,
            "transform": src.window_transform(out_window),
        }
    )

    with rasterio.open("out.tif", "w", **out_kwargs) as out:
        out.write(
            src.read(
                window=out_window, out_shape=(src.count, height, width), boundless=True,
            )
        )
```

It works fine but when I add `OVERVIEW_LEVEL=1` to `open` method it fails.

```
rasterio.open(
    "/vsicurl/https://raw.githubusercontent.com/satellogic/telluric/master/tests/data/google.xml",
    OVERVIEW_LEVEL=1,
)
```

It seems in this case rasterio makes queries to non-existing tiles and gets 404 from Google.

http://erouault.blogspot.com/2014/10/warping-overviews-and-warped-overviews.html


Discussion:
Removing `boundless=True` has helped. @sgillies feel free to close this if you don't think this is a bug.
@drnextgis I don't use the WMS driver very much but it looks like the behavior with respect to unaddressable tiles can be configured in your XML: https://gdal.org/drivers/raster/wms.html#xml-description-file.
Yes this is what I actually use. But the question is why rasterio requests unavailable tiles in case of `boundless=True` and works fine without it.

Resolving patch:
diff --git a/rasterio/vrt.py b/rasterio/vrt.py
--- a/rasterio/vrt.py
+++ b/rasterio/vrt.py
@@ -232,6 +232,13 @@ def _boundless_vrt_doc(
             nodata_elem = ET.SubElement(complexsource, 'NODATA')
             nodata_elem.text = str(src_dataset.nodata)
 
+        if src_dataset.options is not None:
+            openoptions = ET.SubElement(complexsource, 'OpenOptions')
+            for ookey, oovalue in src_dataset.options.items():
+                ooi = ET.SubElement(openoptions, 'OOI')
+                ooi.attrib['key'] = str(ookey)
+                ooi.text = str(oovalue)
+
         # Effectively replaces all values of the source dataset with
         # 255.  Due to GDAL optimizations, the source dataset will not
         # be read, so we get a performance improvement.


Test patch:
diff --git a/tests/test_boundless_read.py b/tests/test_boundless_read.py
--- a/tests/test_boundless_read.py
+++ b/tests/test_boundless_read.py
@@ -8,7 +8,7 @@
 import rasterio
 from rasterio.windows import Window
 
-from .conftest import requires_gdal21
+from .conftest import requires_gdal21, gdal_version
 
 
 @requires_gdal21(reason="Pixel equality tests require float windows and GDAL 2.1")
@@ -115,3 +115,16 @@ def test_boundless_masked_fill_value_overview_masks():
         data = src.read(1, masked=True, boundless=True, window=Window(-300, -335, 1000, 1000), fill_value=5, out_shape=(512, 512))
     assert data.fill_value == 5
     assert data.mask[:, 0].all()
+
+
+@pytest.mark.xfail(
+    gdal_version.major == 1,
+    reason="GDAL versions < 2 do not support OVERVIEW_LEVEL open option",
+)
+def test_boundless_open_options():
+    """Open options are taken into account"""
+    with rasterio.open("tests/data/cogeo.tif", overview_level=1) as src:
+        data1 = src.read(1, boundless=True)
+    with rasterio.open("tests/data/cogeo.tif", overview_level=2) as src:
+        data2 = src.read(1, boundless=True)
+    assert not numpy.array_equal(data1, data2)