Exemplo n.º 1
0
    def test_calculation_of_tie_point_grid_float_coords(self):
        # NOTE: This does not test against unequaly sized output of get_image_windows_to_match().

        # overwrite gt and prj
        ref = GeoArray(self.ref_path)
        ref.to_mem()
        ref.filePath = None
        tgt = GeoArray(self.tgt_path)
        tgt.to_mem()
        tgt.filePath = None

        ref.gt = [
            330000.19999996503, 10.00000001, 0.0, 5862000.7999997628, 0.0,
            -10.00000001
        ]
        # ref.gt = [330000.1, 10.1, 0.0, 5862000.1, 0.0, -10.1]
        tgt.gt = [
            335440.19999996503, 10.00000001, 0.0, 5866490.7999997628, 0.0,
            -10.00000001
        ]
        # tgt.gt = [330000.1, 10.1, 0.0, 5862000.1, 0.0, -10.1]

        # get instance of COREG_LOCAL object
        CRL = COREG_LOCAL(ref, tgt, **dict(CPUs=32, **self.coreg_kwargs))
        CRL.calculate_spatial_shifts()
Exemplo n.º 2
0
def coerce_to_geoarray(dataset):
    """ Attempt to coerce inputs of various types to a GeoArray object. """

    if isinstance(dataset, GeoArray):
        geo_array = dataset

    elif isinstance(dataset, gdal.Dataset):
        gt = dataset.GetGeoTransform()
        crs = dataset.GetProjection()
        crs_wkt = crs.ExportToWkt()
        geo_array = GeoArray(dataset, geotransform=gt, projection=crs_wkt)

    elif isinstance(dataset, np.memmap):
        ### Need to pass gt & crs_wkt as arguments...
        raise NotImplementedError

    # elif isinstance(dataset, hypro.spatial.RasterMap):
    #     raise NotImplementedError

    elif isinstance(dataset, Path):
        geo_array = GeoArray(str(dataset))

    elif type(dataset) is str:
        geo_array = GeoArray(dataset)

    else:
        raise TypeError(f'Cannot coerce type "{type(dataset)}" to GeoArray.')

    return geo_array
Exemplo n.º 3
0
    def setUpClass(cls) -> None:
        config = EnPTConfig(**config_for_testing_dlr)

        # get lons / lats
        with TemporaryDirectory() as td, ZipFile(config.path_l1b_enmap_image,
                                                 "r") as zf:
            zf.extractall(td)
            cls.L1_obj = L1B_Reader(config=config).read_inputdata(
                root_dir_main=td, compute_snr=False)

        cls.data2transform_vnir_sensorgeo_3D = cls.L1_obj.vnir.data
        cls.data2transform_vnir_sensorgeo_2D = cls.L1_obj.vnir.data[:, :,
                                                                    0]  # a single VNIR band in sensor geometry
        cls.gA2transform_vnir_mapgeo = GeoArray(
            config.path_dem)  # a DEM in map geometry given by the user
        cls.data2transform_swir_sensorgeo_3D = cls.L1_obj.swir.data
        cls.data2transform_swir_sensorgeo_2D = cls.L1_obj.swir.data[:, :,
                                                                    -1]  # a single SWIR band in sensor geometry
        cls.gA2transform_swir_mapgeo = GeoArray(
            config.path_dem)  # a DEM in map geometry given by the user

        cls.VS_SGT = VNIR_SWIR_SensorGeometryTransformer(
            lons_vnir=cls.L1_obj.meta.vnir.lons,
            lats_vnir=cls.L1_obj.meta.vnir.lats,
            lons_swir=cls.L1_obj.meta.swir.lons,
            lats_swir=cls.L1_obj.meta.swir.lats,
            prj_vnir=32632,
            prj_swir=32632,
            res_vnir=(30, 30),
            res_swir=(30, 30),
            resamp_alg='nearest',
            # radius_of_influence=45
        )
