OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
smeta_geometry.c
Go to the documentation of this file.
1 /*
2  * Name: smeta_geometry.c
3  *
4  * Purpose:
5  * Source file containing the functions used to relate Level 1T pixel line/sample
6  * coordinates to the corresponding viewing and solar illumination angles. These functions
7  * operate on the SMETA data type defined in "smeta.h".
8  */
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <stdarg.h>
13 #include <math.h>
14 #include "gctp.h" /* Projection constants */
15 #include "ias_logging.h"
16 #include "ias_math.h"
17 #include "ias_geo.h"
18 #include "ias_const.h"
19 #include "smeta_geometry.h" /* Definition of SMETA structure and
20  function prototypes. */
21 #define NUM_INTERP 4 /* Number of points to use in Lagrange interpolation */
22 #define PIX_BUFFER 3 /* Resampling kernel reduction in effective SCA size */
23 
24 static double wgs84_a; /* WGS84 semimajor axis in meters */
25 static double wgs84_flat; /* WGS84 flattening */
26 static int wgs84_init = 0; /* Initialization flag */
27 static IAS_GEO_PROJ_TRANSFORMATION *trans=NULL; /* Map projection transformation structure */
28 
30  double lat, /* Input latitude in radians */
31  double lon, /* Input longitude in radians */
32  double hgt, /* Input height in meters */
33  IAS_VECTOR *ecef ) /* Output ECEF vector */
34 {
35  /* Make sure ellipsoid constants were initialized */
36  if ( wgs84_init < 1 )
37  {
38  IAS_LOG_ERROR("WGS84 ellipsoid constants not initialized.");
39  return(ERROR);
40  }
41 
42  /* Use library routine to perform the computations */
43  ias_geo_convert_geod2cart( lat, lon, hgt, wgs84_a, wgs84_flat, ecef );
44 
45  return(SUCCESS);
46 }
47 
49  double lat, /* Input latitude in radians */
50  double lon, /* Input longitude in radians */
51  double ecf2lsr[3][3] ) /* ECEF to LSR rotation matrix */
52 {
53  double clat, slat; /* cosine and sine of latitude */
54  double clon, slon; /* cosine and sine of longitude */
55 
56  clat = cos( lat );
57  slat = sin( lat );
58  clon = cos( lon );
59  slon = sin( lon );
60  ecf2lsr[0][0] = -slon;
61  ecf2lsr[0][1] = clon;
62  ecf2lsr[0][2] = 0.0;
63  ecf2lsr[1][0] = -slat*clon;
64  ecf2lsr[1][1] = -slat*slon;
65  ecf2lsr[1][2] = clat;
66  ecf2lsr[2][0] = clat*clon;
67  ecf2lsr[2][1] = clat*slon;
68  ecf2lsr[2][2] = slat;
69 
70  return(SUCCESS);
71 }
72 
74  SMETA *smeta, /* Input enhanced metadata info */
75  int band, /* Input band number */
76  double proj_x, /* Input projection X coordinate */
77  double proj_y, /* Input projection Y coordinate */
78  double *l1t_line, /* Output L1T line number */
79  double *l1t_samp ) /* Output L1T sample number */
80 {
81  int band_index; /* Index corresponding to input band number */
82 
83  /* Look for the input band number in the metadata band list */
84  *l1t_line = 0.0;
85  *l1t_samp = 0.0;
86  band_index = smeta_band_number_to_index( smeta, band );
87  /* See if we found the band */
88  if ( band_index < 0 )
89  {
90  IAS_LOG_ERROR("Band %d not found in metadata.", band);
91  return(ERROR);
92  }
93 
94  /* Convert projection X/Y to L1T line/sample */
95  /* Note, this only works for north-up images */
96  if ( smeta->spacecraft_id == IAS_L8 )
97  {
98  *l1t_samp = (proj_x - smeta->projection.corners.upleft.x)/smeta->band_smeta[band_index].pixsize;
99  *l1t_line = (smeta->projection.corners.upleft.y - proj_y)/smeta->band_smeta[band_index].pixsize;
100  }
101  else
102  {
103  *l1t_samp = (proj_x - smeta->projection.corners.upleft.x)/smeta->band_smeta_ls[band_index].pixsize;
104  *l1t_line = (smeta->projection.corners.upleft.y - proj_y)/smeta->band_smeta_ls[band_index].pixsize;
105  }
106 
107  return(SUCCESS);
108 }
109 
111  SMETA_SCENE_PROJ proj ) /* Input enhanced metadata projection info */
112 {
113  int proj_units = 2; /* GCTP numeric code for input units */
114  int geo_units = 0; /* Output angular units of radians */
115  int geo_code = 0; /* Code for geographic output */
116  int geo_zone = NULLZONE; /* Null zone number for geographic output */
117  double geo_parms[IAS_PROJ_PARAM_SIZE]; /* Zero parameter array for geographic output*/
118  int i; /* Loop index */
119  IAS_PROJECTION in_proj; /* Source projection parameters */
120  IAS_PROJECTION out_proj; /* Destination projection parameters */
121 
122  /* Initialized the geographic projection parameters */
123  for ( i=0; i<IAS_PROJ_PARAM_SIZE; i++ ) geo_parms[i] = 0.0;
124 
125  /* Set the input units code */
126  if (!strcmp (proj.units, "RADIANS"))
127  proj_units = 0;
128  else if (!strcmp (proj.units, "FEET"))
129  proj_units = 1;
130  else if (!strcmp (proj.units, "METERS"))
131  proj_units = 2;
132  else if (!strcmp (proj.units, "SECONDS"))
133  proj_units = 3;
134  else if (!strcmp (proj.units, "DEGREES"))
135  proj_units = 4;
136  else if (!strcmp (proj.units, "DMS"))
137  proj_units = 5;
138 
139  /* Load the projection structures */
140  ias_geo_set_projection( geo_code, geo_zone, geo_units, proj.spheroid, geo_parms, &in_proj );
141  ias_geo_set_projection( proj.code, proj.zone, proj_units, proj.spheroid, proj.projprms, &out_proj );
142 
143  /* Create transformation */
144  if ( (trans = ias_geo_create_proj_transformation( &in_proj, &out_proj )) == NULL )
145  {
146  IAS_LOG_ERROR("Initializing map projection transformation.");
147  return(ERROR);
148  }
149 
150  /* Store ellipsoid constants */
151  wgs84_a = proj.wgs84_major_axis;
152  wgs84_flat = (proj.wgs84_major_axis - proj.wgs84_minor_axis) / proj.wgs84_major_axis;
153  wgs84_init = 1;
154 
155  return(SUCCESS);
156 }
157 
159  SMETA_SCENE_PROJ proj, /* Input enhanced metadata projection info */
160  double lat, /* Input latitude (radians) */
161  double lon, /* Input longitude (radians) */
162  double *proj_x, /* Output projection X coordinate */
163  double *proj_y ) /* Output projection Y coordinate */
164 {
165  /* Make sure the projection transformation has been initialized */
166  if ( trans == NULL )
167  {
168  IAS_LOG_ERROR("Map projection transformation not initialized.");
169  return(ERROR);
170  }
171 
172  /* Convert the projection coordinates to latitude/longitude */
173  if ( smeta_transform_projection( lon, lat, proj_x, proj_y ) != SUCCESS )
174  {
175  IAS_LOG_ERROR("Converting projection X/Y to lat/long.");
176  return(ERROR);
177  }
178 
179  return(SUCCESS);
180 }
181 
183  double inx, /* I: Input X projection coordinate */
184  double iny, /* I: Input Y projection coordinate */
185  double *outx, /* O: Output X projection coordinate */
186  double *outy ) /* O: Output Y projection coordinate */
187 {
188  int status; /* Projection package return code */
189 
190  /* Apply transformation */
191  status = ias_geo_transform_coordinate( trans, inx, iny, outx, outy );
192 
193  return( status );
194 }
195 
197 {
198  /* Release the transformation */
200 
201  trans = NULL;
202  return;
203 }
204 
206  SMETA *smeta, /* Input metadata info */
207  int band ) /* Input band number */
208 {
209  int i; /* Loop index */
210  int band_index; /* Index corresponding to input band number */
211 
212  /* Look for the input band number in the metadata band list */
213  band_index = -1;
214  for ( i=0; i<smeta->num_band; i++ )
215  {
216  if ( smeta->spacecraft_id == IAS_L8 )
217  {
218  if ( band == smeta->band_smeta[i].band )
219  {
220  band_index = i;
221  break;
222  }
223  }
224  else
225  {
226  if ( band == smeta->band_smeta_ls[i].band )
227  {
228  band_index = i;
229  /* printf("in smeta_band_number_to_index: band = %d, band_index = %d\n", band, band_index);*/
230  break;
231  }
232  }
233  }
234 
235  return(band_index);
236 }
237 
int band
Definition: smeta.h:82
void ias_geo_set_projection(int proj_code, int zone, int units, int spheroid, const double *parms, IAS_PROJECTION *proj)
SMETA_SCENE_PROJ projection
Definition: smeta.h:130
float * hgt
#define SUCCESS
Definition: ObpgReadGrid.h:15
int smeta_band_number_to_index(SMETA *smeta, int band)
#define IAS_LOG_ERROR(format,...)
Definition: ias_logging.h:96
int status
Definition: l1_czcs_hdf.c:32
#define NULL
Definition: decode_rs.h:63
PARAM_TYPE_NONE Default value No parameter is buried in the product name name_prefix is case insensitive string compared to the product name PARAM_TYPE_VIS_WAVE The visible wavelength bands from the sensor are buried in the product name The product name is compared by appending and name_suffix ie aph_412_giop where prod_ix will be set to PARAM_TYPE_IR_WAVE same search method as PARAM_TYPE_VIS_WAVE except only wavelength above are looped through but prod_ix is still based ie aph_2_giop for the second band
int num_band
Definition: smeta.h:131
float * lat
int smeta_proj_to_l1t(SMETA *smeta, int band, double proj_x, double proj_y, double *l1t_line, double *l1t_samp)
void ias_geo_destroy_proj_transformation(IAS_GEO_PROJ_TRANSFORMATION *trans)
void smeta_release_projection()
double wgs84_major_axis
Definition: smeta.h:60
subroutine ecef(gha, posi, veli, pose, vele)
Definition: ecef.f:2
@ IAS_L8
Definition: smeta.h:35
#define NULLZONE
Definition: ias_geo.h:8
char units[IAS_UNITS_SIZE]
Definition: smeta.h:63
SMETA_BAND band_smeta[IAS_MAX_NBANDS]
Definition: smeta.h:132
double pixsize
Definition: smeta.h:104
int band
Definition: smeta.h:97
LANDSAT_SPACECRAFT spacecraft_id
Definition: smeta.h:121
int smeta_geodetic_to_ecf2lsr(double lat, double lon, double ecf2lsr[3][3])
int ias_geo_transform_coordinate(const IAS_GEO_PROJ_TRANSFORMATION *trans, double inx, double iny, double *outx, double *outy)
SMETA_BAND_LS band_smeta_ls[IAS_MAX_NBANDS_LS]
Definition: smeta.h:133
IAS_DBL_XY upleft
struct IAS_CORNERS corners
Definition: smeta.h:76
int smeta_init_projection(SMETA_SCENE_PROJ proj)
float * lon
int smeta_geodetic_to_ecef(double lat, double lon, double hgt, IAS_VECTOR *ecef)
int smeta_geodetic_to_proj(SMETA_SCENE_PROJ proj, double lat, double lon, double *proj_x, double *proj_y)
int spheroid
Definition: smeta.h:68
void ias_geo_convert_geod2cart(double latitude, double longitude, double height, double semimajor, double flattening, IAS_VECTOR *cart)
Definition: smeta.h:118
int i
Definition: decode_rs.h:71
int smeta_transform_projection(double inx, double iny, double *outx, double *outy)
double wgs84_minor_axis
Definition: smeta.h:61
double projprms[IAS_PROJ_PARAM_SIZE]
Definition: smeta.h:71
#define IAS_PROJ_PARAM_SIZE
Definition: ias_const.h:61
IAS_GEO_PROJ_TRANSFORMATION * ias_geo_create_proj_transformation(const IAS_PROJECTION *source_projection, const IAS_PROJECTION *target_projection)
#define ERROR
Definition: ancil.h:24
double pixsize
Definition: smeta.h:89