Beispiel #1
0
def transect_lalo(z, atr, start_lalo, end_lalo, interpolation='nearest'):
    """Extract 2D matrix (z) value along the line [start_lalo, end_lalo]"""
    coord = coordinate(atr)
    [y0, y1] = coord.lalo2yx([start_lalo[0], end_lalo[0]], coord_type='lat')
    [x0, x1] = coord.lalo2yx([start_lalo[1], end_lalo[1]], coord_type='lon')
    transect = transect_yx(z, atr, [y0, x0], [y1, x1], interpolation)
    return transect
Beispiel #2
0
    def get_los_geometry(self, geom_obj, print_msg=False):
        """Get the Line-of-Sight geometry info in incidence and azimuth angle in degrees."""
        lat, lon = self.get_stat_lat_lon(print_msg=print_msg)

        # get LOS geometry
        if isinstance(geom_obj, str):
            # geometry file
            atr = readfile.read_attribute(geom_obj)
            coord = coordinate(atr, lookup_file=geom_obj)
            y, x = coord.geo2radar(lat, lon, print_msg=print_msg)[0:2]
            # check against image boundary
            y = max(0, y);  y = min(int(atr['LENGTH'])-1, y)
            x = max(0, x);  x = min(int(atr['WIDTH'])-1, x)
            box = (x, y, x+1, y+1)
            inc_angle = readfile.read(geom_obj, datasetName='incidenceAngle', box=box, print_msg=print_msg)[0][0,0]
            az_angle  = readfile.read(geom_obj, datasetName='azimuthAngle',   box=box, print_msg=print_msg)[0][0,0]

        elif isinstance(geom_obj, dict):
            # use mean inc/az_angle from metadata
            inc_angle = ut.incidence_angle(geom_obj, dimension=0, print_msg=print_msg)
            az_angle  = ut.heading2azimuth_angle(float(geom_obj['HEADING']))

        else:
            raise ValueError('input geom_obj is neight str nor dict: {}'.format(geom_obj))

        return inc_angle, az_angle
Beispiel #3
0
def read_timeseries_lalo(lat,
                         lon,
                         ts_file,
                         lookup_file=None,
                         ref_lat=None,
                         ref_lon=None,
                         win_size=1):
    """ Read time-series of one pixel with input lat/lon
    Parameters: lat/lon     : float, latitude/longitude
                ts_file     : string, filename of time-series HDF5 file
                lookup_file : string, filename of lookup table file
                ref_lat/lon : float, latitude/longitude of reference pixel
    Returns:    dates : 1D np.array of datetime.datetime objects, i.e. datetime.datetime(2010, 10, 20, 0, 0)
                dis   : 1D np.array of float in meter
    """
    atr = readfile.read_attribute(ts_file)
    coord = coordinate(atr, lookup_file=lookup_file)
    y, x = coord.geo2radar(lat, lon)[0:2]
    print('input lat / lon: {} / {}'.format(lat, lon))

    ref_y, ref_x = None, None
    if ref_lat is not None:
        ref_y, ref_x = coord.geo2radar(ref_lat, ref_lon)[0:2]

    dates, dis = read_timeseries_yx(y,
                                    x,
                                    ts_file,
                                    ref_y=ref_y,
                                    ref_x=ref_x,
                                    win_size=win_size)
    return dates, dis
Beispiel #4
0
    def get_los_geometry(self, geom_obj, print_msg=False):
        lat, lon = self.get_stat_lat_lon(print_msg=print_msg)

        # get LOS geometry
        if isinstance(geom_obj, str):
            # geometry file
            atr = readfile.read_attribute(geom_obj)
            coord = coordinate(atr, lookup_file=geom_obj)
            y, x = coord.geo2radar(lat, lon, print_msg=print_msg)[0:2]
            box = (x, y, x + 1, y + 1)
            inc_angle = readfile.read(geom_obj,
                                      datasetName='incidenceAngle',
                                      box=box,
                                      print_msg=print_msg)[0][0, 0]
            az_angle = readfile.read(geom_obj,
                                     datasetName='azimuthAngle',
                                     box=box,
                                     print_msg=print_msg)[0][0, 0]
            head_angle = ut.azimuth2heading_angle(az_angle)
        elif isinstance(geom_obj, dict):
            # use mean inc/head_angle from metadata
            inc_angle = ut.incidence_angle(geom_obj,
                                           dimension=0,
                                           print_msg=print_msg)
            head_angle = float(geom_obj['HEADING'])
            # for old reading of los.rdr band2 data into headingAngle directly
            if (head_angle + 180.) > 45.:
                head_angle = ut.azimuth2heading_angle(head_angle)
        else:
            raise ValueError(
                'input geom_obj is neight str nor dict: {}'.format(geom_obj))
        return inc_angle, head_angle
