예제 #1
0
    def _calculate_grid_edges(self, var_name):
        """Calculate coordinate grid from product's projection."""
        from osgeo.gdal import Open
        from osgeo import osr

        variable = Open(var_name)

        sin = osr.SpatialReference()
        sin.ImportFromWkt(variable.GetProjection())

        wgs84 = osr.SpatialReference()
        wgs84.ImportFromEPSG(4326)

        tx = osr.CoordinateTransformation(sin, wgs84)
        transform = np.vectorize(tx.TransformPoint)

        # +1 as we want grid cell edges
        x0, dx, _, y0, _, dy = variable.GetGeoTransform()
        x_ = x0 + dx * np.arange(variable.RasterXSize + 1)
        y_ = y0 + dy * np.arange(variable.RasterYSize + 1)
        x, y = np.meshgrid(x_, y_)
        lat_edges, lon_edges, _ = transform(x, y)

        def make_corner_list(arr):
            """Ravel a grid of cell edges into an ordered list of corners."""
            from acp_utils import rolling_window
            out = rolling_window(arr, (2, 2))
            out = out.reshape(out.shape[:-2] + (4, ))
            out[..., 2:4] = out[..., [3, 2]]
            return out

        lat_bounds = make_corner_list(lat_edges)
        lon_bounds = make_corner_list(lon_edges)

        return lat_bounds, lon_bounds
예제 #2
0
    def test_phase_data_properties(self):
        # Use raw GDAL to isolate raster reading from Ifg functionality
        ds = Open(self.ifg.data_path)
        data = ds.GetRasterBand(1).ReadAsArray()
        del ds

        self.ifg.open()

        # test full array and row by row access
        assert_array_equal(data, self.ifg.phase_data)
        for y, row in enumerate(self.ifg.phase_rows):
            assert_array_equal(data[y], row)

        # test the data is cached if changed
        crd = (5, 4)
        orig = self.ifg.phase_data[crd]
        self.ifg.phase_data[crd] *= 2
        nv = self.ifg.phase_data[crd]  # pull new value out again
        self.assertEqual(nv, 2 * orig)
예제 #3
0
    def load_dem() -> Dataset:
        """
        Loads the file 'dem.tif' on the current system.

        Returns
        -------
        Dataset
            The example digital elevation model.

        """
        file_path = PkgDataAccess.locate_dem()
        LOG.info("Reading DEM from '%s' ...", file_path)
        dem = Open(file_path)
        return dem
예제 #4
0
    def _calculate_grid_centres(self, var_name):
        """Calculate coordinates of cell centres from project's projection"""
        from osgeo.gdal import Open
        from osgeo import osr

        variable = Open(var_name)

        sin = osr.SpatialReference()
        sin.ImportFromWkt(variable.GetProjection())

        wgs84 = osr.SpatialReference()
        wgs84.ImportFromEPSG(4326)

        tx = osr.CoordinateTransformation(sin, wgs84)
        transform = np.vectorize(tx.TransformPoint)

        x0, dx, _, y0, _, dy = variable.GetGeoTransform()
        x_ = x0 + dx * np.arange(0.5, variable.RasterXSize)
        y_ = y0 + dy * np.arange(0.5, variable.RasterYSize)
        x, y = np.meshgrid(x_, y_)
        lat_data, lon_data, _ = transform(x, y)

        return lat_data, lon_data
예제 #5
0
def _convert_to_tif(
    partial_coverage_tiles: List[PartialCoverageTile], wms_crs_code: str
) -> None:
    for tile in partial_coverage_tiles:
        if os.path.exists(tile.wms_path):
            logging.debug(f"Converting {tile.wms_path} to {tile.tif_path}")
            src_file = Open(tile.wms_path, GA_ReadOnly)
            Translate(
                tile.tif_path,
                src_file,
                format="GTiff",
                noData=None,
                outputSRS=wms_crs_code,
                # Translate expects bounds in format ulX, ulY, lrX, lrY so flip minY and maxY
                outputBounds=(tile.x_min, tile.y_max, tile.x_max, tile.y_min),
            )
            if remove_intermediaries():
                os.remove(tile.wms_path)
        else:
            logging.warn(f"Expected file {tile.wms_path} does not exist")
