def test_without_ds(self):
     img = np.ones((self.height, self.width), np.int16)
     ds = GDalDatasetWrapper(array=img, projection=self.projection, geotransform=self.coordinates)
     np.testing.assert_almost_equal(img, ds.array)
     self.assertEqual(ds.geotransform, self.coordinates)
     self.assertIsNone(ds.nodata_value)
     self.assertEqual(ds.epsg, 32631)
     np.testing.assert_almost_equal(np.ones_like(img), ds.nodata_mask)
     # Compare projections by removing all spaces cause of multiline string
     self.assertEqual(ds.projection.replace(" ", ""), self.projection.replace(" ", ""))
Exemplo n.º 2
0
    def test_get_ndsi_float32(self):
        swir = np.arange(0, 9).reshape(3, 3)
        red = np.ones((3, 3))
        swir[-1, -1] = 0
        red[-1, -1] = 0
        ds_swir = GDalDatasetWrapper(array=swir,
                                     projection=self.projection,
                                     geotransform=self.coordinates)
        ds_red = GDalDatasetWrapper(array=red,
                                    projection=self.projection,
                                    geotransform=self.coordinates)
        expected = np.array([[1, 0, -.3333333], [-.5, -.6, -.6666667],
                             [-0.7142857, -0.75, -1]],
                            dtype=np.float32)

        calculated = ImageApps.get_ndsi(ds_red, ds_swir)
        np.testing.assert_almost_equal(calculated.array, expected)
        self.assertEqual(calculated.resolution, ds_swir.resolution)
        self.assertEqual(calculated.resolution, ds_red.resolution)
        self.assertEqual(calculated.extent, ds_red.extent)
        self.assertEqual(calculated.extent, ds_swir.extent)
 def test_write_nodata(self):
     fname = "./test_write_nodata.tif"
     img = np.ones((self.height, self.width), np.int16)
     ds = GDalDatasetWrapper(array=img, projection=self.projection, geotransform=self.coordinates,
                             nodata_value=42)
     ds.write(fname, options=["COMPRESS=DEFLATE"])
     self.assertTrue(os.path.exists(fname))
     ds_read = GDalDatasetWrapper.from_file(fname)
     self.assertEqual(42, ds_read.nodata_value)
     self.assertEqual("DEFLATE", ds_read._info["metadata"]["IMAGE_STRUCTURE"]["COMPRESSION"])
     np.testing.assert_almost_equal(ds_read.array, ds.array)
     os.remove(fname)
     self.assertFalse(os.path.exists(fname))
Exemplo n.º 4
0
    def test_get_ndsi_int16(self):
        swir = np.array(np.arange(0, 9).reshape(3, 3), dtype=np.int16)
        red = np.ones((3, 3), dtype=np.int16)
        swir[-1, -1] = 0
        red[-1, -1] = 0
        ds_swir = GDalDatasetWrapper(array=swir,
                                     projection=self.projection,
                                     geotransform=self.coordinates)
        ds_red = GDalDatasetWrapper(array=red,
                                    projection=self.projection,
                                    geotransform=self.coordinates)

        expected = np.array([[1000, 500, 333], [250, 199, 166], [142, 125, 0]],
                            dtype=np.int16)

        calculated = ImageApps.get_ndsi(ds_red,
                                        ds_swir,
                                        vrange=(0, 1000),
                                        dtype=np.int16)
        np.testing.assert_almost_equal(calculated.array, expected)
        self.assertEqual(calculated.resolution, ds_swir.resolution)
        self.assertEqual(calculated.resolution, ds_red.resolution)
        self.assertEqual(calculated.extent, ds_red.extent)
        self.assertEqual(calculated.extent, ds_swir.extent)