Exemplo n.º 4
0
    def test_shift_calculation_inmem_gAs_path_out_auto(self):
        """Test input parameter path_out='auto' in case input reference/ target image are in-memory GeoArrays."""
        ref = GeoArray(np.random.randint(1, 100, (1000, 1000)))
        tgt = GeoArray(np.random.randint(1, 100, (1000, 1000)))

        with self.assertRaises(ValueError):
            self.run_shift_detection_correction(ref, tgt,
                                                **dict(self.coreg_kwargs,
                                                       path_out='auto',
                                                       fmt_out='ENVI',
                                                       v=True))
Exemplo n.º 5
0
 def data(self, *geoArr_initArgs):
     if geoArr_initArgs[0] is not None:
         # TODO this must be able to handle subset inputs in tiled processing
         if isinstance(geoArr_initArgs[0], np.ndarray):
             self._data = GeoArray(geoArr_initArgs[0],
                                   geotransform=self._data.gt,
                                   projection=self._data.prj)
         else:
             self._data = GeoArray(*geoArr_initArgs)
     else:
         del self.data
Exemplo n.º 6
0
    def test_coreg_init_from_inMem_GeoArray(self):
        # get GeoArray instances
        self.ref_gA = GeoArray(self.ref_path)
        self.tgt_gA = GeoArray(self.tgt_path)

        # assure the raster data are in-memory
        self.ref_gA.to_mem()
        self.tgt_gA.to_mem()

        # get instance of COREG_LOCAL object
        self.CRL = COREG_LOCAL(self.ref_gA, self.tgt_gA, **self.coreg_kwargs)
Exemplo n.º 7
0
    def setUp(self):
        self.vnir_gA = GeoArray(np.random.randint(0, 255, (10, 10, 10)),
                                geotransform=(331185.0, 30.0, -0.0, 5840115.0, -0.0, -30.0),
                                projection=CRS(32633).to_wkt())
        self.swir_gA = GeoArray(np.random.randint(0, 255, (10, 10, 20)),
                                geotransform=(331185.0, 30.0, -0.0, 5840115.0, -0.0, -30.0),
                                projection=CRS(32633).to_wkt())
        self.vnir_wvls = np.arange(900, 1000, 10)
        self.swir_wvls = np.arange(935, 1135, 10)

        self.VSSt = VNIR_SWIR_Stacker(vnir=self.vnir_gA, swir=self.swir_gA,
                                      vnir_wvls=self.vnir_wvls, swir_wvls=self.swir_wvls)
Exemplo n.º 8
0
    def test_shift_calculation_different_geographic_datum(self):
        """Test if shift computation properly raises a RunTimeError if the matching window is centered at a cloudy
        image position.
        """

        ref = GeoArray(self.ref_path).to_mem()
        tgt = GeoArray(self.tgt_path).to_mem()

        # force to overwrite projection
        ref.filePath = None
        ref.prj = EPSG2WKT(3035)  # ETRS89_LAEA_Europe

        with self.assertRaises(RuntimeError):
            self.run_shift_detection_correction(ref, tgt, **dict(self.coreg_kwargs))
