示例#1
0
def is_rotated_proj_working():

    import pyproj
    srs = ('+ellps=WGS84 +proj=ob_tran +o_proj=latlon '
           '+to_meter=0.0174532925199433 +o_lon_p=0.0 +o_lat_p=80.5 '
           '+lon_0=357.5 +no_defs')

    p1 = pyproj.Proj(srs)
    p2 = wgs84

    return np.isclose(transform_proj(p1, p2, -20, -9),
                      [-22.243473889042903, -0.06328365194179102],
                      atol=1e-5).all()
示例#2
0
 def proj(lon, lat):
     return salem.transform_proj(salem.wgs84, gdir.grid.proj, lon, lat)
示例#3
0
def define_nonrgi_glacier_region(gdir: NonRGIGlacierDirectory):
    """
    Very first task: define the glacier's local grid.

    Defines the local projection (Transverse Mercator), centered on the
    glacier. The resolution of the local grid is dx.

    After defining the grid, the topography is transformed into the local
    projection. The default interpolation for the topography is `cubic`.

    Parameters
    ----------
    gdir : :py:class:`oggm.NonRGIGlacierDirectory`
        where to write the data
    dx : float
        grid spacing
    """
    xx, yy = gdir.extent_ll
    dx = gdir.case.dx

    # Make a local glacier map
    proj_params = dict(name='tmerc',
                       lat_0=0.,
                       lon_0=gdir.cenlon,
                       k=0.9996,
                       x_0=0,
                       y_0=0,
                       datum='WGS84')
    proj4_str = "+proj={name} +lat_0={lat_0} +lon_0={lon_0} +k={k} " \
                "+x_0={x_0} +y_0={y_0} +datum={datum}".format(**proj_params)
    # proj_in = pyproj.Proj("+init=EPSG:4326", preserve_units=True)
    proj_out = pyproj.Proj(proj4_str, preserve_units=True)

    merc_xx, merc_yy = salem.transform_proj(salem.wgs84, proj_out, xx, yy)

    # Corners, incl. a buffer of N pix
    ulx = np.min(merc_xx)
    lrx = np.max(merc_xx)
    uly = np.max(merc_yy)
    lry = np.min(merc_yy)

    # n pixels
    nx = np.int((lrx - ulx) / dx)
    ny = np.int((uly - lry) / dx)

    # Back to lon, lat for DEM download/preparation
    tmp_grid = salem.Grid(proj=proj_out,
                          nxny=(nx, ny),
                          x0y0=(ulx, uly),
                          dxdy=(dx, -dx),
                          pixel_ref='corner')
    minlon, maxlon, minlat, maxlat = tmp_grid.extent_in_crs(crs=salem.wgs84)

    dem_list, dem_source = get_topo_file((minlon, maxlon), (minlat, maxlat),
                                         rgi_region=None,
                                         rgi_subregion=None,
                                         source='DEM3')
    log.debug('(%s) DEM source: %s', gdir.name, dem_source)

    # A glacier area can cover more than one tile:
    if len(dem_list) == 1:
        dem_dss = [rasterio.open(dem_list[0])]  # if one tile, just open it
        dem_data = rasterio.band(dem_dss[0], 1)
        if LooseVersion(rasterio.__version__) >= LooseVersion('1.0'):
            src_transform = dem_dss[0].transform
        else:
            src_transform = dem_dss[0].affine
    else:
        dem_dss = [rasterio.open(s) for s in dem_list]  # list of rasters
        dem_data, src_transform = merge_tool(dem_dss)  # merged rasters

    # Use Grid properties to create a transform (see rasterio cookbook)
    dst_transform = rasterio.transform.from_origin(
        ulx,
        uly,
        dx,
        dx  # sign change (2nd dx) is done by rasterio.transform
    )

    # Set up profile for writing output
    profile = dem_dss[0].profile
    profile.update({
        'crs': proj4_str,
        'transform': dst_transform,
        'width': nx,
        'height': ny
    })

    # Could be extended so that the cfg file takes all Resampling.* methods
    if cfg.PARAMS['topo_interp'] == 'bilinear':
        resampling = Resampling.bilinear
    elif cfg.PARAMS['topo_interp'] == 'cubic':
        resampling = Resampling.cubic
    else:
        raise ValueError('{} interpolation not understood'.format(
            cfg.PARAMS['topo_interp']))

    dem_reproj = gdir.get_filepath('dem')

    with rasterio.open(dem_reproj, 'w', **profile) as dest:
        dst_array = np.empty((ny, nx), dtype=dem_dss[0].dtypes[0])
        reproject(
            # Source parameters
            source=dem_data,
            src_crs=dem_dss[0].crs,
            src_transform=src_transform,
            # Destination parameters
            destination=dst_array,
            dst_transform=dst_transform,
            dst_crs=proj4_str,
            # Configuration
            resampling=resampling)

        # TODO: ugly
        if gdir.case.name == 'Borden Peninsula':
            print('Anti icepatch used')
            dst_array[32, 27] = gdir.case.ela_h - 5
            dst_array[:2, -4:] = gdir.case.ela_h - 5
        if gdir.case.name == 'Borden Peninsula HR':
            print('Anti icepatch HR used')
            dst_array[-21:-16, 32:38] = gdir.case.ela_h - 5
            dst_array[-8:-2, 88:98] = gdir.case.ela_h - 5
            dst_array[:-109, 120:] = gdir.case.ela_h - 5
        dest.write(dst_array, 1)

    for dem_ds in dem_dss:
        dem_ds.close()

    # Glacier grid
    x0y0 = (ulx + dx / 2, uly - dx / 2)  # To pixel center coordinates
    glacier_grid = salem.Grid(proj=proj_out,
                              nxny=(nx, ny),
                              dxdy=(dx, -dx),
                              x0y0=x0y0)
    glacier_grid.to_json(gdir.get_filepath('glacier_grid'))

    # Write DEM source info
    source_txt = DEM_SOURCE_INFO.get(dem_source, dem_source)
    with open(gdir.get_filepath('dem_source'), 'w') as fw:
        fw.write(source_txt)