Exemplo n.º 5
0
    def test_merge_then_translate(self):
        datasets = []
        init = np.zeros((2, 2), np.int16)
        path = os.path.join(os.getcwd(), "test_gdal_merge.tif")
        ImageIO.write_geotiff(init, path, self.projection, self.coordinates)
        ds_in = GDalDatasetWrapper.from_file(path)
        for i in range(1, 3, 1):
            img = np.ones((i*2, i*2), np.int16) * i
            ds_n = GDalDatasetWrapper(ds=ds_in.get_ds(), array=img)
            self.assertTrue(os.path.exists(path))
            datasets.append(ds_n)
        ds_merged = ImageTools.gdal_merge(*datasets, dst="out.tif",
                                          separate=True,
                                          q=True,
                                          a_nodata=0)
        # Array of shape (4, 4, 2):
        expected = np.array([[[1, 2],
                              [1, 2],
                              [0, 2],
                              [0, 2]],
                             [[1, 2],
                              [1, 2],
                              [0, 2],
                              [0, 2]],
                             [[0, 2],
                              [0, 2],
                              [0, 2],
                              [0, 2]],
                             [[0, 2],
                              [0, 2],
                              [0, 2],
                              [0, 2]]], dtype=np.int16)
        FileSystem.remove_file("out.tif")
        np.testing.assert_equal(expected.dtype, ds_merged.array.dtype)
        np.testing.assert_almost_equal(expected, ds_merged.array)
        self.assertEqual(ds_merged.nodata_value, 0)
        self.assertEqual(ds_merged.epsg, 32631)
        ds_translate = ImageTools.gdal_translate(ds_merged,
                                                 a_nodata=0)
        FileSystem.remove_file(path)

        np.testing.assert_equal(expected.dtype, ds_translate.array.dtype)
        np.testing.assert_almost_equal(ds_translate.array, expected)
        self.assertEqual(ds_translate.nodata_value, 0)
        self.assertEqual(ds_translate.epsg, 32631)
Exemplo n.º 6
0
def gdal_translate(src, dst=None, **options):
    """
    Translate a dataset.

    :param src: The input filename or dataset.
    :param dst: If specified, the output will be writen to
    the given path on a physical disk.
    Note: This overwrites a previous file at the same location.
    :return: A :class:`Common.GDalDatasetWrapper.GDalDatasetWrapper` object
    :rtype: `osgeo.gdal.dataset` or file on disk (see parameter ``dst``).
    """
    gdal_common_params = ["optfile", "config", "debug"]
    options_list = []
    for k, v in options.items():
        if k in gdal_common_params:
            options_list += ["--%s" % k, "%s" % v]
        elif type(v) is not bool:
            options_list += ["-%s" % k, "%s" % v]
        elif type(v) is bool and v is True:
            options_list.append("-%s" % k)
        else:
            pass
    options_list = " ".join(options_list)

    if type(src) == GDalDatasetWrapper:
        src = src.get_ds()
    # Remove previous existing file if writing to disk is enabled:
    if dst:
        FileSystem.remove_file(dst)
        # Note: De-allocation before file is actually written to disk
        # cf. https://gdal.org/api/python_gotchas.html
        _ = gdal.Translate(dst, src, options=options_list)
        _ = None
        ds_out = gdal.Open(dst)
    else:
        # Write directly into memory if no path specified (faster):
        dst = "/vsimem/" + uuid.uuid4().hex
        ds_out = gdal.Translate(dst, src, options=options_list)
    arr_bands_last = np.array(ds_out.ReadAsArray())
    if arr_bands_last.ndim == 3:
        arr_bands_last = np.moveaxis(arr_bands_last, 0, -1)
    return GDalDatasetWrapper(ds=ds_out, array=arr_bands_last)