Exemplo n.º 9
0
    def _Kriging_sp(self, attrName, skip_nodata=1, skip_nodata_col='ABS_SHIFT', outGridRes=None,
                    fName_out=None, tilepos=None):
        GDF = self.CoRegPoints_table
        GDF2pass = GDF if not skip_nodata else GDF[GDF[skip_nodata_col] != self.outFillVal]

        X_coords, Y_coords, ABS_SHIFT = GDF2pass['X_UTM'], GDF2pass['Y_UTM'], GDF2pass[attrName]

        xmin, ymin, xmax, ymax = GDF2pass.total_bounds

        grid_res = outGridRes if outGridRes else int(min(xmax - xmin, ymax - ymin) / 250)
        grid_x, grid_y = np.arange(xmin, xmax + grid_res, grid_res), np.arange(ymax, ymin - grid_res, -grid_res)

        # Reference: P.K. Kitanidis, Introduction to Geostatistcs: Applications in Hydrogeology,
        #            (Cambridge University Press, 1997) 272 p.
        from pykrige.ok import OrdinaryKriging
        OK = OrdinaryKriging(X_coords, Y_coords, ABS_SHIFT, variogram_model='spherical', verbose=False)
        zvalues, sigmasq = OK.execute('grid', grid_x, grid_y, backend='C', n_closest_points=12)

        if self.CPUs is None or self.CPUs > 1:
            fName_out = fName_out if fName_out else \
                "Kriging__%s__grid%s_ws%s_%s.tif" % (attrName, self.grid_res, self.COREG_obj.win_size_XY, tilepos)
        else:
            fName_out = fName_out if fName_out else \
                "Kriging__%s__grid%s_ws%s.tif" % (attrName, self.grid_res, self.COREG_obj.win_size_XY)
        path_out = get_generic_outpath(dir_out=self.dir_out, fName_out=fName_out)
        # add a half pixel grid points are centered on the output pixels
        xmin, ymin, xmax, ymax = xmin - grid_res / 2, ymin - grid_res / 2, xmax + grid_res / 2, ymax + grid_res / 2

        GeoArray(zvalues,
                 geotransform=(xmin, grid_res, 0, ymax, 0, -grid_res),
                 projection=self.COREG_obj.shift.prj).save(path_out)

        return zvalues
Exemplo n.º 10
0
    def compute_stack(self, algorithm: str) -> GeoArray:
        """Stack VNIR and SWIR bands with respect to their spectral overlap.

        :param algorithm:   'order_by_wvl': keep spectral bands unchanged, order bands by wavelength
                            'average':      average the spectral information within the overlap
                            'vnir_only':    only use the VNIR bands (cut overlapping SWIR bands)
                            'swir_only':    only use the SWIR bands (cut overlapping VNIR bands)
        :return:    the stacked data cube as GeoArray instance
        """
        # TODO: This should also set an output nodata value.
        if algorithm == 'order_by_wvl':
            data_stacked, wvls = self._get_stack_order_by_wvl()
        elif algorithm == 'average':
            data_stacked, wvls = self._get_stack_average()
        elif algorithm == 'vnir_only':
            data_stacked, wvls = self._get_stack_vnir_only()
        elif algorithm == 'swir_only':
            data_stacked, wvls = self._get_stack_swir_only()
        else:
            raise ValueError(algorithm)

        gA_stacked = GeoArray(data_stacked,
                              geotransform=self.vnir.gt, projection=self.vnir.prj, nodata=self.vnir.nodata)
        gA_stacked.meta.band_meta['wavelength'] = list(wvls)

        return gA_stacked
Exemplo n.º 11
0
    def get_flat_dem_from_average_elevation(cls,
                                            corner_coords_lonlat,
                                            average_elevation,
                                            xres=30,
                                            yres=30):
        """Return a 'flat DEM' instance of DEM_Processor.

        (a GeoArray fully covering the given coorner coordinates with the average elevation as pixel values)

        :param corner_coords_lonlat:    corner coordinates to be covered by the output DEM
        :param average_elevation:       average elevation in meters
        :param xres:                    x-resolution in meters
        :param yres:                    y-resolution in meters
        :return:
        """
        # compute the dimensions of the flat output DEM
        tgt_utm_epsg = get_UTMEPSG_from_LonLat(
            *get_center_coord(corner_coords_lonlat))
        corner_coords_utm = [
            transform_any_prj(prj_src=4326, prj_tgt=tgt_utm_epsg, x=x, y=y)
            for x, y in corner_coords_lonlat
        ]
        x_all, y_all = list(zip(*corner_coords_utm))
        cols = int(np.ceil((max(x_all) - min(x_all)) / xres)) + 2
        rows = int(np.ceil((max(y_all) - min(y_all)) / yres)) + 2

        # get a GeoArray instance
        dem_gA = GeoArray(np.full((rows, cols), fill_value=average_elevation),
                          geotransform=(np.floor(min(x_all)) - xres, xres, 0,
                                        np.ceil(max(y_all)) + yres, 0, -yres),
                          projection=CRS(tgt_utm_epsg).to_wkt())

        return cls(dem_gA, corner_coords_lonlat)