示例#4
0
def _reproject_and_scale(gdir, do_error=False):
    """Reproject and scale itslive data, avoid code duplication for error"""


    reg = find_region(gdir)
    if reg is None:
        raise InvalidWorkflowError('There does not seem to be its_live data '
                                   'available for this glacier')

    vnx = 'vx'
    vny = 'vy'
    if do_error:
        vnx += '_err'
        vny += '_err'

    with utils.get_lock():
        fx = utils.file_downloader(region_files[reg][vnx])
        fy = utils.file_downloader(region_files[reg][vny])

    # Open the files
    dsx = salem.GeoTiff(fx)
    dsy = salem.GeoTiff(fy)
    # subset them to our map
    grid_gla = gdir.grid.center_grid
    proj_vel = dsx.grid.proj
    x0, x1, y0, y1 = grid_gla.extent_in_crs(proj_vel)
    dsx.set_subset(corners=((x0, y0), (x1, y1)), crs=proj_vel, margin=4)
    dsy.set_subset(corners=((x0, y0), (x1, y1)), crs=proj_vel, margin=4)
    grid_vel = dsx.grid.center_grid

    # TODO: this should be taken care of by salem
    # https://github.com/fmaussion/salem/issues/171
    with rasterio.Env():
        with rasterio.open(fx) as src:
            nodata = getattr(src, 'nodata', -32767.0)

    # Error files are wrong
    if nodata == 0:
        nodata = -32767.0

    # Get the coords at t0
    xx0, yy0 = grid_vel.center_grid.xy_coordinates

    # Compute coords at t1
    xx1 = dsx.get_vardata()
    yy1 = dsy.get_vardata()
    non_valid = (xx1 == nodata) | (yy1 == nodata)
    xx1[non_valid] = np.NaN
    yy1[non_valid] = np.NaN
    orig_vel = np.sqrt(xx1**2 + yy1**2)
    xx1 += xx0
    yy1 += yy0

    # Transform both to glacier proj
    xx0, yy0 = salem.transform_proj(proj_vel, grid_gla.proj, xx0, yy0)
    xx1, yy1 = salem.transform_proj(proj_vel, grid_gla.proj, xx1, yy1)

    # Correct no data after proj as well (inf)
    xx1[non_valid] = np.NaN
    yy1[non_valid] = np.NaN

    # Compute velocities from there
    vx = xx1 - xx0
    vy = yy1 - yy0

    # Scale back velocities - https://github.com/OGGM/oggm/issues/1014
    new_vel = np.sqrt(vx**2 + vy**2)
    p_ok = new_vel > 1e-5  # avoid div by zero
    vx[p_ok] = vx[p_ok] * orig_vel[p_ok] / new_vel[p_ok]
    vy[p_ok] = vy[p_ok] * orig_vel[p_ok] / new_vel[p_ok]

    # And transform to local map
    vx = grid_gla.map_gridded_data(vx, grid=grid_vel, interp='linear')
    vy = grid_gla.map_gridded_data(vy, grid=grid_vel, interp='linear')

    # Write
    with utils.ncDataset(gdir.get_filepath('gridded_data'), 'a') as nc:
        vn = 'obs_icevel_x'
        if do_error:
            vn = vn.replace('obs', 'err')
        if vn in nc.variables:
            v = nc.variables[vn]
        else:
            v = nc.createVariable(vn, 'f4', ('y', 'x', ), zlib=True)
        v.units = 'm yr-1'
        ln = 'ITS LIVE velocity data in x map direction'
        if do_error:
            ln = 'Uncertainty of ' + ln
        v.long_name = ln
        v[:] = vx.filled(np.nan)

        vn = 'obs_icevel_y'
        if do_error:
            vn = vn.replace('obs', 'err')
        if vn in nc.variables:
            v = nc.variables[vn]
        else:
            v = nc.createVariable(vn, 'f4', ('y', 'x', ), zlib=True)
        v.units = 'm yr-1'
        ln = 'ITS LIVE velocity data in y map direction'
        if do_error:
            ln = 'Uncertainty of ' + ln
        v.long_name = ln
        v[:] = vy.filled(np.nan)
