示例#1
0
文件: SRTM.py 项目: xiashenzhen/MAJA
    def prepare_mnt(self):
        """
        Prepare the srtm files.

        :return: Path to the full resolution DEM file.gsw
        :rtype: str
        """
        # Find/Download SRTM archives:
        srtm_archives = self.get_raw_data()
        # Unzip the downloaded/found srtm zip files:
        unzipped = []
        for arch in srtm_archives:
            basename = os.path.splitext(os.path.basename(arch))[0]
            FileSystem.unzip(arch, self.wdir)
            fn_unzipped = FileSystem.find_single(pattern=basename + ".tif", path=self.wdir)
            unzipped.append(fn_unzipped)
        # Fusion of all SRTM files
        concat = ImageTools.gdal_buildvrt(*unzipped, vrtnodata=-32768)
        # Set nodata to 0
        nodata = ImageTools.gdal_warp(concat,
                                      srcnodata=-32768,
                                      dstnodata=0,
                                      multi=True)
        # Combine to image of fixed extent
        srtm_full_res = os.path.join(self.wdir, "srtm_%sm.tif" % int(self.site.res_x))
        ImageTools.gdal_warp(nodata, dst=srtm_full_res,
                             r="cubic",
                             te=self.site.te_str,
                             t_srs=self.site.epsg_str,
                             tr=self.site.tr_str,
                             dstnodata=0,
                             srcnodata=0,
                             multi=True)
        return srtm_full_res
    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 _reproject_to_epsg(self, img, outpath, epsg):
     tmpfile = tempfile.mktemp(prefix="reproject_", suffix=".tif")
     ImageTools.gdal_warp(tmpfile,
                          img,
                          t_srs="EPSG:%s" % epsg,
                          tr=" ".join(map(str, self.base_resolution)),
                          q=True)
     shutil.move(tmpfile, outpath)
    def test_gdal_buildvrt_concatenate(self):
        from StartMaja.Common import FileSystem
        paths = []
        for i in range(1, 3, 1):
            img = np.ones((i, i, 2), np.int16) * i
            path = os.path.join(os.getcwd(), "test_gdal_merge_%s.tif" % i)
            ImageIO.write_geotiff(img, path, self.projection, self.coordinates)
            self.assertTrue(os.path.exists(path))
            paths.append(path)
        empty = os.path.join(os.getcwd(), "empty.vrt")
        driver = ImageTools.gdal_buildvrt(*paths, dst=empty,
                                          separate=True,
                                          srcnodata=0)
        expected = np.array([[[1, 0],
                              [0, 0]],
                             [[2, 2],
                              [2, 2]]], dtype=np.int16)

        np.testing.assert_almost_equal(driver.array, expected)
        self.assertEqual(driver.nodata_value, 0)
        self.assertEqual(driver.epsg, 32631)
        [FileSystem.remove_file(path) for path in paths]
        FileSystem.remove_file(empty)
        [self.assertFalse(os.path.exists(path)) for path in paths]
        self.assertFalse(os.path.exists(empty))
    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_extract_class_bit(self):
     mask = np.arange(0, 9).reshape(3, 3)
     class_to_extract = [3]
     value_type = "bit"
     expected = np.array([[0, 0, 0],
                          [0, 0, 0],
                          [0, 0, 1]])
     calculated = ImageTools.extract_class(mask, class_to_extract, value_type)
     np.testing.assert_array_almost_equal(expected, calculated)
