Ejemplo n.º 1
0
def test_warp_from_to_file(tmpdir):
    """File to file"""
    tiffname = str(tmpdir.join('foo.tif'))
    with rasterio.open('rasterio/tests/data/RGB.byte.tif') as src:
        dst_transform = [-8789636.708, 300.0, 0.0, 2943560.235, 0.0, -300.0]
        dst_crs = dict(
                    proj='merc',
                    a=6378137,
                    b=6378137,
                    lat_ts=0.0,
                    lon_0=0.0,
                    x_0=0.0,
                    y_0=0,
                    k=1.0,
                    units='m',
                    nadgrids='@null',
                    wktext=True,
                    no_defs=True)
        kwargs = src.meta.copy()
        kwargs.update(
            transform=dst_transform,
            crs=dst_crs)
        with rasterio.open(tiffname, 'w', **kwargs) as dst:
            for i in (1, 2, 3):
                reproject(rasterio.band(src, i), rasterio.band(dst, i))
Ejemplo n.º 2
0
def test_warp_from_to_file_multi(tmpdir):
    """File to file"""
    tiffname = str(tmpdir.join('foo.tif'))
    with rasterio.open('tests/data/RGB.byte.tif') as src:
        dst_crs = dict(
            proj='merc',
            a=6378137,
            b=6378137,
            lat_ts=0.0,
            lon_0=0.0,
            x_0=0.0,
            y_0=0,
            k=1.0,
            units='m',
            nadgrids='@null',
            wktext=True,
            no_defs=True)
        kwargs = src.meta.copy()
        kwargs.update(
            transform=DST_TRANSFORM,
            crs=dst_crs)
        with rasterio.open(tiffname, 'w', **kwargs) as dst:
            for i in (1, 2, 3):
                reproject(
                    rasterio.band(src, i),
                    rasterio.band(dst, i),
                    num_threads=2)
Ejemplo n.º 3
0
def reproject_dataset(geotiff_path):
    """Project a GeoTIFF to the WGS84 coordinate reference system.
    See https://mapbox.github.io/rasterio/topics/reproject.html"""

    # We want to project the GeoTIFF coordinate reference system (crs)
    # to WGS84 (e.g. into the familiar Lat/Lon pairs). WGS84 is analogous
    # to EPSG:4326
    dst_crs = 'EPSG:4326'

    with rasterio.open(geotiff_path) as src:
        transform, width, height = rasterio.warp.calculate_default_transform(
            src.crs, dst_crs, src.width, src.height, *src.bounds)
        kwargs = src.meta.copy()
        kwargs.update({
            'crs': dst_crs,
            'transform': transform,
            'width': width,
            'height': height
        })

        satellite_img_name = get_file_name(geotiff_path)
        out_file_name = "{}_wgs84.tif".format(satellite_img_name)
        out_path = os.path.join(WGS84_DIR, out_file_name)
        with rasterio.open(out_path, 'w', **kwargs) as dst:
            for i in range(1, src.count + 1):
                rasterio.warp.reproject(
                    source=rasterio.band(src, i),
                    destination=rasterio.band(dst, i),
                    src_transform=src.transform,
                    src_crs=src.crs,
                    dst_transform=transform,
                    dst_crs=dst_crs,
                    resampling=rasterio.warp.Resampling.nearest)

        return rasterio.open(out_path), out_path
Ejemplo n.º 4
0
def warp_tif(combined_tif_path, warped_tif_path, dst_crs={
        'init': 'EPSG:3857'
}):
    logger.info('Warping tif to web mercator: %s', combined_tif_path)
    with rasterio.open(combined_tif_path) as src:
        meta = src.meta
        new_meta = meta.copy()
        transform, width, height = calculate_default_transform(
            src.crs, dst_crs, src.width, src.height, *src.bounds)
        new_meta.update({
            'crs': dst_crs,
            'transform': transform,
            'width': width,
            'height': height,
            'nodata': -28762
        })
        with rasterio.open(
                warped_tif_path, 'w', compress='DEFLATE', tiled=True,
                **new_meta) as dst:
            for i in range(1, src.count):
                reproject(
                    source=rasterio.band(src, i),
                    destination=rasterio.band(dst, i),
                    src_transform=src.transform,
                    src_crs=src.crs,
                    dst_transform=transform,
                    dst_crs=dst_crs,
                    resampling=Resampling.nearest,
                    src_nodata=-28762
                )
Ejemplo n.º 5
0
def get_bands(inputs, d, i=None):
    """Get a rasterio.Band object from calc's inputs"""
    path = inputs[d] if d in dict(inputs) else inputs[int(d)-1][1]
    if i:
        return rasterio.band(rasterio.open(path), i)
    else:
        src = rasterio.open(path)
        return [rasterio.band(src, i) for i in src.indexes]
Ejemplo n.º 6
0
    def reproject(self, destination_file, source_file=None, resampling=RESAMPLING.nearest, **kwargs):
        """
        Reprojects the pixels of a source raster map to a destination raster, with a different reference coordinate
        system and Affine transform. It uses `Rasterio <https://github.com/mapbox/rasterio/blob/master/docs/reproject.rst>`_
        calculate_default_transform() to calculate parameters such as the resolution (if not provided), and the destination
        transform and dimensions.

        param string source_file: Full path to the source file containing a raster map

        param string destination_file: Full path to the destination file containing a raster map

        :param int resampling: Resampling method to use. Can be one of the following: ``Resampling.nearest``, ``Resampling.bilinear``, \
        ``Resampling.cubic``, ``Resampling.cubic_spline``, ``Resampling.lanczos``, ``Resampling.average``, ``Resampling.mode``.

        :param dict kwargs: Optional additional arguments passed to the method, to parametrize the reprojection. \
        For example: :attr:`dst_crs` for the target coordinate reference system, :attr:`resolution` for the target resolution, \
        in units of target coordinate reference system.

        """
        if not source_file:
            if not self.file_path:
                raise AttributeError("Please provide a source_file to load the data from.")
            else:
                source_file = self.file_path

        with rasterio.open(source_file) as src:
            affine, width, height = calculate_default_transform(src_crs=src.crs,
                                                                dst_crs=kwargs.get('dst_crs', src.crs),
                                                                width=kwargs.get('width', src.width),
                                                                height=kwargs.get('height', src.height),
                                                                left=kwargs.get('left', src.bounds.left),
                                                                bottom=kwargs.get('bottom', src.bounds.bottom),
                                                                right=kwargs.get('right', src.bounds.right),
                                                                top=kwargs.get('top', src.bounds.top),
                                                                resolution=kwargs.get('resolution', src.res)
                                                                )
            logger.info("Calculated default transformation:")
            logger.info("Affine:\n{0} \n width={1}, height={2}".format(affine, width, height))

            kwargs = src.meta.copy()
            kwargs.update({'transform': affine,
                           'affine': affine,
                           'width': width,
                           'height': height
                           })

            with rasterio.open(destination_file, 'w', **kwargs) as dst:
                for i in range(1, src.count + 1):
                    rasterio.warp.reproject(source=rasterio.band(src, i),
                                            destination=rasterio.band(dst, i),
                                            src_transform=src.affine,
                                            src_crs=src.crs,
                                            dst_transform=affine,
                                            dst_crs=kwargs.get('dst_crs', src.crs),
                                            resampling=resampling
                                            )
            logger.info("Reprojected data in %s " % destination_file)
 def __reproject(self, in_raster, out_raster, affine, new_crs):
     for k in range(1, in_raster.count + 1):
         reproject(
             source=rasterio.band(in_raster, k),
             destination=rasterio.band(out_raster, k),
             src_transform=affine,
             src_crs=in_raster.crs,
             dst_transform=affine,
             dst_crs=new_crs,
             resampling=RESAMPLING.nearest)
     return out_raster
