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
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
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
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
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
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
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
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