Exemplo n.º 7
0
    def test_gdal_merge_optfile(self):
        datasets, written = [], []
        init = np.zeros((2, 2), np.int16)
        path = os.path.join(os.getcwd(), "test_gdal_merge_optfile.tif")
        ImageIO.write_geotiff(init, path, self.projection, self.coordinates)
        ds_in = GDalDatasetWrapper.from_file(path)
        for i in range(1, 3, 1):
            img = np.ones((i*2, i*2), np.int16) * i
            ds_n = GDalDatasetWrapper(ds=ds_in.get_ds(), array=img)
            p_out = "test_gdal_merge_optfile_%s.tif" % i
            ImageIO.write_geotiff_existing(img, p_out, ds_in.get_ds())
            self.assertTrue(os.path.exists(path))
            datasets.append(ds_n)
            written.append(p_out)
        optfile = "test_gdal_merge_optfile.txt"
        with open(optfile, 'w') as file_handler:
            for item in written:
                file_handler.write("{}\n".format(item))

        ds_merged = ImageTools.gdal_merge(*datasets,
                                          q=True,
                                          a_nodata=0)
        ds_optfile = ImageTools.gdal_merge(optfile=optfile,
                                           q=True,
                                           a_nodata=0)
        # Array of shape (4, 4):
        expected = np.array([[2, 2, 2, 2],
                             [2, 2, 2, 2],
                             [2, 2, 2, 2],
                             [2, 2, 2, 2]], dtype=np.int16)

        FileSystem.remove_file(path)
        [FileSystem.remove_file(p) for p in written]
        FileSystem.remove_file(optfile)
        np.testing.assert_equal(expected.dtype, ds_merged.array.dtype)
        np.testing.assert_almost_equal(expected, ds_merged.array)
        self.assertEqual(ds_merged.nodata_value, 0)
        self.assertEqual(ds_merged.epsg, 32631)
        np.testing.assert_equal(expected.dtype, ds_optfile.array.dtype)
        np.testing.assert_almost_equal(expected, ds_optfile.array)
        self.assertEqual(ds_optfile.nodata_value, 0)
        self.assertEqual(ds_optfile.epsg, 32631)
    def test_override_array(self):
        img = np.ones((self.height, self.width), np.int16)
        img_new = np.array(np.arange(0, 40200).reshape(201, 200), dtype=np.uint8)
        path = os.path.join(os.getcwd(), "test_write_read_geotiff.tif")
        ImageIO.write_geotiff(img, path, self.projection, self.coordinates)
        self.assertTrue(os.path.exists(path))

        ds = GDalDatasetWrapper.from_file(path)
        self.assertTrue((ds.array == img).all())
        self.assertEqual(ds.geotransform, self.coordinates)
        self.assertEqual(ds.projection.replace(" ", ""), self.projection.replace(" ", ""))
        self.assertIsNone(ds.nodata_value)
        self.assertEqual(ds.epsg, 32631)
        ds_new = GDalDatasetWrapper(ds=ds.get_ds(), array=img_new, nodata_value=123)
        FileSystem.remove_file(path)
        np.testing.assert_almost_equal(img_new, ds_new.array)
        self.assertEqual(ds_new.geotransform, self.coordinates)
        self.assertEqual(ds_new.projection.replace(" ", ""), self.projection.replace(" ", ""))
        self.assertEqual(ds_new.nodata_value, 123)
        self.assertEqual(ds_new.epsg, 32631)
        self.assertFalse(os.path.exists(path))
Exemplo n.º 9
0
def get_ndvi(red, nir, vrange=(-1, 1), dtype=np.float32):
    """
    Calculate the NDVI (Normalized-Difference Vegetation Index)

    :param red: The red band dataset
    :type red: :class:`Common.GDalDatasetWrapper.GDalDatasetWrapper`
    :param nir: The nir band dataset
    :type nir: :class:`Common.GDalDatasetWrapper.GDalDatasetWrapper`
    :param vrange: The range of output values as tuple. By default: (-1, 1).
    :type vrange: tuple of int
    :param dtype: The output dtype.
    :type dtype: :class`np.dtype`
    :return: The NDVI as numpy array.
    :rtype: :class:`Common.GDalDatasetWrapper.GDalDatasetWrapper`
    """

    if nir.extent != red.extent or nir.epsg != red.epsg:
        raise ValueError("Cannot calculate NDSI on two different extents.")

    if nir.resolution != red.resolution:
        # Resize to nir resolution in this case.
        tr = " ".join([str(i) for i in nir.resolution])
        ds_red = ImageTools.gdal_translate(red, tr=tr, r="cubic")
    else:
        ds_red = red

    # TODO Add new test

    img_red = np.array(ds_red.array, dtype=np.float32)
    img_nir = np.array(nir.array, dtype=np.float32)

    # Compensate for nan:
    np.seterr(divide='ignore', invalid='ignore')
    img_ndvi = np.where((img_red + img_nir) != 0, (img_red - img_nir) / (img_red + img_nir), -1)

    # Scale to vrange
    img_ndvi_scaled = ImageTools.normalize(img_ndvi, value_range_out=vrange, value_range_in=(-1, 1),
                                           dtype=dtype, clip=True)

    return GDalDatasetWrapper(ds=nir.get_ds(), array=img_ndvi_scaled)
