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))
def get_synthetic_band(self, synthetic_band, **kwargs): wdir = kwargs.get("wdir", self.fpath) output_folder = os.path.join(wdir, self.base) output_bname = "_".join( [self.base.split(".")[0], synthetic_band.upper() + ".tif"]) output_filename = kwargs.get("output_filename", os.path.join(output_folder, output_bname)) max_value = kwargs.get("max_value", 10000.) # Skip existing: if os.path.exists(output_filename): return output_filename if synthetic_band.lower() == "ndvi": FileSystem.create_directory(output_folder) b4 = self.find_file(pattern=r"*B0?4(_10m)?.jp2$")[0] b8 = self.find_file(pattern=r"*B0?8(_10m)?.jp2$")[0] ds_red = GDalDatasetWrapper.from_file(b4) ds_nir = GDalDatasetWrapper.from_file(b8) ds_ndvi = ImageApps.get_ndvi(ds_red, ds_nir, vrange=(0, max_value), dtype=np.int16) ds_ndvi.write(output_filename, options=["COMPRESS=DEFLATE"]) elif synthetic_band.lower() == "ndsi": FileSystem.create_directory(output_folder) b3 = self.find_file(pattern=r"*B0?3(_10m)?.jp2$")[0] b11 = self.find_file(pattern=r"*B11(_20m)?.jp2$")[0] ds_green = ImageTools.gdal_translate(b3, tr="20 20", r="cubic") ds_swir = GDalDatasetWrapper.from_file(b11) ds_ndsi = ImageApps.get_ndsi(ds_green, ds_swir, vrange=(0, max_value), dtype=np.int16) ds_ndsi.write(output_filename, options=["COMPRESS=DEFLATE"]) elif synthetic_band.lower() == "mca_sim": FileSystem.create_directory(output_folder) b4 = self.find_file(pattern=r"*B0?4(_10m)?.jp2$")[0] b3 = self.find_file(pattern=r"*B0?3(_10m)?.jp2$")[0] img_red, drv = ImageIO.tiff_to_array(b4, array_only=False) img_green = ImageIO.tiff_to_array(b3) img_mcasim = (img_red + img_green) / 2 ImageIO.write_geotiff_existing(img_mcasim, output_filename, drv, options=["COMPRESS=DEFLATE"]) else: raise ValueError("Unknown synthetic band %s" % synthetic_band) return output_filename
def test_gdal_tile_untile(self): img = np.arange(0., 100.).reshape((10, 10)) path = os.path.join(os.getcwd(), "test_gdal_retile.tif") tile_folder = os.path.join(os.getcwd(), "tiled") ImageIO.write_geotiff(img, path, self.projection, self.coordinates) # Add parasitic file - It should not cause problems path_parasite = os.path.join(tile_folder, "tile_01_01.tif") FileSystem.create_directory(tile_folder) ImageIO.write_geotiff(img, path_parasite, self.projection, self.coordinates) ds_in = GDalDatasetWrapper.from_file(path) self.assertTrue(os.path.exists(path)) tiles = ImageTools.gdal_retile(ds_in, tile_folder, TileWidth=2, TileHeight=2, Overlap=1) self.assertTrue(os.path.isdir(tile_folder)) self.assertEqual(len(tiles), 81) img_read = np.array(ImageIO.tiff_to_array(tiles[-1])) expected = np.array([[88, 89], [98, 99]]) # Some gdal_retile versions are producing the following image: # [[87, 89], [97, 99]]. np.testing.assert_allclose(expected, img_read, atol=1) # Untile ds_untiled = ImageTools.gdal_buildvrt(*tiles) np.testing.assert_allclose(img, ds_untiled.array, atol=1) FileSystem.remove_file(path) FileSystem.remove_directory(tile_folder)
def test_get_s2_epsg_code(self): epsg_ref = 32631 projection = 'PROJCS["WGS 84 / UTM zone 31N",\ GEOGCS["WGS 84",DATUM["WGS_1984",\ SPHEROID["WGS 84",6378137,298.257223563,\ AUTHORITY["EPSG","7030"]],\ AUTHORITY["EPSG","6326"]],\ PRIMEM["Greenwich",0,\ AUTHORITY["EPSG","8901"]],\ UNIT["degree",0.0174532925199433,\ AUTHORITY["EPSG","9122"]],\ AUTHORITY["EPSG","4326"]],\ PROJECTION["Transverse_Mercator"],\ PARAMETER["latitude_of_origin",0],\ PARAMETER["central_meridian",3],\ PARAMETER["scale_factor",0.9996],\ PARAMETER["false_easting",500000],\ PARAMETER["false_northing",0],\ UNIT["metre",1,AUTHORITY["EPSG","9001"]],\ AXIS["Easting",EAST],AXIS["Northing",NORTH],\ AUTHORITY["EPSG","%s"]]' % epsg_ref img = np.ones((self.height, self.width), np.int16) path = os.path.join(os.getcwd(), "test_epsg.tif") ImageIO.write_geotiff(img, path, projection, self.coordinates) self.assertTrue(os.path.exists(path)) ds = GDalDatasetWrapper.from_file(path) epsg_new = ds.epsg self.assertEqual(epsg_new, epsg_ref) FileSystem.remove_file(path) self.assertFalse(os.path.exists(path))
def from_raster(name, raster, **kwargs): """ Create site from a raster on disk :param name: The name of the site :param raster: The gdal raster Optional arguments: - shape_index_y: Select the band index for the Y-size - shape_index_x: Select the band index for the X-size :return: A site class given the infos from the raster. """ driver = GDalDatasetWrapper.from_file(raster) shape_index_y = kwargs.get("shape_index_y", 0) shape_index_x = kwargs.get("shape_index_x", 1) ny, nx = driver.array.shape[shape_index_y], driver.array.shape[ shape_index_x] epsg = driver.epsg ulx, uly, lrx, lry = driver.ul_lr ul = (ulx, uly) lr = (lrx, lry) xmin, xres, skx, ymax, sky, yres = driver.geotransform return Site(name, epsg, ul=ul, lr=lr, px=nx, py=ny, res_x=xres, res_y=yres)
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))
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)
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)
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_get_utm_description(self): img = np.ones((self.height, self.width), np.int16) path = os.path.join(os.getcwd(), "test_get_utm_description.tif") ImageIO.write_geotiff(img, path, self.projection, self.coordinates) self.assertTrue(os.path.exists(path)) ds = GDalDatasetWrapper.from_file(path) utm = ds.utm_description utm_expected = "WGS 84 / UTM zone 31N" self.assertEqual(utm_expected, utm) FileSystem.remove_file(path) self.assertFalse(os.path.exists(path))
def test_get_resolution(self): img = np.ones((self.height, self.width), np.int16) path = os.path.join(os.getcwd(), "test_get_resolution.tif") ImageIO.write_geotiff(img, path, self.projection, self.coordinates) self.assertTrue(os.path.exists(path)) ds = GDalDatasetWrapper.from_file(path) res_expected = (self.coordinates[1], self.coordinates[-1]) self.assertEqual(res_expected, ds.resolution) FileSystem.remove_file(path) self.assertFalse(os.path.exists(path))
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(" ", ""))
def test_get_ul_lr(self): img = np.ones((1000, 1000), np.int16) path = os.path.join(os.getcwd(), "test_get_ul_lr.tif") ImageIO.write_geotiff(img, path, self.projection, self.coordinates) self.assertTrue(os.path.exists(path)) ds = GDalDatasetWrapper.from_file(path) ulx, uly, lrx, lry = ds.ul_lr self.assertEqual((ulx, uly), (300000.0, 4900020.0)) self.assertEqual((lrx, lry), (310000.0, 4890020.0)) self.assertEqual(ds.extent, (300000.0, 4890020.0, 310000.0, 4900020.0)) FileSystem.remove_file(path) self.assertFalse(os.path.exists(path))
def test_write_read_geotiff(self): img = np.ones((self.height, self.width), np.int16) 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) # Compare projections by removing all spaces cause of multiline string self.assertEqual(ds.projection.replace(" ", ""), self.projection.replace(" ", "")) self.assertIsNone(ds.nodata_value) self.assertEqual(ds.epsg, 32631) FileSystem.remove_file(path) self.assertFalse(os.path.exists(path))
def reproject(self, **kwargs): out_dir = kwargs.get("out_dir", self.fpath) assert os.path.isdir(out_dir) out_dir = os.path.join(out_dir, self.base) FileSystem.create_directory(out_dir) patterns = kwargs.get("patterns", [r".(tif|jp2)$"]) imgs = [self.find_file(pattern=p) for p in patterns] epsg = kwargs.get("epsg", None) # Flatten imgs = [i for img in imgs for i in img] for img in imgs: if not epsg: drv = GDalDatasetWrapper.from_file(img) epsg = drv.epsg outpath = os.path.join(out_dir, os.path.basename(img)) self._reproject_to_epsg(img, outpath, epsg) return out_dir
def __init__(self, site, dem_full_res): self.name = site.nom self.epsg = site.epsg_str self.ulx = site.ul[0] self.uly = site.ul[1] self.resx = site.res_x self.resy = site.res_y self.lx = site.px self.ly = site.py self.alt = dem_full_res driver = GDalDatasetWrapper.from_file(dem_full_res) self.mean_alt = np.mean(driver.array) self.std_dev_alt = np.std(driver.array) self.short_description = driver.utm_description self.nodata = driver.nodata_value res_arr = driver.resolution self.dem_subsampling_ratio = str( int(float(res_arr[0]) / float(site.res_x)))
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)
def test_srtm_prepare_mnt_vns_maccanw2(self): resx, resy = 5000, -5000 px, py = 11, 14 site = SiteInfo.Site("MACCANW2", 32633, px=px, py=py, ul=(246439.500, 4672656.500), lr=(299769.500, 4604231.500), res_x=resx, res_y=resy) dem_dir = os.path.join(os.getcwd(), "test_srtm_prepare_mnt_vns_maccanw2") s = SRTM.SRTM(site, dem_dir=dem_dir, raw_dem=self.raw_srtm, raw_gsw=self.raw_gsw, wdir=dem_dir) self.assertTrue(os.path.isdir(dem_dir)) srtm = s.prepare_mnt() self.assertTrue(os.path.isfile(srtm)) driver = GDalDatasetWrapper.from_file(srtm) expected_img = [[ 293, 210, 337, 390, 238, 218, 237, 245, 270, 208, 132 ], [302, 293, 277, 302, 182, 172, 237, 270, 262, 171, 60], [155, 239, 239, 231, 238, 199, 164, 173, 137, 85, 33], [0, 28, 94, 138, 150, 131, 116, 117, 72, 37, 73], [0, 0, 18, 67, 81, 79, 84, 117, 72, 36, 59], [0, 0, 0, 11, 38, 58, 68, 87, 68, 38, 33], [0, 0, 0, 0, 6, 41, 52, 62, 52, 43, 41], [0, 0, 0, 0, 1, 0, 30, 34, 30, 48, 68], [0, 0, 0, 0, 0, -1, 12, 26, 42, 70, 101], [0, 0, 0, 0, 0, 4, 11, 50, 59, 89, 136], [0, 0, 0, 0, 0, 0, 0, 30, 76, 97, 130], [0, 0, 0, 0, 0, 0, 0, 0, 44, 72, 86], [0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 59], [0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 54]] self.assertEqual(driver.resolution, (resx, resy)) self.assertEqual(driver.array.shape, (site.py, site.px)) self.assertEqual(driver.nodata_value, 0) np.testing.assert_allclose(expected_img, driver.array, atol=1.5) FileSystem.remove_directory(dem_dir)
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)
def test_get_water_data_spain_s2(self): """ Download the given gsw file and project it to a 10km x 10km resolution (11x11 image) """ resx, resy = 10000, -10000 px, py = 11, 11 site = SiteInfo.Site("T30SYJ", 32630, px=px, py=py, ul=(699960.000, 4400040.000), lr=(809760.000, 4290240.000), res_x=resx, res_y=resy) dem_dir = os.path.join(os.getcwd(), "test_get_water_data_spain_s2") mnt = MNTBase.MNT(site, dem_dir=dem_dir, raw_dem=self.raw_dem, raw_gsw=self.raw_gsw) water_mask = mnt.gsw_dst self.assertTrue(os.path.exists(dem_dir)) mnt.prepare_water_data() self.assertTrue(os.path.exists(water_mask)) driver = GDalDatasetWrapper.from_file(water_mask) img_expected = [[0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1], [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1], [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1], [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1], [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1], [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1], [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1], [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1], [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1]] self.assertEqual(driver.resolution, (resx, resy)) self.assertEqual(driver.epsg, 32630) self.assertEqual(driver.array.shape, (py, px)) np.testing.assert_almost_equal(img_expected, driver.array) self.assertIsNone(driver.nodata_value) FileSystem.remove_directory(dem_dir)
def test_get_water_data_maccanw2_vns(self): resx, resy = 5000, -5000 px, py = 11, 14 site = SiteInfo.Site("MACCANW2", 32633, px=px, py=py, ul=(246439.500, 4672656.500), lr=(299769.500, 4604231.500), res_x=resx, res_y=resy) dem_dir = os.path.join(os.getcwd(), "test_get_water_data_maccanw2_vns") mnt = MNTBase.MNT(site, dem_dir=dem_dir, raw_dem=self.raw_dem, raw_gsw=self.raw_gsw) water_mask = mnt.gsw_dst self.assertTrue(os.path.exists(dem_dir)) mnt.prepare_water_data() self.assertTrue(os.path.exists(water_mask)) driver = GDalDatasetWrapper.from_file(water_mask) img_expected = [[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0]] self.assertEqual(driver.resolution, (resx, resy)) self.assertEqual(driver.epsg, 32633) self.assertEqual(driver.array.shape, (py, px)) np.testing.assert_almost_equal(img_expected, driver.array) self.assertIsNone(driver.nodata_value) FileSystem.remove_directory(dem_dir)
def test_get_water_data_tls_l8(self): resx, resy = 15000, -15000 px, py = 15, 14 site = SiteInfo.Site("19080", 32631, px=px, py=py, ul=(285431.584, 4884950.507), lr=(510124.885, 4680403.373), res_x=resx, res_y=resy) dem_dir = os.path.join(os.getcwd(), "test_get_water_data_tls_l8") mnt = MNTBase.MNT(site, dem_dir=dem_dir, raw_dem=self.raw_dem, raw_gsw=self.raw_gsw) water_mask = mnt.gsw_dst self.assertTrue(os.path.exists(dem_dir)) mnt.prepare_water_data() self.assertTrue(os.path.exists(water_mask)) driver = GDalDatasetWrapper.from_file(water_mask) img_expected = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] self.assertEqual(driver.resolution, (resx, resy)) self.assertEqual(driver.epsg, 32631) self.assertEqual(driver.array.shape, (py, px)) self.assertIsNone(driver.nodata_value) np.testing.assert_almost_equal(img_expected, driver.array) FileSystem.remove_directory(dem_dir)
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)
def test_srtm_prepare_mnt_s2_tls(self): resx, resy = 10000, -10000 site = SiteInfo.Site("T31TCJ", 32631, px=11, py=11, ul=(300000.000, 4900020.000), lr=(409800.000, 4790220.000), res_x=resx, res_y=resy) dem_dir = os.path.join(os.getcwd(), "test_srtm_prepare_mnt_s2_tls") s = SRTM.SRTM(site, dem_dir=dem_dir, raw_dem=self.raw_srtm, raw_gsw=self.raw_gsw, wdir=dem_dir) self.assertTrue(os.path.isdir(dem_dir)) srtm = s.prepare_mnt() self.assertTrue(os.path.isfile(srtm)) driver = GDalDatasetWrapper.from_file(srtm) expected_img = [ [85, 85, 115, 142, 138, 147, 151, 163, 162, 258, 282], [136, 98, 96, 90, 101, 91, 120, 118, 121, 243, 302], [137, 133, 135, 137, 101, 89, 92, 131, 162, 246, 294], [139, 144, 170, 184, 157, 115, 108, 132, 176, 210, 212], [148, 140, 161, 162, 206, 138, 133, 134, 150, 164, 160], [169, 173, 168, 171, 222, 168, 128, 158, 162, 151, 164], [193, 199, 181, 186, 186, 193, 158, 147, 189, 204, 199], [209, 223, 207, 195, 215, 215, 166, 161, 187, 214, 228], [240, 247, 225, 206, 268, 211, 172, 203, 195, 213, 242], [281, 268, 246, 272, 282, 216, 216, 208, 231, 211, 220], [335, 302, 319, 311, 265, 234, 262, 251, 236, 259, 250] ] self.assertEqual(driver.resolution, (resx, resy)) self.assertEqual(driver.array.shape, (site.py, site.px)) self.assertEqual(driver.nodata_value, 0) np.testing.assert_allclose(expected_img, driver.array, atol=1.5) FileSystem.remove_directory(dem_dir)
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)
def test_eudem_prepare_mnt_s2_tls(self): resx, resy = 10000, -10000 site = SiteInfo.Site("T31TCJ", 32631, ul=(300000.000, 4900020.000), lr=(409800.000, 4790220.000), px=11, py=11, res_x=resx, res_y=resy) dem_dir = os.path.join(os.getcwd(), "test_eudem_prepare_mnt_s2_31ucr") s = EuDEM.EuDEM(site, dem_dir=dem_dir, raw_dem=self.raw_eudem, raw_gsw=self.raw_gsw, wdir=dem_dir) self.assertTrue(os.path.isdir(dem_dir)) srtm = s.prepare_mnt() self.assertTrue(os.path.isfile(srtm)) driver = GDalDatasetWrapper.from_file(srtm) expected_img = [[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]] self.assertEqual(driver.resolution, (resx, resy)) self.assertEqual(driver.array.shape, (site.py, site.px)) self.assertEqual(driver.nodata_value, 0) np.testing.assert_allclose(expected_img, driver.array) FileSystem.remove_directory(dem_dir)
def test_srtm_prepare_mnt_l8_tls(self): resx, resy = 15000, -15000 px, py = 15, 14 site = SiteInfo.Site("19080", 32631, px=px, py=py, ul=(285431.584, 4884950.507), lr=(510124.885, 4680403.373), res_x=resx, res_y=resy) dem_dir = os.path.join(os.getcwd(), "test_srtm_prepare_mnt_l8_tls") s = SRTM.SRTM(site, dem_dir=dem_dir, raw_dem=self.raw_srtm, raw_gsw=self.raw_gsw, wdir=dem_dir) self.assertTrue(os.path.isdir(dem_dir)) srtm = s.prepare_mnt() self.assertTrue(os.path.isfile(srtm)) driver = GDalDatasetWrapper.from_file(srtm) expected_img = np.array([[ 126, 134, 125, 114, 88, 104, 144, 265, 266, 283, 388, 487, 592, 571, 617 ], [ 144, 139, 161, 177, 134, 117, 161, 198, 189, 205, 328, 487, 457, 444, 634 ], [ 166, 163, 164, 189, 177, 137, 156, 153, 198, 231, 384, 619, 698, 707, 638 ], [ 194, 201, 194, 188, 198, 154, 178, 205, 218, 196, 303, 634, 898, 925, 586 ], [ 216, 235, 223, 223, 226, 175, 194, 220, 234, 318, 462, 637, 752, 547, 275 ], [ 273, 287, 268, 283, 234, 222, 226, 227, 215, 423, 581, 548, 404, 246, 86 ], [ 429, 383, 352, 315, 277, 283, 265, 274, 269, 170, 148, 120, 72, 43, 27 ], [ 598, 472, 402, 387, 427, 379, 362, 328, 365, 291, 270, 328, 186, 114, 42 ], [ 1151, 897, 977, 763, 647, 814, 708, 596, 514, 458, 458, 576, 383, 231, 0 ], [ 1591, 1303, 1697, 1728, 1229, 1342, 1085, 1173, 1137, 829, 685, 513, 289, 158, 27 ], [ 2261, 2075, 1964, 2052, 1916, 2087, 1923, 1634, 1741, 1576, 1185, 490, 198, 36, -24 ], [ 1671, 1898, 2127, 2148, 1475, 1992, 2126, 2301, 2098, 1749, 1235, 1060, 448, 135, 159 ], [ 1264, 1283, 1496, 1520, 1529, 1398, 1684, 1735, 1472, 2044, 1949, 1344, 684, 374, 302 ], [ 871, 980, 988, 1052, 1401, 1051, 1526, 1479, 1487, 1457, 1253, 753, 567, 179, 32 ]]) self.assertEqual(driver.resolution, (resx, resy)) self.assertEqual(driver.array.shape, (site.py, site.px)) self.assertEqual(driver.nodata_value, 0) np.testing.assert_allclose(expected_img, driver.array, atol=1.5) FileSystem.remove_directory(dem_dir)