Exemplo n.º 1
0
def test_tiled_dataset_blocksize_guard(tmp_path):
    """Tiled datasets with dimensions less than blocksize are not permitted"""
    pytest.importorskip("pathlib")
    tmp_file = tmp_path / "test.tif"
    with pytest.raises(ValueError):
        rasterio.open(
            tmp_file, "w", driver="GTiff", count=1, height=13, width=13, dtype="uint8", crs="epsg:3857",
            transform=Affine.identity(), tiled=True, blockxsize=256, blockysize=256)
Exemplo n.º 2
0
def test_untiled_dataset_blocksize(tmp_path):
    """Blocksize is not relevant to untiled datasets (see #1689)"""
    pytest.importorskip("pathlib")
    tmp_file = tmp_path / "test.tif"
    with rasterio.open(
            tmp_file, "w", driver="GTiff", count=1, height=13, width=13, dtype="uint8", crs="epsg:3857",
            transform=Affine.identity(), blockxsize=256, blockysize=256) as dataset:
        pass

    with rasterio.open(tmp_file) as dataset:
        assert not dataset.profile["tiled"]
        assert dataset.shape == (13, 13)
Exemplo n.º 3
0
def test_tiled_dataset_blocksize_guard(tmp_path):
    """Tiled datasets with dimensions less than blocksize are not permitted"""
    pytest.importorskip("pathlib")
    tmp_file = tmp_path / "test.tif"
    with pytest.raises(ValueError):
        rasterio.open(tmp_file,
                      "w",
                      driver="GTiff",
                      count=1,
                      height=13,
                      width=13,
                      dtype="uint8",
                      crs="epsg:3857",
                      transform=Affine.identity(),
                      tiled=True,
                      blockxsize=256,
                      blockysize=256)
Exemplo n.º 4
0
def test_untiled_dataset_blocksize(tmpdir):
    """Blocksize is not relevant to untiled datasets (see #1689)"""
    tmpfile = str(tmpdir.join("test.tif"))
    with rasterio.open(tmpfile,
                       "w",
                       driver="GTiff",
                       count=1,
                       height=13,
                       width=23,
                       dtype="uint8",
                       crs="epsg:3857",
                       transform=Affine.identity(),
                       blockxsize=64,
                       blockysize=64) as dataset:
        pass

    with rasterio.open(tmpfile) as dataset:
        assert not dataset.profile["tiled"]
        assert dataset.shape == (13, 23)
        assert dataset.block_shapes == [(13, 23)]
Exemplo n.º 5
0
def test_untiled_dataset_blocksize(tmp_path):
    """Blocksize is not relevant to untiled datasets (see #1689)"""
    pytest.importorskip("pathlib")
    tmp_file = tmp_path / "test.tif"
    with rasterio.open(tmp_file,
                       "w",
                       driver="GTiff",
                       count=1,
                       height=13,
                       width=13,
                       dtype="uint8",
                       crs="epsg:3857",
                       transform=Affine.identity(),
                       blockxsize=256,
                       blockysize=256) as dataset:
        pass

    with rasterio.open(tmp_file) as dataset:
        assert not dataset.profile["tiled"]
        assert dataset.shape == (13, 13)
Exemplo n.º 6
0
def test_open_specific_driver_with_options():
    """Open a GeoTIFF with the GTiff driver and GEOREF_SOURCES option"""
    with rasterio.open(
            'tests/data/RGB.byte.tif', driver='GTiff', GEOREF_SOURCES='NONE') as src:
        assert src.transform == Affine.identity()
Exemplo n.º 7
0
def test_open_specific_driver_with_options():
    """Open a GeoTIFF with the GTiff driver and GEOREF_SOURCES option"""
    with rasterio.open('tests/data/RGB.byte.tif',
                       driver='GTiff',
                       GEOREF_SOURCES='NONE') as src:
        assert src.transform == Affine.identity()