Ejemplo n.º 8
0
def test_reproject_no_init_nodata_tofile(tmpdir):
    """Test that nodata is not being initialized."""
    params = default_reproject_params()

    tiffname = str(tmpdir.join('foo.tif'))

    source1 = np.zeros((params.width, params.height), dtype=np.uint8)
    source2 = source1.copy()

    # fill both sources w/ arbitrary values
    rows, cols = source1.shape
    source1[:rows // 2, :cols // 2] = 200
    source2[rows // 2:, cols // 2:] = 100

    kwargs = {
        'count': 1,
        'width': params.width,
        'height': params.height,
        'dtype': np.uint8,
        'driver': 'GTiff',
        'crs': params.dst_crs,
        'transform': params.dst_transform
    }

    with rasterio.open(tiffname, 'w', **kwargs) as dst:
        reproject(
            source1,
            rasterio.band(dst, 1),
            src_transform=params.src_transform,
            src_crs=params.src_crs,
            src_nodata=0.0,
            dst_transform=params.dst_transform,
            dst_crs=params.dst_crs,
            dst_nodata=0.0
        )

        reproject(
            source2,
            rasterio.band(dst, 1),
            src_transform=params.src_transform,
            src_crs=params.src_crs,
            src_nodata=0.0,
            dst_transform=params.dst_transform,
            dst_crs=params.dst_crs,
            dst_nodata=0.0,
            init_dest_nodata=False
        )

    # 200s should remain along with 100s
    with rasterio.open(tiffname) as src:
        data = src.read()

    assert data.max() == 200
Ejemplo n.º 9
0
def test_reproject_no_init_nodata_tofile(tmpdir):
    """Test that nodata is not being initialized."""
    params = default_reproject_params()

    tiffname = str(tmpdir.join("foo.tif"))

    source1 = np.zeros((params.width, params.height), dtype=np.uint8)
    source2 = source1.copy()

    # fill both sources w/ arbitrary values
    rows, cols = source1.shape
    source1[:rows // 2, :cols // 2] = 200
    source2[rows // 2:, cols // 2:] = 100

    kwargs = {
        "count": 1,
        "width": params.width,
        "height": params.height,
        "dtype": np.uint8,
        "driver": "GTiff",
        "crs": params.dst_crs,
        "transform": params.dst_transform,
    }

    with rasterio.open(tiffname, "w", **kwargs) as dst:
        reproject(
            source1,
            rasterio.band(dst, 1),
            src_transform=params.src_transform,
            src_crs=params.src_crs,
            src_nodata=0.0,
            dst_transform=params.dst_transform,
            dst_crs=params.dst_crs,
            dst_nodata=0.0,
        )

        reproject(
            source2,
            rasterio.band(dst, 1),
            src_transform=params.src_transform,
            src_crs=params.src_crs,
            src_nodata=0.0,
            dst_transform=params.dst_transform,
            dst_crs=params.dst_crs,
            dst_nodata=0.0,
            init_dest_nodata=False,
        )

    # 200s should remain along with 100s
    with rasterio.open(tiffname) as src:
        data = src.read()

    assert data.max() == 200
Ejemplo n.º 10
0
def test_band():
    with rasterio.open('tests/data/RGB.byte.tif') as src:
        b = rasterio.band(src, 1)
        assert b.ds == src
        assert b.bidx == 1
        assert b.dtype in src.dtypes
        assert b.shape == src.shape
Ejemplo n.º 11
0
def test_warp_from_file():
    """File to ndarray"""
    with rasterio.open('rasterio/tests/data/RGB.byte.tif') as src:
        dst_transform = [-8789636.708, 300.0, 0.0, 2943560.235, 0.0, -300.0]
        dst_crs = dict(
                    proj='merc',
                    a=6378137,
                    b=6378137,
                    lat_ts=0.0,
                    lon_0=0.0,
                    x_0=0.0,
                    y_0=0,
                    k=1.0,
                    units='m',
                    nadgrids='@null',
                    wktext=True,
                    no_defs=True)
        destin = numpy.empty(src.shape, dtype=numpy.uint8)
        reproject(
            rasterio.band(src, 1), 
            destin, 
            dst_transform=dst_transform, 
            dst_crs=dst_crs)
    assert destin.any()
    try:
        import matplotlib.pyplot as plt
        plt.imshow(destin)
        plt.gray()
        plt.savefig('test_warp_from_filereproject.png')
    except:
        pass
Ejemplo n.º 12
0
def process_tile(tile):
    """Process a single MBTiles tile."""
    global base_kwds, src
    # Get the bounds of the tile.
    ulx, uly = mercantile.xy(*mercantile.ul(tile.x, tile.y, tile.z))
    lrx, lry = mercantile.xy(*mercantile.ul(tile.x + 1, tile.y + 1, tile.z))

    kwds = base_kwds.copy()
    kwds["transform"] = from_bounds(ulx, lry, lrx, uly, 256, 256)

    with rasterio.open("/vsimem/tileimg", "w", **kwds) as tmp:
        # Reproject the src dataset into image tile.
        for bidx in tmp.indexes:
            reproject(rasterio.band(src, bidx), rasterio.band(tmp, bidx))

    # Get contents of the virtual file.
    contents = bytearray(virtual_file_to_buffer("/vsimem/tileimg"))
    return tile, contents
Ejemplo n.º 13
0
def test_shapes_band_shortcut():
    """Access to shapes of labeled features"""
    with rasterio.drivers():
        with rasterio.open('rasterio/tests/data/shade.tif') as src:
            shapes = ftrz.shapes(rasterio.band(src, 1))
            shape, val = next(shapes)
            assert shape['type'] == 'Polygon'
            assert len(shape['coordinates']) == 1
            assert val == 255
Ejemplo n.º 14
0
def process_chunk(tile, input, creation_options, resampling):
    """Process a single tile."""

    from rasterio.warp import RESAMPLING

    input = input.replace("s3://", "/vsicurl/http://s3.amazonaws.com/")

    print("Chunking initial image for", tile)

    # Get the bounds of the tile.
    ulx, uly = mercantile.xy(
        *mercantile.ul(tile.x, tile.y, tile.z))
    lrx, lry = mercantile.xy(
        *mercantile.ul(tile.x + 1, tile.y + 1, tile.z))

    tmp_path = "/vsimem/tile"

    with rasterio.drivers():
        with rasterio.open(input, "r") as src:
            meta = src.meta.copy()
            meta.update(creation_options)
            meta["height"] = CHUNK_SIZE
            meta["width"] = CHUNK_SIZE
            meta["transform"] = from_bounds(ulx, lry, lrx, uly, CHUNK_SIZE, CHUNK_SIZE)

            # write to a tmp file to allow GDAL to handle the transform
            with rasterio.open(tmp_path, "w", **meta) as tmp:
                # Reproject the src dataset into image tile.
                for bidx in src.indexes:
                    reproject(
                        source=rasterio.band(src, bidx),
                        destination=rasterio.band(tmp, bidx),
                        resampling=getattr(RESAMPLING, resampling),
                        num_threads=multiprocessing.cpu_count(),
                    )

                # check for chunks containing only NODATA
                data = tmp.read(masked=True)

            if data.mask.all():
                return

            # TODO hard-coded for the first band
            return (tile, data[0])
Ejemplo n.º 15
0
def test_shapes_band_shortcut():
    """Test rasterio bands as input to shapes"""

    with rasterio.drivers():
        with rasterio.open('tests/data/shade.tif') as src:
            shapes = ftrz.shapes(rasterio.band(src, 1))
            shape, val = next(shapes)
            assert shape['type'] == 'Polygon'
            assert len(shape['coordinates']) == 1
            assert val == 255
Ejemplo n.º 16
0
def test_shapes_band(pixelated_image, pixelated_image_file):
    """Shapes from a band should match shapes from an array."""
    truth = list(shapes(pixelated_image))

    with rasterio.open(pixelated_image_file) as src:
        band = rasterio.band(src, 1)
        assert truth == list(shapes(band))

        # Mask band should function, but will mask out some results
        assert truth[0] == list(shapes(band, mask=band))[0]
Ejemplo n.º 17
0
def process_chunk_task(task):
    """
    Chunks the image into tile_dim x tile_dim tiles,
    and saves them to the target folder (s3 or local)

    Returns the extent of the output raster.
    """

    creation_options = {
        "driver": "GTiff",
        "crs": "EPSG:3857",
        "tiled": True,
        "compress": "deflate",
        "predictor":   2, # 3 for floats, 2 otherwise
        "sparse_ok": True
    }

    with rasterio.open(task.source_uri, "r") as src:
        meta = src.meta.copy()
        meta.update(creation_options)
        meta.update(task.target_meta)
        
        cols = meta["width"]
        rows = meta["height"]

        tmp_path = "/vsimem/" + get_filename(task.target)

        with rasterio.open(tmp_path, "w", **meta) as tmp:
            # Reproject the src dataset into image tile.
            warped = []
            for bidx in src.indexes:
                source = rasterio.band(src, bidx)
                warped.append(numpy.zeros((cols, rows), dtype=meta['dtype']))

                warp.reproject(
                    source=source,
                    src_nodata=0,
                    destination=warped[bidx - 1],
                    dst_transform=meta["transform"],
                    dst_crs=meta["crs"],
                    # resampling=RESAMPLING.bilinear
                )

            # check for chunks containing only zero values
            if not any(map(lambda b: b.any(), warped)):
                return False

            # write out our warped data to the vsimem raster
            for bidx in src.indexes:
                tmp.write_band(bidx, warped[bidx - 1])

    contents = bytearray(virtual_file_to_buffer(tmp_path))

    write_bytes_to_target(task.target, contents)
    return True
Ejemplo n.º 18
0
def project_raster(src_raster, dst_raster, dst_crs):
    """Reproject a raster from one coordinate system to another using Rasterio
    code from: https://github.com/mapbox/rasterio/blob/master/docs/reproject.rst

    Parameters
    ----------
    src_raster : str
        Filename of source raster.
    dst_raster : str
        Filename of reprojected (destination) raster.
    dst_crs : str
        Coordinate system of reprojected raster.
        Examples:
            'EPSG:26715' 
    """
    try:
        import rasterio
        from rasterio.warp import calculate_default_transform, reproject, RESAMPLING
    except:
        print('This function requires rasterio.')

    with rasterio.open(src_raster) as src:
        affine, width, height = calculate_default_transform(
            src.crs, dst_crs, src.width, src.height, *src.bounds)
        kwargs = src.meta.copy()
        kwargs.update({
            'crs': dst_crs,
            'transform': affine,
            'affine': affine,
            'width': width,
            'height': height
        })
        with rasterio.open(dst_raster, 'w', **kwargs) as dst:
            for i in range(1, src.count + 1):
                reproject(
                    source=rasterio.band(src, i),
                    destination=rasterio.band(dst, i),
                    src_transform=src.affine,
                    src_crs=src.crs,
                    dst_transform=affine,
                    dst_crs=dst_crs,
                    resampling=RESAMPLING.nearest)
Ejemplo n.º 19
0
def project2wgs(gtiff, output):
    with rio.Env():
        with rio.open(gtiff) as src:
            out_kwargs = src.meta.copy()
            out_kwargs['driver'] = 'GTiff'

            print(out_kwargs)

            res = (0.01, 0.01)
            dst_crs = crs.from_string('+units=m +init=epsg:4326')

            #dst_width, dst_height = src.width, src.height
            xmin, ymin, xmax, ymax = [-127.8294048826629989,5.1830409679864857,
                                      -59.0561278820333229,49.9999999955067977]
            dst_transform = Affine(res[0], 0, xmin, 0, -res[1], ymax)
            dst_width = max(int(ceil((xmax - xmin) / res[0])), 1)
            dst_height = max(int(ceil((ymax - ymin) / res[1])), 1)
            print(dst_transform)

            out_kwargs.update({
                    'crs': dst_crs,
                    'transform': dst_transform,
                    'affine': dst_transform,
                    'width': dst_width,
                    'height': dst_height
                })

            print(out_kwargs)

            with rio.open(output, 'w', **out_kwargs) as dst:
                reproject(
                    source=rio.band(src, 1),
                    destination=rio.band(dst, 1),
                    src_transform=src.affine,
                    src_crs=src.crs,
                    src_nodata=src.nodata,
                    dst_transform=out_kwargs['transform'],
                    dst_crs=out_kwargs['crs'],
                    dst_nodata=src.nodata,
                    resampling=0,
                    num_threads=2)
Ejemplo n.º 20
0
def run(input_file, out_file, dst_crs):
    try:
        print("Starting proccess...")

        createOutFolder(out_file)

        with rasterio.open(input_file) as src:

            affine, width, height = calculate_default_transform(
                src.crs, dst_crs, src.width, src.height,*src.bounds)
            kwargs = src.meta.copy()
            kwargs.update({
                'crs': dst_crs,
                'transform': affine,
                'affine': affine,
                'width': width,
                'height': height,
                'compress': 'lzw',
                'nodata': 0
            })

            with rasterio.open(out_file, 'w', **kwargs) as dst:

                reproject(
                    source=rasterio.band(src, 1),
                    destination=rasterio.band(dst, 1),
                    src_transform=src.affine,
                    src_crs=src.crs,
                    dst_transform=affine,
                    dst_crs=dst_crs,
                    resampling=RESAMPLING.nearest)

                for i in dst.indexes:
                    band_dst = dst.read(i) / 100
                    dst.write_band(i, band_dst)

        print("Successfully finished proccess!")

    except Exception as error:
        print("Error creating out folder: {}".format(error))
def ConvertRaster2LatLong(InputRasterFile,OutputRasterFile):

    """
    Convert a raster to lat long WGS1984 EPSG:4326 coordinates for global plotting

    MDH

    """

    # import modules
    import rasterio
    from rasterio.warp import reproject, calculate_default_transform as cdt, Resampling

    # read the source raster
    with rasterio.open(InputRasterFile) as src:
        #get input coordinate system
        Input_CRS = src.crs
        # define the output coordinate system
        Output_CRS = {'init': "epsg:4326"}
        # set up the transform
        Affine, Width, Height = cdt(Input_CRS,Output_CRS,src.width,src.height,*src.bounds)
        kwargs = src.meta.copy()
        kwargs.update({
            'crs': Output_CRS,
            'transform': Affine,
            'affine': Affine,
            'width': Width,
            'height': Height
        })

        with rasterio.open(OutputRasterFile, 'w', **kwargs) as dst:
            for i in range(1, src.count+1):
                reproject(
                    source=rasterio.band(src, i),
                    destination=rasterio.band(dst, i),
                    src_transform=src.affine,
                    src_crs=src.crs,
                    dst_transform=Affine,
                    dst_crs=Output_CRS,
                    resampling=Resampling.bilinear)
Ejemplo n.º 22
0
def test_issue1056():
    """Warp sucessfully from RGB's upper bands to an array"""
    with rasterio.open('tests/data/RGB.byte.tif') as src:

        dst_crs = {'init': 'EPSG:3857'}
        out = np.zeros(src.shape, dtype=np.uint8)
        reproject(
            rasterio.band(src, 2),
            out,
            src_transform=src.transform,
            src_crs=src.crs,
            dst_transform=DST_TRANSFORM,
            dst_crs=dst_crs,
            resampling=Resampling.nearest)
Ejemplo n.º 23
0
def test_sieve_band(pixelated_image, pixelated_image_file):
    """Sieving a band from a raster file should match sieve of array."""

    truth = sieve(pixelated_image, 9)

    with rasterio.open(pixelated_image_file) as src:
        band = rasterio.band(src, 1)
        assert np.array_equal(truth, sieve(band, 9))

        # Mask band should also work but will be a no-op
        assert np.array_equal(
            pixelated_image,
            sieve(band, 9, mask=band)
        )
Ejemplo n.º 24
0
def test_warp_from_to_file(tmpdir):
    """File to file."""
    tiffname = str(tmpdir.join("foo.tif"))
    with rasterio.open("tests/data/RGB.byte.tif") as src:
        dst_crs = dict(
            proj="merc",
            a=6378137,
            b=6378137,
            lat_ts=0.0,
            lon_0=0.0,
            x_0=0.0,
            y_0=0,
            k=1.0,
            units="m",
            nadgrids="@null",
            wktext=True,
            no_defs=True,
        )
        kwargs = src.meta.copy()
        kwargs.update(transform=DST_TRANSFORM, crs=dst_crs)
        with rasterio.open(tiffname, "w", **kwargs) as dst:
            for i in (1, 2, 3):
                reproject(rasterio.band(src, i), rasterio.band(dst, i))
Ejemplo n.º 25
0
def test_issue1401():
    """The warp_mem_limit keyword argument is in effect"""
    with rasterio.open('tests/data/RGB.byte.tif') as src:
        dst_crs = {'init': 'EPSG:3857'}
        out = np.zeros(src.shape, dtype=np.uint8)
        reproject(
            rasterio.band(src, 2),
            out,
            src_transform=src.transform,
            src_crs=src.crs,
            dst_transform=DST_TRANSFORM,
            dst_crs=dst_crs,
            resampling=Resampling.nearest,
            warp_mem_limit=4000)
Ejemplo n.º 26
0
def test_warp_from_to_file_multi(tmpdir):
    """File to file"""
    tiffname = str(tmpdir.join("foo.tif"))
    with rasterio.open("tests/data/RGB.byte.tif") as src:
        dst_transform = affine.Affine.from_gdal(-8789636.708, 300.0, 0.0, 2943560.235, 0.0, -300.0)
        dst_crs = dict(
            proj="merc",
            a=6378137,
            b=6378137,
            lat_ts=0.0,
            lon_0=0.0,
            x_0=0.0,
            y_0=0,
            k=1.0,
            units="m",
            nadgrids="@null",
            wktext=True,
            no_defs=True,
        )
        kwargs = src.meta.copy()
        kwargs.update(transform=dst_transform, crs=dst_crs)
        with rasterio.open(tiffname, "w", **kwargs) as dst:
            for i in (1, 2, 3):
                reproject(rasterio.band(src, i), rasterio.band(dst, i), num_threads=2)
Ejemplo n.º 27
0
def warp_image(infile, outfile, dst_crs="EPSG:3857", dst_driver='GTiff'):
    """
    Use rasterio to warp an image from one projection to another
    :param infile: Origina raster image
    :param outfile: Warped raster image
    :param dst_crs: Output projection
    :param dst_driver: Output filetype driver
    :return: None
    """
    with rasterio.drivers(CPL_DEBUG=False):
        with rasterio.open(infile) as src:
            res = None
            dst_transform, dst_width, dst_height = calculate_default_transform(
                src.crs, dst_crs, src.width, src.height,
                *src.bounds, resolution=res)
            out_kwargs = src.meta.copy()
            out_kwargs.update({
                'crs': dst_crs,
                'transform': dst_transform,
                'affine': dst_transform,
                'width': dst_width,
                'height': dst_height,
                'driver': dst_driver
            })

            with rasterio.open(outfile, 'w', **out_kwargs) as dst:
                for i in range(1, src.count + 1):
                    reproject(
                        source=rasterio.band(src, i),
                        destination=rasterio.band(dst, i),
                        src_transform=src.affine,
                        src_crs=src.crs,
                        dst_transform=out_kwargs['transform'],
                        dst_crs=out_kwargs['crs'],
                        resampling=RESAMPLING.nearest,
                        num_threads=1)
Ejemplo n.º 28
0
def test_band(rgb_image, band_idx):
    band = core.Band(rgb_image, bidx=band_idx)

    with rasterio.open(rgb_image) as src:
        # Assert the properties are the same
        props = [(p, v) for p, v in
                 inspect.getmembers(src, lambda x: not callable(x))
                 if not p.startswith('_')]
        for prop, value in props:
            assert getattr(band.src, prop) == value

        filter_ = (lambda x: not callable(x) and
                             not isinstance(x, rasterio._io.RasterReader))
        props = [(p, v) for p, v in
                 inspect.getmembers(rasterio.band(src, band_idx), filter_)
                 if not p.startswith('_')]
        for prop, value in props:
            assert getattr(band.band, prop) == value
Ejemplo n.º 29
0
def test_reproject_dst_alpha(path_rgb_msk_byte_tif):
    """Materialization of external mask succeeds"""

    with rasterio.open(path_rgb_msk_byte_tif) as src:

        nrows, ncols = src.shape

        dst_arr = np.zeros((src.count + 1, nrows, ncols), dtype=np.uint8)

        reproject(
            rasterio.band(src, src.indexes),
            dst_arr,
            src_transform=src.transform,
            src_crs=src.crs,
            dst_transform=DST_TRANSFORM,
            dst_crs={'init': 'EPSG:3857'},
            dst_alpha=4)

        assert dst_arr[3].any()
Ejemplo n.º 30
0
def test_reproject_dst_alpha(path_rgb_msk_byte_tif):
    """Materialization of external mask succeeds"""

    with rasterio.open(path_rgb_msk_byte_tif) as src:

        nrows, ncols = src.shape

        dst_arr = np.zeros((src.count + 1, nrows, ncols), dtype=np.uint8)

        reproject(
            rasterio.band(src, src.indexes),
            dst_arr,
            src_transform=src.transform,
            src_crs=src.crs,
            dst_transform=DST_TRANSFORM,
            dst_crs={"init": "EPSG:3857"},
            dst_alpha=4,
        )

        assert dst_arr[3].any()
Ejemplo n.º 31
0
def test_warp_from_file():
    """File to ndarray."""
    with rasterio.open('tests/data/RGB.byte.tif') as src:
        dst_crs = dict(proj='merc',
                       a=6378137,
                       b=6378137,
                       lat_ts=0.0,
                       lon_0=0.0,
                       x_0=0.0,
                       y_0=0,
                       k=1.0,
                       units='m',
                       nadgrids='@null',
                       wktext=True,
                       no_defs=True)
        destin = np.empty(src.shape, dtype=np.uint8)
        reproject(rasterio.band(src, 1),
                  destin,
                  dst_transform=DST_TRANSFORM,
                  dst_crs=dst_crs)
    assert destin.any()
Ejemplo n.º 32
0
def _tile_worker(tile):
    """
    For each tile, and given an open rasterio src, plus a`global_args` dictionary
    with attributes of `base_val`, `interval`, and a `writer_func`,
    warp a continous single band raster to a 512 x 512 mercator tile,
    then encode this tile into RGB.

    Parameters
    -----------
    tile: list
        [x, y, z] indices of tile

    Returns
    --------
    tile, buffer
        tuple with the input tile, and a bytearray with the data encoded into
        the format created in the `writer_func`

    """
    x, y, z = tile

    bounds = [
        c for i in (mercantile.xy(*mercantile.ul(x, y + 1, z)),
                    mercantile.xy(*mercantile.ul(x + 1, y, z))) for c in i
    ]

    toaffine = transform.from_bounds(*bounds + [512, 512])

    out = np.empty((512, 512), dtype=src.meta['dtype'])

    reproject(rasterio.band(src, 1),
              out,
              dst_transform=toaffine,
              dst_crs="init='epsg:3857'",
              resampling=RESAMPLING.bilinear)

    out = data_to_rgb(out, global_args['base_val'], global_args['interval'])

    return tile, global_args['writer_func'](out, global_args['kwargs'].copy(),
                                            toaffine)
Ejemplo n.º 33
0
def test_warp_from_file():
    """File to ndarray."""
    with rasterio.open("tests/data/RGB.byte.tif") as src:
        dst_crs = dict(
            proj="merc",
            a=6378137,
            b=6378137,
            lat_ts=0.0,
            lon_0=0.0,
            x_0=0.0,
            y_0=0,
            k=1.0,
            units="m",
            nadgrids="@null",
            wktext=True,
            no_defs=True,
        )
        destin = np.empty(src.shape, dtype=np.uint8)
        reproject(
            rasterio.band(src, 1), destin, dst_transform=DST_TRANSFORM, dst_crs=dst_crs
        )
    assert destin.any()
Ejemplo n.º 34
0
def test_issue1350():
    """Warp bands other than 1 or All"""

    with rasterio.open('tests/data/RGB.byte.tif') as src:
        dst_crs = {'init': 'EPSG:3857'}

        reprojected = []

        for dtype, idx in zip(src.dtypes, src.indexes):
            out = np.zeros((1,) + src.shape, dtype=dtype)

            reproject(
                rasterio.band(src, idx),
                out,
                resampling=Resampling.nearest,
                dst_transform=DST_TRANSFORM,
                dst_crs=dst_crs)

            reprojected.append(out)

        for i in range(1, len(reprojected)):
            assert not (reprojected[0] == reprojected[i]).all()
Ejemplo n.º 35
0
    def open(self) -> Iterator[GeoRasterReader]:
        """Context manager which returns a :class:`BandDataSource`"""
        try:
            _LOG.debug("opening %s", self.filename)
            with rasterio.open(self.filename) as src:
                override = False

                transform = src.transform
                if transform.is_identity:
                    override = True
                    transform = self.get_transform(src.shape)

                try:
                    crs = geometry.CRS(_rasterio_crs_wkt(src))
                except ValueError:
                    override = True
                    crs = self.get_crs()

                # The [1.0a1-1.0a8] releases of rasterio had a bug that means it
                # cannot read multiband data into a numpy array during reprojection
                # We override it here to force the reading and reprojection into separate steps
                # TODO: Remove when we no longer care about those versions of rasterio
                bandnumber = self.get_bandnumber(src)
                band = rasterio.band(src, bandnumber)
                nodata = src.nodatavals[band.bidx - 1] if src.nodatavals[
                    band.bidx - 1] is not None else self.nodata
                nodata = num2numpy(nodata, band.dtype)

                if override:
                    yield OverrideBandDataSource(band,
                                                 nodata=nodata,
                                                 crs=crs,
                                                 transform=transform)
                else:
                    yield BandDataSource(band, nodata=nodata)

        except Exception as e:
            _LOG.error("Error opening source dataset: %s", self.filename)
            raise e
Ejemplo n.º 36
0
    def open(self):
        """Context manager which returns a :class:`BandDataSource`"""
        try:
            _LOG.debug("opening %s", self.filename)
            with rasterio.open(self.filename) as src:
                override = False

                transform = _rasterio_transform(src)
                if transform.is_identity:
                    override = True
                    transform = self.get_transform(src.shape)

                try:
                    crs = geometry.CRS(_rasterio_crs_wkt(src))
                except ValueError:
                    override = True
                    crs = self.get_crs()

                # The 1.0 onwards release of rasterio has a bug that means it
                # cannot read multiband data into a numpy array during reprojection
                # We override it here to force the reading and reprojection into separate steps
                # TODO: Remove when rasterio bug fixed
                bandnumber = self.get_bandnumber(src)
                if bandnumber > 1 and str(rasterio.__version__) >= '1.0':
                    override = True

                band = rasterio.band(src, bandnumber)
                nodata = numpy.dtype(band.dtype).type(src.nodatavals[0] if src.nodatavals[0] is not None
                                                      else self.nodata)

                if override:
                    yield OverrideBandDataSource(band, nodata=nodata, crs=crs, transform=transform)
                else:
                    yield BandDataSource(band, nodata=nodata)

        except Exception as e:
            _LOG.error("Error opening source dataset: %s", self.filename)
            raise e
Ejemplo n.º 37
0
def transform_raster_to_metre_projection(country_geotiff_uri: str,
                                         destination_epsg: str,
                                         reprojected_geotiff_uri: str):
    """
    Mosaicked(or single tile) SRTM files are projected in WGS84 degrees.
    To be able to calculate slope, we need the raster in a local projection
    in metres
    :param country_geotiff_uri: the geotiff raster for the country
    :param destination_epsg: the target projection as string "EPSG:#####"
    :param reprojected_geotiff_uri: the raster for the country in the new
           projection
    """

    with rasterio.open(country_geotiff_uri) as src:
        dst_transform, dst_width, dst_height = \
            warp.calculate_default_transform(src.crs, destination_epsg, src.width,
                                             src.height, *src.bounds)
        src_data = src.read(1)
        src_meta = src.meta
        src_crs = src.crs
        src_transform = src.transform

    dst_meta = src_meta.copy()
    dst_meta.update(crs=destination_epsg)
    dst_meta.update(transform=dst_transform)
    dst_meta.update(width=dst_width)
    dst_meta.update(height=dst_height)
    dst_meta.update(compress='lzw')

    with rasterio.open(reprojected_geotiff_uri, 'w', **dst_meta) as dst:
        warp.reproject(source=src_data,
                       destination=rasterio.band(dst, 1),
                       src_transform=src_transform,
                       src_crs=src_crs,
                       dst_transform=dst_transform,
                       dst_crs=destination_epsg,
                       resampling=warp.Resampling.nearest)
Ejemplo n.º 38
0
def scatter(raster_path1, raster_path2, band1=1, band2=1, buckets=100):
    print "here2"

    with rasterio.open(raster_path1) as ds1:
        with rasterio.open(raster_path2) as ds2:

            print "here1"
            b = rasterio.band(ds1, band1)
            print b

            array1 = ds1.read(band1)
            band1 = ds1.read_band(band1)

            meta1 = ds1.meta
            rows = meta1['height']
            cols = meta1['width']
            min1 = band1.min()
            max1 = band1.max()

            array2 = ds2.read(band2)
            band2 = ds2.read_band(band2)
            min2 = band2.min()
            max2 = band2.max()

            step1 = (max1 - min1) / buckets
            step2 = (max2 - min2) / buckets

            print len(array1), len(array1[0]), len(array2),len(array1[0])
            print rows, cols, min1, min2


            matrix = couple_data(array1, array2,  min1, min2, max1, max2, rows, cols)

            print "end"

            return matrix, min1, min2, max1, max2, step1, step2
def reproject2wgs84(src_path, dst_path):
    dataset = rasterio.open(src_path)
    dataread = dataset.read()
    dataread = dataread.astype('uint8')
    dst_crs = 'EPSG:4326'
    transform, width, height = calculate_default_transform(
        dataset.crs, dst_crs, dataset.width, dataset.height, *dataset.bounds)
    kwargs = dataset.profile.copy()
    kwargs.update({
        'crs': dst_crs,
        'transform': transform,
        'width': width,
        'height': height,
        'dtype': rasterio.uint8,
    })
    with rasterio.open(dst_path, 'w', **kwargs) as dst:
        for i in range(1, dataset.count + 1):
            reproject(source=dataread[i - 1],
                      destination=rasterio.band(dst, i),
                      src_transform=dataset.transform,
                      src_crs=dataset.crs,
                      dst_transform=transform,
                      dst_crs=dst_crs,
                      resampling=Resampling.nearest)
Ejemplo n.º 40
0
def crop_geotiff_to_glacier(gdir, img_list, dim_name, dim_label, var_name,
                            time_stamp, file_group):
    """
    A function that reads Tiles in .tif format from
     folder for different dates
    and processes them to the size of the each glacier.
    The output is then stored in the sentinel.nc file with the
    dimensions of all 12 Sentinel bands with the current time stamp

    Structure of the function:
    - Reading Data from imgfolder
    - Cropping Data to glacier outline
    - Reprojecting Raster of Glacier to local grid
    - Resampling all bands to 10 Meter resolution
    - Writing local raster of all bands to multi-temporal
       netCDF file xxxx.nc

    Parameters:
    -----------
    gdir: :py:class:`crampon.GlacierDirectory`
        A GlacierDirectory instance.
    img_list: os.listdir(img_path)
        list with paths of all
        tiles (need to have same resolution and projection)
        to be processed into netCDF
    dim_name: str
        dimension name for variables: e.g. height, bands, angles
    dim_label: list of str
        name of e.g. each band or each angle
         ['solar_azimuth','solar_zenith'], range(len(list(range(1,len(b_sub)+1))
    var_name: str
        Name of variable: e.g. 'img_values', 'height', 'angles'
    time_stamp: int
        date in format yyyymmdd (no datetime.datetime!)
    file_group: str
        filepath in cfg.PATH, e.g. 'sentinel', 'solar_angles'


    Returns:
    --------
    None
    """
    glacier = gpd.read_file(gdir.get_filepath('outlines'))

    # iterate over all bands
    b_sub = []
    band_index = 0
    for band in img_list:
        with rasterio.open(band) as src:
            # Read crs from first Tile of list:
            if band == img_list[0]:
                local_crs = glacier.crs
                src_crs = src.crs
                list_conts = os.listdir(cfg.PATHS['dem_dir'])[0]
                # Problem with Swiss CRS, set crs manually for DEM
                if band == os.path.join(cfg.PATHS['dem_dir'], list_conts):
                    src_crs = CRS.to_proj4(src.crs)
                # Convert outline to projection of tile (src_crs) to crop it out
                glacier = glacier.to_crs(src_crs)
                glacier.to_file(
                    driver='ESRI Shapefile',
                    filename=gdir.get_filepath('outlines_proj_tile'))
                with fiona.open(gdir.get_filepath('outlines_proj_tile'), "r") \
                        as glacier_reprojected:
                    # Read local geometry
                    features = [
                        feature["geometry"] for feature in glacier_reprojected
                    ]

            # --- 1.   Open file: CROP file to glacier outline

            try:
                out_image, out_transform = rasterio.mask.mask(src,
                                                              features,
                                                              crop=True)
            except ValueError:
                # Glacier not located in tile
                return
            out_meta = src.meta.copy()
            out_meta.update({
                "driver": "GTiff",
                "height": out_image.shape[1],
                "width": out_image.shape[2],
                "transform": out_transform
            })

            with rasterio.open(gdir.get_filepath('cropped_cache'),'w', **out_meta) \
                    as src1:
                src1.write(out_image)
            # ---  2. REPROJECT to local grid: we want to project out_image with
            # out_meta to local_crs of glacier
            # Calculate Transform
            dst_transform, width, height = calculate_default_transform(
                src_crs, local_crs, out_image.shape[1], out_image.shape[2],
                *src1.bounds)

            out_meta.update({
                'crs': local_crs,
                'transform': dst_transform,
                'width': width,
                'height': height
            })

            with rasterio.open(gdir.get_filepath('cropped_cache'), 'w',
                               **out_meta) as src1:
                reproject(source=out_image,
                          destination=rasterio.band(src1, 1),
                          src_transform=src1.transform,
                          src_crs=src_crs,
                          dst_transform=dst_transform,
                          dst_crs=local_crs,
                          resampling=Resampling.nearest)

                # Write to geotiff in cache
                src1.write(out_image)

            # Open with xarray into DataArray
        band_array = xarray.open_rasterio(gdir.get_filepath('cropped_cache'))
        band_array = band_array.squeeze('band').drop('band')
        try:
            band_array = band_array.assign_coords(band=dim_label[band_index])
        except IndexError:
            return
        band_array = band_array.expand_dims('band')

        # write all bands into list b_sub:
        b_sub.append(band_array)
        band_index = band_index + 1

    # Merge all bands to write into netcdf file!
    all_bands = xr.concat(b_sub, dim=dim_name)
    # all_bands[dim_name] = dim_label
    all_bands.name = var_name

    all_bands = all_bands.assign_coords(time=time_stamp)
    all_bands = all_bands.expand_dims('time')
    all_bands_attrs = all_bands.attrs

    # check if netcdf file for this glacier already exists, create if not, append if exists
    if not os.path.isfile(gdir.get_filepath(file_group)):
        all_bands = all_bands.to_dataset(name=var_name)
        all_bands.attrs = all_bands_attrs
        all_bands.attrs['pyproj_srs'] = rasterio.crs.CRS.to_proj4(src1.crs)
        all_bands.to_netcdf(gdir.get_filepath(file_group),
                            'w',
                            unlimited_dims={'time': True})
        all_bands.close()
    else:
        #  Open existing file
        existing = xr.open_dataset(gdir.get_filepath(file_group))
        # Convert all_bands from DataArray to Dataset
        all_bands = all_bands.to_dataset(name=var_name)
        if not all_bands.time.values in existing.time.values:
            try:
                appended = xr.concat([existing, all_bands], dim='time')
            except MemoryError:
                print("Memory Error on", gdir, ". Skipping this entry")
                return
            existing.close()
            appended.attrs = all_bands_attrs
            appended.attrs['pyproj_srs'] = rasterio.crs.CRS.to_proj4(src1.crs)
            #Write to file
            appended.to_netcdf(gdir.get_filepath(file_group),
                               'w',
                               unlimited_dims={'time': True})
            appended.close()
        # shutil.move(gdir.get_filepath("sentinel_temp"), gd-ir.get_filepath(file_group))

    # Remove cropped_cache.tif file:
    os.remove(gdir.get_filepath('cropped_cache'))
    os.remove(gdir.get_filepath('outlines_proj_tile'))
Ejemplo n.º 41
0
def crop_dem_to_glacier(gdir):
    """
    Crop 10 Meter resolution Geotiff of DEM
    to glacier extent

    Reads DEM of entinre Area of interest
    , crops to individual glacier, changes projection to local crs and
    saves into netCDF file for current date

    Parameters:
    -----------
    gdir: py:class:'crampon.GlavierDirectory'
        A GlacierDirectoryInstance

    Returns:
    --------
    None
    """
    print("Crop DEM to glacier")
    img_path = cfg.PATHS['dem_dir']
    img_list = os.listdir(img_path)
    img_list = [os.path.join(img_path, band) for band in img_list]
    dim_name = "band"
    dim_label = ['height_in_m']
    var_name = 'height_in_m'
    time_stamp = 20180101
    file_group = 'dem_ts'

    # check if cropped dem for glacier already exists:
    if os.path.isfile(os.path.join(gdir.get_filepath('dem_ts'))):
        # exit function, no need to read again
        return

    # for first time:
    # Project DEM to same crs as sentinel tiles:

    # get crs from sentinel tile:
    # TODO: something wrong with this, currently the DEM needs to have
    # the same projection as the sentinel images

# with rasterio.open(os.path.join(os.path.join(os.path.join(
#         cfg.PATHS['working_dir'],
#         'cache', str(cfg.PARAMS['date'][0]),
#         'mosaic')), os.listdir(os.path.join(os.path.join(
#              cfg.PATHS['working_dir'],
#             'cache', str(cfg.PARAMS['date'][0]),
#         'mosaic')))[1])) as sentinel:
#     dst_crs = sentinel.crs
    dst_crs = 'EPSG:32632'

    for band in img_list:
        with rasterio.open(band) as src:
            if dst_crs == src.crs:
                # DEM is already reprojected
                crop_geotiff_to_glacier(gdir, img_list, dim_name, dim_label,
                                        var_name, time_stamp, file_group)

            else:  # reproject
                # TODO: something is not right with reprojection...
                print(src.crs)
                src_crs = CRS.to_proj4(src.crs)
                transform, width, height = calculate_default_transform(
                    src_crs, dst_crs, src.width, src.height, *src.bounds)
                kwargs = src.meta.copy()
                kwargs.update({
                    'crs': dst_crs,
                    'transform': transform,
                    'width': width,
                    'height': height
                })

                with rasterio.open(band, 'w', **kwargs) as dst:
                    for i in range(1, src.count + 1):
                        # safe reprojected file:
                        reproject(source=rasterio.band(src, i),
                                  destination=rasterio.band(dst, i),
                                  src_transform=src.transform,
                                  src_crs=src_crs,
                                  dst_transform=transform,
                                  dst_crs=dst_crs,
                                  resampling=Resampling.nearest)
                    print(dst.meta)

    crop_geotiff_to_glacier(gdir, img_list, dim_name, dim_label, var_name,
                            time_stamp, file_group)
Ejemplo n.º 42
0
def warp(ctx, files, output, driver, like, dst_crs, dimensions, src_bounds,
         dst_bounds, res, resampling, src_nodata, dst_nodata, threads,
         check_invert_proj, force_overwrite, creation_options,
         target_aligned_pixels):
    """
    Warp a raster dataset.

    If a template raster is provided using the --like option, the
    coordinate reference system, affine transform, and dimensions of
    that raster will be used for the output.  In this case --dst-crs,
    --bounds, --res, and --dimensions options are not applicable and
    an exception will be raised.

    \b
        $ rio warp input.tif output.tif --like template.tif

    The output coordinate reference system may be either a PROJ.4 or
    EPSG:nnnn string,

    \b
        --dst-crs EPSG:4326
        --dst-crs '+proj=longlat +ellps=WGS84 +datum=WGS84'

    or a JSON text-encoded PROJ.4 object.

    \b
        --dst-crs '{"proj": "utm", "zone": 18, ...}'

    If --dimensions are provided, --res and --bounds are not applicable and an
    exception will be raised.
    Resolution is calculated based on the relationship between the
    raster bounds in the target coordinate system and the dimensions,
    and may produce rectangular rather than square pixels.

    \b
        $ rio warp input.tif output.tif --dimensions 100 200 \\
        > --dst-crs EPSG:4326

    If --bounds are provided, --res is required if --dst-crs is provided
    (defaults to source raster resolution otherwise).

    \b
        $ rio warp input.tif output.tif \\
        > --bounds -78 22 -76 24 --res 0.1 --dst-crs EPSG:4326

    """
    output, files = resolve_inout(files=files,
                                  output=output,
                                  force_overwrite=force_overwrite)

    resampling = Resampling[resampling]  # get integer code for method

    if not len(res):
        # Click sets this as an empty tuple if not provided
        res = None
    else:
        # Expand one value to two if needed
        res = (res[0], res[0]) if len(res) == 1 else res

    if target_aligned_pixels:
        if not res:
            raise click.BadParameter(
                '--target-aligned-pixels requires a specified resolution')
        if src_bounds or dst_bounds:
            raise click.BadParameter(
                '--target-aligned-pixels cannot be used with '
                '--src-bounds or --dst-bounds')

    # Check invalid parameter combinations
    if like:
        invalid_combos = (dimensions, dst_bounds, dst_crs, res)
        if any(p for p in invalid_combos if p is not None):
            raise click.BadParameter(
                "--like cannot be used with any of --dimensions, --bounds, "
                "--dst-crs, or --res")

    elif dimensions:
        invalid_combos = (dst_bounds, res)
        if any(p for p in invalid_combos if p is not None):
            raise click.BadParameter(
                "--dimensions cannot be used with --bounds or --res")

    with ctx.obj['env']:
        setenv(CHECK_WITH_INVERT_PROJ=check_invert_proj)

        with rasterio.open(files[0]) as src:
            l, b, r, t = src.bounds
            out_kwargs = src.profile.copy()
            out_kwargs['driver'] = driver

            # Sort out the bounds options.
            if src_bounds and dst_bounds:
                raise click.BadParameter(
                    "--src-bounds and destination --bounds may not be "
                    "specified simultaneously.")

            if like:
                with rasterio.open(like) as template_ds:
                    dst_crs = template_ds.crs
                    dst_transform = template_ds.transform
                    dst_height = template_ds.height
                    dst_width = template_ds.width

            elif dst_crs is not None:
                try:
                    dst_crs = CRS.from_string(dst_crs)
                except ValueError as err:
                    raise click.BadParameter(str(err),
                                             param='dst_crs',
                                             param_hint='dst_crs')

                if dimensions:
                    # Calculate resolution appropriate for dimensions
                    # in target.
                    dst_width, dst_height = dimensions
                    try:
                        xmin, ymin, xmax, ymax = transform_bounds(
                            src.crs, dst_crs, *src.bounds)
                    except CRSError as err:
                        raise click.BadParameter(str(err),
                                                 param='dst_crs',
                                                 param_hint='dst_crs')
                    dst_transform = Affine(
                        (xmax - xmin) / float(dst_width), 0, xmin, 0,
                        (ymin - ymax) / float(dst_height), ymax)

                elif src_bounds or dst_bounds:
                    if not res:
                        raise click.BadParameter(
                            "Required when using --bounds.",
                            param='res',
                            param_hint='res')

                    if src_bounds:
                        try:
                            xmin, ymin, xmax, ymax = transform_bounds(
                                src.crs, dst_crs, *src_bounds)
                        except CRSError as err:
                            raise click.BadParameter(str(err),
                                                     param='dst_crs',
                                                     param_hint='dst_crs')
                    else:
                        xmin, ymin, xmax, ymax = dst_bounds

                    dst_transform = Affine(res[0], 0, xmin, 0, -res[1], ymax)
                    dst_width = max(int(ceil((xmax - xmin) / res[0])), 1)
                    dst_height = max(int(ceil((ymax - ymin) / res[1])), 1)

                elif target_aligned_pixels:
                    try:
                        xmin, ymin, xmax, ymax = transform_bounds(
                            src.crs, dst_crs, *src.bounds)
                    except CRSError as err:
                        raise click.BadParameter(str(err),
                                                 param='dst_crs',
                                                 param_hint='dst_crs')

                    xmin = floor(xmin / res[0]) * res[0]
                    xmax = ceil(xmax / res[0]) * res[0]
                    ymin = floor(ymin / res[1]) * res[1]
                    ymax = ceil(ymax / res[1]) * res[1]

                    dst_transform = Affine(res[0], 0, xmin, 0, -res[1], ymax)
                    dst_width = max(int(ceil((xmax - xmin) / res[0])), 1)
                    dst_height = max(int(ceil((ymax - ymin) / res[1])), 1)

                else:
                    try:
                        if src.transform.is_identity and src.gcps:
                            src_crs = src.gcps[1]
                            kwargs = {'gcps': src.gcps[0]}
                        else:
                            src_crs = src.crs
                            kwargs = src.bounds._asdict()
                        dst_transform, dst_width, dst_height = calcdt(
                            src_crs,
                            dst_crs,
                            src.width,
                            src.height,
                            resolution=res,
                            **kwargs)
                    except CRSError as err:
                        raise click.BadParameter(str(err),
                                                 param='dst_crs',
                                                 param_hint='dst_crs')

            elif dimensions:
                # Same projection, different dimensions, calculate resolution.
                dst_crs = src.crs
                dst_width, dst_height = dimensions
                dst_transform = Affine((r - l) / float(dst_width), 0, l, 0,
                                       (b - t) / float(dst_height), t)

            elif src_bounds or dst_bounds:
                # Same projection, different dimensions and possibly
                # different resolution.
                if not res:
                    res = (src.transform.a, -src.transform.e)

                dst_crs = src.crs
                xmin, ymin, xmax, ymax = (src_bounds or dst_bounds)
                dst_transform = Affine(res[0], 0, xmin, 0, -res[1], ymax)
                dst_width = max(int(ceil((xmax - xmin) / res[0])), 1)
                dst_height = max(int(ceil((ymax - ymin) / res[1])), 1)

            elif res:
                # Same projection, different resolution.
                dst_crs = src.crs
                dst_transform = Affine(res[0], 0, l, 0, -res[1], t)
                dst_width = max(int(ceil((r - l) / res[0])), 1)
                dst_height = max(int(ceil((t - b) / res[1])), 1)

            else:
                dst_crs = src.crs
                dst_transform = src.transform
                dst_width = src.width
                dst_height = src.height

            # If src_nodata is not None, update the dst metadata NODATA
            # value to src_nodata (will be overridden by dst_nodata if it is not None
            if src_nodata is not None:
                # Update the dst nodata value
                out_kwargs.update({'nodata': src_nodata})

            # Validate a manually set destination NODATA value
            # against the input datatype.
            if dst_nodata is not None:
                if src_nodata is None and src.meta['nodata'] is None:
                    raise click.BadParameter(
                        "--src-nodata must be provided because dst-nodata is not None"
                    )
                else:
                    # Update the dst nodata value
                    out_kwargs.update({'nodata': dst_nodata})

            # When the bounds option is misused, extreme values of
            # destination width and height may result.
            if (dst_width < 0 or dst_height < 0 or dst_width > MAX_OUTPUT_WIDTH
                    or dst_height > MAX_OUTPUT_HEIGHT):
                raise click.BadParameter(
                    "Invalid output dimensions: {0}.".format(
                        (dst_width, dst_height)))

            out_kwargs.update({
                'crs': dst_crs,
                'transform': dst_transform,
                'width': dst_width,
                'height': dst_height
            })

            # Adjust block size if necessary.
            if ('blockxsize' in out_kwargs
                    and dst_width < out_kwargs['blockxsize']):
                del out_kwargs['blockxsize']
            if ('blockysize' in out_kwargs
                    and dst_height < out_kwargs['blockysize']):
                del out_kwargs['blockysize']

            out_kwargs.update(**creation_options)

            with rasterio.open(output, 'w', **out_kwargs) as dst:
                reproject(source=rasterio.band(src,
                                               list(range(1, src.count + 1))),
                          destination=rasterio.band(
                              dst, list(range(1, src.count + 1))),
                          src_transform=src.transform,
                          src_crs=src.crs,
                          src_nodata=src_nodata,
                          dst_transform=out_kwargs['transform'],
                          dst_crs=out_kwargs['crs'],
                          dst_nodata=dst_nodata,
                          resampling=resampling,
                          num_threads=threads)
Ejemplo n.º 43
0
        'crs': dst_crs,
        'transform': dst_transform,
        'width': width,
        'height': height
    })
    with rasterio.open('reprojected_and_cropped_scene_file.tif', 'w',
                       **kwargs) as dst:
        #############################################################
        ####
        ####    Issues: combining projecting and cropping in one open comman (when first cropping then reprojecting it has problems to open the .tif of the clipped image.
        ####     Otherwise not sure wichinput parameters for reproject fct, especially for source = out_image??
        ####
        ####
        #############################################################
        reproject(source=out_image,
                  destination=rasterio.band(dst, 1),
                  src_transform=out_transform,
                  src_crs=src.crs,
                  dst_transform=dst_transform,
                  dst_crs=dst_crs,
                  resampling=Resampling.nearest)
        print('New CRS of Scene file;', dst.crs)
        #####  Write reprojected and cropped image to .tif file
        dst.write(out_image)

#####  Plot results:
#    img = mpimg.imread('reprojected_and_cropped_scene_file.tif')
#    imgplot = plt.imshow(img)
#    plt.show()

# # #
Ejemplo n.º 44
0
def reproject_s2(pth: str, date: str, lat: float, lng: float, dst_crs: str):
    """Reproject GTiff to target CRS
    EPSG:3005 - BC Albers - output tif and plot
    EPSG:4326 - KML generation

    Parameters
    ----------
    pth : str
        Path to source GTiff to be reprojected
    date : str
        Date selected in format YYYY.MM.DD
    lat : float
        Target latitude
    lng : float
        Target longitude
    dst_crs : str
        Desired CRS to reproject to

    Returns
    -------
    str
        Path to output GTiff
    """
    logger.info(f'[sentinel2.reproject_s2] REPROJECTING S2 TO {dst_crs}')
    base = os.path.split(pth)[0]
    if dst_crs == 'EPSG:4326':
        out_pth = os.path.join(base, f'{date}_EPSG4326.tif')
        res = 0.000285245221099300378  # Value from QGIS reprojection inspection
    elif dst_crs == 'EPSG:3153':
        out_pth = os.path.join(base, f'{date}_EPSG3153.tif')
        res = 20.00754121032614563  # Value from QGIS reprojection inspection
    else:
        logger.warning('[sentinel2.reproject_s2] Invalid CRS')
        return None
    if os.path.exists(out_pth):
        os.remove(out_pth)
        logger.debug(
            f'[sentinel2.reproject_s2] Removing residual file:  {out_pth}')
    with rio.open(pth, 'r') as src:
        transform, width, height = calculate_default_transform(src.crs,
                                                               dst_crs,
                                                               src.width,
                                                               src.height,
                                                               *src.bounds,
                                                               resolution=res)
        kwargs = src.meta.copy()
        # Update meta information to desired CRS
        kwargs.update({
            'driver': 'GTiff',
            'crs': dst_crs,
            'transform': transform,
            'width': width,
            'height': height,
            'dtype': rio.uint16,
            'nodata': nodata_val
        })
        # Write reprojected granule into GTiff format
        with rio.open(out_pth, 'w', **kwargs) as dst:
            reproject(source=rio.band(src, 1),
                      destination=rio.band(dst, 1),
                      src_transform=src.transform,
                      src_crs=src.crs,
                      dst_transform=transform,
                      dst_crs=dst_crs,
                      resampling=Resampling.nearest,
                      dst_nodata=nodata_val)
    if dst_crs == 'EPSG:3153':
        mv_pth = os.path.join(const.SENTINEL_OUTPUT, date,
                              f'lat{lat}_lng{lng}',
                              os.path.split(out_pth)[-1])
        try:
            os.makedirs(os.path.split(mv_pth)[0])
        except:
            pass
        shutil.copy(out_pth, mv_pth)
    return out_pth
Ejemplo n.º 45
0
    def _arith(self, function, other=None):
        """General method for performing arithmetic operations on RasterLayer objects

        Parameters
        ----------
        function : function
            Custom function that takes either one or two arrays, and returns a single
            array following a pre-defined calculation.

        other : pyspatialml.RasterLayer (optional, default None)
            If not specified, then a `function` should be provided that performs a
            calculation using only the selected RasterLayer. If `other` is specified,
            then a `function` should be supplied that takes to ndarrays as arguments
            and performs a calculation using both layers, i.e. layer1 - layer2.

        Returns
        -------
        pyspatialml.RasterLayer
            Returns a single RasterLayer containing the calculated result.
        """

        _, tfile = _file_path_tempfile(None)
        driver = self.driver

        # determine dtype of result based on calc on single pixel
        if other is not None:
            arr1 = self.read(masked=True, window=Window(0, 0, 1, 1))

            try:
                arr2 = other.read(masked=True, window=Window(0, 0, 1, 1))
            except AttributeError:
                arr2 = other

            test = function(arr1, arr2)
            dtype = test.dtype
        else:
            dtype = self.dtype

        nodata = _get_nodata(dtype)

        # open output file with updated metadata
        meta = self.meta
        meta.update(driver=driver, count=1, dtype=dtype, nodata=nodata)

        with rasterio.open(tfile.name, "w", **meta) as dst:

            # define windows
            windows = [window for ij, window in dst.block_windows()]

            # generator gets raster arrays for each window
            self_gen = (self.read(window=w, masked=True) for w in windows)

            if isinstance(other, RasterLayer):
                other_gen = (other.read(window=w, masked=True)
                             for w in windows)
            else:
                other_gen = (other for w in windows)

            for window, arr1, arr2 in zip(windows, self_gen, other_gen):

                if other is not None:
                    result = function(arr1, arr2)
                else:
                    result = function(arr1)

                result = np.ma.filled(result, fill_value=nodata)
                dst.write(result.astype(dtype), window=window, indexes=1)

        # create RasterLayer from result
        src = rasterio.open(tfile.name)
        band = rasterio.band(src, 1)
        layer = pyspatialml.RasterLayer(band)

        # overwrite close attribute with close method from temporaryfilewrapper
        layer.close = tfile.close

        return layer
Ejemplo n.º 46
0
def snap_raster_to_other(raster_path, ex_path, out_path, src_crs=None):
    '''Resample a raster to match the size and extent of another raster.
    args : 
        raster_path - raster to alter.
        ex_path - raster to use as template
        out_path - path of output raster.
    '''

    #collect template data
    with rasterio.open(ex_path) as ex:

        dst_res = (ex.transform[0], ex.transform[4] * -1)
        dst_crs = ex.crs
        height = ex.height
        width = ex.width
        dst_transform = ex.transform
        bounds = ex.bounds
        crs = ex.crs

    if src_crs:
        with rasterio.open(raster_path, 'r') as src:
            data = src.read()
            meta = src.meta

        meta.update({'crs': src_crs})
        with rasterio.open(raster_path, 'w+', **meta) as dst:
            dst.write(data)

    src = rasterio.open(raster_path)

    #if extents dont match, mask the raster to bounding box of the example.
    if src.bounds != bounds:
        src.close()
        mask_raster(raster_path, [box(*bounds)], out_path, crs)
        src = rasterio.open(out_path)

    # make the out array
    dst_data = np.zeros((1, height, width))

    try:
        rasterio.warp.reproject(
            rasterio.band(src, 1),
            destination=dst_data,
            dst_resolution=dst_res,
            dst_crs=dst_crs,
            src_crs=src.crs,
            dst_transform=dst_transform,
        )

        out_meta = src.meta.copy()
    finally:
        src.close()

    assert width == dst_data.shape[-1]
    assert height == dst_data.shape[-2]

    out_meta.update({
        'transform': dst_transform,
        'width': dst_data.shape[-1],
        'height': dst_data.shape[-2],
    })

    with rasterio.open(out_path, 'w+', **out_meta) as dst:
        dst.write(dst_data.astype(out_meta['dtype']))

    assert rasterio.open(out_path).read(1).shape == rasterio.open(
        ex_path).read(1).shape
Ejemplo n.º 47
0
        dst_dataset = os.path.join(path_myd_processed,
                                   '03mask_SouthKorea_MYD13A2', str(yr),
                                   f'm_{os.path.basename(src_dataset)[2:]}')
        matlab.check_make_dir(os.path.dirname(dst_dataset))
        with rio.open(src_dataset) as src:
            kwargs = src.meta.copy()
            kwargs['transform'] = masksrc.transform

            temp_dataset = os.path.join(os.path.dirname(dst_dataset),
                                        'temp.tif')
            resolution = 1.02308446206551E-02
            dst_crs = masksrc.crs
            with rio.open(temp_dataset, 'w+', **kwargs) as temp_dst:
                for i in range(1, src.count + 1):
                    reproject(
                        source=rio.band(src, i),
                        destination=rio.band(temp_dst, i),
                        src_transform=src.transform,
                        src_crs=src.crs,
                        src_nodata=-9999,
                        dst_transform=masksrc.transform,
                        dst_crs=dst_crs,
                        dst_nodata=-9999,
                        dst_resolution=resolution,
                    )
                out_img, out_transform = mask(dataset=temp_dst,
                                              shapes=shapes,
                                              crop=True)
                with rio.open(temp_dataset) as temp_dst:
                    out_meta = temp_dst.meta.copy()
                    out_meta.update({
Ejemplo n.º 48
0
def reproject_raster(input_raster_name,
                     reprojection,
                     blocksize=None,
                     reprojected_raster_name=None):

    if blocksize is not None:
        if isinstance(blocksize, int):
            pass
        elif isinstance(blocksize, str):
            blocksize = int(blocksize)
        elif isinstance(blocksize, float):
            blocksize = int(blocksize)
        else:
            raise TypeError("Pass integer for blocksize")
    else:
        blocksize = 256

    assert input_raster_name.endswith('.tif'), "input raster needs to be a tif"

    reprojection = rasterio.crs.CRS.from_string(reprojection)

    with rasterio.open(input_raster_name) as src:

        # Check projection
        if src.crs.to_string() != reprojection:
            if src.crs.to_string().startswith('EPSG'):
                epsg = src.crs.to_epsg()
                proj_crs = CRS.from_epsg(epsg)
                rio_crs = rasterio.crs.CRS.from_user_input(
                    proj_crs).to_string()
            else:
                rio_crs = src.crs.to_string()

            print(f"{input_raster_name} not projected")
            print(f"Reprojecting from {rio_crs} to {reprojection}")

            transform, width, height = calculate_default_transform(
                src.crs, reprojection, src.width, src.height, *src.bounds)
            kwargs = src.meta.copy()
            kwargs.update({
                'crs': reprojection,
                'transform': transform,
                'width': width,
                'height': height,
                'compress': 'lzw'
            })

            if reprojected_raster_name is None:
                reprojected_raster_name = input_raster_name

            assert reprojected_raster_name.endswith(
                '.tif'), "output raster needs to be a tif"

            with rasterio.open(reprojected_raster_name,
                               'w',
                               **kwargs,
                               tiled=True,
                               blockxsize=blocksize,
                               blockysize=blocksize,
                               BIGTIFF='YES') as dst:
                reproject(source=rasterio.band(src, 1),
                          destination=rasterio.band(dst, 1),
                          src_transform=src.transform,
                          src_crs=rio_crs,
                          dst_transform=transform,
                          dst_crs=reprojection.to_string(),
                          resampling=Resampling.nearest)
                del dst
        del src
Ejemplo n.º 49
0
    def reproject(self, dst_crs, dst_res=None, fp=None, interpolation='nearest'):
        """ Change coordinate system (projection) of the band.
        It does not alter the existing file, and creates a new file either in the specified location or a temporary file.

        The band ground sampling distance is not changed, however the resolution may change due to the new coordinate system
        It is based on `rasterio.warp.reproject
        <https://rasterio.readthedocs.io/en/latest/api/rasterio.warp.html#rasterio.warp.reproject>`_,
        see for more variants of interpolation.

        Args:
            dst_crs: new CRS, may be in any form acceptable by rasterio, for example as EPSG code, string, CRS object; if dst_crs == `utm`, the appropriate UTM zone is used according to the center of the image
            fp (str): a filename for the new resampled band. If none, a temporary file is created
            interpolation: interpolation type as in rasterio,  `nearest`, `bilinear`, `cubic`, `lanzsos` or others
            dst_res (Tuple[float, float]): new resoluton, georeferenced pixel size for the new band

        Returns:
            a new reprojected and resampled Band
        """
        if dst_crs == 'utm':
            dst_crs = get_utm_zone(self.crs, self.transform, (self.height, self.width))
        else:
            dst_crs = dst_crs if isinstance(dst_crs, CRS) else CRS.from_user_input(dst_crs)

        # Old rasterio compatibility: a separate check for validity
        if not dst_crs.is_valid:
            raise rasterio.errors.CRSError('Invalid CRS {} given'.format(dst_crs))

        # get temporary filepath if such is not provided
        tmp_file = False if fp is not None else True
        if fp is None:
            fp = '{tmp}/reprojected_{crs}/{directory}/{name}.tif'.format(
                tmp=TMP_DIR, crs=dst_crs, directory=random_name(), name=self.name)
        os.makedirs(os.path.dirname(fp), exist_ok=True)

        # calculate params of new reprojected Band
        transform, width, height = calculate_default_transform(
            self.crs, dst_crs, self.width, self.height, resolution=dst_res,*self.bounds)
        
        kwargs = self.meta.copy()
        kwargs.update({
            'crs': dst_crs,
            'transform': transform,
            'width': width,
            'height': height
        })

        # reproject
        with rasterio.open(fp, 'w', **kwargs) as dst:
                reproject(
                    source=rasterio.band(self._band, 1),
                    destination=rasterio.band(dst, 1),
                    src_transform=self.transform,
                    src_crs=self.crs,
                    dst_transform=transform,
                    dst_crs=dst_crs,
                    resampling=getattr(Resampling, interpolation))

        # new band
        band = Band(fp)
        band._tmp_file = tmp_file # file will be automatically removed when `Band` instance will be deleted
        return band
Ejemplo n.º 50
0
with rasterio.open(path) as src:
    profile = src.profile.copy()

    transform, width, height = rasterio.warp.calculate_default_transform(
        src.crs, dst_crs, src.width, src.height, *src.bounds)

    profile.update({
        'crs': {'init': 'EPSG:3857'},
        'transform': transform,
        'width': width,
        'height': height
    })

    with rasterio.open('C:/data/new_tif', 'w', **profile) as dst:
        rasterio.warp.reproject(
            source=rasterio.band(src, 1),
            destination=rasterio.band(dst, 1),
            src_transform=transform,
            src_crs=source_crs,
            dst_transform=transform,
            dst_crs={'init': 'EPSG:3857'},
            resampling=rasterio.warp.Resampling.bilinear)


source_crs = ccrs.LambertConformal(central_longitude=-95,central_latitude=38.936454, cutoff=20)
ax = plt.subplot(projection = ccrs.LambertConformal(central_longitude=-95,central_latitude=38.936454, cutoff=20))
ax.add_feature(shape_michigan['MI'], facecolor='none', edgecolor='yellow', linewidth=0.5)    

def main():
    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1, projection=ccrs.PlateCarree())
Ejemplo n.º 51
0
def define_glacier_region(gdir, entity=None):
    """
    Very first task: define the glacier's local grid.

    Defines the local projection (Transverse Mercator), centered on the
    glacier. There is some options to set the resolution of the local grid.
    It can be adapted depending on the size of the glacier with::

        dx (m) = d1 * AREA (km) + d2 ; clipped to dmax

    or be set to a fixed value. See ``params.cfg`` for setting these options.
    Default values of the adapted mode lead to a resolution of 50 m for
    Hintereisferner, which is approx. 8 km2 large.
    After defining the grid, the topography and the outlines of the glacier
    are transformed into the local projection. The default interpolation for
    the topography is `cubic`.

    Parameters
    ----------
    gdir : :py:class:`oggm.GlacierDirectory`
        where to write the data
    entity : geopandas GeoSeries
        the glacier geometry to process
    """

    # choose a spatial resolution with respect to the glacier area
    dxmethod = cfg.PARAMS['grid_dx_method']
    area = gdir.rgi_area_km2
    if dxmethod == 'linear':
        dx = np.rint(cfg.PARAMS['d1'] * area + cfg.PARAMS['d2'])
    elif dxmethod == 'square':
        dx = np.rint(cfg.PARAMS['d1'] * np.sqrt(area) + cfg.PARAMS['d2'])
    elif dxmethod == 'fixed':
        dx = np.rint(cfg.PARAMS['fixed_dx'])
    else:
        raise ValueError('grid_dx_method not supported: {}'.format(dxmethod))
    # Additional trick for varying dx
    if dxmethod in ['linear', 'square']:
        dx = np.clip(dx, cfg.PARAMS['d2'], cfg.PARAMS['dmax'])

    log.debug('%s: area %.2f km, dx=%.1f', gdir.rgi_id, area, dx)

    # Make a local glacier map
    proj_params = dict(name='tmerc',
                       lat_0=0.,
                       lon_0=gdir.cenlon,
                       k=0.9996,
                       x_0=0,
                       y_0=0,
                       datum='WGS84')
    proj4_str = "+proj={name} +lat_0={lat_0} +lon_0={lon_0} +k={k} " \
                "+x_0={x_0} +y_0={y_0} +datum={datum}".format(**proj_params)
    proj_in = pyproj.Proj("+init=EPSG:4326", preserve_units=True)
    proj_out = pyproj.Proj(proj4_str, preserve_units=True)
    project = partial(pyproj.transform, proj_in, proj_out)
    # transform geometry to map
    geometry = shapely.ops.transform(project, entity['geometry'])
    geometry = _check_geometry(geometry)
    xx, yy = geometry.exterior.xy

    # Corners, incl. a buffer of N pix
    ulx = np.min(xx) - cfg.PARAMS['border'] * dx
    lrx = np.max(xx) + cfg.PARAMS['border'] * dx
    uly = np.max(yy) + cfg.PARAMS['border'] * dx
    lry = np.min(yy) - cfg.PARAMS['border'] * dx
    # n pixels
    nx = np.int((lrx - ulx) / dx)
    ny = np.int((uly - lry) / dx)

    # Back to lon, lat for DEM download/preparation
    tmp_grid = salem.Grid(proj=proj_out,
                          nxny=(nx, ny),
                          x0y0=(ulx, uly),
                          dxdy=(dx, -dx),
                          pixel_ref='corner')
    minlon, maxlon, minlat, maxlat = tmp_grid.extent_in_crs(crs=salem.wgs84)

    # save transformed geometry to disk
    entity = entity.copy()
    entity['geometry'] = geometry
    # Avoid fiona bug: https://github.com/Toblerity/Fiona/issues/365
    for k, s in entity.iteritems():
        if type(s) in [np.int32, np.int64]:
            entity[k] = int(s)
    towrite = gpd.GeoDataFrame(entity).T
    towrite.crs = proj4_str
    # Delete the source before writing
    if 'DEM_SOURCE' in towrite:
        del towrite['DEM_SOURCE']
    towrite.to_file(gdir.get_filepath('outlines'))

    # Also transform the intersects if necessary
    gdf = cfg.PARAMS['intersects_gdf']
    gdf = gdf.loc[(gdf.RGIId_1 == gdir.rgi_id) | (gdf.RGIId_2 == gdir.rgi_id)]
    if len(gdf) > 0:
        gdf = salem.transform_geopandas(gdf, to_crs=proj_out)
        if hasattr(gdf.crs, 'srs'):
            # salem uses pyproj
            gdf.crs = gdf.crs.srs
        gdf.to_file(gdir.get_filepath('intersects'))

    # Open DEM
    source = entity.DEM_SOURCE if hasattr(entity, 'DEM_SOURCE') else None
    dem_list, dem_source = get_topo_file((minlon, maxlon), (minlat, maxlat),
                                         rgi_region=gdir.rgi_region,
                                         source=source)
    log.debug('%s: DEM source: %s', gdir.rgi_id, dem_source)

    # A glacier area can cover more than one tile:
    if len(dem_list) == 1:
        dem_dss = [rasterio.open(dem_list[0])]  # if one tile, just open it
        dem_data = rasterio.band(dem_dss[0], 1)
        src_transform = dem_dss[0].transform
    else:
        dem_dss = [rasterio.open(s) for s in dem_list]  # list of rasters
        dem_data, src_transform = merge_tool(dem_dss)  # merged rasters

    # Use Grid properties to create a transform (see rasterio cookbook)
    dst_transform = rasterio.transform.from_origin(
        ulx,
        uly,
        dx,
        dx  # sign change (2nd dx) is done by rasterio.transform
    )

    # Set up profile for writing output
    profile = dem_dss[0].profile
    profile.update({
        'crs': proj4_str,
        'transform': dst_transform,
        'width': nx,
        'height': ny
    })

    # Could be extended so that the cfg file takes all Resampling.* methods
    if cfg.PARAMS['topo_interp'] == 'bilinear':
        resampling = Resampling.bilinear
    elif cfg.PARAMS['topo_interp'] == 'cubic':
        resampling = Resampling.cubic
    else:
        raise ValueError('{} interpolation not understood'.format(
            cfg.PARAMS['topo_interp']))

    dem_reproj = gdir.get_filepath('dem')
    with rasterio.open(dem_reproj, 'w', **profile) as dest:
        dst_array = np.empty((ny, nx), dtype=dem_dss[0].dtypes[0])
        reproject(
            # Source parameters
            source=dem_data,
            src_crs=dem_dss[0].crs,
            src_transform=src_transform,
            # Destination parameters
            destination=dst_array,
            dst_transform=dst_transform,
            dst_crs=proj4_str,
            # Configuration
            resampling=resampling)

        dest.write(dst_array, 1)

    for dem_ds in dem_dss:
        dem_ds.close()

    # Glacier grid
    x0y0 = (ulx + dx / 2, uly - dx / 2)  # To pixel center coordinates
    glacier_grid = salem.Grid(proj=proj_out,
                              nxny=(nx, ny),
                              dxdy=(dx, -dx),
                              x0y0=x0y0)
    glacier_grid.to_json(gdir.get_filepath('glacier_grid'))
    gdir.write_pickle(dem_source, 'dem_source')

    # Looks in the database if the glacier has divides.
    gdf = cfg.PARAMS['divides_gdf']
    if gdir.rgi_id in gdf.index.values:
        divdf = [g for g in gdf.loc[gdir.rgi_id].geometry]

        # Reproject the shape
        def proj(lon, lat):
            return salem.transform_proj(salem.wgs84, gdir.grid.proj, lon, lat)

        divdf = [shapely.ops.transform(proj, g) for g in divdf]

        # Keep only the ones large enough
        log.debug('%s: divide candidates: %d', gdir.rgi_id, len(divdf))
        divdf = [g for g in divdf if (g.area >= (25 * dx**2))]
        log.debug('%s: number of divides: %d', gdir.rgi_id, len(divdf))

        # Write the directories and the files
        for i, g in enumerate(divdf):
            _dir = os.path.join(gdir.dir, 'divide_{0:0=2d}'.format(i + 1))
            if not os.path.exists(_dir):
                os.makedirs(_dir)
            # File
            entity['geometry'] = g
            towrite = gpd.GeoDataFrame(entity).T
            towrite.crs = proj4_str
            towrite.to_file(os.path.join(_dir, cfg.BASENAMES['outlines']))
    else:
        # Make a single directory and link the files
        log.debug('%s: number of divides: %d', gdir.rgi_id, 1)
        _dir = os.path.join(gdir.dir, 'divide_01')
        if not os.path.exists(_dir):
            os.makedirs(_dir)
        linkname = os.path.join(_dir, cfg.BASENAMES['outlines'])
        sourcename = gdir.get_filepath('outlines')
        for ending in ['.cpg', '.dbf', '.shp', '.shx', '.prj']:
            _s = sourcename.replace('.shp', ending)
            _l = linkname.replace('.shp', ending)
            if os.path.exists(_s):
                try:
                    # we are on UNIX
                    os.link(_s, _l)
                except AttributeError:
                    # we are on windows
                    copyfile(_s, _l)
Ejemplo n.º 52
0
def define_nonrgi_glacier_region(gdir: NonRGIGlacierDirectory):
    """
    Very first task: define the glacier's local grid.

    Defines the local projection (Transverse Mercator), centered on the
    glacier. The resolution of the local grid is dx.

    After defining the grid, the topography is transformed into the local
    projection. The default interpolation for the topography is `cubic`.

    Parameters
    ----------
    gdir : :py:class:`oggm.NonRGIGlacierDirectory`
        where to write the data
    dx : float
        grid spacing
    """
    xx, yy = gdir.extent_ll
    dx = gdir.case.dx

    # Make a local glacier map
    proj_params = dict(name='tmerc',
                       lat_0=0.,
                       lon_0=gdir.cenlon,
                       k=0.9996,
                       x_0=0,
                       y_0=0,
                       datum='WGS84')
    proj4_str = "+proj={name} +lat_0={lat_0} +lon_0={lon_0} +k={k} " \
                "+x_0={x_0} +y_0={y_0} +datum={datum}".format(**proj_params)
    # proj_in = pyproj.Proj("+init=EPSG:4326", preserve_units=True)
    proj_out = pyproj.Proj(proj4_str, preserve_units=True)

    merc_xx, merc_yy = salem.transform_proj(salem.wgs84, proj_out, xx, yy)

    # Corners, incl. a buffer of N pix
    ulx = np.min(merc_xx)
    lrx = np.max(merc_xx)
    uly = np.max(merc_yy)
    lry = np.min(merc_yy)

    # n pixels
    nx = np.int((lrx - ulx) / dx)
    ny = np.int((uly - lry) / dx)

    # Back to lon, lat for DEM download/preparation
    tmp_grid = salem.Grid(proj=proj_out,
                          nxny=(nx, ny),
                          x0y0=(ulx, uly),
                          dxdy=(dx, -dx),
                          pixel_ref='corner')
    minlon, maxlon, minlat, maxlat = tmp_grid.extent_in_crs(crs=salem.wgs84)

    dem_list, dem_source = get_topo_file((minlon, maxlon), (minlat, maxlat),
                                         rgi_region=None,
                                         rgi_subregion=None,
                                         source='DEM3')
    log.debug('(%s) DEM source: %s', gdir.name, dem_source)

    # A glacier area can cover more than one tile:
    if len(dem_list) == 1:
        dem_dss = [rasterio.open(dem_list[0])]  # if one tile, just open it
        dem_data = rasterio.band(dem_dss[0], 1)
        if LooseVersion(rasterio.__version__) >= LooseVersion('1.0'):
            src_transform = dem_dss[0].transform
        else:
            src_transform = dem_dss[0].affine
    else:
        dem_dss = [rasterio.open(s) for s in dem_list]  # list of rasters
        dem_data, src_transform = merge_tool(dem_dss)  # merged rasters

    # Use Grid properties to create a transform (see rasterio cookbook)
    dst_transform = rasterio.transform.from_origin(
        ulx,
        uly,
        dx,
        dx  # sign change (2nd dx) is done by rasterio.transform
    )

    # Set up profile for writing output
    profile = dem_dss[0].profile
    profile.update({
        'crs': proj4_str,
        'transform': dst_transform,
        'width': nx,
        'height': ny
    })

    # Could be extended so that the cfg file takes all Resampling.* methods
    if cfg.PARAMS['topo_interp'] == 'bilinear':
        resampling = Resampling.bilinear
    elif cfg.PARAMS['topo_interp'] == 'cubic':
        resampling = Resampling.cubic
    else:
        raise ValueError('{} interpolation not understood'.format(
            cfg.PARAMS['topo_interp']))

    dem_reproj = gdir.get_filepath('dem')

    with rasterio.open(dem_reproj, 'w', **profile) as dest:
        dst_array = np.empty((ny, nx), dtype=dem_dss[0].dtypes[0])
        reproject(
            # Source parameters
            source=dem_data,
            src_crs=dem_dss[0].crs,
            src_transform=src_transform,
            # Destination parameters
            destination=dst_array,
            dst_transform=dst_transform,
            dst_crs=proj4_str,
            # Configuration
            resampling=resampling)

        # TODO: ugly
        if gdir.case.name == 'Borden Peninsula':
            print('Anti icepatch used')
            dst_array[32, 27] = gdir.case.ela_h - 5
            dst_array[:2, -4:] = gdir.case.ela_h - 5
        if gdir.case.name == 'Borden Peninsula HR':
            print('Anti icepatch HR used')
            dst_array[-21:-16, 32:38] = gdir.case.ela_h - 5
            dst_array[-8:-2, 88:98] = gdir.case.ela_h - 5
            dst_array[:-109, 120:] = gdir.case.ela_h - 5
        dest.write(dst_array, 1)

    for dem_ds in dem_dss:
        dem_ds.close()

    # Glacier grid
    x0y0 = (ulx + dx / 2, uly - dx / 2)  # To pixel center coordinates
    glacier_grid = salem.Grid(proj=proj_out,
                              nxny=(nx, ny),
                              dxdy=(dx, -dx),
                              x0y0=x0y0)
    glacier_grid.to_json(gdir.get_filepath('glacier_grid'))

    # Write DEM source info
    source_txt = DEM_SOURCE_INFO.get(dem_source, dem_source)
    with open(gdir.get_filepath('dem_source'), 'w') as fw:
        fw.write(source_txt)
Ejemplo n.º 53
0
def process_pci_dataset(src,
                        outfile,
                        dst_crs='EPSG:4326',
                        resolution=None,
                        resample_method=Resampling.nearest):
    """Simpely process sentinel 2 PCI image(line strech and apply gamma
    value) then projected to WGS 1984.

    Args:
        src (rasterio dataset): Input rasterio dataset.
        outfile (str): Result file (TIFF format).
        dst_crs : Target coordinate reference system.
        resolution (:tuple: x resolution, y resolution or float, optional):
            Target resolution, in units of target coordinate reference system.
        resample_method: Resampling method to use.  One of the following:
            Resampling.nearest,
            Resampling.bilinear,
            Resampling.cubic,
            Resampling.cubic_spline,
            Resampling.lanczos,
            Resampling.average,
            Resampling.mode,
            Resampling.max (GDAL >= 2.2),
            Resampling.min (GDAL >= 2.2),
            Resampling.med (GDAL >= 2.2),
            Resampling.q1 (GDAL >= 2.2),
            Resampling.q3 (GDAL >= 2.2),

    """
    # calculate_default_transform
    if resolution is not None:
        transform, width, height = calculate_default_transform(
            src.crs,
            dst_crs,
            src.width,
            src.height,
            resolution=resolution,
            *src.bounds)
    else:
        transform, width, height = calculate_default_transform(
            src.crs, dst_crs, src.width, src.height, *src.bounds)

    kwargs = src.meta.copy()
    kwargs.update({
        'driver': 'GTIFF',
        'nodata': 0,
        'crs': dst_crs,
        'transform': transform,
        'width': width,
        'height': height
    })
    # reproject data
    with rasterio.open(outfile, 'w', **kwargs) as dst:
        for i in range(1, src.count + 1):
            # strech image data
            # green band
            if i == 2:
                source = gamma(bytscl(src.read(i), maxValue=155), 1.4)
            # other band
            else:
                source = gamma(bytscl(src.read(i), maxValue=160), 1.3)
            reproject(source=source,
                      destination=rasterio.band(dst, i),
                      src_transform=src.transform,
                      src_crs=src.crs,
                      dst_transform=transform,
                      dst_crs=dst_crs,
                      resampling=resample_method)
Ejemplo n.º 54
0
def extract_esalc(esa_lc='H:/C3S-LC-L4-LCCS-Map-300m-P1Y-2018-v2.1.data/lccs_class.img',
                  source_crs='EPSG:4326',
                  region='Arctic_a60',
                  outpath='C:/Users/Pascal/Desktop/GEUS_2019/masks/github/',
                  target_crs='EPSG:4326',
                  clean_temp_files=False,
                  to_SICEMask=False,
                  binary_mask=False):
    '''
    INPUTS:
        esa_lc: path of ESA Land Classes .img file [string]
        source_crs: CRS of ESA Land Classes, default to 4326 [string]
        region: region to clip [string]
        outpath: folder where to store outputs [string]
        target_crs: Output CRS [string]
        to_SICEMask: set to True to have a SICE useable mask as output [boolean]
        binary_mask: set to True to have a SICE useable binary mask (land/ocean) 
                     if False, mask contains the 22 ESALC [boolean]
    
    OUTPUTS:
        if to_SICEMASK set to True:
            {outpath}/{region}.tif: binary or ESALC (depending on
                                    binary_mask option) SICE useable mask  for 
                                    the selected region [.tif]
        if to_SICEMASK set to False:
            {outpath}/esalc__clipped_{region}.tif: clipped ESALC for the selected 
                                               region [.tif]
            {outpath}/esalc_clipped_{region}_{target_crs}.tif: clipped and reprojected
                                                               in {target_crs}
                                                               ESALC for the selected 
                                                               region [.tif]
        
    
    
    '''
    
    
    import rasterio
    from shapely.geometry import box
    import geopandas as gpd
    from fiona.crs import from_epsg
    from rasterio.mask import mask
    from rasterio.warp import calculate_default_transform, reproject, Resampling
    import os
    from IPython import get_ipython
    
    
    #clear all variables to enable file deletion
    get_ipython().magic('reset -sf') 
        
    #initialize output names
    target_crs_name=target_crs.split(':')[1]
    out_tif=outpath+'esalc_clipped_'+region+'.tif'
    out_tif_3413=outpath+'esalc_clipped_'+target_crs_name+'_'+region+'.tif'
    SICEmask_tif=outpath+region+'.tif'
    
    #Delete outputs if already exists
    if os.path.exists(out_tif)==True:
        print('WARNING: Clipped ESA LC already exists...')
        print('Deleting clipped ESA LC...')
        os.remove(out_tif)
    if os.path.exists(out_tif_3413)==True:
        print('WARNING: Reprojected and clipped ESA LC already exists...')
        print('Deleting reprojected and clipped ESA LC...')
        os.remove(out_tif_3413)
    if os.path.exists(SICEmask_tif)==True:
        print('WARNING: SICE mask already exists...')
        print('Deleting SICE mask...')
    
    
    
    data = rasterio.open(esa_lc)
    
    
    if source_crs=='EPSG:4326':
        
        if region=='Greenland':
            minx, miny =  -80.35, 56.33
            maxx, maxy = -3.17, 84.17
            bbox = box(minx, miny, maxx, maxy)
            
        elif region=='Iceland':
            minx, miny = -24.93, 63.18
            maxx, maxy = -12.8, 66.6
            bbox = box(minx, miny, maxx, maxy)
        
        elif region=='Svalbard':
            minx, miny = 7.65, 76.18
            maxx, maxy = 37.3, 80.84
            bbox = box(minx, miny, maxx, maxy)
            
        elif region=='NovayaZemlya':
            minx, miny = 47.64, 70.4
            maxx, maxy = 70.96, 77.22
            bbox = box(minx, miny, maxx, maxy)
        
        elif region=='FransJosefLand':
            minx, miny = 40.88, 79.85
            maxx, maxy = 71.66, 81.93
            bbox = box(minx, miny, maxx, maxy)
        
        elif region=='SevernayaZemlya':
            minx, miny = 82.77, 78.00
            maxx, maxy = 112.26, 83.11
            bbox = box(minx, miny, maxx, maxy)
        
        elif region=='JanMayen':
            minx, miny = -9.47, 70.77
            maxx, maxy = -7.45, 71.21
            bbox = box(minx, miny, maxx, maxy)
        
        elif region=='NorthernArcticCanada':
            minx, miny = -128.27, 73.78
            maxx, maxy = -57.69, 83.24
            bbox = box(minx, miny, maxx, maxy)
            
        elif region=='SouthernArcticCanada':
            minx, miny = -92.23, 61.19
            maxx, maxy = -60.96, 74.43
            bbox = box(minx, miny, maxx, maxy)
        
        elif region=='Norway':
            minx, miny = 4.49, 59.44
            maxx, maxy = 9.08, 62.12
            bbox = box(minx, miny, maxx, maxy)
            
        elif region=='Beaufort':
            minx, miny = -148.87, 68.28
            maxx, maxy = -122.28, 75.39
            bbox = box(minx, miny, maxx, maxy)
        elif region=='AntarcticPeninsula':
            minx, miny = -78.23, -74.76
            maxx, maxy = -49.23, -57.98
            bbox = box(minx, miny, maxx, maxy)
        elif region=='AlaskaYukon':
            minx, miny = -158.07, 54.96
            maxx, maxy = -127.22, 64.42
            bbox = box(minx, miny, maxx, maxy)
        elif region=='Russia':
            minx, miny = 25, 48
            maxx, maxy = 188, 80
            bbox = box(minx, miny, maxx, maxy)
        elif region=='Arctic_a60':
            minx, miny = -180, 60
            maxx, maxy = 180, 90
            bbox = box(minx, miny, maxx, maxy)
            
        else:
            print('Wrong region name or not implemented')
            return
            
            
    elif source_crs=='EPSG:3413':
        
        if region=='Iceland':
                minx, miny = 825968.82, -2422134.15
                maxx, maxy = 1405420.90, -2377180.81
                bbox = box(minx, miny, maxx, maxy)
            
        elif region=='Svalbard':
            minx, miny = 7.65, 76.18
            maxx, maxy = 37.3, 80.84
            bbox = box(minx, miny, maxx, maxy)
                
        elif region=='Novaya Zemlya':
            minx, miny = 47.64, 70.4
            maxx, maxy = 70.96, 77.22
            bbox = box(minx, miny, maxx, maxy)
        
        else:
            print('Wrong region name or not implemented')
            return
            
        
    
    
    #insert the bbox into a GeoDataFrame
    if source_crs=='EPSG:4326':
        geo = gpd.GeoDataFrame({'geometry': bbox}, index=[0], crs=from_epsg(4326))
    elif source_crs=='EPSG:3413':
        geo = gpd.GeoDataFrame({'geometry': bbox}, index=[0], crs=from_epsg(3413))
    
    #reproject to the raster crs (safer)
    geo = geo.to_crs(crs=data.crs.data)
    
    #coordinates of the geometry so that rasterio handles it
    def getFeatures(gdf):
        """Function to parse features from GeoDataFrame in such a manner that rasterio wants them"""
        import json
        return [json.loads(gdf.to_json())['features'][0]['geometry']]
    
    print('Creating mask...')
    coords = getFeatures(geo)
    
    #clip source image using coords
    print('Clipping input...')
    out_img, out_transform = mask(dataset=data, shapes=coords, crop=True)
    
    # Copy the metadata
    out_meta = data.meta.copy()
    
    out_meta.update({"driver": "GTiff",
                    "height": out_img.shape[1],
                    "width": out_img.shape[2],
                    "transform": out_transform,
                    "crs": data.crs})
    
    print('Saving output...')
    with rasterio.open(out_tif, "w",compress='deflate', **out_meta) as dest:
        dest.write(out_img)
        

    if source_crs != target_crs:
        
        print('Reprojecting output...')
        dst_crs = target_crs
        with rasterio.open(out_tif) as src:
            transform, width, height = calculate_default_transform(src.crs, dst_crs, 
                                                                    src.width, 
                                                                    src.height, 
                                                                    *src.bounds)
            kwargs = src.meta.copy()
            kwargs.update({'crs': dst_crs,'transform': transform, 'width': width,'height': height})
        
            with rasterio.open(out_tif_3413, 'w', compress='deflate', **kwargs) as dst:
                    reproject(source=rasterio.band(src, 1),destination=rasterio.band(dst, 1),
                        src_transform=src.transform,
                        src_crs=src.crs,
                        dst_transform=transform,
                        dst_crs=dst_crs,
                        resampling=Resampling.nearest)
    
    
    if to_SICEMask==True:
        '''
        ESA LC:
            210: ocean
            0: out of footprint
            60-90(10)/100-150(10)/122/180/200-220(10): land 
        
        SICE MASK:
            255: ocean
            2: land
        '''
        
        print('Converting output to SICE mask...')
        esalc_tp=rasterio.open(out_tif_3413)
        esalc=esalc_tp.read(1)
        
        if binary_mask==True:
            if region!='BeaufortSea':
                mask_esalc=esalc.copy()
                mask_esalc[(mask_esalc!=210) & (mask_esalc!=0)]=2
                mask_esalc[mask_esalc!=2]=255
            else:
                mask_esalc=esalc.copy()
                mask_esalc[(mask_esalc==210) & (mask_esalc!=0)]=2
                mask_esalc[mask_esalc!=2]=255
            
        elif binary_mask==False:
            if region!='BeaufortSea':
                mask_esalc=esalc.copy()
                mask_esalc[mask_esalc==210]=255
                mask_esalc[mask_esalc==0]=255
            else:
                print('BeaufortSea mask could only be binary (covers ocean only)')
                mask_esalc=esalc.copy()
                mask_esalc[(mask_esalc==210) & (mask_esalc!=0)]=2
                mask_esalc[mask_esalc!=2]=255

        print('Saving SICE mask...')
        profile = esalc_tp.profile 
        profile.update(nodata=255) 
        
        with rasterio.open(SICEmask_tif, 'w', **profile) as dst:
            dst.write(mask_esalc, 1)
            
        
        return out_tif, out_tif_3413, clean_temp_files,to_SICEMask
Ejemplo n.º 55
0
def _get_bands(inputs, sources, d, i=None):
    """Get a rasterio.Band object from calc's inputs"""
    idx = d if d in dict(inputs) else int(d) - 1
    src = sources[idx]
    return (rasterio.band(src, i)
            if i else [rasterio.band(src, j) for j in src.indexes])
def warp_like(
    input, output, like, format=None, co={}, resampling=warp.Resampling.nearest
):
    """Warp a raster to lie on top op of an existing dataset.

    This function is meant to be similar to the ``rio warp --like`` CLI,
    and uses code from the implementation. Once https://github.com/mapbox/rasterio/issues/784
    is resolved this function may no longer be required. For further information see
    https://mapbox.github.io/rasterio/cli.html#warp and
    https://mapbox.github.io/rasterio/topics/reproject.html

    Parameters
    ----------
    input : str
        Path to the input raster.
    output : str
        Path to the output raster.
    like : str or rasterio.DatasetReader
        The raster whose affine transform, size, and crs are used.
    format : str, optional
        The GDAL raster driver code of the output, see http://www.gdal.org/formats_list.html
        By default, use the same format as the input.
    co : dict, optional
        Creation options for creating the output.
    resampling : Resampling enum, optional
        Default value is ``rasterio.warp.Resampling.nearest``. For other values see
        https://mapbox.github.io/rasterio/topics/resampling.html?highlight=resampling#resampling-methods
    
    Example
    -------
    >>> warp_like('input.map', 'output.tif', 'like.tif', format='GTiff',
                  co={'COMPRESS':'DEFLATE'}, resampling=warp.Resampling.med)
    """

    dst_crs, dst_transform, dst_height, dst_width = _like(like)

    with rasterio.open(input) as src:
        out_kwargs = src.profile.copy()
        out_kwargs.update(
            {
                "crs": dst_crs,
                "transform": dst_transform,
                "width": dst_width,
                "height": dst_height,
            }
        )

        # else the format is equal to the input format
        if format is not None:
            out_kwargs["driver"] = format

        # Adjust block size if necessary.
        if "blockxsize" in out_kwargs and dst_width < out_kwargs["blockxsize"]:
            del out_kwargs["blockxsize"]
        if "blockysize" in out_kwargs and dst_height < out_kwargs["blockysize"]:
            del out_kwargs["blockysize"]

        out_kwargs.update(co)

        with rasterio.open(output, "w", **out_kwargs) as dst:
            warp.reproject(
                source=rasterio.band(src, list(range(1, src.count + 1))),
                destination=rasterio.band(dst, list(range(1, src.count + 1))),
                src_transform=src.transform,
                src_crs=src.crs,
                src_nodata=src.nodata,
                dst_transform=out_kwargs["transform"],
                dst_crs=out_kwargs["crs"],
                dst_nodata=dst.nodata,
                resampling=resampling,
            )
Ejemplo n.º 57
0
def reproject_and_save_tile(gs_tuple, pixel_size=10):

    tile_name = gs_tuple[-1].split('_')[-2]
    tile_folder_base = '/Volumes/Conlon Backup 2TB/sentinel_imagery/reprojected_tiles'
    tile_folder = os.path.join(tile_folder_base, tile_name)

    if not os.path.exists(tile_folder):
        os.mkdir(tile_folder)

    print('Downloading Tile: {}'.format(gs_tuple[-1]))

    valid_bands = ['B02', 'B03', 'B04', 'B08']

    cmd_string = '/Users/terenceconlon/anaconda3/envs/gis/bin/gsutil ls -r ' + gs_tuple[
        -1] + '/GRANULE'
    image_list_output = subprocess.Popen(cmd_string,
                                         shell=True,
                                         stdout=subprocess.PIPE)
    image_list_clean = [
        j.decode('utf-8') for j in image_list_output.stdout.readlines()
    ]

    image_list_output.kill()

    jp2_list = sorted(
        [j.replace('\n', '') for j in image_list_clean if '.jp2' in j])
    jp2_band_list = sorted(
        [i for i in jp2_list if i.split('_')[-1][0:3] in valid_bands])
    jp2_single_image = [
        j.replace('\n', '') for j in image_list_clean
        if valid_bands[0] + '.jp2' in j
    ][0]
    cloud_cover_gml = [
        j.replace('\n', '') for j in image_list_clean if 'CLOUDS' in j
    ][0]

    year = jp2_single_image.split('_')[-2][0:4]
    month = jp2_single_image.split('_')[-2][4:6]
    day = jp2_single_image.split('_')[-2][6:8]

    dir_folder, cloud_folder = create_dirs(tile_folder_base, tile_name, year,
                                           month, valid_bands)

    cloud_path = os.path.join(
        cloud_folder,
        'cloud_cover_polygons_{}_{}_{}.shp'.format(year, month, day))

    tile_template = '/Volumes/Conlon Backup 2TB/sentinel_imagery/tile_template_tifs/' \
                    'pixel_{}m/template_{}.tif'.format(pixel_size, tile_name)

    with rasterio.open(tile_template, 'r') as band_dest:
        metadata = band_dest.meta.copy()

        for file in jp2_band_list:
            band = file.split('_')[-1][0:3]
            band_folder = os.path.join(dir_folder, band)
            previously_saved_images = glob.glob(band_folder + '/*.tif')

            save_file_str = '{}_{}_{}_{}.tif'.format(year, month, day, band)
            save_file = os.path.join(band_folder, save_file_str)
            save_new_file = True

            print(save_file)
            if os.path.exists(save_file):
                with rasterio.open(save_file, 'r',
                                   driver='GTiff') as saved_img:
                    print(np.max(saved_img.read()))
                    if np.max(saved_img.read()) > 0:
                        save_new_file = False

            print(save_new_file)
            if save_new_file:

                with rasterio.open(
                        file,
                        'r',
                        driver='JP2OpenJPEG',
                ) as band_src:

                    print('before reproject: {}'.format(file))

                    with rasterio.open(save_file, 'w', **metadata) as dest_jp2:
                        reproject(source=rasterio.band(band_src, 1),
                                  destination=rasterio.band(dest_jp2, 1),
                                  resampling=Resampling.nearest)

                    print('after reproject')

    cloud_file = os.path.join(tile_folder, cloud_path)

    if not os.path.exists(cloud_file):
        with fiona.open(cloud_cover_gml, 'r') as src_cc:
            with fiona.open(cloud_file,
                            'w',
                            crs=src_cc.crs,
                            driver='ESRI Shapefile',
                            schema=src_cc.schema) as output:
                for f in src_cc:
                    output.write(f)
Ejemplo n.º 58
0
                resolution=resolution)

        kwargs = src.meta.copy()
        kwargs.update({
                'crs': dst_crs,
                'transform': transform,
                'width': width,
                'height': height,
                'nodata':-9999,
                'compress':'LZW',
        })

        with rio.open(dst_dataset02, 'w', **kwargs) as dst02:
            for i in range(1, src.count+1):
                reproject(
                    source=rio.band(src, i),
                    destination=rio.band(dst02, i),
                    src_transform=src.transform,
                    src_crs=src.crs,
                    src_nodata=-9999,
                    dst_transform=transform,
                    dst_crs=dst_crs,
                    dst_nodata=-9999,
                    dst_resolution=resolution,
                    resampling=Resampling.nearest,
                )
    with rio.open(dst_dataset02) as dst02:
        out_img, out_transform = mask(dataset=dst02, shapes=shapes, crop=True)
        out_meta = dst02.meta.copy()
        out_meta.update({"height": out_img.shape[1],
                         "width": out_img.shape[2],
Ejemplo n.º 59
0
import numpy as np
import rasterio
from rasterio.warp import calculate_default_transform, reproject, Resampling
import sys

dst_crs = 'EPSG:32606'
input_ = sys.argv[1]
output = sys.argv[2]

with rasterio.open(input_) as src:
    transform, width, height = calculate_default_transform(
        src.crs, dst_crs, src.width, src.height, *src.bounds)
    kwargs = src.meta.copy()
    kwargs.update({
        'crs': dst_crs,
        'transform': transform,
        'width': width,
        'height': height
    })

    with rasterio.open(output, 'w', **kwargs) as dst:
        for i in range(1, src.count + 1):
            reproject(source=rasterio.band(src, i),
                      destination=rasterio.band(dst, i),
                      src_transform=src.transform,
                      src_crs=src.crs,
                      dst_transform=transform,
                      dst_crs=dst_crs,
                      resampling=Resampling.nearest)
Ejemplo n.º 60
0
def align_rasters(rasters, template, outputdir, method="Resampling.nearest"):
    """Aligns a list of rasters (paths to files) to a template raster.
    The rasters to that are to be realigned are assumed to represent
    single band raster files.

    Nodata values are also reclassified to the template raster's nodata values

    Args
    ----
    rasters : list, str
        List containing file paths to multiple rasters that are to be realigned.

    template : str
        File path to raster that is to be used as a template to transform the
        other rasters to.

    outputdir : str
        Directory to output the realigned rasters. This should not be the
        existing directory unless it is desired that the existing rasters to be
        realigned should be overwritten.

    method : str
        Resampling method to use. One of the following:
            Resampling.average,
            Resampling.bilinear,
            Resampling.cubic,
            Resampling.cubic_spline,
            Resampling.gauss,
            Resampling.lanczos,
            Resampling.max,
            Resampling.med,
            Resampling.min,
            Resampling.mode,
            Resampling.nearest,
            Resampling.q1,
            Resampling.q3
    """

    # check resampling methods
    methods = dir(rasterio.enums.Resampling)
    methods = [i for i in methods if i.startswith('__') is False]
    methods = ['Resampling.' + i for i in methods]

    if method not in methods:
        raise ValueError('Invalid resampling method: ' + method + os.linesep +
                         'Valid methods are: ' + str(methods))

    # open raster to be used as the template and create numpy array
    template = rasterio.open(template)
    kwargs = template.meta.copy()

    for raster in rasters:
        output = os.path.join(outputdir, os.path.basename(raster))

        with rasterio.open(raster) as src:
            with rasterio.open(output, 'w', **kwargs) as dst:
                reproject(source=rasterio.band(src, 1),
                          destination=rasterio.band(dst, 1),
                          dst_transform=template.transform,
                          dst_nodata=template.nodata,
                          dst_crs=template.nodata)

    template.close()

    return ()