def proj_to_wgs84_nsidc_sea_ice_stere_n(self, x, y, inverse=False): ''' :param x: 1D array -->lon :param y: 1D array -->lat :param iinverse: :return: ''' # WGS84 srs_src = NSR(4326) # WGS 84 / NSIDC Sea Ice Polar Stereographic srs_dst = NSR(3413) src_points = (x, y) if inverse: dst_point = VRT.transform_coordinates(srs_dst, src_points, srs_src) else: dst_point = VRT.transform_coordinates(srs_src, src_points, srs_dst) return dst_point
def test_transform_coordinates_1d_array(self): src_srs = NSR() dst_srs = NSR(str('+proj=stere')) src_points = (np.array([1,2,3,4]), np.array([5,6,7,8]), np.array([5,6,7,8])) dst_x, dst_y, dst_z = VRT.transform_coordinates(src_srs, src_points, dst_srs) # check if shape of the result matches the expected shape (list with four points) self.assertEqual(dst_x.shape, (4,)) self.assertEqual(dst_y.shape, (4,)) self.assertEqual(dst_z.shape, (4,))
def test_transform_coordinates_2d_array(self): src_srs = NSR() dst_srs = NSR(str('+proj=stere')) src_points = (np.array([[1,2,3,4],[1,2,3,4]]), np.array([[5,6,7,8],[5,6,7,8]]), np.array([[5,6,7,8],[5,6,7,8]]),) dst_x, dst_y, dst_z = VRT.transform_coordinates(src_srs, src_points, dst_srs) # check if shape of the result matches the expected shape (2x4 array) self.assertEqual(dst_x.shape, (2,4)) self.assertEqual(dst_y.shape, (2,4)) self.assertEqual(dst_z.shape, (2,4))
def correct_geolocation_data(data, max_height=5): """ Correct lon/lat values in geolocation data for points high above ground (incorrect) Each GCP in Sentinel-1 L1 image (both in the GeoTIF files and Annotation LUT) have five coordinates: X, Y, Z (height), Pixel and Line. On some scenes that cover Greenland (and probably other lands) some GCPs have height above zero even over ocean. This is incorrect, because the radar signal comes actually from the surface and not from a point above the ground as stipulated in such GCPs. This function provides correction of such GCPs. First, Lon/Lat are converted to X/Y in meters. Second, Pixel coordinates are approximated by a 2nd order polynomial of input X,Y,Z. Third, this polynomial is used to calculate new Pixel coordinate for ocean surface (Z=0). Fourth, a temporary VRT from original X, Y, Line and corrected Z,Pixel coordinates is created. Fifth, the temporary VRT is used for converting original Pixel/Line coordinates into correct Lon/Lat Parameters ---------- data : dict Original geolocation data from Mapper.read_annotation() max_height : int Maximum afordable height (meters) Returns ------- data : dict Corrected geolocation data with new longitude and latitude """ # don't correct geolocation data if only few points are affected if (data['height'] > max_height).sum() < 10: return data # convert XY from degrees to meters in stereographic projection central_point = int(data['shape'][0] / 2), int(data['shape'][1] / 2) dst_srs = '+proj=stere +datum=WGS84 +ellps=WGS84 +lat_0=%f +lon_0=%f +no_defs' % ( data['latitude'][central_point], data['longitude'][central_point]) x, y, z = VRT.transform_coordinates( NSR(), (data['longitude'].flat, data['latitude'].flat, data['height'].flat), NSR(dst_srs)) # create training data a = np.vstack( [np.ones(x.size), x, x**2, y, y**2, x * y, z, z**2, x * z, y * z]).T # calculate polynomial coefficients for values of Pixel (using least squares) b = np.linalg.lstsq(a, data['pixel'].flat)[0] # pixel_test = np.dot(a, b) # for debugging # set height to zero (ocean surface) a[:, 6:] = 0 # calculate Pixel at ocean surface pixel_ocean = np.dot(a, b) high_pixels_idx = data['height'] > max_height tmp_pixel = np.array(data['pixel']) tmp_pixel[high_pixels_idx] = pixel_ocean[high_pixels_idx.flat] new_height = np.zeros(data['height'].shape) # create temporary VRT with correct GCPs for converting original pixel/line into lon/lat tmp_gcps = Mapper.create_gcps(x, y, new_height, tmp_pixel, data['line']) tmp_vrt = VRT(data['x_size'], data['y_size']) tmp_vrt.dataset.SetGCPs(tmp_gcps, NSR(dst_srs).wkt) tmp_vrt.tps = True new_lon, new_lat = tmp_vrt.transform_points(data['pixel'].flatten(), data['line'].flatten()) data['latitude'] = new_lat.reshape(data['shape']) data['longitude'] = new_lon.reshape(data['shape']) data['height'] = new_height return data