示例#7
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)
 def test_get_nodata(self):
     expected_nodata = 42.0
     img = np.ones((self.height, self.width), np.int16)
     path = os.path.join(os.getcwd(), "test_get_nodata_init.tif")
     ImageIO.write_geotiff(img, path, self.projection, self.coordinates)
     ds = ImageTools.gdal_buildvrt(path, VRTNodata=expected_nodata)
     self.assertEqual(expected_nodata, ds.nodata_value)
     np.testing.assert_almost_equal(ds.nodata_mask, np.ones_like(img))
     FileSystem.remove_file(path)
     self.assertFalse(os.path.exists(path))
    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_normalize(self):
     img = np.arange(0, 9).reshape(3, 3)
     value_range_in = (0, 10)
     value_range_out = (0, 1)
     expected = np.array([[0, .1, .2],
                          [.3, .4, .5],
                          [.6, .7, .8]])
     calculated = ImageTools.normalize(img,
                                       value_range_in=value_range_in,
                                       value_range_out=value_range_out)
     np.testing.assert_array_almost_equal(expected, calculated)
 def test_extract_class_threshold(self):
     mask = np.arange(0, 25).reshape(5, 5)
     class_to_extract = 10
     value_type = "threshold"
     expected = np.array([[0, 0, 0, 0, 0],
                          [0, 0, 0, 0, 0],
                          [1, 1, 1, 1, 1],
                          [1, 1, 1, 1, 1],
                          [1, 1, 1, 1, 1]])
     calculated = ImageTools.extract_class(mask, class_to_extract, value_type)
     np.testing.assert_array_almost_equal(expected, calculated)
 def test_normalize_0to255(self):
     img = np.arange(-4, 5).reshape(3, 3) / 5
     value_range_in = (-1, 1)
     value_range_out = (0, 255)
     expected = np.array([[25.5, 51.,  76.5],
                          [102., 127.5, 153.],
                          [178.5, 204., 229.5]])
     calculated = ImageTools.normalize(img,
                                       value_range_in=value_range_in,
                                       value_range_out=value_range_out)
     np.testing.assert_array_almost_equal(expected, calculated)
    def test_gdal_buildvrt(self):
        path = os.path.join(os.getcwd(), "test_gdal_buildvrt.tif")
        vrt = os.path.join(os.getcwd(), "test_vrt.vrt")
        img = np.arange(-4, 5).reshape(3, 3) / 5

        ImageIO.write_geotiff(img, path, self.projection, self.coordinates)
        self.assertTrue(os.path.exists(path))
        driver = ImageTools.gdal_buildvrt(path, dst=vrt)
        self.assertTrue(os.path.exists(vrt))
        np.testing.assert_almost_equal(driver.array, img)
        FileSystem.remove_file(vrt)
        FileSystem.remove_file(path)
 def test_normalize_clip(self):
     img = np.arange(0, 9).reshape(3, 3)
     value_range_in = (0, 5)
     value_range_out = (0, 1)
     expected = np.array([[0, .2, .4],
                          [.6, .8, 1],
                          [1, 1, 1]])
     calculated = ImageTools.normalize(img,
                                       value_range_in=value_range_in,
                                       value_range_out=value_range_out,
                                       clip=True)
     np.testing.assert_array_almost_equal(expected, calculated)
示例#15
0
    def prepare_mnt(self):
        """
        Prepare the eudem files.

        :return: Path to the full resolution DEM file.gsw
        :rtype: str
        """
        # Find/Download EuDEM archives:
        eudem_files = self.get_raw_data()
        # Unzip the downloaded/found EuDEM zip files:
        unzipped = []
        for arch in eudem_files:
            basename = os.path.splitext(os.path.basename(arch))[0]
            FileSystem.unzip(arch, self.wdir)
            fn_unzipped = FileSystem.find_single(pattern=basename + ".TIF$",
                                                 path=self.wdir)
            unzipped.append(fn_unzipped)
        # Fusion of all EuDEM files
        ds_cropped = []
        for fn in unzipped:
            ds = ImageTools.gdal_warp(fn,
                                      of="GTiff",
                                      ot="Int16",
                                      r="cubic",
                                      te=self.site.te_str,
                                      t_srs=self.site.epsg_str,
                                      tr=self.site.tr_str,
                                      multi=True)
            ds.array[ds.array < self.lowest_allowed_height] = -32767
            ds_cropped.append(ds)
        eudem_full_res = os.path.join(self.wdir,
                                      "eudem_%sm.tif" % int(self.site.res_x))
        ImageTools.gdal_merge(*ds_cropped,
                              dst=eudem_full_res,
                              n=-32767,
                              a_nodata=0,
                              q=True)
        return eudem_full_res
 def test_gdal_translate(self):
     img = np.ones((self.height, self.width, 2), np.int16)
     path = os.path.join(os.getcwd(), "test_gdal_translate.tif")
     scaled = os.path.join(os.getcwd(), "scaled.tif")
     out_resolution = (20, -20)
     ImageIO.write_geotiff(img, path, self.projection, self.coordinates)
     self.assertTrue(os.path.exists(path))
     ds = ImageTools.gdal_translate(path, scaled,
                                    tr=" ".join([str(i) for i in out_resolution]),
                                    scale="0 1 0 255")
     self.assertEqual(ds.resolution, out_resolution)
     self.assertEqual(ds.array.shape, (self.height // 2, self.width // 2, 2))
     np.testing.assert_almost_equal(ds.array, 255)
     FileSystem.remove_file(path)
     FileSystem.remove_file(scaled)
 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_warp(self):
     img = np.ones((self.height, self.width, 2), np.int16)
     img_rescaled = np.ones((int(self.height/2), int(self.width/2), 2), np.int16)
     out_resolution = (20, -20)
     path = os.path.join(os.getcwd(), "test_gdal_warp.tif")
     scaled = os.path.join(os.getcwd(), "res_changed.tif")
     ImageIO.write_geotiff(img, path, self.projection, self.coordinates)
     self.assertTrue(os.path.exists(path))
     ds = ImageTools.gdal_warp(path, scaled,
                               tr=" ".join(str(e) for e in out_resolution),
                               r="max", q=True)
     self.assertTrue(os.path.isfile(scaled))
     self.assertEqual(ds.resolution, out_resolution)
     self.assertEqual(ds.array.shape, (self.height // 2, self.width // 2, 2))
     np.testing.assert_almost_equal(ds.array, img_rescaled)
     FileSystem.remove_file(path)
     FileSystem.remove_file(scaled)