Exemplo n.º 12
0
    def _get_enmap_band_for_matching(self)\
            -> GeoArray:
        """Return the EnMAP band to be used in co-registration in the projection of the reference image."""
        self._EnMAP_Im.logger.warning(
            'Statically using band 40 for co-registration.')
        bandidx = 39  # FIXME hardcoded
        enmap_band_sensorgeo = self._EnMAP_Im.vnir.data[:, :, bandidx]

        # transform from sensor to map geometry to make it usable for tie point detection
        self._EnMAP_Im.logger.info(
            'Temporarily transforming EnMAP band %d to map geometry for co-registration.'
            % (bandidx + 1))
        GT = Geometry_Transformer(lons=self._EnMAP_Im.meta.vnir.lons[:, :,
                                                                     bandidx],
                                  lats=self._EnMAP_Im.meta.vnir.lats[:, :,
                                                                     bandidx],
                                  fill_value=0,
                                  resamp_alg='gauss',
                                  radius_of_influence=30,
                                  nprocs=self.cfg.CPUs)

        self._EnMAP_band = \
            GeoArray(*GT.to_map_geometry(enmap_band_sensorgeo,
                                         tgt_prj=self._ref_Im.prj,  # TODO correct?
                                         tgt_coordgrid=self._ref_Im.xygrid_specs),
                     nodata=0)

        return self._EnMAP_band
Exemplo n.º 13
0
    def to_map_geometry(self,
                        path_or_geoarray_sensorgeo: Union[str, GeoArray,
                                                          np.ndarray],
                        tgt_prj: Union[str, int] = None,
                        tgt_extent: Tuple[float, float, float, float] = None,
                        tgt_res: Tuple[float, float] = None,
                        tgt_coordgrid: Tuple[Tuple, Tuple] = None,
                        area_definition: AreaDefinition = None):
        data_sensorgeo = GeoArray(path_or_geoarray_sensorgeo)

        if data_sensorgeo.is_map_geo:
            raise RuntimeError(
                'The dataset to be transformed into map geometry already represents map geometry.'
            )

        # run transformation (output extent/area definition etc. is internally computed from the geolayers if not given)
        out_data, out_gt, out_prj = \
            super(Geometry_Transformer, self).to_map_geometry(data_sensorgeo[:],
                                                              tgt_prj=tgt_prj,
                                                              tgt_extent=tgt_extent,
                                                              tgt_res=tgt_res,
                                                              tgt_coordgrid=tgt_coordgrid,
                                                              area_definition=self.area_definition)

        return out_data, out_gt, out_prj
Exemplo n.º 14
0
    def __init__(self,
                 filepath='',
                 satellite='',
                 sensor='',
                 LayerBandsAssignment=None):
        # type: (str, str, str, list) -> None
        """Get instance of RefCube.

        :param filepath:                file path for importing an existing reference cube from disk
        :param satellite:               the satellite for which the reference cube holds its spectral data
        :param sensor:                  the sensor for which the reference cube holds its spectral data
        :param LayerBandsAssignment:    the LayerBandsAssignment for which the reference cube holds its spectral data
        """
        # privates
        self._col_imName_dict = dict()
        self._wavelenths = []

        # defaults
        self.data = GeoArray(np.empty(
            (0, 0, len(LayerBandsAssignment) if LayerBandsAssignment else 0)),
                             nodata=-9999)
        self.srcImNames = []

        # args/ kwargs
        self.filepath = filepath
        self.satellite = satellite
        self.sensor = sensor
        self.LayerBandsAssignment = LayerBandsAssignment or []

        if filepath:
            self.read_data_from_disk(filepath)

        if self.satellite and self.sensor and self.LayerBandsAssignment:
            self._add_bandnames_wavelenghts_to_meta()