Exemplo n.º 8
0
def read_window(src, bounds, target_shape, source):
    source_resolution = get_resolution_in_meters(Bounds(src.bounds, src.crs),
                                                 (src.height, src.width))
    target_resolution = get_resolution(bounds, target_shape)

    # GDAL chooses target extents such that reprojected pixels are square; this
    # may produce pixel offsets near the edges of projected bounds
    #   http://lists.osgeo.org/pipermail/gdal-dev/2016-August/045046.html
    #
    # A workaround for this is to produce a VRT with the explicit target extent
    # in projected coordinates (assuming that the target CRS is known).
    # Otherwise, we could tweak the origin (.c, .f) of the generated
    # dst_transform, but that would require knowing projected bounds of all
    # CRSes in use.

    if ("dem" in source.recipes and bounds.crs == WEB_MERCATOR_CRS
            and (target_resolution[0] > source_resolution[0]
                 and target_resolution[1] > source_resolution[1])):
        # special case for web Mercator to prevent crosshatch artifacts; use a
        # target image size that most closely matches the source resolution
        # (and is a power of 2)
        zoom = min(
            22,  # going beyond this results in overflow within GDAL
            get_zoom(
                max(
                    get_resolution_in_meters(Bounds(src.bounds, src.crs),
                                             (src.height, src.width))),
                op=math.ceil,
            ),
        )

        dst_width = dst_height = (2**zoom) * 256
        extent = get_extent(bounds.crs)
        resolution = ((extent[2] - extent[0]) / dst_width,
                      (extent[3] - extent[1]) / dst_height)

        dst_transform = Affine(resolution[0], 0.0, extent[0], 0.0,
                               -resolution[1], extent[3])
    else:
        resolution = None

        if (target_resolution[0] < source_resolution[0]
                or target_resolution[1] < source_resolution[1]):
            # provide resolution for improved resampling when overzooming
            resolution = target_resolution

        (dst_transform, dst_width,
         dst_height) = warp.calculate_default_transform(src.crs,
                                                        bounds.crs,
                                                        src.width,
                                                        src.height,
                                                        *src.bounds,
                                                        resolution=resolution)

    # Some OAM sources have invalid NODATA values (-1000 for a file with a
    # dtype of Byte). rasterio returns None under these circumstances
    # (indistinguishable from sources that actually have no NODATA values).
    # Providing a synthetic value "correctly" masks the output at the expense
    # of masking valid pixels with that value. This was previously (partially;
    # in the form of the bounding box but not NODATA pixels) addressed by
    # creating a VRT that mapped the mask to an alpha channel (something we
    # can't do w/o adding nDstAlphaBand to rasterio/_warp.pyx).
    #
    # Creating external masks and reading them separately (as below) is a
    # better solution, particularly as it avoids artifacts introduced when the
    # NODATA values are resampled using something other than nearest neighbor.

    if any([ColorInterp.palette in src.colorinterp]):
        resampling = Resampling[source.recipes.get("resample", "mode")]
    else:
        resampling = Resampling[source.recipes.get("resample", "bilinear")]

    src_nodata = source.recipes.get("nodata",
                                    source.meta.get("nodata", src.nodata))
    add_alpha = True

    if (any([
            MaskFlags.per_dataset in flags for flags in src.mask_flag_enums
    ]) and not any([MaskFlags.alpha in flags
                    for flags in src.mask_flag_enums])):
        # prefer the mask if available
        src_nodata = None

    if any([MaskFlags.alpha in flags for flags in src.mask_flag_enums]):
        add_alpha = False

    w, s, e, n = bounds.bounds
    vrt_transform = (Affine.translation(w, n) *
                     Affine.scale(dst_transform.a, dst_transform.e) *
                     Affine.identity())
    vrt_width = math.floor((e - w) / dst_transform.a)
    vrt_height = math.floor((s - n) / dst_transform.e)

    with WarpedVRT(
            src,
            src_nodata=src_nodata,
            crs=bounds.crs,
            width=vrt_width,
            height=vrt_height,
            transform=vrt_transform,
            resampling=resampling,
            add_alpha=add_alpha,
    ) as vrt:
        dst_window = vrt.window(*bounds.bounds)

        data = vrt.read(out_shape=(vrt.count, ) + target_shape,
                        window=dst_window)

        mask = np.ma.nomask
        if source.mask:
            with rasterio.Env(OGR_ENABLE_PARTIAL_REPROJECTION=True):
                geom_mask = transform_geom(WGS84_CRS, bounds.crs, source.mask)

            mask_transform = from_bounds(*bounds.bounds,
                                         height=target_shape[0],
                                         width=target_shape[1])
            mask = geometry_mask([geom_mask],
                                 target_shape,
                                 transform=mask_transform,
                                 invert=True)

        if any([ColorInterp.alpha in vrt.colorinterp]):
            alpha_idx = vrt.colorinterp.index(ColorInterp.alpha)
            mask = [~data[alpha_idx] | mask] * (vrt.count - 1)
            bands = [data[i] for i in range(0, vrt.count) if i != alpha_idx]
            data = np.ma.masked_array(bands, mask=mask)
        else:
            # mask with NODATA values
            if src_nodata is not None and vrt.nodata is not None:
                data = _mask(data, vrt.nodata)
                data.mask = data.mask | mask
            else:
                data = np.ma.masked_array(data, mask=mask)

    return PixelCollection(data, bounds)