def try_MENSRB(): tre = None if tres is None else tres['MENSRB'] if tre is None: return mensrb = tre.DATA arp_llh = numpy.array( [lat_lon_parser(mensrb.ACFT_LOC[:12]), lat_lon_parser(mensrb.ACFT_LOC[12:25]), foot*float(mensrb.ACFT_ALT)], dtype='float64') scp_llh = numpy.array( [lat_lon_parser(mensrb.RP_LOC[:12]), lat_lon_parser(mensrb.RP_LOC[12:25]), foot*float(mensrb.RP_ELV)], dtype='float64') # TODO: handle the conversion from msl to hae arp_ecf = geodetic_to_ecf(arp_llh) scp_ecf = geodetic_to_ecf(scp_llh) set_arp_position(arp_ecf, override=True) set_scp(scp_ecf, (int(mensrb.RP_COL)-1, int(mensrb.RP_ROW)-1), override=False) row_unit_ned = numpy.array( [float(mensrb.C_R_NC), float(mensrb.C_R_EC), float(mensrb.C_R_DC)], dtype='float64') col_unit_ned = numpy.array( [float(mensrb.C_AZ_NC), float(mensrb.C_AZ_EC), float(mensrb.C_AZ_DC)], dtype='float64') set_uvects(ned_to_ecf(row_unit_ned, scp_ecf, absolute_coords=False), ned_to_ecf(col_unit_ned, scp_ecf, absolute_coords=False))
def try_MENSRA(): tre = None if tres is None else tres['MENSRA'] if tre is None: return mensra = tre.DATA arp_llh = numpy.array( [lat_lon_parser(mensra.ACFT_LOC[:10]), lat_lon_parser(mensra.ACFT_LOC[10:21]), foot*float(mensra.ACFT_ALT)], dtype='float64') scp_llh = numpy.array( [lat_lon_parser(mensra.CP_LOC[:10]), lat_lon_parser(mensra.CP_LOC[10:21]), foot*float(mensra.CP_ALT)], dtype='float64') # TODO: handle the conversion from msl to hae arp_ecf = geodetic_to_ecf(arp_llh) scp_ecf = geodetic_to_ecf(scp_llh) set_arp_position(arp_ecf, override=True) # TODO: is this already zero based? set_scp(geodetic_to_ecf(scp_llh), (int(mensra.CCRP_COL), int(mensra.CCRP_ROW)), override=False) row_unit_ned = numpy.array( [float(mensra.C_R_NC), float(mensra.C_R_EC), float(mensra.C_R_DC)], dtype='float64') col_unit_ned = numpy.array( [float(mensra.C_AZ_NC), float(mensra.C_AZ_EC), float(mensra.C_AZ_DC)], dtype='float64') set_uvects(ned_to_ecf(row_unit_ned, scp_ecf, absolute_coords=False), ned_to_ecf(col_unit_ned, scp_ecf, absolute_coords=False))
def test_geodetic_to_ecf(self): out = geocoords.geodetic_to_ecf(llh[0, :]) with self.subTest(msg="basic shape check"): self.assertEqual(out.shape, (3,)) with self.subTest(msg="basic value check"): self.assertTrue(numpy.all(numpy.abs(out - ecf[0, :]) < tolerance)) out2 = geocoords.geodetic_to_ecf(llh) with self.subTest(msg="2d shape check"): self.assertEqual(out2.shape, llh.shape) with self.subTest(msg="2d value check"): self.assertTrue(numpy.all(numpy.abs(out2 - ecf) < tolerance)) with self.subTest(msg="error check"): self.assertRaises(ValueError, geocoords.geodetic_to_ecf, numpy.arange(4))
def test_values_both_ways(self): shp = (8, 5) rand_llh = numpy.empty(shp + (3, ), dtype=numpy.float64) rand_llh[:, :, 0] = 180 * (numpy.random.rand(*shp) - 0.5) rand_llh[:, :, 1] = 360 * (numpy.random.rand(*shp) - 0.5) rand_llh[:, :, 2] = 1e5 * numpy.random.rand(*shp) rand_ecf = geocoords.geodetic_to_ecf(rand_llh) rand_llh2 = geocoords.ecf_to_geodetic(rand_ecf) rand_ecf2 = geocoords.geodetic_to_ecf(rand_llh2) llh_diff = numpy.abs(rand_llh - rand_llh2) ecf_diff = numpy.abs(rand_ecf - rand_ecf2) with self.subTest(msg="llh match"): self.assertTrue(numpy.all(llh_diff < tolerance)) with self.subTest(msg="ecf match"): self.assertTrue(numpy.all(ecf_diff < tolerance))
def _split_lat_lon_quad(ll_quad, split_fractions): """ Helper method for recursively splitting the lat/lon quad box. Parameters ---------- ll_quad : numpy.ndarray split_fractions : list|tuple Returns ------- numpy.ndarray """ r1, r2, c1, c2 = split_fractions # [0] corresponds to (max_row, 0) # [1] corresponds to (max row, max_col) # [2] corresponds to (0, max_col) # [3] corresponds to (0, 0) # do row split # [0] = r2*[0] + (1-r2)*[3] # [1] = r2*[1] + (1-r2)*[2] # [2] = r1*[1] + (1-r1)*[2] # [3] = r1*[0] + (1-r1)*[3] row_split = numpy.array([ [r2, 0, 0, 1-r2], [0, r2, 1-r2, 0], [0, r1, 1-r1, 0], [r1, 0, 0, 1-r1], ], dtype='float64') # do column split # [0] = (1-c1)*[0] + c1*[1] # [1] = (1-c2)*[0] + c2*[1] # [2] = c2*[2] + (1-c2)*[3] # [3] = c1*[2] + (1-c1)*[3] col_split = numpy.array([ [1-c1, c1, 0, 0], [1-c2, c2, 0, 0], [0, 0, c2, 1-c2], [0, 0, c1, 1-c1],], dtype='float64') split = col_split.dot(row_split) llh_temp = numpy.zeros((4, 3)) llh_temp[:, :2] = ll_quad ecf_coords = geodetic_to_ecf(llh_temp) split_ecf = split.dot(ecf_coords) return ecf_to_geodetic(split_ecf)[:, :2]
def interpolate_corner_points_string(entry, rows, cols, icp): """ Interpolate the corner points for the given subsection from the given corner points. This supplies entries for the NITF headers. Parameters ---------- entry : numpy.ndarray The corner pints of the form `(row_start, row_stop, col_start, col_stop)` rows : int The number of rows in the parent image. cols : int The number of cols in the parent image. icp : the parent image corner points in geodetic coordinates. Returns ------- str """ if icp is None: return '' if icp.shape[1] == 2: icp_new = numpy.zeros((icp.shape[0], 3), dtype=numpy.float64) icp_new[:, :2] = icp icp = icp_new icp_ecf = geodetic_to_ecf(icp) const = 1. / (rows * cols) pattern = entry[numpy.array([(0, 2), (1, 2), (1, 3), (0, 3)], dtype=numpy.int64)] out = [] for row, col in pattern: pt_array = const * numpy.sum( icp_ecf * (numpy.array([rows - row, row, row, rows - row]) * numpy.array( [cols - col, cols - col, col, col]))[:, numpy.newaxis], axis=0) pt = LatLonType.from_array(ecf_to_geodetic(pt_array)[:2]) dms = pt.dms_format(frac_secs=False) out.append('{0:02d}{1:02d}{2:02d}{3:s}'.format(*dms[0]) + '{0:03d}{1:02d}{2:02d}{3:s}'.format(*dms[1])) return ''.join(out)
def extract_location(): ll_coords = None if isinstance(sidd, SIDDType2): try: ll_coords = sidd.GeoData.ImageCorners.get_array( dtype=numpy.dtype('float64')) except AttributeError: pass elif isinstance(sidd, SIDDType1): try: ll_coords = sidd.GeographicAndTarget.GeographicCoverage.Footprint.get_array( dtype=numpy.dtype('float64')) except AttributeError: pass if ll_coords is not None: llh_coords = numpy.zeros((ll_coords.shape[0], 3), dtype=numpy.float64) llh_coords[:, :2] = ll_coords ecf_coords = geodetic_to_ecf(llh_coords) coords = ecf_to_geodetic(numpy.mean(ecf_coords, axis=0)) variables['lat'] = coords[0] variables['lon'] = coords[1]
def get_arp(self): """ Gets the Aperture Position, at SCP Time, in ECF coordinates. Returns ------- numpy.ndarray """ cg_model = self.DATA.CG_MODEL.strip() arp_array = numpy.array([ float(self.DATA.CG_APCEN_X), float(self.DATA.CG_APCEN_Y), float(self.DATA.CG_APCEN_Z) ], dtype='float64') if cg_model == 'ECEF': return arp_array elif cg_model == 'WGS84': return geodetic_to_ecf(arp_array) else: raise ValueError('Got unhandled CG_MODEL {}'.format(cg_model))
def get_scp(self): """ Gets the SCP location in ECF coordinates. Returns ------- numpy.ndarray """ cg_model = self.DATA.CG_MODEL.strip() scp_array = numpy.array([ float(self.DATA.CG_SCECN_X), float(self.DATA.CG_SCECN_Y), float(self.DATA.CG_SCECN_Z) ], dtype='float64') if cg_model == 'ECEF': return scp_array elif cg_model == 'WGS84': return geodetic_to_ecf(scp_array) else: raise ValueError('Got unhandled CG_MODEL {}'.format(cg_model))
def extract_global(): if cphd.Global is None: return try: variables['collect_start'] = cphd.Global.CollectStart except AttributeError: pass try: variables['collect_duration'] = cphd.Global.CollectDuration except AttributeError: pass try: llh_coords = cphd.Global.ImageArea.Corner.get_array( dtype=numpy.dtype('float64')) ecf_coords = geodetic_to_ecf(llh_coords) coords = ecf_to_geodetic(numpy.mean(ecf_coords, axis=0)) variables['lat'] = coords[0] variables['lon'] = coords[1] except AttributeError: pass
def create_ortho( self, output_ny, output_nx, ): input_image_data = self.display_image display_image_nx = input_image_data.shape[1] display_image_ny = input_image_data.shape[0] image_points = np.zeros((display_image_nx * display_image_ny, 2)) canvas_coords_1d = np.zeros(2 * display_image_nx * display_image_ny) tmp_x_vals = np.arange(0, display_image_ny) tmp_y_vals = np.zeros(display_image_ny) for x in range(display_image_nx): start_index = display_image_ny * 2 * x + 1 end_index = start_index + display_image_ny * 2 canvas_coords_1d[start_index:end_index:2] = tmp_x_vals canvas_coords_1d[display_image_ny * x * 2::2][0:display_image_ny] = tmp_y_vals + x full_image_coords = self.canvas_coords_to_full_image_yx( canvas_coords_1d) image_points[:, 0] = full_image_coords[0::2] image_points[:, 1] = full_image_coords[1::2] sicd_meta = self.reader_object.sicd_meta ground_points_ecf = point_projection.image_to_ground( image_points, sicd_meta) ground_points_latlon = geocoords.ecf_to_geodetic(ground_points_ecf) world_y_coordinates = ground_points_latlon[:, 0] world_x_coordinates = ground_points_latlon[:, 1] x = np.ravel(world_x_coordinates) y = np.ravel(world_y_coordinates) z = np.ravel(np.transpose(input_image_data)) ground_x_grid, ground_y_grid = self._create_ground_grid( min(x), max(x), min(y), max(y), output_nx, output_ny) ortho_image = interp.griddata((x, y), z, (ground_x_grid, ground_y_grid), method='nearest') s = np.zeros((output_nx * output_ny, 3)) s[:, 0] = ground_y_grid.ravel() s[:, 1] = ground_x_grid.ravel() s[:, 2] = ground_points_latlon[0, 2] s_ecf = geocoords.geodetic_to_ecf(s) gridded_image_pixels = point_projection.ground_to_image( s_ecf, sicd_meta) full_image_coords_y = full_image_coords[0::2] full_image_coords_x = full_image_coords[1::2] mask = np.ones_like(gridded_image_pixels[0][:, 0]) indices_1 = np.where( gridded_image_pixels[0][:, 0] < min(full_image_coords_y)) indices_2 = np.where( gridded_image_pixels[0][:, 1] < min(full_image_coords_x)) indices_3 = np.where( gridded_image_pixels[0][:, 0] > max(full_image_coords_y)) indices_4 = np.where( gridded_image_pixels[0][:, 1] > max(full_image_coords_x)) mask[indices_1] = 0 mask[indices_2] = 0 mask[indices_3] = 0 mask[indices_4] = 0 mask_2d = np.reshape(mask, (output_ny, output_nx)) return ortho_image * mask_2d
def LLH(self, value): if value is not None: self._LLH = _parse_serializable(value, 'LLH', self, LatLonHAERestrictionType) self._ECF = XYZType.from_array( geodetic_to_ecf(self._LLH.get_array(order='LAT')))
def try_CMETAA(): tre = None if tres is None else tres['CMETAA'] if tre is None: return cmetaa = tre.DATA if the_sicd.GeoData is None: the_sicd.GeoData = GeoDataType() if the_sicd.SCPCOA is None: the_sicd.SCPCOA = SCPCOAType() if the_sicd.Grid is None: the_sicd.Grid = GridType() if the_sicd.Timeline is None: the_sicd.Timeline = TimelineType() if the_sicd.RadarCollection is None: the_sicd.RadarCollection = RadarCollectionType() if the_sicd.ImageFormation is None: the_sicd.ImageFormation = ImageFormationType() the_sicd.SCPCOA.SCPTime = 0.5 * cmetaa.WF_CDP if cmetaa.CG_MODEL == 'ECEF': the_sicd.GeoData.SCP = SCPType(ECF=[ cmetaa.CG_SCECN_X, cmetaa.CG_SCECN_Y, cmetaa.cmetaa.CG_SCECN_Z ]) the_sicd.SCPCOA.ARPPos = [ cmetaa.CG_APCEN_X, cmetaa.CG_APCEN_Y, cmetaa.CG_APCEN_Z ] elif cmetaa.CG_MODEL == 'WGS84': the_sicd.GeoData.SCP = SCPType(LLH=[ cmetaa.CG_SCECN_X, cmetaa.CG_SCECN_Y, cmetaa.cmetaa.CG_SCECN_Z ]) the_sicd.SCPCOA.ARPPos = geodetic_to_ecf( [cmetaa.CG_APCEN_X, cmetaa.CG_APCEN_Y, cmetaa.CG_APCEN_Z]) the_sicd.SCPCOA.SideOfTrack = cmetaa.CG_LD the_sicd.SCPCOA.SlantRange = cmetaa.CG_SRAC the_sicd.SCPCOA.DopplerConeAng = cmetaa.CG_CAAC the_sicd.SCPCOA.GrazeAng = cmetaa.CG_GAAC the_sicd.SCPCOA.IncidenceAng = 90 - cmetaa.CG_GAAC if hasattr(cmetaa, 'CG_TILT'): the_sicd.SCPCOA.TwistAng = cmetaa.CG_TILT if hasattr(cmetaa, 'CG_SLOPE'): the_sicd.SCPCOA.SlopeAng = cmetaa.CG_SLOPE the_sicd.ImageData.SCPPixel = [ cmetaa.IF_DC_IS_COL, cmetaa.IF_DC_IS_ROW ] if cmetaa.CG_MAP_TYPE == 'GEOD': the_sicd.GeoData.ImageCorners = [ [cmetaa.CG_PATCH_LTCORUL, cmetaa.CG_PATCH_LGCORUL], [cmetaa.CG_PATCH_LTCORUR, cmetaa.CG_PATCH_LGCORUR], [cmetaa.CG_PATCH_LTCORLR, cmetaa.CG_PATCH_LGCORLR], [cmetaa.CG_PATCH_LTCORLL, cmetaa.CG_PATCH_LNGCOLL] ] if cmetaa.CMPLX_SIGNAL_PLANE[0].upper() == 'S': the_sicd.Grid.ImagePlane = 'SLANT' elif cmetaa.CMPLX_SIGNAL_PLANE[0].upper() == 'G': the_sicd.Grid.ImagePlane = 'GROUND' the_sicd.Grid.Row = DirParamType( SS=cmetaa.IF_RSS, ImpRespWid=cmetaa.IF_RGRES, Sgn=1 if cmetaa.IF_RFFTS == '-' else -1, # opposite sign convention ImpRespBW=cmetaa.IF_RFFT_SAMP / (cmetaa.IF_RSS * cmetaa.IF_RFFT_TOT)) the_sicd.Grid.Col = DirParamType( SS=cmetaa.IF_AZSS, ImpRespWid=cmetaa.IF_AZRES, Sgn=1 if cmetaa.IF_AFFTS == '-' else -1, # opposite sign convention ImpRespBW=cmetaa.IF_AZFFT_SAMP / (cmetaa.IF_AZSS * cmetaa.IF_AZFFT_TOT)) cmplx_weight = cmetaa.CMPLX_WEIGHT if cmplx_weight == 'UWT': the_sicd.Grid.Row.WgtType = WgtTypeType(WindowName='UNIFORM') the_sicd.Grid.Col.WgtType = WgtTypeType(WindowName='UNIFORM') elif cmplx_weight == 'HMW': the_sicd.Grid.Row.WgtType = WgtTypeType(WindowName='HAMMING') the_sicd.Grid.Col.WgtType = WgtTypeType(WindowName='HAMMING') elif cmplx_weight == 'HNW': the_sicd.Grid.Row.WgtType = WgtTypeType(WindowName='HANNING') the_sicd.Grid.Col.WgtType = WgtTypeType(WindowName='HANNING') elif cmplx_weight == 'TAY': the_sicd.Grid.Row.WgtType = WgtTypeType( WindowName='TAYLOR', Parameters={ 'SLL': '{0:0.16G}'.format(-cmetaa.CMPLX_RNG_SLL), 'NBAR': '{0:0.16G}'.format(cmetaa.CMPLX_RNG_TAY_NBAR) }) the_sicd.Grid.Col.WgtType = WgtTypeType( WindowName='TAYLOR', Parameters={ 'SLL': '{0:0.16G}'.format(-cmetaa.CMPLX_AZ_SLL), 'NBAR': '{0:0.16G}'.format(cmetaa.CMPLX_AZ_TAY_NBAR) }) the_sicd.Grid.Row.define_weight_function() the_sicd.Grid.Col.define_weight_function() # noinspection PyBroadException try: date_str = cmetaa.T_UTC_YYYYMMMDD time_str = cmetaa.T_HHMMSSUTC date_time = '{}-{}-{}T{}:{}:{}Z'.format( date_str[:4], date_str[4:6], date_str[6:8], time_str[:2], time_str[2:4], time_str[4:6]) the_sicd.Timeline.CollectStart = numpy.datetime64(date_time, 'us') except: pass the_sicd.Timeline.CollectDuration = cmetaa.WF_CDP the_sicd.Timeline.IPP = [ IPPSetType(TStart=0, TEnd=cmetaa.WF_CDP, IPPStart=0, IPPEnd=numpy.floor(cmetaa.WF_CDP * cmetaa.WF_PRF), IPPPoly=[0, cmetaa.WF_PRF]) ] the_sicd.RadarCollection.TxFrequency = TxFrequencyType( Min=cmetaa.WF_SRTFR, Max=cmetaa.WF_ENDFR) the_sicd.RadarCollection.TxPolarization = cmetaa.POL_TR.upper() the_sicd.RadarCollection.Waveform = [ WaveformParametersType(TxPulseLength=cmetaa.WF_WIDTH, TxRFBandwidth=cmetaa.WF_BW, TxFreqStart=cmetaa.WF_SRTFR, TxFMRate=cmetaa.WF_CHRPRT * 1e12) ] tx_rcv_pol = '{}:{}'.format(cmetaa.POL_TR.upper(), cmetaa.POL_RE.upper()) the_sicd.RadarCollection.RcvChannels = [ ChanParametersType(TxRcvPolarization=tx_rcv_pol) ] the_sicd.ImageFormation.TxRcvPolarizationProc = tx_rcv_pol if_process = cmetaa.IF_PROCESS if if_process == 'PF': the_sicd.ImageFormation.ImageFormAlgo = 'PFA' scp_ecf = the_sicd.GeoData.SCP.ECF.get_array() fpn_ned = numpy.array( [cmetaa.CG_FPNUV_X, cmetaa.CG_FPNUV_Y, cmetaa.CG_FPNUV_Z], dtype='float64') ipn_ned = numpy.array( [cmetaa.CG_IDPNUVX, cmetaa.CG_IDPNUVY, cmetaa.CG_IDPNUVZ], dtype='float64') fpn_ecf = ned_to_ecf(fpn_ned, scp_ecf, absolute_coords=False) ipn_ecf = ned_to_ecf(ipn_ned, scp_ecf, absolute_coords=False) the_sicd.PFA = PFAType(FPN=fpn_ecf, IPN=ipn_ecf) elif if_process in ['RM', 'CD']: the_sicd.ImageFormation.ImageFormAlgo = 'RMA' # the remainder of this is guesswork to define required fields the_sicd.ImageFormation.TStartProc = 0 # guess work the_sicd.ImageFormation.TEndProc = cmetaa.WF_CDP the_sicd.ImageFormation.TxFrequencyProc = TxFrequencyProcType( MinProc=cmetaa.WF_SRTFR, MaxProc=cmetaa.WF_ENDFR) # all remaining guess work the_sicd.ImageFormation.STBeamComp = 'NO' the_sicd.ImageFormation.ImageBeamComp = 'SV' if cmetaa.IF_BEAM_COMP[ 0] == 'Y' else 'NO' the_sicd.ImageFormation.AzAutofocus = 'NO' if cmetaa.AF_TYPE[ 0] == 'N' else 'SV' the_sicd.ImageFormation.RgAutofocus = 'NO'
def llh_to_ortho(self, llh_coords): llh_coords, o_shape = self._reshape(llh_coords, 3) ground = geodetic_to_ecf(llh_coords) return self.ecf_to_ortho(numpy.reshape(ground, o_shape))