Exemplo n.º 15
0
    def correct_shifts(self,
                       max_GCP_count: int = None,
                       cliptoextent: bool = False,
                       min_points_local_corr: int = 5) -> OrderedDict:
        """Perform a local shift correction using all points from the previously calculated tie point grid.

        NOTE: Only valid matches are used as GCP points.

        :param max_GCP_count: maximum number of GCPs to use
        :param cliptoextent:  whether to clip the output image to its real extent
        :param min_points_local_corr:   number of valid tie points, below which a global shift correction is
                                        performed instead of a local correction (global X/Y shift is then computed as
                                        the mean shift of the remaining points)(default: 5 tie points)
        :return:
        """
        if not self._tiepoint_grid:
            self.calculate_spatial_shifts()

        if self.tiepoint_grid.GCPList:
            if max_GCP_count:
                self.coreg_info['GCPList'] = self.coreg_info[
                    'GCPList'][:max_GCP_count]

            # make sure the correction is applied to the original target image
            im2shift = GeoArray(self.params['im_tgt'],
                                nodata=self.nodata[1],
                                progress=self.progress,
                                q=self.q)

            if has_metaRotation(im2shift):
                # resample the target image because (so far) the computed shifts cannot be applied to a dataset with
                # a metadata rotation (GDAL GeoTransform not 0 at positons 2 and 4)
                im2shift = remove_metaRotation(im2shift)

            # apply the correction
            DS = DESHIFTER(
                im2shift,
                self.coreg_info,
                path_out=self.path_out,
                fmt_out=self.fmt_out,
                out_crea_options=self.out_creaOpt,
                align_grids=self.align_grids,
                match_gsd=self.match_gsd,
                out_gsd=self.out_gsd,
                target_xyGrid=self.target_xyGrid,
                min_points_local_corr=min_points_local_corr,
                resamp_alg=self.rspAlg_DS,
                cliptoextent=cliptoextent,
                # clipextent=self.im2shift.box.boxMapYX,
                progress=self.progress,
                v=self.v,
                q=self.q)

            self.deshift_results = DS.correct_shifts()
            return self.deshift_results
        else:
            if not self.q:
                warnings.warn(
                    'Correction of geometric shifts failed because the input GCP list is empty!'
                )
Exemplo n.º 16
0
    def test_shift_calculation_noWGS84(self):
        """Test if shift computation properly raises a RunTimeError if the matching window is centered at a cloudy
        image position.
        """

        ref = GeoArray(self.ref_path).to_mem()
        tgt = GeoArray(self.tgt_path).to_mem()

        # force to overwrite projection
        ref.filePath = None
        tgt.filePath = None
        ref.prj = EPSG2WKT(3035)  # ETRS89_LAEA_Europe
        tgt.prj = EPSG2WKT(3035)  # ETRS89_LAEA_Europe

        CR = self.run_shift_detection_correction(ref, tgt, **dict(self.coreg_kwargs))
        self.assertTrue(CR.success)
Exemplo n.º 17
0
    def __init__(self, rpc_coeffs: dict, elevation: Union[str, GeoArray, int,
                                                          float],
                 enmapIm_cornerCoords: Tuple[Tuple[float, float]],
                 enmapIm_dims_sensorgeo: Tuple[int, int]):
        """Get an instance of RPC_Geolayer_Generator.

        :param rpc_coeffs:              RPC coefficients for a single EnMAP band
        :param elevation:               digital elevation model in map geometry (file path or instance of GeoArray) OR
                                        average elevation in meters as integer or float
        :param enmapIm_cornerCoords:    corner coordinates as tuple of lon/lat pairs
        :param enmapIm_dims_sensorgeo:  dimensions of the EnMAP image in sensor geometry (rows, colunms)
        """
        self.row_off = rpc_coeffs['row_off']
        self.col_off = rpc_coeffs['col_off']
        self.lat_off = rpc_coeffs['lat_off']
        self.lon_off = rpc_coeffs['long_off']
        self.height_off = rpc_coeffs['height_off']
        self.row_scale = rpc_coeffs['row_scale']
        self.col_scale = rpc_coeffs['col_scale']
        self.lat_scale = rpc_coeffs['lat_scale']
        self.lon_scale = rpc_coeffs['long_scale']
        self.height_scale = rpc_coeffs['height_scale']
        self.row_num_coeffs = rpc_coeffs['row_num_coeffs']
        self.row_den_coeffs = rpc_coeffs['row_den_coeffs']
        self.col_num_coeffs = rpc_coeffs['col_num_coeffs']
        self.col_den_coeffs = rpc_coeffs['col_den_coeffs']

        self.elevation = elevation if isinstance(
            elevation, (int, float)) else GeoArray(elevation)
        self.enmapIm_cornerCoords = enmapIm_cornerCoords
        self.enmapIm_dims_sensorgeo = enmapIm_dims_sensorgeo