Beispiel #5
0
def read_timeseries_lalo(lat,
                         lon,
                         ts_file,
                         lookup_file=None,
                         ref_lat=None,
                         ref_lon=None,
                         zero_first=True,
                         win_size=1,
                         unit='m',
                         method='mean',
                         print_msg=True):
    """ Read time-series of one pixel with input lat/lon
    Parameters: lat/lon     - float, latitude/longitude
                ts_file     - string, filename of time-series HDF5 file
                lookup_file - string, filename of lookup table file
                ref_lat/lon - float, latitude/longitude of reference pixel
                zero_first  - bool, shift the time-series so that it starts from zero
                win_size    - int, windows size centered at point of interest
                unit        - str, output displacement unit
                method      - str, method to calculate the output displacement and its dispersity
    Returns:    dates       - 1D np.ndarray of datetime.datetime objects, i.e. datetime.datetime(2010, 10, 20, 0, 0)
                dis         - 1D np.ndarray of float32, displacement
                dis_std     - 1D np.ndarray of float32, displacement dispersity
    """
    atr = readfile.read_attribute(ts_file)
    coord = coordinate(atr, lookup_file=lookup_file)
    y, x = coord.geo2radar(lat, lon)[0:2]
    if print_msg:
        print('input lat / lon: {} / {}'.format(lat, lon))
        print('corresponding y / x: {} / {}'.format(y, x))

    # reference pixel
    ref_y, ref_x = None, None
    if ref_lat is not None:
        ref_y, ref_x = coord.geo2radar(ref_lat, ref_lon)[0:2]

    # call read_timeseries_yx()
    dates, dis, dis_std = read_timeseries_yx(y,
                                             x,
                                             ts_file,
                                             ref_y=ref_y,
                                             ref_x=ref_x,
                                             zero_first=zero_first,
                                             win_size=win_size,
                                             unit=unit,
                                             method=method,
                                             print_msg=False)
    return dates, dis, dis_std