Exemplo n.º 10
0
def gdal_merge(*src, dst=None, **options):
    """
    Merge a dataset using a modified gdal_merge.

    :param src: The list of input filenames or datasets.
    :param dst: If specified, the output will be writen to
    the given path on a physical disk.
    :param options: Optional keyword arguments
    :return:
    """
    gdal_common_params = ["optfile"]
    options_list = [""]
    for k, v in options.items():
        if k in gdal_common_params:
            options_list += ["--%s" % k, "%s" % v]
        elif type(v) is not bool:
            options_list += ["-%s" % k, "%s" % v]
        elif type(v) is bool and v is True:
            options_list.append("-%s" % k)
        else:
            pass
    #src = [i.get_ds() if type(i) == GDalDatasetWrapper else i for i in src]
    # Remove previous existing file if writing to disk is enabled:
    if dst and type(dst) == str:
        FileSystem.remove_file(dst)
        # Note: De-allocation before file is actually written to disk
        # cf. https://gdal.org/api/python_gotchas.html
        options_list += ["-o", "%s" % dst]
        _ = merge.run_merge(*[s for s in src], argv=options_list)
        _ = None
        ds_out = gdal.Open(dst)
    else:
        # Write directly into memory if no path specified (faster):
        ds_out = merge.run_merge(*[s for s in src], argv=options_list)
    arr_bands_last = np.array(ds_out.ReadAsArray())
    if arr_bands_last.ndim == 3:
        arr_bands_last = np.moveaxis(arr_bands_last, 0, -1)
    return GDalDatasetWrapper(ds=ds_out, array=arr_bands_last)
Exemplo n.º 11
0
def gdal_buildvrt(*inputs, dst=None, **options):
    """
    Build a gdalvrt using in memory bindings.

    :param inputs: The list of input filenames or datasets.
    :param dst: If specified, the vrt will be writen to
    the given path on a physical disk.
    Note: This overwrites a previous vrt at the same location.
    :return: VRT of the given inputs, by default as an in-memory file.
    :type: `osgeo.gdal.dataset` or .vrt on disk (see param ``dst``).
    """
    gdal_common_params = ["optfile"]
    options_list = []
    for k, v in options.items():
        if k in gdal_common_params:
            options_list += ["--%s" % k, "%s" % v]
        elif type(v) is not bool:
            options_list += ["-%s" % k, "%s" % v]
        elif type(v) is bool and v is True:
            options_list.append("-%s" % k)
        else:
            pass
    options_list = " ".join(options_list)

    inputs = [i.get_ds() if type(i) == GDalDatasetWrapper else i for i in inputs]
    # Remove previous existing file if writing to disk is enabled:
    if dst:
        FileSystem.remove_file(dst)
        # Note: De-allocation before file is actually written to disk
        # cf. https://gdal.org/api/python_gotchas.html
        _ = gdal.BuildVRT(dst, [i for i in inputs], options=options_list)
        _ = None
        ds_out = gdal.Open(dst)
    else:
        # Write directly into memory if no path specified (faster):
        dst = "/vsimem/" + uuid.uuid4().hex
        ds_out = gdal.BuildVRT(dst, [i for i in inputs], options=options_list)
    return GDalDatasetWrapper(ds=ds_out)