MISR Toolkit  1.5.1
misrcoordex.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <hdf.h>
5 #include <HdfEosDef.h>
6 #include <proj.h>
7 #include "misrproj.h"
8 #include "MisrCoordQuery.h"
9 #include "errormacros.h"
10 
11 #define MAXNDIM 10
12 
13 typedef struct {
14  int block;
15  float line;
16  float sample;
17 } pts_t;
18 
19 int npts = 40;
20 pts_t pts[] = { { 1, -0.5, -0.5 }, \
21  { 1, -0.499999, -0.499999 }, \
22  { 1, 0.0, 0.0 }, \
23  { 1, 0.5, 0.5 }, \
24  { 1, 127.0, 511.0 }, \
25  { 1, 127.5, 511.5 }, \
26  { 1, 511.0, 2047.0 }, \
27  { 1, 511.5, 2047.5 }, \
28  { 1, 101.97, 64.23 }, \
29  { 1, 101.0, 64.0 }, \
30  { 65, -0.5, -0.5 }, \
31  { 65, -0.499999, -0.499999 }, \
32  { 65, 0.0, 0.0 }, \
33  { 65, 0.5, 0.5 }, \
34  { 65, 127.0, 511.0 }, \
35  { 65, 127.5, 511.5 }, \
36  { 65, 511.0, 2047.0 }, \
37  { 65, 511.5, 2047.5 }, \
38  { 65, 101.97, 64.23 }, \
39  { 65, 101.0, 64.0 }, \
40  { 91, -0.5, -0.5 }, \
41  { 91, -0.499999, -0.499999 }, \
42  { 91, 0.0, 0.0 }, \
43  { 91, 0.5, 0.5 }, \
44  { 91, 127.0, 511.0 }, \
45  { 91, 127.5, 511.5 }, \
46  { 91, 511.0, 2047.0 }, \
47  { 91, 511.5, 2047.5 }, \
48  { 91, 101.97, 64.23 }, \
49  { 91, 101.0, 64.0 }, \
50  { 180, -0.5, -0.5 }, \
51  { 180, -0.499999, -0.499999 }, \
52  { 180, 0.0, 0.0 }, \
53  { 180, 0.5, 0.5 }, \
54  { 180, 127.0, 511.0 }, \
55  { 180, 127.5, 511.5 }, \
56  { 180, 511.0, 2047.0 }, \
57  { 180, 511.5, 2047.5 }, \
58  { 180, 101.97, 64.23 }, \
59  { 180, 101.0, 64.0 }, \
60 };
61 
62 int main(int argc, char *argv[]) {
63 
64  int32 fid = FAIL;
65  int32 gid = FAIL;
66  int igrid, i;
67  int32 ngrid;
68  int32 nline, nsample;
69  double lat_r, lon_r;
70  double savelon_r1, savelon_r2;
71  double somx, somy;
72  int b;
73  float l, s;
74  int32 strbufsize;
75  char *filepath;
76  char **gridname;
77  char *gridlist;
78  float64 ulc[2], lrc[2];
79  int32 spherecode, zonecode, projcode;
80  float64 projparam[NPROJ];
81  float32 offset[NOFFSET];
82  long iflg;
83  int status;
84  char diffflg;
85  int32 ndim;
86  int32 dim[MAXNDIM];
87  char dimlist[STRLEN];
88  intn hdfeos_status_code;
89  void *mem_status_code;
90  long (*for_trans[MAXPROJ+1])();
91  long (*inv_trans[MAXPROJ+1])();
92 
93  /* --------------- */
94  /* Check arguments */
95  /* --------------- */
96 
97  if (argc != 2) {
98  fprintf(stderr, "Usage: %s hdfeos_grid_file\n", argv[0]);
99  exit(1);
100  }
101  filepath = argv[1];
102 
103  /* ---------------------------------------------------- */
104  /* Inquire and allocate memory for the hdfeos gridnames */
105  /* This is only require if you need the gridnames */
106  /* ---------------------------------------------------- */
107 
108  hdfeos_status_code = GDinqgrid(filepath, NULL, &strbufsize);
109  HDFEOS_ERROR_CHECK("GDinqgrid");
110 
111  mem_status_code = gridlist = (char *)malloc(strbufsize+1);
112  MEM_ERROR_CHECK("malloc");
113 
114  hdfeos_status_code = ngrid = GDinqgrid(filepath, gridlist, NULL);
115  HDFEOS_ERROR_CHECK("GDinqgrid");
116 
117  mem_status_code = gridname = (char **)malloc(ngrid * sizeof(char *));
118  MEM_ERROR_CHECK("malloc");
119 
120  gridname[0] = strtok(gridlist, ",");
121  for (igrid = 1; igrid < ngrid; igrid++) gridname[igrid] = strtok(NULL,",");
122 
123  /* ------------------------- */
124  /* Open the hdfeos grid file */
125  /* ------------------------- */
126 
127  hdfeos_status_code = fid = GDopen(filepath, DFACC_READ);
128  HDFEOS_ERROR_CHECK("GDopen");
129 
130  /* ---------------------------------------- */
131  /* Loop through all the grids because I can */
132  /* ---------------------------------------- */
133 
134  for (igrid = 0; igrid < ngrid; igrid++) {
135 
136  /* ---------------------------- */
137  /* Attach to the grid of choice */
138  /* ---------------------------- */
139 
140  hdfeos_status_code = gid = GDattach(fid, gridname[igrid]);
141  HDFEOS_ERROR_CHECK("GDattach");
142 
143  /* --------------------------------------------------------------- */
144  /* Inquire grid dimensions to check number of blocks */
145  /* Inquire grid info to get the number of lines/sample and ulc/lrc */
146  /* Inquire SOM relative block offsets */
147  /* Initialize misr block/line/sample projection routines */
148  /* --------------------------------------------------------------- */
149 
150  hdfeos_status_code = ndim = GDinqdims(gid, dimlist, dim);
151  HDFEOS_ERROR_CHECK("GDinqdims");
152 
153  /* Block dimension is always last dimension returned by GDinqdims. */
154  if (dim[ndim - 1] != NBLOCK) MTK_ERROR("File does not have 180 blocks");
155 
156  hdfeos_status_code = GDgridinfo(gid, &nline, &nsample, ulc, lrc);
157  HDFEOS_ERROR_CHECK("GDgridinfo");
158 
159  hdfeos_status_code = GDblkSOMoffset(gid, offset, NOFFSET, "r");
160  HDFEOS_ERROR_CHECK("GDblkSOMoffset");
161 
162  status = misr_init(NBLOCK, nline, nsample, offset, ulc, lrc);
163  if (status) MTK_ERROR("misr_init");
164 
165  printf("\nFilename (path/orbit): %s\n", filepath);
166  printf("Gridname: %s\n", gridname[igrid]);
167  printf("Lines/Samples: (%d, %d)\n", nline, nsample);
168  printf("ULC (x,y) (m): (%f, %f)\n", ulc[0], ulc[1]);
169  printf("LRC (x,y) (m): (%f, %f)\n", lrc[0], lrc[1]);
170  printf("Block offsets: (%f", offset[0]);
171  for (i = 1; i < NOFFSET; i++) printf(", %f", offset[i]);
172  printf(")\n");
173 
174  /* ------------------------------------------------------------ */
175  /* Inquire grid projection info to get project codes/parameters */
176  /* Initialize gctp SOM forward and inverse projection routines */
177  /* ------------------------------------------------------------ */
178 
179  hdfeos_status_code = GDprojinfo(gid, &projcode, &zonecode,
180  &spherecode, projparam);
181  HDFEOS_ERROR_CHECK("GDprojinfo");
182 
183  for_init((long)projcode, (long)zonecode, (double*)projparam,
184  (long)spherecode, NULL, NULL, &iflg, for_trans);
185  if (iflg) MTK_ERROR("for_init");
186 
187  inv_init((long)projcode, (long)zonecode, (double*)projparam,
188  (long)spherecode, NULL, NULL, &iflg, inv_trans);
189  if (iflg) MTK_ERROR("inv_init");
190 
191  printf("GCTP projection code: %d\n", projcode);
192  printf("GCTP zone code (not used for SOM): %d\n", zonecode);
193  printf("GCTP sphere code: %d\n", spherecode);
194  printf("GCTP projection parameters: (%f",projparam[0]);
195  for (i = 1; i < NPROJ; i++) printf(", %f", projparam[i]);
196  printf(")\n");
197 
198  /* --------------------------------------------------------------------- */
199  /* Detach from the grid because we don't need it anymore in this example */
200  /* We would need it if we go on to access fields, so don't detach here */
201  /* --------------------------------------------------------------------- */
202 
203  if (gid != FAIL) GDdetach(gid);
204 
205  /* ----------------------------------------- */
206  /* Loop over some inverse transformations */
207  /* (b,l.l,s.s) -> (X,Y) -> (lat,lon) */
208  /* and over some forward transformations */
209  /* (lat,lon) -> (X,Y) -> (b,l.l,s.s) */
210  /* ----------------------------------------- */
211 
212  printf(" (blk, line , sample ) "
213  "( SOM X , SOM Y ) "
214  "( Lat , Lon )\n");
215 
216  for (i = 0; i < npts; i++) {
217 
218  b = pts[i].block;
219  l = pts[i].line;
220  s = pts[i].sample;
221 
222  /* -------------------------------------------------------- */
223  /* Inverse transformation (b,l.l,s.s) -> (X,Y) -> (lat,lon) */
224  /* -------------------------------------------------------- */
225 
226  misrinv(b, l, s, &somx, &somy); /* (b,l.l,s.s) -> (X,Y) */
227  sominv(somx, somy, &lon_r, &lat_r); /* (X,Y) -> (lat,lon) */
228 
229  printf("%2d: (%3d,%11.6f,%12.6f) -> (%17.6f,%17.6f) -> "
230  "(%10.6f,%11.6f) --|\n",
231  i, b, l, s, somx, somy, lat_r * R2D, lon_r * R2D);
232 
233  /* -------------------------------------------------------- */
234  /* Forward transformation (lat,lon) -> (X,Y) -> (b,l.l,s.s) */
235  /* -------------------------------------------------------- */
236 
237  somfor(lon_r, lat_r, &somx, &somy); /* (lat,lon) -> (X,Y) */
238  misrfor(somx, somy, &b, &l, &s); /* (X,Y) -> (b,l.l,s.s) */
239 
240  if (b != pts[i].block) diffflg = '*';
241  else diffflg = ' ';
242 
243  printf(" %c (%3d,%11.6f,%12.6f) <- (%17.6f,%17.6f) <- "
244  "(%10.6f,%11.6f) <-|\n",
245  diffflg, b, l, s, somx, somy, lat_r * R2D, lon_r * R2D);
246 
247  /* -------------------------------------------------- */
248  /* Save the longitude of block 91 to find location of */
249  /* equator crossing */
250  /* -------------------------------------------------- */
251 
252  if (pts[i].block == 91 &&
253  pts[i].line == 0.0 &&
254  pts[i].sample == 0.0) {
255  savelon_r1 = lon_r;
256  }
257  if (pts[i].block == 91 &&
258  pts[i].line == (float)(nline-1) &&
259  pts[i].sample == (float)(nsample-1)) {
260  savelon_r2 = lon_r;
261  }
262  }
263 
264  /* --------------------------------------------------- */
265  /* Determine block/line/sample of the equator crossing */
266  /* approximately in the center of the block */
267  /* --------------------------------------------------- */
268 
269  lat_r = 0.0;
270  if (savelon_r1 < 0.0 && savelon_r2 > 0.0 ||
271  savelon_r1 > 0.0 && savelon_r2 < 0.0) {
272  lon_r = (savelon_r1 - savelon_r2) / 2.0;
273  } else {
274  lon_r = (savelon_r1 + savelon_r2) / 2.0;
275  }
276 
277  /* -------------------------------------------------------- */
278  /* Forward transformation (lat,lon) -> (X,Y) -> (b,l.l,s.s) */
279  /* -------------------------------------------------------- */
280 
281  somfor(lon_r, lat_r, &somx, &somy); /* (lat,lon) -> (X,Y) */
282  misrfor(somx, somy, &b, &l, &s); /* (X,Y) -> (b,l.l,s.s) */
283 
284  printf("%2d: (%3d,%11.6f,%12.6f) <- (%17.6f,%17.6f) <- "
285  "(%10.6f,%11.6f) = equator crossing\n",
286  npts, b, l, s, somx, somy, lat_r * R2D, lon_r * R2D);
287 
288  /* -------------------------------------- */
289  /* Extreme upper left corner (not center) */
290  /* -------------------------------------- */
291 
292  somx = ulc[0];
293  somy = lrc[1]; /* Notice the switch from ulc[1]. */
294 
295  sominv(somx, somy, &lon_r, &lat_r);
296  misrfor(somx, somy, &b, &l, &s);
297 
298  printf("%2d: (%3d,%11.6f,%12.6f) <- (%17.6f,%17.6f) -> "
299  "(%10.6f,%11.6f) = ulc of block 1\n",
300  npts+1, b, l, s, somx, somy, lat_r * R2D, lon_r * R2D);
301 
302  /* ------------------- ------------------- */
303  /* Extreme lower right corner (not center) */
304  /* -------------------- ------------------ */
305 
306  somx = lrc[0];
307  somy = ulc[1]; /* Notice the switch from lrc[1]. */
308 
309  sominv(somx, somy, &lon_r, &lat_r);
310  misrfor(somx, somy, &b, &l, &s);
311 
312  printf("%2d: (%3d,%11.6f,%12.6f) <- (%17.6f,%17.6f) -> "
313  "(%10.6f,%11.6f) = lrc of block 1\n",
314  npts+2, b, l, s, somx, somy, lat_r * R2D, lon_r * R2D);
315 
316  /* -------------------------------------- */
317  /* Origin of SOM projection for this path */
318  /* -------------------------------------- */
319 
320  somx = 0.0;
321  somy = 0.0;
322 
323  sominv(somx, somy, &lon_r, &lat_r);
324  misrfor(somx, somy, &b, &l, &s);
325 
326  printf("%2d: (%3d,%11.6f,%12.6f) <- (%17.6f,%17.6f) -> "
327  "(%10.6f,%11.6f) = SOM origin (long of asc node)\n",
328  npts+3, b, l, s, somx, somy, lat_r * R2D, lon_r * R2D);
329 
330  /* --------------------------------------------------- */
331  /* Origin of SOM projection plus 180 degrees longitude */
332  /* --------------------------------------------------- */
333 
334  lat_r = 0.0;
335  lon_r = (lon_r > 0.0 ? lon_r - (180.0*D2R) : lon_r + (180.0*D2R));
336 
337  somfor(lon_r, lat_r, &somx, &somy);
338  misrfor(somx, somy, &b, &l, &s);
339 
340  printf("%2d: (%3d,%11.6f,%12.6f) <- (%17.6f,%17.6f) <- "
341  "(%10.6f,%11.6f) = SOM origin plus 180 in long.\n",
342  npts+4, b, l, s, somx, somy, lat_r * R2D, lon_r * R2D);
343 
344  /* --------------------------------------- */
345  /* Equator crossing using SOM X from above */
346  /* --------------------------------------- */
347 
348  somy = 0.0;
349 
350  sominv(somx, somy, &lon_r, &lat_r);
351  misrfor(somx, somy, &b, &l, &s);
352 
353  printf("%2d: (%3d,%11.6f,%12.6f) <- (%17.6f,%17.6f) -> "
354  "(%10.6f,%11.6f) = equator crossing\n",
355  npts+5, b, l, s, somx, somy, lat_r * R2D, lon_r * R2D);
356 
357  }
358 
359  if (fid != FAIL) GDclose(fid);
360  if (gridlist) free(gridlist);
361  if (gridname) free(gridname);
362 
363  printf("\nNotes:\n\n"
364 "1) Given a block, fractional line and fraction sample triplet the\n"
365 " following transformations performed:\n\n"
366 " Inverse transformation: (b,l.l,s.s) -> (X,Y) -> (lat,lon) -|\n"
367 " |--------------------------------------|\n"
368 " Forward transformation: |-> (lat,lon) -> (X,Y) -> (b,l.l,s.s)\n\n"
369 "2) The transforms marked with a * did not reproduce the same\n"
370 " answer either because of rounding errors in the GCTP codes or because\n"
371 " they are out of bounds of the particular grid. The misr transform\n"
372 " routines (misr_init, misrfor and misrinv) are designed to handle out\n"
373 " of bounds conditions and return all -1's. This enables a resampling\n"
374 " routine to determine whether resampling can be done or not, if these\n"
375 " routines are used for reprojection.\n\n"
376 "3) Notice that the ULC Y/LRC Y values returned by gridinfo are incorrectly \n"
377 " switched when compared to transform number 0, 5 or 7 (depending\n"
378 " on resolution).\n\n"
379 "4) Also note that the ULC/LRC values returned by gridinfo are for block 1\n"
380 " extreme pixel edges (not pixel centers).\n\n"
381 "5) Note that SOM X is always increasing as blocks increase (in fact,\n"
382 " SOM X is zero meters at the longitude of the ascending node - the\n"
383 " 5th parameter of projection paramters). SOM Y tends to be mostly\n"
384 " positive in the Northern blocks and negative in the Southern blocks.\n"
385 " Each SOM path is a separate projection with the origin at the\n"
386 " night side equator and the longitude of the ascending node.\n\n"
387 "6) The block offsets are the number of 1.1km subregions from the\n"
388 " previous block. The first offset is relative first block.\n\n"
389 "7) The 4th and 5th projection parameter are in the format of packed\n"
390 " dddmmmsss.ss as documented in the GCTP codes (see paksz.c).\n\n"
391 "8) MISR uses the GCTP SOM projection A which specifies the inclination\n"
392 " angle and longitude of the ascending node instead of path number\n\n"
393 "9) The last six transformations compute various special case locations.\n"
394 " Note the direction of the transform arrows. Can you determine why the\n"
395 " lrc of block 1 is actually in block 2? Hint: it is not the pixel\n"
396 " center, but rather the edge.\n\n"
397 "10) Last note. Remember that the SOM projection is singular at the poles\n"
398 " and thus undefined there.\n\n"
399  );
400  exit(0);
401 }
#define MAXPROJ
Definition: proj.h:84
int32 GDattach(int32, char *)
int misr_init(const int nblock, const int nline, const int nsample, const float relOff[NOFFSET], const double ulc_coord[], const double lrc_coord[])
Definition: misr_init.c:18
#define DFACC_READ
Definition: hdf.h:44
intn GDclose(int32)
float sample
Definition: misrcoordex.c:16
intn GDprojinfo(int32, int32 *, int32 *, int32 *, float64 [])
int npts
Definition: misrcoordex.c:19
#define STRLEN
Definition: misrproj.h:6
double ulc[2]
Definition: misr_init.c:9
intn GDdetach(int32)
int main(int argc, char *argv[])
Definition: misrcoordex.c:62
long b
Definition: jpegint.h:371
#define MTK_ERROR(msg)
Definition: errormacros.h:18
#define NOFFSET
Definition: misrproj.h:8
intn GDblkSOMoffset(int32, float32 [], int32, char *)
double lrc[2]
Definition: misr_init.c:10
int misrfor(const double x, const double y, int *block, float *line, float *sample)
Definition: misrfor.c:18
intn GDgridinfo(int32, int32 *, int32 *, float64 [], float64 [])
int sominv(double y, double x, double *lon, double *lat)
#define R2D
Definition: misrproj.h:9
#define NBLOCK
Definition: MisrProjParam.h:51
#define D2R
Definition: misrproj.h:10
int misrinv(const int block, const float line, const float sample, double *x, double *y)
Definition: misrinv.c:17
pts_t pts[]
Definition: misrcoordex.c:20
#define MAXNDIM
Definition: misrcoordex.c:11
int for_init(int outsys, int outzone, const double *outparm, int outdatum, char *fn27, char *fn83, int *iflg, int(*for_trans[])(double, double, double *, double *))
int block
Definition: misrcoordex.c:14
float line
Definition: misrcoordex.c:15
#define NPROJ
Definition: misrproj.h:11
int32 GDinqdims(int32, char *, int32 [])
int32 GDinqgrid(char *, char *, int32 *)
int somfor(double lon, double lat, double *y, double *x)
HDFFCLIBAPI intf * offset
int32 GDopen(char *, intn)
int inv_init(int insys, int inzone, const double *inparm, int indatum, char *fn27, char *fn83, int *iflg, int(*inv_trans[])(double, double, double *, double *))
#define MEM_ERROR_CHECK(msg)
Definition: errormacros.h:12
#define FAIL
Definition: hdf.h:94
#define HDFEOS_ERROR_CHECK(msg)
Definition: errormacros.h:6

MISR Toolkit - Copyright © 2005 - 2020 Jet Propulsion Laboratory
Generated on Fri Jun 19 2020 22:49:51