Exemplo n.º 18
0
    def to_map_geometry(self,
                        path_or_geoarray_sensorgeo: Union[str, GeoArray,
                                                          np.ndarray],
                        tgt_prj: Union[str, int] = None,
                        tgt_extent: Tuple[float, float, float, float] = None,
                        tgt_res: Tuple[float, float] = None,
                        tgt_coordgrid: Tuple[Tuple, Tuple] = None,
                        area_definition: AreaDefinition = None):
        data_sensorgeo = GeoArray(path_or_geoarray_sensorgeo)

        if data_sensorgeo.is_map_geo:
            raise RuntimeError(
                'The dataset to be transformed into map geometry already represents map geometry.'
            )

        # run transformation (output extent/area definition etc. is internally computed from the geolayers if not given)
        with warnings.catch_warnings():
            # FIXME remove that after removing pyresample pinning
            warnings.filterwarnings(
                'ignore',
                category=DeprecationWarning,
                message='.*is a deprecated alias for the builtin.*')

            out_data, out_gt, out_prj = \
                super(Geometry_Transformer, self).to_map_geometry(data_sensorgeo[:],
                                                                  tgt_prj=tgt_prj,
                                                                  tgt_extent=tgt_extent,
                                                                  tgt_res=tgt_res,
                                                                  tgt_coordgrid=tgt_coordgrid,
                                                                  area_definition=self.area_definition)

        return out_data, out_gt, out_prj
Exemplo n.º 19
0
 def test_cluster_image_and_get_uniform_samples(self):
     src_im = self.SHC.ims_ref[0]
     baseN = os.path.splitext(os.path.basename(src_im))[0]
     unif_random_spectra = self.SHC.cluster_image_and_get_uniform_spectra(
         src_im, basename_clf_dump=baseN)
     self.assertIsInstance(unif_random_spectra, np.ndarray)
     self.assertEqual(unif_random_spectra.shape,
                      (self.tgt_n_samples, GeoArray(src_im).bands))
Exemplo n.º 20
0
    def setUpClass(cls):
        cls.geoArr = GeoArray(testdata)
        cls.geoArr.to_mem()

        # get RSR instance for Landsat-8
        cls.rsr_l8 = RSR(satellite='Landsat-8',
                         sensor='OLI_TIRS',
                         no_thermal=True)
Exemplo n.º 21
0
def interpolate_1x1(lon, lat, values, lon0=0.):
    """ Make a regional mean and get a time series
    """
    newlon, newlat, newvalues = grid.interpolate_1x1(lon,
                                                     lat,
                                                     values,
                                                     lon0=lon0)
    return GeoArray(newvalues, lat=newlat, lon=newlon)
Exemplo n.º 22
0
    def setUpClass(cls):
        cls.geoArr = GeoArray(testdata, nodata=-9999)
        cls.geoArr.to_mem()
        cls.geoArr[:10, :10, :10] = -9999  # simulate some pixels that have nodata in some bands (unusable for KMeans)

        cls.kmeans = KMeansRSImage(cls.geoArr, n_clusters=5,
                                   sam_classassignment=False)

        os.environ['MPLBACKEND'] = 'Template'  # disables matplotlib figure popups # NOTE: import geoarray sets 'Agg'