示例#5
0
文件: test_prepro.py 项目: OGGM/oggm
 def proj(lon, lat):
     return salem.transform_proj(salem.wgs84, gdir.grid.proj, lon, lat)
示例#6
0
def its_live_to_gdir(gdir, dsx, dsy, dex, dey, fx):
    """ Re-project its_live files to a given glacier directory.
        based on the function from oggm_shop:
        https://github.com/OGGM/oggm/blob/master/oggm/shop/its_live.py#L79
        Variables are added to the gridded_data nc file.
        Re-projecting velocities from one map proj to another is done
        re-projecting the vector distances.
        In this process, absolute velocities might change as well because
        map projections do not always preserve
        distances -> we scale them back to the original velocities as per the
        ITS_LIVE documentation. Which states that velocities are given in
        ground units, i.e. absolute velocities.
        We use bi-linear interpolation to re-project the velocities to
        the local glacier map.

        Parameters
        ----------
        gdir : :py:class:`oggm.GlacierDirectory`
            where to write the data
        dsx: :salem.Geotiff: velocity in the x direction for Greenland
        dsy: :salem.Geotiff: velocity in the y direction for Greenland
        dex: :salem.Geotiff: velocity error in the x direction Greenland
        dey: :salem.Geotiff: velocity error in the y direction Greenland
        fx: path directory to original velocity data (x direction)
        """

    # subset its live data to our glacier map
    grid_gla = gdir.grid.center_grid
    proj_vel = dsx.grid.proj

    x0, x1, y0, y1 = grid_gla.extent_in_crs(proj_vel)

    # Same projection for all the itslive data
    dsx.set_subset(corners=((x0, y0), (x1, y1)), crs=proj_vel, margin=4)
    dsy.set_subset(corners=((x0, y0), (x1, y1)), crs=proj_vel, margin=4)

    dex.set_subset(corners=((x0, y0), (x1, y1)), crs=proj_vel, margin=4)
    dey.set_subset(corners=((x0, y0), (x1, y1)), crs=proj_vel, margin=4)

    grid_vel = dsx.grid.center_grid

    # TODO: this should be taken care of by salem
    # https://github.com/fmaussion/salem/issues/171
    with rasterio.Env():
        with rasterio.open(fx) as src:
            nodata = getattr(src, 'nodata', -32767.0)

    # Get the coords at t0
    xx0, yy0 = grid_vel.center_grid.xy_coordinates

    # Compute coords at t1
    xx1 = dsx.get_vardata()
    yy1 = dsy.get_vardata()

    ex1 = dex.get_vardata()
    ey1 = dey.get_vardata()

    non_valid = (xx1 == nodata) | (yy1 == nodata)
    non_valid_e = (ex1 == nodata) | (ey1 == nodata)

    xx1[non_valid] = np.NaN
    yy1[non_valid] = np.NaN

    ex1[non_valid_e] = np.NaN
    ey1[non_valid_e] = np.NaN

    orig_vel = np.sqrt(xx1**2 + yy1**2)
    orig_vel_e = np.sqrt(ex1**2 + ey1**2)

    xx1 += xx0
    yy1 += yy0

    ex1 += xx0
    ey1 += yy0

    # Transform both to glacier proj
    xx0, yy0 = salem.transform_proj(proj_vel, grid_gla.proj, xx0, yy0)
    xx1, yy1 = salem.transform_proj(proj_vel, grid_gla.proj, xx1, yy1)

    ex0, ey0 = salem.transform_proj(proj_vel, grid_gla.proj, xx0, yy0)
    ex1, ey1 = salem.transform_proj(proj_vel, grid_gla.proj, ex1, ey1)

    # Correct no data after proj as well (inf)
    xx1[non_valid] = np.NaN
    yy1[non_valid] = np.NaN

    ex1[non_valid_e] = np.NaN
    ey1[non_valid_e] = np.NaN

    # Compute velocities from there
    vx = xx1 - xx0
    vy = yy1 - yy0

    ex = ex1 - ex0
    ey = ey1 - ey0

    # Scale back velocities - https://github.com/OGGM/oggm/issues/1014
    new_vel = np.sqrt(vx**2 + vy**2)
    new_vel_e = np.sqrt(ex**2 + ey**2)

    p_ok = new_vel > 1e-5  # avoid div by zero
    vx[p_ok] = vx[p_ok] * orig_vel[p_ok] / new_vel[p_ok]
    vy[p_ok] = vy[p_ok] * orig_vel[p_ok] / new_vel[p_ok]

    p_ok_e = new_vel_e > 1e-5  # avoid div by zero
    ex[p_ok_e] = ex[p_ok_e] * orig_vel_e[p_ok_e] / new_vel_e[p_ok_e]
    ey[p_ok_e] = ey[p_ok_e] * orig_vel_e[p_ok_e] / new_vel_e[p_ok_e]

    # And transform to local map
    vx = grid_gla.map_gridded_data(vx, grid=grid_vel, interp='linear')
    vy = grid_gla.map_gridded_data(vy, grid=grid_vel, interp='linear')

    ex = grid_gla.map_gridded_data(ex, grid=grid_vel, interp='linear')
    ey = grid_gla.map_gridded_data(ey, grid=grid_vel, interp='linear')

    # Write
    with utils.ncDataset(gdir.get_filepath('gridded_data'), 'a') as nc:
        vn = 'obs_icevel_x'
        if vn in nc.variables:
            v = nc.variables[vn]
        else:
            v = nc.createVariable(vn, 'f4', (
                'y',
                'x',
            ), zlib=True)
        v.units = 'm yr-1'
        v.long_name = 'ITS LIVE velocity data in x map direction'
        v[:] = vx

        vn = 'obs_icevel_y'
        if vn in nc.variables:
            v = nc.variables[vn]
        else:
            v = nc.createVariable(vn, 'f4', (
                'y',
                'x',
            ), zlib=True)
        v.units = 'm yr-1'
        v.long_name = 'ITS LIVE velocity data in y map direction'
        v[:] = vy

        vn = 'obs_icevel_x_error'
        if vn in nc.variables:
            v = nc.variables[vn]
        else:
            v = nc.createVariable(vn, 'f4', (
                'y',
                'x',
            ), zlib=True)
        v.units = 'm yr-1'
        v.long_name = 'ITS LIVE error velocity data in x map direction'
        v[:] = ex

        vn = 'obs_icevel_y_error'
        if vn in nc.variables:
            v = nc.variables[vn]
        else:
            v = nc.createVariable(vn, 'f4', (
                'y',
                'x',
            ), zlib=True)
        v.units = 'm yr-1'
        v.long_name = 'ITS LIVE error velocity data in y map direction'
        v[:] = ey
