1"""Tests for :py:class:`rasterio.warp.WarpedVRT`."""
2
3from __future__ import division
4import logging
5
6import affine
7import boto3
8import numpy
9import pytest
10
11import rasterio
12from rasterio.crs import CRS
13from rasterio.enums import Resampling, MaskFlags
14from rasterio.errors import RasterioDeprecationWarning, WarpOptionsError, WarpedVRTError
15from rasterio.io import MemoryFile
16from rasterio import shutil as rio_shutil
17from rasterio.vrt import WarpedVRT
18from rasterio.warp import transform_bounds
19from rasterio.windows import Window
20
21from .conftest import requires_gdal21, requires_gdal2
22
23log = logging.getLogger(__name__)
24
25# Custom markers.
26credentials = pytest.mark.skipif(
27    not (boto3.Session().get_credentials()),
28    reason="S3 raster access requires credentials",
29)
30
31DST_CRS = "EPSG:3857"
32
33
34def _copy_update_profile(path_in, path_out, **kwargs):
35    """Create a copy of path_in in path_out updating profile with **kwargs"""
36    with rasterio.open(str(path_in)) as src:
37        profile = src.profile.copy()
38        profile.update(kwargs)
39        with rasterio.open(str(path_out), "w", **profile) as dst:
40            dst.write(src.read())
41    return str(path_out)
42
43
44def test_deprecated_param(path_rgb_byte_tif):
45    """dst_crs is deprecated"""
46    with rasterio.open(path_rgb_byte_tif) as src:
47        with pytest.warns(RasterioDeprecationWarning):
48            vrt = WarpedVRT(src, dst_crs=DST_CRS)
49            assert vrt.dst_crs == CRS.from_string(DST_CRS)
50
51
52def test_warped_vrt(path_rgb_byte_tif):
53    """A VirtualVRT has the expected VRT properties."""
54    with rasterio.open(path_rgb_byte_tif) as src:
55        vrt = WarpedVRT(src, crs=DST_CRS)
56        assert vrt.dst_crs == CRS.from_string(DST_CRS)
57        assert vrt.src_nodata == 0.0
58        assert vrt.dst_nodata == 0.0
59        assert vrt.tolerance == 0.125
60        assert vrt.resampling == Resampling.nearest
61        assert vrt.warp_extras == {"init_dest": "NO_DATA"}
62        assert vrt.mask_flag_enums == ([MaskFlags.nodata],) * 3
63
64
65@requires_gdal21
66def test_warped_vrt_nondefault_nodata(path_rgb_byte_tif):
67    """A VirtualVRT has expected nondefault nodata values."""
68    with rasterio.open(path_rgb_byte_tif) as src:
69        vrt = WarpedVRT(src, crs=DST_CRS, src_nodata=None, nodata=None)
70        assert vrt.dst_crs == CRS.from_string(DST_CRS)
71        assert vrt.src_nodata is None
72        assert vrt.dst_nodata is None
73        assert vrt.tolerance == 0.125
74        assert vrt.resampling == Resampling.nearest
75        assert vrt.warp_extras == {"init_dest": "NO_DATA"}
76        assert vrt.mask_flag_enums == ([MaskFlags.all_valid],) * 3
77
78
79@requires_gdal21(reason="Nodata deletion requires GDAL 2.1+")
80def test_warped_vrt_add_alpha(dsrec, path_rgb_byte_tif):
81    """A VirtualVRT has the expected VRT properties."""
82    with rasterio.Env() as env:
83        with rasterio.open(path_rgb_byte_tif) as src:
84            vrt = WarpedVRT(src, crs=DST_CRS, add_alpha=True)
85
86            records = dsrec(env)
87            assert len(records) == 1
88            assert "2 N GTiff" in records[0]
89
90            assert vrt.dst_crs == CRS.from_string(DST_CRS)
91            assert vrt.src_nodata == 0.0
92            assert vrt.dst_nodata is None
93            assert vrt.tolerance == 0.125
94            assert vrt.resampling == Resampling.nearest
95            assert vrt.warp_extras == {"init_dest": "NO_DATA"}
96            assert vrt.count == 4
97            assert vrt.mask_flag_enums == (
98                [MaskFlags.per_dataset, MaskFlags.alpha],
99            ) * 3 + (
100                [MaskFlags.all_valid],
101            )
102
103        records = dsrec(env)
104        assert len(records) == 1
105        assert "1 N GTiff" in records[0]
106
107
108@requires_gdal21(reason="Nodata deletion requires GDAL 2.1+")
109def test_warped_vrt_msk_add_alpha(path_rgb_msk_byte_tif, caplog):
110    """Add an alpha band to the VRT to access per-dataset mask of a source"""
111    with rasterio.open(path_rgb_msk_byte_tif) as src:
112        vrt = WarpedVRT(src, crs=DST_CRS, add_alpha=True)
113        assert vrt.src_nodata is None
114        assert vrt.dst_nodata is None
115        assert vrt.count == 4
116        assert vrt.mask_flag_enums == (
117            [MaskFlags.per_dataset, MaskFlags.alpha],
118        ) * 3 + (
119            [MaskFlags.all_valid],
120        )
121
122        caplog.set_level(logging.DEBUG)
123        with rasterio.Env(CPL_DEBUG=True):
124            masks = vrt.read_masks()
125            assert masks[0, 0, 0] == 0
126            assert masks[0].mean() > 0
127
128        assert "RGB2.byte.tif.msk" in caplog.text
129
130
131@requires_gdal21(reason="nodata deletion requires gdal 2.1+")
132def test_warped_vrt_msk_nodata(path_rgb_msk_byte_tif, caplog):
133    """Specifying dst nodata also works for source with .msk"""
134    with rasterio.open(path_rgb_msk_byte_tif) as src:
135        vrt = WarpedVRT(src, crs=DST_CRS, nodata=0.0)
136        assert vrt.dst_crs == CRS.from_string(DST_CRS)
137        assert vrt.src_nodata is None
138        assert vrt.dst_nodata == 0.0
139        assert vrt.count == 3
140        assert vrt.mask_flag_enums == ([MaskFlags.nodata],) * 3
141
142        masks = vrt.read_masks()
143        assert masks[0, 0, 0] == 0
144        assert masks[0].mean() > 0
145
146
147def test_warped_vrt_source(path_rgb_byte_tif):
148    """A VirtualVRT has the expected source dataset."""
149    with rasterio.open(path_rgb_byte_tif) as src:
150        vrt = WarpedVRT(src, crs=DST_CRS)
151        assert vrt.src_dataset == src
152
153
154def test_warped_vrt_set_src_crs_default(path_rgb_byte_tif, tmpdir):
155    """A warped VRT's dst_src defaults to the given src_crs"""
156    path_crs_unset = str(tmpdir.join("rgb_byte_crs_unset.tif"))
157    _copy_update_profile(path_rgb_byte_tif, path_crs_unset, crs=None)
158    with rasterio.open(path_rgb_byte_tif) as src:
159        original_crs = src.crs
160    with rasterio.open(path_crs_unset) as src:
161        with WarpedVRT(src, src_crs=original_crs) as vrt:
162            assert vrt.src_crs == original_crs
163            assert vrt.dst_crs == original_crs
164
165
166def test_wrap_file(path_rgb_byte_tif):
167    """A VirtualVRT has the expected dataset properties."""
168    with rasterio.open(path_rgb_byte_tif) as src:
169        vrt = WarpedVRT(src, crs=DST_CRS)
170        assert vrt.crs == CRS.from_string(DST_CRS)
171        assert tuple(round(x, 1) for x in vrt.bounds) == (
172            -8789636.7, 2700460.0, -8524406.4, 2943560.2
173        )
174        assert vrt.name.startswith("WarpedVRT(")
175        assert vrt.name.endswith("tests/data/RGB.byte.tif)")
176        assert vrt.indexes == (1, 2, 3)
177        assert vrt.nodatavals == (0, 0, 0)
178        assert vrt.dtypes == ("uint8", "uint8", "uint8")
179        assert vrt.read().shape == (3, 736, 803)
180
181
182def test_warped_vrt_dimensions(path_rgb_byte_tif):
183    """
184    A WarpedVRT with target dimensions has the expected dataset
185    properties.
186    """
187    with rasterio.open(path_rgb_byte_tif) as src:
188        extent = (-20037508.34, 20037508.34)
189        size = (2 ** 16) * 256
190        resolution = (extent[1] - extent[0]) / size
191        dst_transform = affine.Affine(
192            resolution, 0.0, extent[0], 0.0, -resolution, extent[1]
193        )
194        vrt = WarpedVRT(
195            src, crs=DST_CRS, width=size, height=size, transform=dst_transform
196        )
197        assert vrt.dst_crs == CRS.from_string(DST_CRS)
198        assert vrt.src_nodata == 0.0
199        assert vrt.dst_nodata == 0.0
200        assert vrt.resampling == Resampling.nearest
201        assert vrt.width == size
202        assert vrt.height == size
203        assert vrt.transform == dst_transform
204        assert vrt.warp_extras == {"init_dest": "NO_DATA"}
205
206
207def test_warp_extras(path_rgb_byte_tif):
208    """INIT_DEST warp extra is passed through."""
209    with rasterio.open(path_rgb_byte_tif) as src:
210        with WarpedVRT(src, crs=DST_CRS, init_dest=255) as vrt:
211            rgb = vrt.read()
212            assert (rgb[:, 0, 0] == 255).all()
213
214
215@requires_gdal21(reason="S3 raster access requires GDAL 2.1+")
216@credentials
217@pytest.mark.network
218def test_wrap_s3():
219    """A warp wrapper's dataset has the expected properties"""
220    L8TIF = "s3://landsat-pds/L8/139/045/LC81390452014295LGN00/LC81390452014295LGN00_B1.TIF"
221    with rasterio.open(L8TIF) as src:
222        with WarpedVRT(src, crs=DST_CRS, src_nodata=0, nodata=0) as vrt:
223            assert vrt.crs == DST_CRS
224            assert tuple(round(x, 1) for x in vrt.bounds) == (
225                9556764.6, 2345109.3, 9804595.9, 2598509.1
226            )
227            assert vrt.name == "WarpedVRT(s3://landsat-pds/L8/139/045/LC81390452014295LGN00/LC81390452014295LGN00_B1.TIF)"
228            assert vrt.indexes == (1,)
229            assert vrt.nodatavals == (0,)
230            assert vrt.dtypes == ("uint16",)
231            assert vrt.shape == (7827, 7655)
232
233
234def test_warped_vrt_nodata_read(path_rgb_byte_tif):
235    """A read from a VirtualVRT respects dst_nodata."""
236    with rasterio.open(path_rgb_byte_tif) as src:
237        with WarpedVRT(src, crs=DST_CRS, src_nodata=0) as vrt:
238            data = vrt.read(1, masked=True)
239            assert data.mask.any()
240            mask = vrt.dataset_mask()
241            assert not mask.all()
242
243
244@pytest.mark.parametrize("complex", (True, False))
245def test_crs_should_be_set(path_rgb_byte_tif, tmpdir, complex):
246
247    """When ``dst_height``, ``dst_width``, and ``dst_transform`` are set
248    :py:class:`rasterio.warp.WarpedVRT` calls ``GDALCreateWarpedVRT()``,
249    which requires the caller to then set a projection with
250    ``GDALSetProjection()``.
251
252    Permalink to ``GDALCreateWarpedVRT()`` call:
253
254        https://github.com/mapbox/rasterio/blob/1f759e5f67628f163ea2550d8926b91545245712/rasterio/_warp.pyx#L753
255
256    """
257
258    vrt_path = str(tmpdir.join("test_crs_should_be_set.vrt"))
259
260    with rasterio.open(path_rgb_byte_tif) as src:
261
262        dst_crs = "EPSG:4326"
263        dst_height = dst_width = 10
264        dst_bounds = transform_bounds(src.crs, dst_crs, *src.bounds)
265
266        # Destination transform
267        left, bottom, right, top = dst_bounds
268        xres = (right - left) / dst_width
269        yres = (top - bottom) / dst_height
270        dst_transform = affine.Affine(xres, 0.0, left, 0.0, -yres, top)
271
272        # The 'complex' test case hits the affected code path
273        vrt_options = {"dst_crs": dst_crs}
274        if complex:
275            vrt_options.update(
276                dst_crs=dst_crs,
277                dst_height=dst_height,
278                dst_width=dst_width,
279                dst_transform=dst_transform,
280                resampling=Resampling.nearest,
281            )
282
283        with WarpedVRT(src, **vrt_options) as vrt:
284            rio_shutil.copy(vrt, vrt_path, driver="VRT")
285        with rasterio.open(vrt_path) as src:
286            assert src.crs
287
288
289def test_boundless_read_prohibited(path_rgb_byte_tif):
290    """Boundless read of a VRT is prohibited"""
291    with rasterio.open(path_rgb_byte_tif) as src, WarpedVRT(src) as vrt:
292        with pytest.raises(ValueError):
293            vrt.read(
294                boundless=True,
295                window=Window(-200, -200, 1000, 1000),
296                out_shape=((3, 600, 600)),
297            )
298
299
300def test_boundless_masks_read_prohibited(path_rgb_byte_tif):
301    """Boundless masks read of a VRT is prohibited"""
302    with rasterio.open(path_rgb_byte_tif) as src, WarpedVRT(src) as vrt:
303        with pytest.raises(ValueError):
304            vrt.read_masks(
305                boundless=True,
306                window=Window(-200, -200, 1000, 1000),
307                out_shape=((3, 600, 600)),
308            )
309
310
311def test_no_add_alpha_read(path_rgb_msk_byte_tif):
312    """An alpha band is not added if add_alpha=False"""
313    with rasterio.open(path_rgb_msk_byte_tif) as src, WarpedVRT(
314        src, add_alpha=False
315    ) as vrt:
316        assert vrt.count == 3
317
318
319def test_image(red_green):
320    """Read a red image with black background"""
321    with rasterio.Env():
322        with rasterio.open(str(red_green.join("red.tif"))) as src, WarpedVRT(
323            src,
324            transform=affine.Affine.translation(-src.width / 4, src.height / 4) * src.transform,
325            width=2 * src.width,
326            height=2 * src.height
327        ) as vrt:
328            data = vrt.read()
329            image = numpy.moveaxis(data, 0, -1)
330            assert image[31, 31, 0] == 0
331            assert image[32, 32, 0] == 204
332            assert image[32, 32, 1] == 17
333
334
335def test_image_nodata_mask(red_green):
336    """Nodata of 0 masks out the black background"""
337    with rasterio.Env():
338        with rasterio.open(str(red_green.join("red.tif"))) as src, WarpedVRT(
339            src,
340            nodata=0,
341            transform=affine.Affine.translation(-src.width / 2, src.height / 2) * src.transform,
342            width=3 * src.width,
343            height=3 * src.height
344        ) as vrt:
345            masks = vrt.read_masks()
346            image = numpy.moveaxis(masks, 0, -1)
347            assert image[63, 63, 0] == 0
348            assert image[64, 64, 0] == 255
349
350
351@requires_gdal2(reason="Warped VRT overviews require GDAL 2")
352def test_hit_ovr(red_green):
353    """Zoomed out read hits the overviews"""
354    # GDAL doesn't log overview hits for local files , so we copy the
355    # overviews of green.tif over the red overviews and expect to find
356    # green pixels below.
357    green_ovr = red_green.join("green.tif.ovr")
358    green_ovr.rename(red_green.join("red.tif.ovr"))
359    assert not green_ovr.exists()
360    with rasterio.open(str(red_green.join("red.tif.ovr"))) as ovr:
361        data = ovr.read()
362        assert (data[1] == 204).all()
363
364    with rasterio.open(str(red_green.join("red.tif"))) as src, WarpedVRT(src) as vrt:
365        data = vrt.read(out_shape=(vrt.count, vrt.height // 2, vrt.width // 2))
366        image = numpy.moveaxis(data, 0, -1)
367        assert image[0, 0, 0] == 17
368        assert image[0, 0, 1] == 204
369
370
371@requires_gdal21(reason="add_alpha requires GDAL 2.1+")
372def test_warped_vrt_1band_add_alpha():
373    """Add an alpha band to the VRT to access per-dataset mask of a source"""
374    with rasterio.open('tests/data/shade.tif') as src:
375        vrt = WarpedVRT(src, add_alpha=True)
376        assert vrt.count == 2
377        assert vrt.mask_flag_enums == (
378            [MaskFlags.per_dataset, MaskFlags.alpha],
379            [MaskFlags.all_valid]
380        )
381
382
383@requires_gdal21(reason="add_alpha requires GDAL 2.1+")
384def test_invalid_add_alpha():
385    """Adding an alpha band to a VRT that already has one fails"""
386    with rasterio.open('tests/data/RGBA.byte.tif') as src:
387        with pytest.raises(WarpOptionsError):
388            WarpedVRT(src, add_alpha=True)
389
390
391def test_warpedvrt_float32_preserve(data):
392    """WarpedVRT preserves float32 dtype of source"""
393    with rasterio.open("tests/data/float32.tif") as src:
394        with WarpedVRT(src, src_crs="EPSG:4326") as vrt:
395            assert src.dtypes == vrt.dtypes == ("float32",)
396
397
398def test_warpedvrt_float32_override(data):
399    """Override GDAL defaults for working data type"""
400    float32file = str(data.join("float32.tif"))
401    with rasterio.open(float32file, "r+") as dst:
402        dst.nodata = -3.4028230607370965e+38
403
404    with rasterio.open(float32file) as src:
405        with WarpedVRT(src, src_crs="EPSG:4326", dtype="float32") as vrt:
406            assert src.dtypes == vrt.dtypes == ("float32",)
407
408
409def test_warpedvrt_float32_override_nodata(data):
410    """Override GDAL defaults for working data type"""
411    float32file = str(data.join("float32.tif"))
412    with rasterio.open(float32file, "r+") as dst:
413        dst.nodata = -3.4028230607370965e+38
414
415    with rasterio.open(float32file) as src:
416        with WarpedVRT(src, src_crs="EPSG:4326", nodata=0.0001, dtype="float32") as vrt:
417            assert src.dtypes == vrt.dtypes == ("float32",)
418
419
420@pytest.mark.xfail(reason="GDAL's output defaults to float64")
421def test_warpedvrt_issue1744(data):
422    """Reproduce the bug reported in 1744"""
423    float32file = str(data.join("float32.tif"))
424    with rasterio.open(float32file, "r+") as dst:
425        dst.nodata = -3.4028230607370965e+38
426
427    with rasterio.open(float32file) as src:
428        with WarpedVRT(src, src_crs="EPSG:4326") as vrt:
429            assert src.dtypes == vrt.dtypes == ("float32",)
430
431
432@requires_gdal2
433def test_open_datasets(capfd, path_rgb_byte_tif):
434    """Number of open datasets is expected"""
435    with rasterio.Env() as env:
436
437        with rasterio.open(path_rgb_byte_tif) as src:
438            env._dump_open_datasets()
439            captured = capfd.readouterr()
440            assert "1 N GTiff" in captured.err
441            assert "1 S GTiff" not in captured.err
442
443            with WarpedVRT(src) as vrt:
444                env._dump_open_datasets()
445                captured = capfd.readouterr()
446                assert "2 N GTiff" in captured.err
447
448        env._dump_open_datasets()
449        captured = capfd.readouterr()
450        assert "1 N GTiff" not in captured.err
451
452
453@requires_gdal2
454def test_warp_warp(dsrec, path_rgb_byte_tif):
455    """Vincent! :P"""
456    with rasterio.Env() as env:
457
458        with rasterio.open(path_rgb_byte_tif) as src:
459            # We should have one open dataset with a refcount of 1.
460            records = dsrec(env)
461            assert len(records) == 1
462            assert "1 N GTiff" in records[0]
463
464            with WarpedVRT(src) as vrt:
465                # The VRT increments the refcount of the source by 1.
466                records = dsrec(env)
467                assert len(records) == 1
468                assert "2 N GTiff" in records[0]
469
470                with WarpedVRT(vrt) as vrtvrt:
471                    assert vrtvrt.profile
472                    # Apparently VRTs are tracked in the same way.
473                    records = dsrec(env)
474                    assert len(records) == 1
475                    assert "2 N GTiff" in records[0]
476
477                # Inner VRT is closed.
478                records = dsrec(env)
479                assert len(records) == 1
480                assert "2 N GTiff" in records[0]
481
482            # VRTs are closed, we have one open dataset.
483            records = dsrec(env)
484            assert len(records) == 1
485            assert "1 N GTiff" in records[0]
486
487
488def test_out_dtype(red_green):
489    """Read as float"""
490    with rasterio.Env():
491        with rasterio.open(str(red_green.join("red.tif"))) as src, WarpedVRT(
492            src,
493            transform=affine.Affine.translation(-src.width / 4, src.height / 4) * src.transform,
494            width=2 * src.width,
495            height=2 * src.height
496        ) as vrt:
497            data = vrt.read(out_dtype="float32")
498            image = numpy.moveaxis(data, 0, -1)
499            assert image[31, 31, 0] == 0.0
500            assert image[32, 32, 0] == 204.0
501            assert image[32, 32, 1] == 17.0
502
503
504def test_sample(red_green):
505    """See https://github.com/mapbox/rasterio/issues/1833."""
506    with rasterio.Env():
507        with rasterio.open(str(red_green.join("red.tif"))) as src, WarpedVRT(
508            src,
509            transform=affine.Affine.translation(-src.width / 4, src.height / 4) * src.transform,
510            width=2 * src.width,
511            height=2 * src.height
512        ) as vrt:
513            sample = next(vrt.sample([(-20, -50)]))
514            assert not sample.any()
515
516
517@pytest.fixture
518def dsrec(capfd):
519    """GDAL's open dataset records as a pytest fixture"""
520    def func(env):
521        """Get records of GDAL's open datasets
522
523        Parameters
524        ----------
525        env : Env
526            A rasterio environment.
527
528        Returns
529        -------
530        list of str
531            Each string record represents an open dataset and tells the
532            filename, the driver used to open the dataset, the reference
533            count, and other information.
534
535        """
536        env._dump_open_datasets()
537        captured = capfd.readouterr()
538        records = captured.err.strip("\n").split("\n")[1:]
539        return records
540    return func
541
542
543def test_warped_vrt_resizing():
544    """Confirm fix of #1921"""
545    with rasterio.open("tests/data/RGB.byte.tif") as rgb:
546        with WarpedVRT(rgb, height=10, width=10) as vrt:
547            assert vrt.height == 10
548            assert vrt.width == 10
549
550
551def test_warped_vrt_resizing_repro():
552    """Confirm fix of #1921"""
553    with rasterio.open("tests/data/RGB.byte.tif") as rgb:
554        with WarpedVRT(rgb, crs="EPSG:3857", height=10, width=10) as vrt:
555            assert vrt.height == 10
556            assert vrt.width == 10
557
558
559def test_vrt_src_mode(path_rgb_byte_tif):
560    """VRT source dataset must be opened in read mode"""
561
562    with rasterio.open(path_rgb_byte_tif) as src:
563        profile = src.profile
564        bands = src.read()
565
566    with MemoryFile() as memfile:
567
568        with memfile.open(**profile) as dst:
569            dst.write(bands)
570
571            with pytest.warns(FutureWarning):
572                vrt = WarpedVRT(dst, crs="EPSG:3857")
573
574
575def test_vrt_src_kept_alive(path_rgb_byte_tif):
576    """VRT source dataset is kept alive, preventing crashes"""
577
578    with rasterio.open(path_rgb_byte_tif) as dst:
579        vrt = WarpedVRT(dst, crs="EPSG:3857")
580
581    assert (vrt.read() != 0).any()
582    vrt.close()
583
584
585def test_vrt_mem_src_kept_alive(path_rgb_byte_tif):
586    """VRT in-memory source dataset is kept alive, preventing crashes"""
587
588    with open(path_rgb_byte_tif, "rb") as fp:
589        bands = fp.read()
590
591    with MemoryFile(bands) as memfile, memfile.open() as dst:
592        vrt = WarpedVRT(dst, crs="EPSG:3857")
593
594    assert (vrt.read() != 0).any()
595    vrt.close()
596
597
598def test_warped_vrt_is_closed(path_rgb_byte_tif):
599    """A VirtualVRT should be set as closed on exit."""
600    with rasterio.open(path_rgb_byte_tif) as src:
601        with WarpedVRT(src, crs=DST_CRS) as vrt:
602            assert not vrt.closed
603        assert vrt.closed
604
605
606def test_issue2086():
607    """Create a WarpedVRT from a dataset with GCPs"""
608    with rasterio.open("tests/data/white-gemini-iv.vrt") as src:
609        with WarpedVRT(src, crs=DST_CRS) as vrt:
610            assert vrt.shape == (1031, 1146)
611
612
613def test_gauss_no(path_rgb_byte_tif):
614    """Guard against the issue reported in #2190"""
615    with rasterio.open(path_rgb_byte_tif) as src:
616        with pytest.raises(Exception):
617            WarpedVRT(src, resampling=Resampling.gauss)
618