Exemplo n.º 23
0
    def test_init_demTooSmall(self):
        # covers only 100x100 px in the upper left (<5%)
        dem = GeoArray(np.random.randint(0, 500, (100, 100)),
                       geotransform=(626938.928052, 30.0, 0, 5267203.56579, 0,
                                     -30.0),
                       projection=CRS(32632).to_wkt())

        with self.assertRaises(ValueError):
            DEM_Processor(dem, enmapIm_cornerCoords=self.ll_cornerCoords)
Exemplo n.º 24
0
 def test_init_noWGS84(self):
     # NAD83 projection ({'proj': 'longlat', 'ellps': 'GRS80', 'towgs84': '0,0,0,0,0,0,0'})
     with self.assertRaises(ValueError):
         dem = GeoArray(
             np.array([1, 2]),
             geotransform=(10.6, 0.00036, -0.0, 47.5, -0.0,
                           -0.00036),  # can be anything
             projection=CRS(4269).to_wkt())  # NAD83
         DEM_Processor(dem, enmapIm_cornerCoords=self.ll_cornerCoords)
Exemplo n.º 25
0
    def __init__(self, config: EnPTConfig):
        """Create an instance of Spatial_Optimizer."""
        self.cfg = config
        self._ref_Im: Optional[GeoArray,
                               None] = GeoArray(self.cfg.path_reference_image)

        self._EnMAP_Im: Optional[EnMAPL1Product_SensorGeo, None] = None
        self._EnMAP_band: Optional[GeoArray, None] = None
        self._EnMAP_mask: Optional[GeoArray, None] = None
Exemplo n.º 26
0
    def __init__(self,
                 dem_path_geoarray: Union[str, GeoArray],
                 enmapIm_cornerCoords: Tuple[Tuple[float, float]],
                 CPUs: int = None):
        self.dem = GeoArray(dem_path_geoarray)
        self.enmapIm_cornerCoords = enmapIm_cornerCoords
        self.CPUs = CPUs or cpu_count()

        self._set_nodata_if_not_provided()
        self._validate_input()
Exemplo n.º 27
0
    def test_shift_calculation_nonquadratic_pixels(self):
        """Test with default parameters - should compute X/Y shifts properly and write the de-shifted target image."""

        # overwrite gt and prj
        ref = GeoArray(self.ref_path)
        ref.to_mem()
        ref.filePath = None
        ref.gt = [330000.00000001, 5.8932, 0.0, 5862000.0000001, 0.0, -10.1]
        tgt = GeoArray(self.tgt_path)
        tgt.to_mem()
        tgt.filePath = None
        tgt.gt = [335440.0000001, 5.8933, 0.0, 5866490.0000001, 0.0, -10.1]

        CR = self.run_shift_detection_correction(ref, tgt,
                                                 **dict(self.coreg_kwargs,
                                                        wp=(341500.0, 5861440.0),
                                                        footprint_poly_ref=None,
                                                        footprint_poly_tgt=None))
        self.assertTrue(CR.success)