Beispiel #6
0
def transect_yx(z, atr, start_yx, end_yx, interpolation='nearest'):
    """Extract 2D matrix (z) value along the line [x0,y0;x1,y1]
    Link: http://stackoverflow.com/questions/7878398/how-to-extract-an-arbitrary-line-of-values-from-a-numpy-array

    Parameters: z : (np.array) 2D data matrix
                atr : (dict) attribute
                start_yx : (list) y,x coordinate of start point
                end_yx : (list) y,x coordinate of end   point
                interpolation : str, sampling/interpolation method, including:
                    'nearest' - nearest neighbour
                    'linear'  - linear  spline interpolation (order of 1)
                    'cubic'   - cubic   spline interpolation (order of 3)
                    'quintic' - quintic spline interpolation (order of 5)

    Returns:    transect: (dict) containing 1D matrix:
                    'X' - 1D np.array for X/column coordinates in float32
                    'Y' - 1D np.array for Y/row.   coordinates in float32
                    'value' - 1D np.array for z value in float32
                    'distance' - 1D np.array for distance in float32

    Example: transect = transect_yx(dem, demRsc, [10,15], [100,115])
    """
    interpolation = interpolation.lower()
    [y0, x0] = start_yx
    [y1, x1] = end_yx

    # check
    length, width = int(atr['LENGTH']), int(atr['WIDTH'])
    if not all(0 <= i < width and 0 <= j < length
               for i, j in zip([x0, x1], [y0, y1])):
        msg = 'input start/end point is out of data coverage'
        msg += '\nstart_yx: {}'.format(start_yx)
        msg += '\nend_yx:{}'.format(end_yx)
        msg += '\ndata size: ({}, {})'.format(length, width)
        raise ValueError(msg)

    # Determine points coordinates along the line
    num_pts = int(np.hypot(x1 - x0, y1 - y0))
    ys = np.linspace(y0, y1, num_pts, dtype=np.float32)
    xs = np.linspace(x0, x1, num_pts, dtype=np.float32)

    # Extract z value along the line
    # for nearest neighbor sampling, use indexing directly
    # for other interpolation, use scipy.ndimage.map_coordinates
    if interpolation == 'nearest':
        z_line = z[np.rint(ys).astype(np.int), np.rint(xs).astype(np.int)]

    else:
        # interpolation name to order
        interpolate_name2order = {
            'linear': 1,
            'cubic': 3,
            'quintic': 5,
        }
        if interpolation not in interpolate_name2order.keys():
            msg = 'un-supported interpolation method: {}'.format(interpolation)
            msg += '\navailable methods: {}'.format(
                interpolate_name2order.keys())
            raise ValueError(msg)
        interp_order = interpolate_name2order[interpolation.lower()]
        # run interpolation
        z_line = map_coordinates(z, np.vstack((ys, xs)), order=interp_order)

    # Calculate Distance along the line
    earth_radius = 6.3781e6  # in meter
    dist_unit = 'm'
    if 'Y_FIRST' in atr.keys():
        [lat0, lat1] = coordinate(atr).yx2lalo([y0, y1], coord_type='y')
        lat_c = (lat0 + lat1) / 2.
        x_step = float(atr['X_STEP']) * np.pi / 180.0 * earth_radius * np.cos(
            lat_c * np.pi / 180)
        y_step = float(atr['Y_STEP']) * np.pi / 180.0 * earth_radius
    else:
        try:
            x_step = range_ground_resolution(atr)
            y_step = azimuth_ground_resolution(atr)
        except KeyError:
            x_step = 1
            y_step = 1
            dist_unit = 'pixel'
    dist_line = np.hypot((xs - x0) * x_step, (ys - y0) * y_step)

    # remove points in masked out areas
    mask = ~np.isnan(z_line)
    mask *= z_line != 0.0

    # prepare output
    transect = {}
    transect['Y'] = ys[mask]
    transect['X'] = xs[mask]
    transect['value'] = z_line[mask]
    transect['distance'] = dist_line[mask]
    transect['distance_unit'] = dist_unit

    return transect
Beispiel #7
0
def transect_yx(z, atr, start_yx, end_yx, interpolation='nearest'):
    """Extract 2D matrix (z) value along the line [x0,y0;x1,y1]
    Ref link: http://stackoverflow.com/questions/7878398/how-to-e
              xtract-an-arbitrary-line-of-values-from-a-numpy-array

    Parameters: z : (np.array) 2D data matrix
                atr : (dict) attribute
                start_yx : (list) y,x coordinate of start point
                end_yx : (list) y,x coordinate of end   point
                interpolation : str, sampling/interpolation method, including:
                    'nearest'  - nearest neighbour, by default
                    'cubic'    - cubic interpolation
                    'bilinear' - bilinear interpolation

    Returns:    transect: (dict) containing 1D matrix:
                    'X' - 1D np.array for X/column coordinates in float32
                    'Y' - 1D np.array for Y/row.   coordinates in float32
                    'value' - 1D np.array for z value in float32
                    'distance' - 1D np.array for distance in float32

    Example: transect = transect_yx(dem, demRsc, [10,15], [100,115])
    """
    [y0, x0] = start_yx
    [y1, x1] = end_yx

    # check
    length, width = int(atr['LENGTH']), int(atr['WIDTH'])
    if not all(0 <= i < width and 0 <= j < length
               for i, j in zip([x0, x1], [y0, y1])):
        msg = 'input start/end point is out of data coverage'
        msg += '\nstart_yx: {}'.format(start_yx)
        msg += '\nend_yx:{}'.format(end_yx)
        msg += '\ndata size: ({}, {})'.format(length, width)
        raise ValueError(msg)

    # Determine points coordinates along the line
    num_pts = int(np.hypot(x1 - x0, y1 - y0))
    ys = np.linspace(y0, y1, num_pts, dtype=np.float32)
    xs = np.linspace(x0, x1, num_pts, dtype=np.float32)

    # Extract z value along the line
    if interpolation.lower() == 'nearest':
        z_line = z[np.rint(ys).astype(np.int), np.rint(xs).astype(np.int)]
    elif interpolation.lower() == 'cubic':
        z_line = map_coordinates(z, np.vstack((ys, xs)), order=3)
    elif interpolation.lower() == 'bilinear':
        z_line = map_coordinates(z, np.vstack((ys, xs)), order=2)
    else:
        print('Un-recognized interpolation method: ' + interpolation)
        print('Continue with nearest ...')
        z_line = z[np.rint(ys).astype(np.int),
                   np.rint(xs).astype(np.int)]  # nearest neighbour

    # Calculate Distance along the line
    earth_radius = 6.3781e6  # in meter
    if 'Y_FIRST' in atr.keys():
        [lat0, lat1] = coordinate(atr).yx2lalo([y0, y1], coord_type='y')
        lat_c = (lat0 + lat1) / 2.
        x_step = float(atr['X_STEP']) * np.pi / 180.0 * earth_radius * np.cos(
            lat_c * np.pi / 180)
        y_step = float(atr['Y_STEP']) * np.pi / 180.0 * earth_radius
    else:
        x_step = range_ground_resolution(atr)
        y_step = azimuth_ground_resolution(atr)
    dist_line = np.hypot((xs - x0) * x_step, (ys - y0) * y_step)

    # remove points in masked out areas
    mask = ~np.isnan(z_line)
    mask *= z_line != 0.0

    # prepare output
    transect = {}
    transect['Y'] = ys[mask]
    transect['X'] = xs[mask]
    transect['value'] = z_line[mask]
    transect['distance'] = dist_line[mask]
    return transect