示例#7
0
def velocity_to_gdir(gdir):
    """Reproject the its_live files to the given glacier directory.

    Variables are added to the gridded_data nc file.

    Reprojecting velocities from one map proj to another is done
    reprojecting the vector distances. In this process, absolute velocities
    might change as well because map projections do not always preserve
    distances -> we scale them back to the original velocities as per the
    ITS_LIVE documentation that states that velocities are given in
    ground units, i.e. absolute velocities.

    We use bilinear interpolation to reproject the velocities to the local
    glacier map.

    Parameters
    ----------
    gdir : :py:class:`oggm.GlacierDirectory`
        where to write the data

    """

    reg = find_region(gdir)
    if reg is None:
        raise InvalidWorkflowError('There does not seem to be its_live data '
                                   'available for this glacier')

    if not gdir.has_file('gridded_data'):
        raise InvalidWorkflowError('Please run `glacier_masks` before running '
                                   'this task')

    with utils.get_lock():
        fx = utils.file_downloader(region_files[reg]['vx'])
        fy = utils.file_downloader(region_files[reg]['vy'])

    # Open the files
    dsx = salem.GeoTiff(fx)
    dsy = salem.GeoTiff(fy)
    # subset them to our map
    grid_gla = gdir.grid.center_grid
    proj_vel = dsx.grid.proj
    x0, x1, y0, y1 = grid_gla.extent_in_crs(proj_vel)
    dsx.set_subset(corners=((x0, y0), (x1, y1)), crs=proj_vel, margin=4)
    dsy.set_subset(corners=((x0, y0), (x1, y1)), crs=proj_vel, margin=4)
    grid_vel = dsx.grid.center_grid

    # TODO: this should be taken care of by salem
    # https://github.com/fmaussion/salem/issues/171
    with rasterio.Env():
        with rasterio.open(fx) as src:
            nodata = getattr(src, 'nodata', -32767.0)

    # Get the coords at t0
    xx0, yy0 = grid_vel.center_grid.xy_coordinates

    # Compute coords at t1
    xx1 = dsx.get_vardata()
    yy1 = dsy.get_vardata()
    non_valid = (xx1 == nodata) | (yy1 == nodata)
    xx1[non_valid] = np.NaN
    yy1[non_valid] = np.NaN
    orig_vel = np.sqrt(xx1**2 + yy1**2)
    xx1 += xx0
    yy1 += yy0

    # Transform both to glacier proj
    xx0, yy0 = salem.transform_proj(proj_vel, grid_gla.proj, xx0, yy0)
    xx1, yy1 = salem.transform_proj(proj_vel, grid_gla.proj, xx1, yy1)

    # Correct no data after proj as well (inf)
    xx1[non_valid] = np.NaN
    yy1[non_valid] = np.NaN

    # Compute velocities from there
    vx = xx1 - xx0
    vy = yy1 - yy0

    # Scale back velocities - https://github.com/OGGM/oggm/issues/1014
    new_vel = np.sqrt(vx**2 + vy**2)
    p_ok = new_vel > 0.1  # avoid div by zero
    vx[p_ok] = vx[p_ok] * orig_vel[p_ok] / new_vel[p_ok]
    vy[p_ok] = vy[p_ok] * orig_vel[p_ok] / new_vel[p_ok]

    # And transform to local map
    vx = grid_gla.map_gridded_data(vx, grid=grid_vel, interp='linear')
    vy = grid_gla.map_gridded_data(vy, grid=grid_vel, interp='linear')

    # Write
    with utils.ncDataset(gdir.get_filepath('gridded_data'), 'a') as nc:
        vn = 'obs_icevel_x'
        if vn in nc.variables:
            v = nc.variables[vn]
        else:
            v = nc.createVariable(vn, 'f4', (
                'y',
                'x',
            ), zlib=True)
        v.units = 'm yr-1'
        v.long_name = 'ITS LIVE velocity data in x map direction'
        v[:] = vx

        vn = 'obs_icevel_y'
        if vn in nc.variables:
            v = nc.variables[vn]
        else:
            v = nc.createVariable(vn, 'f4', (
                'y',
                'x',
            ), zlib=True)
        v.units = 'm yr-1'
        v.long_name = 'ITS LIVE velocity data in xy map direction'
        v[:] = vy