Exemplo n.º 28
0
    def get_preprocessed_dem(self) -> GeoArray:
        """Get a digital elevation model in EnMAP sensor geometry of the current detector."""
        if self.cfg.path_dem:
            self.logger.info('Pre-processing DEM for %s...' %
                             self.detector_name)
            DP = DEM_Processor(self.cfg.path_dem,
                               enmapIm_cornerCoords=tuple(
                                   zip(self.detector_meta.lon_UL_UR_LL_LR,
                                       self.detector_meta.lat_UL_UR_LL_LR)),
                               CPUs=self.cfg.CPUs)
            DP.fill_gaps()  # FIXME this will also be needed at other places

            R, C = self.data.shape[:2]
            if DP.dem.is_map_geo:
                lons = self.detector_meta.lons
                lats = self.detector_meta.lats

                if not (lons.ndim == 2 and lats.ndim
                        == 2) and not (lons.ndim == 3 and lats.ndim == 3):
                    raise ValueError(
                        (lons.ndim, lats.ndim),
                        'Geolayer must be either 2- or 3-dimensional.')

                msg_bandinfo = ''
                if lons.ndim == 3:
                    # 3D geolayer (the usual case for EnMAP data provided by DLR)
                    lons = lons[:, :, 0]
                    lats = lats[:, :, 0]
                    msg_bandinfo = ' (using first band of %s geolayer)' % self.detector_name
                else:
                    # 2D geolayer (GFZ-internal test case)
                    # FIXME replace linear interpolation by native geolayers
                    if lons.shape != self.data.shape:
                        lons = self.detector_meta.interpolate_corners(
                            *self.detector_meta.lon_UL_UR_LL_LR, nx=C, ny=R)
                    if lats.shape != self.data.shape:
                        lats = self.detector_meta.interpolate_corners(
                            *self.detector_meta.lat_UL_UR_LL_LR, nx=C, ny=R)

                self.logger.info(
                    ('Transforming DEM to %s sensor geometry%s...' %
                     (self.detector_name, msg_bandinfo)))
                self.dem = DP.to_sensor_geometry(lons=lons, lats=lats)
            else:
                self.dem = DP.dem

        else:
            self.logger.info(
                'No DEM for the %s detector provided. Falling back to an average elevation of %d meters.'
                % (self.detector_name, self.cfg.average_elevation))
            self.dem = GeoArray(
                np.full(self.data.shape[:2],
                        self.cfg.average_elevation).astype(np.int16))

        return self.dem
Exemplo n.º 29
0
def arosics_test():
    """
    测试几何校正工具
    See https://gitext.gfz-potsdam.de/danschef/arosics
    https://www.mdpi.com/2072-4292/9/7/676

    """
    # Global coregistration test
    from geoarray import GeoArray
    from arosics import COREG

    im_reference = r'I:\sentinel\unzip\T49QEE_20180930T030541_B08.jp2'
    im_target = r'I:\sentinel\unzip\T49QEE_20181005T030549_B08.jp2'
    # im_target = r'D:\T50QKM_geo.tif'
    # get a sample numpy array with corresponding geoinformation as reference
    geoArr = GeoArray(im_reference)

    ref_ndarray = geoArr[:]  # numpy.ndarray with shape (10980, 10980)
    ref_gt = geoArr.geotransform  # GDAL geotransform
    ref_prj = geoArr.projection  # projection as WKT string

    # get a sample numpy array with corresponding geoinformation as target
    geoArr = GeoArray(im_target)

    tgt_ndarray = geoArr[:]  # numpy.ndarray with shape (10980, 10980)
    tgt_gt = geoArr.geotransform  # GDAL geotransform
    tgt_prj = geoArr.projection  # projection as WKT string

    # pass an instance of GeoArray to COREG and calculate spatial shifts
    geoArr_reference = GeoArray(ref_ndarray, ref_gt, ref_prj)
    geoArr_target = GeoArray(tgt_ndarray, tgt_gt, tgt_prj)

    CR = COREG(geoArr_reference,
               geoArr_target,
               path_out='D:/T49QEE_20181005_correct.tif',
               wp=(595951, 2480095),
               ws=(256, 256),
               v=True,
               max_iter=20,
               max_shift=100)
    CR.calculate_spatial_shifts()
    CR.correct_shifts()
Exemplo n.º 30
0
def remove_metaRotation(gA_rot: GeoArray, rspAlg='cubic') -> GeoArray:
    """Remove any metadata rotation (a rotation that only exists in the map info)."""
    gA = GeoArray(*warp_ndarray(gA_rot[:], gA_rot.gt, gA_rot.prj,
                                rspAlg=rspAlg,
                                # out_gsd=(gA_rot.xgsd, gA_rot.ygsd)
                                ),
                  nodata=gA_rot.nodata)
    gA.basename = os.path.basename(gA.basename)
    gA.meta = gA.meta

    return gA