Beispiel #8
0
def update_attribute4radar2geo(atr_in,
                               shape2d=None,
                               lalo_step=None,
                               SNWE=None,
                               lut_file=None,
                               res_obj=None,
                               print_msg=True):
    """update input dictionary of attributes due to resampling from radar to geo coordinates

    Parameters: atr_in  - dict, input dictionary of attributes
                # combination 1
                shape2d - tuple of 2 int in (length, width)
                lalo_step - tuple of 2 float, step size in lat/lon direction
                SNWE      - tuple of 4 float
                lut_file  - str, path of lookup table file
                # combination 2
                res_obj   - mintpy.objects.resample.resample object
    Returns:    atr     - dict, updated dictionary of attributes
    """
    # make a copy of original meta dict
    atr = dict(atr_in)

    # grab info from res_obj
    if res_obj is not None:
        shape2d = (res_obj.length, res_obj.width)
        lalo_step = res_obj.lalo_step
        SNWE = res_obj.SNWE
        lut_file = res_obj.lut_file

    atr['LENGTH'] = shape2d[0]
    atr['WIDTH'] = shape2d[1]
    atr['Y_STEP'] = lalo_step[0]
    atr['X_STEP'] = lalo_step[1]
    atr['Y_FIRST'] = SNWE[1]
    atr['X_FIRST'] = SNWE[2]

    lut_meta = readfile.read_attribute(lut_file)
    atr['Y_UNIT'] = lut_meta.get('Y_UNIT', 'degrees')
    atr['X_UNIT'] = lut_meta.get('X_UNIT', 'degrees')

    # Reference point from y/x to lat/lon
    if 'REF_Y' in atr.keys():
        coord = coordinate(atr_in, lookup_file=lut_file)
        ref_lat, ref_lon = coord.radar2geo(np.array(int(atr['REF_Y'])),
                                           np.array(int(atr['REF_X'])),
                                           print_msg=False)[0:2]
        if ~np.isnan(ref_lat) and ~np.isnan(ref_lon):
            ref_y = int(
                np.rint(
                    (ref_lat - float(atr['Y_FIRST'])) / float(atr['Y_STEP'])))
            ref_x = int(
                np.rint(
                    (ref_lon - float(atr['X_FIRST'])) / float(atr['X_STEP'])))
            atr['REF_LAT'] = str(ref_lat)
            atr['REF_LON'] = str(ref_lon)
            atr['REF_Y'] = str(ref_y)
            atr['REF_X'] = str(ref_x)
            if print_msg:
                print('update REF_LAT/LON/Y/X')
        else:
            warnings.warn(
                "original reference pixel is out of .trans file's coverage. Continue."
            )
            try:
                atr.pop('REF_Y')
                atr.pop('REF_X')
            except:
                pass
            try:
                atr.pop('REF_LAT')
                atr.pop('REF_LON')
            except:
                pass
    return atr