예제 #6
0
    def __init__(
        self,
        dem_path: str,
        model_name: Optional[str] = None,
        ela: int = 2850,
        m: float = 0.006,
        plot: bool = True,
    ) -> None:
        """
        Class constructor for the GlacierFlowModel class.

        Parameters
        ----------
        dem_path : str
            Path to the file that holds the DEM.
        model_name: Optional[str]
            Name of the model, if not provided the name of the input dem file
            without extension is set.
        ela : int, default 2850
            The equilibrium-line altitude (ELA) marks the area or zone on
            a glacier where accumulation is balanced by ablation over a 1-year
            period.
        m : float, default 0.006
            Glacier mass balance gradient [m/m], the linear relationship
            between altitude and mass balance.
        plot : bool, default True
            Visualization of the simulation process.

        Returns
        -------
        None

        """

        # Load DEM ------------------------------------------------------------
        dem = Open(dem_path)
        band = dem.GetRasterBand(1)
        ele = band.ReadAsArray().astype(np.float32)

        # Instance variables --------------------------------------------------
        self.model_name = Path(
            dem_path).stem if model_name is None else model_name
        self.dem_path = dem_path

        # Mass balance parameters
        self.m = m  # Mass balance gradient
        self.ela_start = ela  # Equilibrium line altitude
        self._setup_params()  # Variable parameters (i, ela, steady_state)

        # 2D arrays
        self.ele_orig = np.copy(ele)  # Original topography
        self._setup_ndarrays()  # Variable arrays (ele, h, u ,hs)

        # Coordinate reference system and dem resolution
        self._geo_trans = dem.GetGeoTransform()
        self._geo_proj = dem.GetProjection()
        self.res = self._geo_trans[1]

        # Geographical extent of the dem
        nrows, ncols = ele.shape
        x0, dx, dxdy, y0, dydx, dy = self._geo_trans
        x1 = x0 + dx * ncols
        y1 = y0 + dy * nrows
        self.extent = (x0, x1, y1, y0)

        # Setup statistics
        self._setup_stats()

        # Setup plot
        self.plot = plot
예제 #7
0
    def _calculate_grid_time(self, var_name, lat_data, lon_data):
        """Approximate time from a pair of corresponding MOD03 files"""
        from osgeo.gdal import Open
        from scipy.interpolate import griddata

        def fetch_MOD03_coordinates(start_time, aqua=False):
            import os.path
            from glob import glob
            from pyhdf.SD import SD
            from pyhdf.error import HDF4Error

            # Locate MOD03 file
            search_path = start_time.strftime(
                os.path.join(self.mod03_path, "MOD03.A%Y%j.%H%M.061*hdf"))
            if aqua:
                # NOTE: System dependent approximation
                search_path = search_path.replace("MOD", "MYD")
            try:
                mod03_file = glob(search_path)[0]
            except IndexError:
                raise FileNotFoundError("MOD03: " + search_path)

            # Read space-time grid from that file
            try:
                file_object = SD(mod03_file)
                dims = file_object.datasets()["Longitude"][1]
                count = dims[0] // 10, dims[1] // 10
                mod_lon = _get_hdf_data(file_object,
                                        "Longitude",
                                        start=(0, 2),
                                        count=count,
                                        stride=(10, 10))
                mod_lat = _get_hdf_data(file_object,
                                        "Latitude",
                                        start=(0, 2),
                                        count=count,
                                        stride=(10, 10))
                mod_time = _get_hdf_data(file_object,
                                         "EV start time",
                                         count=count[:1])
                file_object.end()
            except HDF4Error:
                raise IOError("Corrupted file: " + mod03_file)

            return mod_lon, mod_lat, mod_time

        time_data = []
        variable = Open(var_name)
        meta = variable.GetMetadata_Dict()
        for timestamp in meta["Orbit_time_stamp"].split():
            # Parse time stamp
            start_time = dt.datetime.strptime(timestamp[:-1], "%Y%j%H%M")

            try:
                # Interpolate time from MOD03 files
                mod_lon0, mod_lat0, mod_time0 = fetch_MOD03_coordinates(
                    start_time - dt.timedelta(seconds=300),
                    timestamp[-1] == "A")
                mod_lon1, mod_lat1, mod_time1 = fetch_MOD03_coordinates(
                    start_time, timestamp[-1] == "A")
                mod_lon = concatenate([mod_lon0, mod_lon1])
                mod_lat = concatenate([mod_lat0, mod_lat1])
                mod_time = concatenate([mod_time0, mod_time1])
                if (mod_lon.max() - mod_lon.min()) > 180.:
                    # Sodding dateline
                    mod_lon[mod_lon < 0.] += 360.

                # Interpolate that grid onto the sinusoidal projection
                time = griddata((mod_lon.ravel(), mod_lat.ravel()),
                                np.tile(mod_time, mod_lon.shape[1]),
                                (lon_data, lat_data),
                                method="nearest")
            except (FileNotFoundError, TypeError):
                # Just use the orbit start time
                seconds = start_time - MODIS_REFERENCE_TIME
                time = np.full(lat_data.shape, seconds.total_seconds())

            time_data.append(time)

        return concatenate(time_data)