OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
l3mapgen.cpp
Go to the documentation of this file.
1 /*
2  * l3mapgen.cpp
3  *
4  * Created on: Jan 15, 2014
5  * Author: dshea
6  */
7 #include "l3mapgen.h"
8 
9 #include "OutFile.h"
10 #include <L3FileSMI.h>
11 
12 #include <iostream>
13 #include <iomanip>
14 #include <fstream>
15 
16 #include <genutils.h>
17 #include <timeutils.h>
18 #include <string>
19 
20 #include <proj.h>
21 #include <sensorInfo.h>
22 #include <productInfo.h>
23 
24 using namespace std;
25 using namespace l3;
26 
27 #define VERSION "1.0"
28 
29 #define NUM_SEARCH_POINTS 51
30 
33 };
34 enum InterpType {
36 };
37 enum EastWest {
39 };
40 
41 // global params for program
42 double widthInDeg;
43 double heightInDeg;
44 double mapEast;
45 double mapWest;
46 
47 int imageWidth = 0;
48 int imageHeight = 0;
49 bool doingQuality = false;
50 bool doingRGB = false;
51 bool doingTransparency = false;
52 bool trimNSEW = true;
53 bool write_projtext = false;
54 
55 string prodName;
56 vector<string> prodNameList;
57 vector<MeasurementType> prodMeasurementList;
58 string qualName;
59 
61 
62 // landmask
63 bool applyMask = false;
64 static grid_info_t* landmaskGrid = {0};
65 
66 int isLand(float lat, float lon) {
67  if (landmaskGrid != NULL) {
68  double value;
69  int status = get_bylatlon(landmaskGrid, lat, lon, &value);
70  if (!status)
71  return ((short) value != 1); // 1 = water
72  }
73  return (0); // assume water if lon, lat not found
74 }
75 
76 void printStartInfo(vector<OutFile*> outFiles) {
77  if (want_verbose) {
78  meta_l3bType* metaData = outFiles[0]->getMetadata();
79 
81  printf("ifile : %s\n", clo_getString(optionList, "ifile"));
82  printf("ofile : ");
83  for(OutFile* outFile : outFiles) {
84  if(outFile == outFiles[0])
85  printf("%s", outFile->getFileName().c_str());
86  else
87  printf(",%s", outFile->getFileName().c_str());
88  }
89  printf("\n");
90 
91  printf("oformat : %s\n", clo_getString(optionList, "oformat"));
92  if (clo_isSet(optionList, "ofile2")) {
93  printf("ofile2 : %s\n", clo_getString(optionList, "ofile2"));
94  printf("oformat2 : %s\n", clo_getString(optionList, "oformat2"));
95  }
96  printf("projection : %s\n", clo_getRawString(optionList, "projection"));
97  printf("resolution : %.3fm\n", outFiles[0]->getResolution());
98  if (clo_isSet(optionList, "width"))
99  printf("width : %d\n", clo_getInt(optionList, "width"));
100  if (doingRGB)
101  printf("product_rgb: %s\n", prodName.c_str());
102  else
103  printf("product : %s\n", prodName.c_str());
104  if (doingQuality)
105  printf("qual_prod : %s\n", qualName.c_str());
106  printf("north : %8.3f\n", metaData->north);
107  printf("south : %8.3f\n", metaData->south);
108  printf("east : %8.3f\n", metaData->east);
109  printf("west : %8.3f\n", metaData->west);
110  float tmpf = clo_getFloat(optionList, "central_meridian");
111  if (tmpf > -900.0) {
112  printf("central_meridian : %8.3f\n", tmpf);
113  }
114  if (clo_isSet(optionList, "lat_ts")) {
115  printf("lat_ts : %8.3f\n", clo_getFloat(optionList, "lat_ts"));
116  }
117  if (clo_isSet(optionList, "lat_0")) {
118  printf("lat_0 : %8.3f\n", clo_getFloat(optionList, "lat_0"));
119  }
120  if (clo_isSet(optionList, "azimuth")) {
121  printf("azimuth : %8.3f\n", clo_getFloat(optionList, "azimuth"));
122  }
123  printf("image size : %d x %d\n", imageHeight, imageWidth);
124 
125  printf("\n");
126  }
127 }
128 
129 void printEndInfo(OutFile* outFile) {
130  if (want_verbose) {
131  printf("\n\n");
132  printf("actual data min : %f\n", outFile->getFileMinVal());
133  printf("actual data max : %f\n", outFile->getFileMaxVal());
134  printf("num filled pixels : %d\n", outFile->getNumFilledPixels());
135  printf("percent filled pixels : %.2f%%\n",
136  outFile->getPercentFilledPixels());
137  printf("\n");
138  }
139 }
140 
141 void printPercentDone(float percentDone) {
142  static float percentPrev = 0.0;
143  static const float percentDelta = 0.01;
144  if (want_verbose && (percentDone - percentPrev > percentDelta)) {
145  percentPrev = percentDone;
146  printf("\r%2d%% complete", (int) (percentDone * 100));
147  fflush(stdout);
148  }
149 }
150 
152  int i;
153  float centralMeridian = clo_getFloat(optionList, "central_meridian");
154  if (centralMeridian > -900.0) {
155  i = 0;
156  while (centralMeridian < -180.0) {
157  centralMeridian += 360.0;
158  i++;
159  if (i > 5) {
160  printf("-E- central meridian is way off\n");
161  exit(EXIT_FAILURE);
162  }
163  }
164  i = 0;
165  while (centralMeridian > 180.0) {
166  centralMeridian -= 360.0;
167  i++;
168  if (i > 5) {
169  printf("-E- central meridian is way off\n");
170  exit(EXIT_FAILURE);
171  }
172  }
173  } else {
174  centralMeridian = (mapWest + mapEast) / 2.0;
175  }
176  return constrainLon(centralMeridian);
177 }
178 
180  string s = str;
181  boost::trim(s);
182  boost::to_lower(s);
183 
184  if (s.compare("bin") == 0)
185  return Interp_Bin;
186  if (s.compare("linear") == 0)
187  return Interp_Linear;
188  if (s.compare("area") == 0)
189  return Interp_Area;
190 
191  return Interp_Nearest;
192 }
193 
195  switch (interp) {
196  case Interp_Nearest:
197  return "nearest";
198  case Interp_Bin:
199  return "bin";
200  case Interp_Linear:
201  return "linear";
202  case Interp_Area:
203  return "area";
204  default:
205  return "unknown";
206  }
207 }
208 
209 bool checkDateLineCrossed(double lon, double deltaLon) {
210  bool crossed = false;
211 
212  float minlon = constrainLon(lon) - (deltaLon / 2.0);
213  float maxlon = constrainLon(lon) + (deltaLon / 2.0);
214 
215  if (minlon > 0 && maxlon < 0)
216  crossed = true;
217 
218  return crossed;
219 
220 }
221 
222 Box_t getBox(float lat, float lon, float deltaLat, float deltaLon, int eastwest = notEastOrWest) {
223  Point_t pMin;
224  Point_t pMax;
225  lon = constrainLon(lon);
226  if (eastwest == IsEast) {
227  pMin.set<0>(180.0);
228  pMin.set<1>(lat - (deltaLat / 2.0));
229  pMax.set<0>(lon + (deltaLon / 2.0));
230  pMax.set<1>(lat + (deltaLat / 2.0));
231  } else if (eastwest == IsWest) {
232  pMin.set<0>(lon - (deltaLon / 2.0));
233  pMin.set<1>(lat - (deltaLat / 2.0));
234  pMax.set<0>(180.0);
235  pMax.set<1>(lat + (deltaLat / 2.0));
236  } else {
237  pMin.set<0>(lon - (deltaLon / 2.0));
238  pMin.set<1>(lat - (deltaLat / 2.0));
239  pMax.set<0>(lon + (deltaLon / 2.0));
240  pMax.set<1>(lat + (deltaLat / 2.0));
241  }
242  Box_t box(pMin, pMax);
243  return box;
244 }
245 
246 L3Bin* getBoxBins(L3File* l3File, float lat, float lon, float deltaLat,
247  float deltaLon, float fudge, bool areaWeighted, int eastwest = notEastOrWest) {
248 
249  Box_t box = getBox(lat, lon, deltaLat, deltaLon, eastwest);
250 
251  L3Bin* l3Bin = l3File->getBinsInside(box, areaWeighted);
252 
253  if (!l3Bin && fudge > 1) { // try again with fudge factor
254  Box_t box = getBox(lat, lon, deltaLat*fudge, deltaLon*fudge, eastwest);
255  l3Bin = l3File->getBinsInside(box, areaWeighted);
256  }
257  return l3Bin;
258 }
259 
265 bool setupQualityProcessing(L3File* l3File, vector<OutFile*> outFiles,
266  OutFile* outFile2) {
267  doingQuality = true;
268  clo_option_t* option = clo_findOption(optionList, "use_quality");
269  if (clo_isOptionSet(option)) {
270  if (clo_getOptionBool(option)) {
271  if (l3File->hasQuality()) {
272  doingQuality = true;
273  } else {
274  printf("-E- Quality processing was requested, "
275  "but the input file does not have quality data.\n");
276  exit(EXIT_FAILURE);
277  }
278  if (clo_isSet(optionList, "quality_product")) {
279  qualName = clo_getRawString(optionList, "quality_product");
280  } else {
281  qualName = "qual_" + prodNameList[0];
282  }
283  } else {
284  doingQuality = false;
285  }
286  } else {
287  if (l3File->hasQuality())
288  doingQuality = true;
289  else
290  doingQuality = false;
291  }
292 
294  for(OutFile* outFile : outFiles) {
295  outFile->setQualityProcessing(doingQuality);
296  outFile->setQualityName(qualName);
297  }
298  if (outFile2) {
300  outFile2->setQualityName(qualName);
301  }
302  return doingQuality;
303 }
304 
305 void setupProduct(string &prodName, MeasurementType measure, OutFile* outFile,
306  OutFile* outFile2) {
307  // get the product info
308  productInfo_t *p_info;
309  p_info = allocateProductInfo();
310 
311  int sensorId = sensorName2SensorId(outFile->getMetadata()->sensor_name);
312  if (sensorId == -1) {
313  printf("-E- Unknown sensor name %s\n",
314  outFile->getMetadata()->sensor_name);
315  exit(EXIT_FAILURE);
316  }
317 
318  if (!findProductInfo(prodName.c_str(), sensorId, p_info)) {
319  printf("-E- product %s not found in XML product table\n",
320  prodName.c_str());
321  exit(EXIT_FAILURE);
322  }
323 
324  // now we have to fix the p_info structure
325  // Avg, Stdev, Variance, Nobs, Nscenes, ObsTime, BinNum
326  string tmpStr;
327  switch (measure) {
328  case Avg:
329  break;
330  case Stdev:
331  tmpStr = p_info->description;
332  free(p_info->description);
333  tmpStr += " (Standard Deviation)";
334  p_info->description = strdup(tmpStr.c_str());
335  free(p_info->palette);
336  p_info->palette = strdup(PRODUCT_DEFAULT_palette);
337  free(p_info->dataType);
338  p_info->dataType = strdup("float");
339  tmpStr = p_info->suffix;
340  free(p_info->suffix);
341  tmpStr += "_stdev";
342  p_info->suffix = strdup(tmpStr.c_str());
343  free(p_info->displayScale);
344  p_info->displayScale = strdup("linear");
345  p_info->addOffset = 0.0;
346  p_info->scaleFactor = 1.0;
347  break;
348  case Variance:
349  tmpStr = p_info->description;
350  free(p_info->description);
351  tmpStr += " (Variance)";
352  p_info->description = strdup(tmpStr.c_str());
353  free(p_info->palette);
354  p_info->palette = strdup(PRODUCT_DEFAULT_palette);
355  free(p_info->dataType);
356  p_info->dataType = strdup("float");
357  tmpStr = p_info->suffix;
358  free(p_info->suffix);
359  tmpStr += "_var";
360  p_info->suffix = strdup(tmpStr.c_str());
361  free(p_info->displayScale);
362  p_info->displayScale = strdup("linear");
363  p_info->addOffset = 0.0;
364  p_info->scaleFactor = 1.0;
365  break;
366  case Nobs:
367  tmpStr = p_info->description;
368  free(p_info->description);
369  tmpStr += " (number of observations)";
370  p_info->description = strdup(tmpStr.c_str());
371  free(p_info->units);
372  p_info->units = strdup("counts");
373  free(p_info->palette);
374  p_info->palette = strdup(PRODUCT_DEFAULT_palette);
375  free(p_info->dataType);
376  p_info->dataType = strdup("short");
377  tmpStr = p_info->suffix;
378  free(p_info->suffix);
379  tmpStr += "_nobs";
380  p_info->suffix = strdup(tmpStr.c_str());
381  p_info->fillValue = PRODUCT_DEFAULT_fillValue;
382  p_info->validMin = 0;
383  p_info->validMax = 32767;
384  free(p_info->displayScale);
385  p_info->displayScale = strdup("linear");
386  p_info->displayMin = PRODUCT_DEFAULT_displayMin;
387  p_info->displayMax = PRODUCT_DEFAULT_displayMax;
388  p_info->addOffset = 0.0;
389  p_info->scaleFactor = 1.0;
390  break;
391  case Nscenes:
392  tmpStr = p_info->description;
393  free(p_info->description);
394  tmpStr += " (number of scenes)";
395  p_info->description = strdup(tmpStr.c_str());
396  free(p_info->units);
397  p_info->units = strdup("counts");
398  free(p_info->palette);
399  p_info->palette = strdup(PRODUCT_DEFAULT_palette);
400  free(p_info->dataType);
401  p_info->dataType = strdup("short");
402  tmpStr = p_info->suffix;
403  free(p_info->suffix);
404  tmpStr += "_nscenes";
405  p_info->suffix = strdup(tmpStr.c_str());
406  p_info->fillValue = PRODUCT_DEFAULT_fillValue;
407  p_info->validMin = 0;
408  p_info->validMax = 32767;
409  free(p_info->displayScale);
410  p_info->displayScale = strdup("linear");
411  p_info->displayMin = PRODUCT_DEFAULT_displayMin;
412  p_info->displayMax = PRODUCT_DEFAULT_displayMax;
413  p_info->addOffset = 0.0;
414  p_info->scaleFactor = 1.0;
415  break;
416  case ObsTime:
417  tmpStr = p_info->description;
418  free(p_info->description);
419  tmpStr += " (observation time, TAI93)";
420  p_info->description = strdup(tmpStr.c_str());
421  free(p_info->units);
422  p_info->units = strdup("counts");
423  free(p_info->palette);
424  p_info->palette = strdup(PRODUCT_DEFAULT_palette);
425  free(p_info->dataType);
426  p_info->dataType = strdup("float");
427  tmpStr = p_info->suffix;
428  free(p_info->suffix);
429  tmpStr += "_obs_time";
430  p_info->suffix = strdup(tmpStr.c_str());
431  p_info->fillValue = PRODUCT_DEFAULT_fillValue;
432  p_info->validMin = PRODUCT_DEFAULT_validMin;
433  p_info->validMax = PRODUCT_DEFAULT_validMin;
434  free(p_info->displayScale);
435  p_info->displayScale = strdup("linear");
436  p_info->displayMin = PRODUCT_DEFAULT_displayMin;
437  p_info->displayMax = PRODUCT_DEFAULT_displayMax;
438  p_info->addOffset = 0.0;
439  p_info->scaleFactor = 1.0;
440  break;
441  case BinNum:
442  tmpStr = p_info->description;
443  free(p_info->description);
444  tmpStr += " (bin ID number)";
445  p_info->description = strdup(tmpStr.c_str());
446  free(p_info->units);
447  p_info->units = strdup("dimensionless");
448  free(p_info->palette);
449  p_info->palette = strdup(PRODUCT_DEFAULT_palette);
450  free(p_info->dataType);
451  p_info->dataType = strdup("int");
452  tmpStr = p_info->suffix;
453  free(p_info->suffix);
454  tmpStr += "_bin_num";
455  p_info->suffix = strdup(tmpStr.c_str());
456  p_info->fillValue = PRODUCT_DEFAULT_fillValue;
457  p_info->validMin = PRODUCT_DEFAULT_validMin;
458  p_info->validMax = PRODUCT_DEFAULT_validMin;
459  free(p_info->displayScale);
460  p_info->displayScale = strdup("linear");
461  p_info->displayMin = PRODUCT_DEFAULT_displayMin;
462  p_info->displayMax = PRODUCT_DEFAULT_displayMax;
463  p_info->addOffset = 0.0;
464  p_info->scaleFactor = 1.0;
465  break;
466  } // switch
467 
468  // load landmask options before palette
469  applyMask = clo_getBool(optionList, "mask_land");
470  if (applyMask) {
471  char *strVal = clo_getOptionString(clo_findOption(optionList, "land"));
472  char landmaskFile[FILENAME_MAX];
473  parse_file_name(strVal, landmaskFile);
474  static const char* landmaskVars[] ={"watermask", "landmask", "z", NULL};
475  landmaskGrid = allocate_gridinfo();
476  int status = init_gridinfo(landmaskFile, landmaskVars, landmaskGrid);
477  if (status != NC_NOERR) {
478  free(landmaskGrid);
479  landmaskGrid = NULL;
480  cerr << "Error reading file " << landmaskFile << ": "
481  << nc_strerror(status) << "\n"
482  << "Land mask will not be applied.\n";
483  applyMask = false;
484  }
485  }
486 
487  // load palette
488  if (clo_getBool(optionList, "apply_pal")) {
489 
490  // set land_rgb before loading palette
491  outFile->setLandRGB(clo_getRawString(optionList, "rgb_land"));
492  if (outFile2)
493  outFile2->setLandRGB(clo_getRawString(optionList, "rgb_land"));
494 
495  clo_option_t* option = clo_findOption(optionList, "palfile");
496  if (clo_isOptionSet(option)) {
497  outFile->setPalette(clo_getOptionString(option), applyMask);
498  if (outFile2)
499  outFile2->setPalette(clo_getOptionString(option), applyMask);
500  } else {
501  outFile->setPalette(p_info->palette, applyMask);
502  if (outFile2)
503  outFile2->setPalette(p_info->palette, applyMask);
504  }
505  }
506 
507  // set the default scale factors for RGB
508  if (doingRGB) {
509  p_info->displayMin = 0.01;
510  p_info->displayMax = 0.9;
511  if (p_info->displayScale)
512  free(p_info->displayScale);
513  p_info->displayScale = strdup("log");
514  }
515 
516  // override default scale parameters if set on command line
517  if (clo_isSet(optionList, "datamin")) {
518  p_info->displayMin = clo_getFloat(optionList, "datamin");
519  }
520  if (clo_isSet(optionList, "datamax")) {
521  p_info->displayMax = clo_getFloat(optionList, "datamax");
522  }
523  if (clo_isSet(optionList, "scale_type")) {
524  if (p_info->displayScale)
525  free(p_info->displayScale);
526  p_info->displayScale = strdup(clo_getString(optionList, "scale_type"));
527  }
528 
529  outFile->addProduct(p_info);
530  if (outFile2)
531  outFile2->addProduct(p_info);
532 
533  freeProductInfo(p_info);
534 }
535 
536 void writeRawFile(L3File* l3File, vector<OutFile*> outFiles, OutFile* outFile2) {
537  L3Bin* l3Bin;
538  L3Row* l3Row;
539  imageHeight = l3File->getNumRows();
540  double resolution = EARTH_CIRCUMFERENCE / (imageHeight * 2);
541  imageWidth = imageHeight * 2;
542  int32_t start;
543  int32_t numBins;
544  int64_t baseBin;
545  int64_t endBin;
546  int64_t binNum;
547  int32_t row, col;
548 
549  int32_t numFilledPixels = 0;
550  meta_l3bType* metaData = outFiles[0]->getMetadata();
551 
552  string mapDesc = "Bin";
553  string projName = "Integerized Sinusoidal";
554 
555  sprintf(metaData->title, "%s Level-3 %s Mapped Image",
556  metaData->sensor_name, mapDesc.c_str());
557  for(OutFile* outFile : outFiles) {
558  strcpy(outFile->getMetadata()->title, metaData->title);
559  outFile->setFullLatLon(false);
560  outFile->setMapProjection(projName);
561  outFile->setResolution(resolution);
562  outFile->setSize(imageWidth, imageHeight);
563  }
564  if (outFile2) {
565  strcpy(outFile2->getMetadata()->title, metaData->title);
566  outFile2->setFullLatLon(false);
567  outFile2->setMapProjection(projName);
568  outFile2->setResolution(resolution);
569  outFile2->setSize(imageWidth, imageHeight);
570  }
571 
572  // setup all the product structures
573  for (size_t i = 0; i < prodNameList.size(); i++) {
574  OutFile* outFile;
575  if(outFiles.size() == 1)
576  outFile = outFiles[0];
577  else
578  outFile = outFiles[i];
580  outFile2);
581  }
582 
583  printStartInfo(outFiles);
584 
585 
586  for(OutFile* outFile : outFiles) {
587  if (!outFile->open()) {
588  printf("-E- Could not open ofile=\"%s\".\n",
589  outFile->getFileName().c_str());
590  exit(EXIT_FAILURE);
591  }
592  }
593  if (outFile2) {
594  if (!outFile2->open()) {
595  printf("-E- Could not open ofile2=\"%s\".\n",
596  outFile2->getFileName().c_str());
597  exit(EXIT_FAILURE);
598  }
599  }
600 
601  float centralMeridian = getCentralMeridian();
602 
603  for (row = imageHeight - 1; row >= 0; row--) {
604  printPercentDone(1.0 - (float) row / (float) imageHeight);
605 
606  l3Row = l3File->getRow(row);
607  numBins = l3File->getShape()->getNumCols(row);
608  baseBin = l3File->getShape()->getBaseBin(row);
609  endBin = baseBin + numBins;
610  if (centralMeridian < 0)
611  binNum = baseBin + numBins * (centralMeridian + 360.0) / 360.0;
612  else
613  binNum = baseBin + numBins * centralMeridian / 360.0;
614  start = (imageWidth - numBins) / 2;
615 
616  // clear out beginning empty pixels
617  for (col = 0; col < start; col++) {
618  for(OutFile* outFile : outFiles)
619  outFile->fillPixel(col);
620  if (outFile2)
621  outFile2->fillPixel(col);
622  }
623 
624  // set pixel values
625  for (int i = 0; i < numBins; i++) {
626  l3Bin = l3Row->getBin(binNum);
627  if (l3Bin) {
628  if (doingRGB) {
629  outFiles[0]->setPixelRGB(col, l3Bin->getMean(0),
630  l3Bin->getMean(1), l3Bin->getMean(2));
631  if (outFile2)
632  outFile2->setPixelRGB(col, l3Bin->getMean(0),
633  l3Bin->getMean(1), l3Bin->getMean(2));
634  } else {
635  for (size_t prod = 0; prod < prodNameList.size(); prod++) {
636  float val;
637  switch (prodMeasurementList[prod]) {
638  case Avg:
639  val = l3Bin->getMean(prod);
640  break;
641  case Stdev:
642  val = l3Bin->getStdev(prod);
643  break;
644  case Variance:
645  val = l3Bin->getVariance(prod);
646  break;
647  case Nobs:
648  val = l3Bin->getNobs();
649  break;
650  case Nscenes:
651  val = l3Bin->getNscenes();
652  break;
653  case ObsTime:
654  val = l3Bin->getObsTime();
655  break;
656  case BinNum:
657  val = l3Bin->getBinNum();
658  break;
659  default:
660  val = l3Bin->getMean(prod);
661  }
662  if(outFiles.size() == 1)
663  outFiles[0]->setPixel(col, val, prod);
664  else
665  outFiles[prod]->setPixel(col, val, 0);
666  if (outFile2)
667  outFile2->setPixel(col, val, prod);
668  }
669  }
670  numFilledPixels++;
671  } else {
672  for(OutFile* outFile : outFiles)
673  outFile->missingPixel(col);
674  if (outFile2)
675  outFile2->missingPixel(col);
676  }
677  col++;
678  binNum++;
679  if (binNum >= endBin)
680  binNum = baseBin;
681  }
682 
683  // clear out trailing empty pixels
684  for (; col < imageWidth; col++) {
685  for(OutFile* outFile : outFiles)
686  outFile->fillPixel(col);
687  if (outFile2)
688  outFile2->fillPixel(col);
689  }
690 
691  for(OutFile* outFile : outFiles)
692  outFile->writeLine();
693  if (outFile2)
694  outFile2->writeLine();
695  }
696 
697  for(OutFile* outFile : outFiles) {
698  outFile->setNumFilledPixels(numFilledPixels);
699  outFile->close();
700  }
701  if (outFile2) {
702  outFile2->setNumFilledPixels(numFilledPixels);
703  outFile2->close();
704  }
705 }
706 
707 void writeSmiFile(L3File* l3File, vector<OutFile*> outFiles, OutFile* outFile2) {
708 
709  int32_t numFilledPixels = 0;
710  meta_l3bType* metaData = outFiles[0]->getMetadata();
711  double resolution = outFiles[0]->getResolution();
712 
713  string mapDesc = "Standard";
714  string projName = "Equidistant Cylindrical";
715 
716  sprintf(metaData->title, "%s Level-3 %s Mapped Image",
717  metaData->sensor_name, mapDesc.c_str());
718 
719  // set up image parameters
720  if (imageWidth <= 0) {
722  if(imageWidth == 0)
723  imageWidth = 1;
724  } else {
726  for(OutFile* outFile : outFiles)
727  outFile->setResolution(resolution);
728  if (outFile2)
729  outFile2->setResolution(resolution);
730  }
732  if(imageHeight == 0)
733  imageHeight = 1;
734  double deltaLon = widthInDeg / imageWidth;
735  double deltaLat = heightInDeg / imageHeight;
736 
737  for(OutFile* outFile : outFiles) {
738  strcpy(outFile->getMetadata()->title, metaData->title);
739  outFile->setSize(imageWidth, imageHeight);
740  outFile->setMapProjection(projName);
741  }
742  if (outFile2) {
743  strcpy(outFile2->getMetadata()->title, metaData->title);
744  outFile2->getMetadata()->east = metaData->east;
745  outFile2->getMetadata()->west = metaData->west;
746  outFile2->setSize(imageWidth, imageHeight);
747  outFile2->setMapProjection(projName);
748  }
749 
750  // set up all the product structures
751  for (size_t i = 0; i < prodNameList.size(); i++) {
752  OutFile* outFile;
753  if(outFiles.size() == 1)
754  outFile = outFiles[0];
755  else
756  outFile = outFiles[i];
758  outFile2);
759  }
760 
761  // set up quality processing
762  setupQualityProcessing(l3File, outFiles, outFile2);
763 
764  printStartInfo(outFiles);
765 
766  for(OutFile* outFile : outFiles) {
767  if (!outFile->open()) {
768  printf("-E- Could not open ofile=\"%s\".\n",
769  outFile->getFileName().c_str());
770  exit(EXIT_FAILURE);
771  }
772  }
773 
774  if (outFile2) {
775  if (!outFile2->open()) {
776  printf("-E- Could not open ofile2=\"%s\".\n",
777  outFile2->getFileName().c_str());
778  exit(EXIT_FAILURE);
779  }
780  }
781 
783  float fudge = clo_getFloat(optionList, "fudge");
784 
785  // loop through output pixels
786  double lat = metaData->north - (deltaLat / 2.0);
787  L3Bin* l3Bin;
788 
789  for (int row = 0; row < imageHeight; row++) {
790  printPercentDone((float) row / (float) imageHeight);
791  double lon = metaData->west + (deltaLon / 2.0);
792 
793  for (int col = 0; col < imageWidth; col++) {
794  if (applyMask && isLand(lat, lon)) {
795  for(OutFile* outFile : outFiles)
796  outFile->landPixel(col);
797  if (outFile2)
798  outFile2->landPixel(col);
799 
800  } else {
801  switch (interp) {
802  case Interp_Nearest:
803  l3Bin = l3File->getClosestBin(lat, lon);
804  break;
805  case Interp_Bin:
806  case Interp_Area:
807  {
808  bool areaWeighted;
809 
810  if (interp == Interp_Area)
811  areaWeighted = true;
812  else
813  areaWeighted = false;
814 
815  l3Bin = getBoxBins(l3File, lat, lon, deltaLat, deltaLon, fudge, areaWeighted);
816 
817  break;
818  }
819  default:
820  printf("-E- interp = %s is not implemented.",
822  exit(EXIT_FAILURE);
823  }
824 
825  if (l3Bin) {
826  numFilledPixels++;
827  if (doingRGB) {
828  outFiles[0]->setPixelRGB(col, l3Bin->getMean(0),
829  l3Bin->getMean(1), l3Bin->getMean(2));
830  if (outFile2)
831  outFile2->setPixelRGB(col, l3Bin->getMean(0),
832  l3Bin->getMean(1), l3Bin->getMean(2));
833  } else {
834  for (size_t prod = 0; prod < prodNameList.size();
835  prod++) {
836  float val;
837  switch (prodMeasurementList[prod]) {
838  case Avg:
839  val = l3Bin->getMean(prod);
840  break;
841  case Stdev:
842  val = l3Bin->getStdev(prod);
843  break;
844  case Variance:
845  val = l3Bin->getVariance(prod);
846  break;
847  case Nobs:
848  val = l3Bin->getNobs();
849  break;
850  case Nscenes:
851  val = l3Bin->getNscenes();
852  break;
853  case ObsTime:
854  val = l3Bin->getObsTime();
855  break;
856  case BinNum:
857  val = l3Bin->getBinNum();
858  break;
859  default:
860  val = l3Bin->getMean(prod);
861  }
862  if(outFiles.size() == 1)
863  outFiles[0]->setPixel(col, val, prod);
864  else
865  outFiles[prod]->setPixel(col, val, 0);
866  if (outFile2)
867  outFile2->setPixel(col, val, prod);
868  }
869  }
870  if (doingQuality) {
871  for(OutFile* outFile : outFiles)
872  outFile->setQuality(col, l3Bin->getQuality());
873  if (outFile2)
874  outFile2->setQuality(col, l3Bin->getQuality());
875  }
876  } else {
877  for(OutFile* outFile : outFiles)
878  outFile->missingPixel(col);
879  if (outFile2)
880  outFile2->missingPixel(col);
881  }
882  }
883  lon += deltaLon;
884  } // for col
885  for(OutFile* outFile : outFiles)
886  outFile->writeLine();
887  if (outFile2)
888  outFile2->writeLine();
889  lat -= deltaLat;
890  } // for row
891 
892  for(OutFile* outFile : outFiles) {
893  outFile->setNumFilledPixels(numFilledPixels);
894  outFile->close();
895  }
896  if (outFile2) {
897  outFile2->setNumFilledPixels(numFilledPixels);
898  outFile2->close();
899  }
900 }
901 
902 void writeProj4File(L3File* l3File, char* projectionStr, vector<OutFile*> outFiles,
903  OutFile* outFile2, bool trimNSEW) {
904 
905  int32_t numFilledPixels = 0;
906  meta_l3bType* metaData = outFiles[0]->getMetadata();
907  double resolution = outFiles[0]->getResolution();
908 
909  // how about circumference of earth + 25%
910  double limitMin = EARTH_CIRCUMFERENCE * -0.625;
911  double limitMax = EARTH_CIRCUMFERENCE * 0.625;
912 
913  // parse central meridian (lon_0)
914  float centralMeridian = getCentralMeridian();
915  string cmStr = " +lon_0=" + to_string(centralMeridian);
916  string tsStr;
917  if (clo_isSet(optionList, "lat_ts")) {
918  tsStr = " +lat_ts=" + to_string(clo_getFloat(optionList, "lat_ts"));
919  }
920  string lat0Str;
921  if (clo_isSet(optionList, "lat_0")) {
922  lat0Str = " +lat_0=" + to_string(clo_getFloat(optionList, "lat_0"));
923  } else {
924  lat0Str = " +lat_0=" + to_string((metaData->north + metaData->south) / 2.0);
925  }
926  string lat1Str;
927  if (clo_isSet(optionList, "lat_1")) {
928  lat1Str = " +lat_1=" + to_string(clo_getFloat(optionList, "lat_1"));
929  } else {
930  lat1Str = " +lat_1=" + to_string(metaData->south);
931  }
932  string lat2Str;
933  if (clo_isSet(optionList, "lat_2")) {
934  lat2Str = " +lat_2=" + to_string(clo_getFloat(optionList, "lat_2"));
935  } else {
936  lat2Str = " +lat_2=" + to_string(metaData->north);
937  }
938  string aziStr;
939  if (clo_isSet(optionList, "azimuth")) {
940  aziStr = " +alpha=" + to_string(clo_getFloat(optionList, "azimuth"));
941  }
942  string utmStr;
943  if (clo_isSet(optionList, "utm_zone")) {
944  string zone = clo_getString(optionList, "utm_zone");
945  utmStr = " +zone=";
946  utmStr += zone;
947  if (utmStr.find('S') != std::string::npos) {
948  utmStr.pop_back();
949  utmStr += " +south" ;
950  }
951  }
952 
953  // define proj.4 parameters according to shortcut
954  string mapDesc;
955  string projName;
956  string projStr;
957 
958  if (strcasecmp(projectionStr, "mollweide") == 0) {
959  mapDesc = "Mollweide";
960  projName = "Mollweide";
961  projStr = "+proj=moll +ellps=WGS84 +datum=WGS84";
962  projStr += cmStr;
963 
964  } else if (strcasecmp(projectionStr, "lambert") == 0) {
965  mapDesc = "Lambert";
966  projName = "Lambert";
967  projStr = "+proj=lcc +ellps=WGS84 +datum=WGS84";
968  projStr += cmStr + lat0Str + lat1Str + lat2Str;
969 
970  } else if (strcasecmp(projectionStr, "albersconic") == 0) {
971  mapDesc = "Albers Equal Area Conic";
972  projName = "Albersconic";
973  projStr = "+proj=aea +ellps=WGS84 +datum=WGS84";
974  projStr += cmStr + lat0Str + lat1Str + lat2Str;
975 
976  } else if (strcasecmp(projectionStr, "mercator") == 0) {
977  mapDesc = "Mercator";
978  projName = "Mercator";
979  projStr = "+proj=merc +ellps=WGS84 +datum=WGS84";
980  projStr += cmStr;
981 
982  } else if (strcasecmp(projectionStr, "tmerc") == 0) {
983  mapDesc = "Transverse Mercator";
984  projName = "TransverseMercator";
985  projStr = "+proj=tmerc +ellps=WGS84 +datum=WGS84";
986  projStr += cmStr + lat0Str;
987 
988  } else if (strcasecmp(projectionStr, "utm") == 0) {
989  mapDesc = "Universal Transverse Mercator";
990  projName = "UTM";
991  projStr = "+proj=utm";
992  projStr += utmStr;
993 
994  } else if (strcasecmp(projectionStr, "obliquemerc") == 0) {
995  if (!clo_isSet(optionList, "lat_0") || !clo_isSet(optionList, "azimuth")) {
996  printf("-E- lat_0 and azimuth need to be defined for obliquemerc projection");
997  exit(EXIT_FAILURE);
998  }
999  mapDesc = "Oblique Mercator";
1000  projName = "ObliqueMercator";
1001  projStr = "+proj=omerc +gamma=0 +k_0=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84";
1002  projStr += lat0Str;
1003  projStr += " +lonc=" + to_string(centralMeridian);
1004  projStr += aziStr;
1005 
1006  } else if (strcasecmp(projectionStr, "ease2") == 0) {
1007  mapDesc = "Ease Grid 2";
1008  projName = "Ease2";
1009  projStr = "EPSG:6933";
1010 
1011  } else if (strcasecmp(projectionStr, "stere") == 0) {
1012  if (!clo_isSet(optionList, "lat_0") || !clo_isSet(optionList, "lat_ts")) {
1013  printf("-E- lat_0 and lat_ts need to be defined for stere projection");
1014  exit(EXIT_FAILURE);
1015  }
1016  mapDesc = "Stereographic";
1017  projName = "Stereo";
1018  projStr = "+proj=stere "
1019  " +ellps=WGS84 +datum=WGS84 +units=m +no_defs";
1020  projStr += cmStr + tsStr + lat0Str;
1021 
1022  } else if (strcasecmp(projectionStr, "conus") == 0) {
1023  mapDesc = "USA Contiguous Albers Equal Area Conic USGS version";
1024  projName = "Conus";
1025  projStr = "+proj=aea +lat_1=29.5 +lat_2=45.5"
1026  " +lat_0=23.0 +lon_0=-96 +x_0=0 +y_0=0"
1027  " +ellps=GRS80 +datum=NAD83 +units=m +no_defs";
1028 
1029  } else if (strcasecmp(projectionStr, "alaska") == 0) {
1030  mapDesc = "Alaska Albers Equal Area Conic USGS version";
1031  projName = "Alaska";
1032  projStr = "EPSG:3338";
1033 
1034  } else if (strcasecmp(projectionStr, "gibs") == 0) {
1035  if (((metaData->north + metaData->south) / 2.) > 60.) {
1036  mapDesc = "Stereographic";
1037  projName = "GIBS Stereo";
1038  projStr = "EPSG:3413";
1039 
1040  } else if (((metaData->north + metaData->south) / 2.) < -60.) {
1041  mapDesc = "Stereographic";
1042  projName = "GIBS Stereo";
1043  projStr = "EPSG:3031";
1044 
1045  } else {
1046  mapDesc = "Equidistant Cylindrical";
1047  projName = "PlateCarree";
1048  projStr = "+proj=eqc"
1049  " +lat_ts=0 +lat_0=0 +x_0=0 +y_0=0"
1050  " +ellps=WGS84 +datum=WGS84 +units=m +no_defs";
1051  projStr += cmStr;
1052  }
1053 
1054  } else if (strcasecmp(projectionStr, "platecarree") == 0) {
1055  mapDesc = "Equidistant Cylindrical";
1056  projName = "PlateCarree";
1057  projStr = "+proj=eqc"
1058  " +lat_ts=0 +lat_0=0 +x_0=0 +y_0=0"
1059  " +ellps=WGS84 +datum=WGS84 +units=m +no_defs";
1060  projStr += cmStr;
1061 
1062  } else {
1063  mapDesc = "Proj4";
1064  projName = projectionStr;
1065  projStr = projectionStr;
1066  }
1067 
1068  // save parameters in metadata
1069  sprintf(metaData->title, "%s Level-3 %s Mapped Image",
1070  metaData->sensor_name, mapDesc.c_str());
1071  for(OutFile* outFile : outFiles) {
1072  strcpy(outFile->getMetadata()->title, metaData->title);
1073  outFile->setMapProjection(projName);
1074  }
1075 
1076  if (outFile2) {
1077  strcpy(outFile2->getMetadata()->title, metaData->title);
1078  outFile2->getMetadata()->east = metaData->east;
1079  outFile2->getMetadata()->west = metaData->west;
1080  outFile2->setMapProjection(projName);
1081  }
1082 
1083  PJ *pj, *pj_new;
1084  PJ_COORD c, c_out;
1085 
1086  // init the proj4 projections
1087  pj = proj_create_crs_to_crs(PJ_DEFAULT_CTX,
1088  "+proj=longlat +ellps=WGS84 +datum=WGS84",
1089  projStr.c_str(),
1090  NULL);
1091  if(pj == NULL) {
1092  printf("Error - l3mapgen first PROJ projection failed to init\n");
1093  exit(1);
1094  }
1095  pj_new = proj_normalize_for_visualization(PJ_DEFAULT_CTX, pj);
1096  if(pj_new == NULL) {
1097  printf("Error - l3mapgen visualization PROJ projection failed to init\n");
1098  exit(1);
1099  }
1100  proj_destroy(pj);
1101  pj = NULL;
1102 
1103  // calculate start and delta for grid
1104  // set default z and t
1105  c.xyzt.z = 0.0;
1106  c.xyzt.t = HUGE_VAL;
1107 
1108  // calculate the min and max
1109  double minX = limitMax;
1110  double minY = limitMax;
1111  double maxX = limitMin;
1112  double maxY = limitMin;
1113  bool *inBox;
1114  double lat, lon;
1115  double x,y;
1116  double deltaLat = (metaData->north - metaData->south)
1117  / (NUM_SEARCH_POINTS - 1);
1118  double deltaLon = (mapEast - mapWest)
1119  / (NUM_SEARCH_POINTS - 1);
1120 
1121  lat = metaData->south;
1122  for (int j = 0; j < NUM_SEARCH_POINTS; j++) {
1123  lon = metaData->west;
1124 
1125  for (int i = 0; i < NUM_SEARCH_POINTS; i++) {
1126  c.xy.x = lon;
1127  c.xy.y = lat;
1128  c_out = proj_trans(pj_new, PJ_FWD, c);
1129  x = c_out.xy.x;
1130  y = c_out.xy.y;
1131 
1132  if (isnormal(x) && isnormal(y)) {
1133  if (x < limitMax && x > limitMin) {
1134  if (x < minX)
1135  minX = x;
1136  if (x > maxX)
1137  maxX = x;
1138  }
1139  if (y < limitMax && y > limitMin) {
1140  if (y < minY)
1141  minY = y;
1142  if (y > maxY)
1143  maxY = y;
1144  }
1145  }
1146  lon += deltaLon;
1147  }
1148  lat += deltaLat;
1149  }
1150 
1151  // set up image parameters
1152  if (imageWidth <= 0) {
1153  imageWidth = rint((maxX - minX) / resolution);
1154  if(imageWidth <= 0)
1155  imageWidth = 1;
1156  } else {
1157  resolution = (maxX - minX) / imageWidth;
1158  for(OutFile* outFile : outFiles)
1159  outFile->setResolution(resolution);
1160  if (outFile2)
1161  outFile2->setResolution(resolution);
1162  }
1163  imageHeight = rint((maxY - minY) / resolution);
1164  if(imageHeight <= 0)
1165  imageHeight = 1;
1166  for(OutFile* outFile : outFiles)
1167  outFile->setSize(imageWidth, imageHeight);
1168  if (outFile2)
1169  outFile2->setSize(imageWidth, imageHeight);
1170 
1171  for(OutFile* outFile : outFiles) {
1172  outFile->setProj4Info(projStr, minX, maxY);
1173  }
1174 
1175  if (outFile2) {
1176  outFile2->setProj4Info(projStr, minX, maxY);
1177  }
1178 
1179  // set up all the product structures
1180  for (size_t i = 0; i < prodNameList.size(); i++) {
1181  OutFile* outFile;
1182  if(outFiles.size() == 1)
1183  outFile = outFiles[0];
1184  else
1185  outFile = outFiles[i];
1187  outFile2);
1188  }
1189 
1190  // set up quality processing
1191  setupQualityProcessing(l3File, outFiles, outFile2);
1192 
1193  printStartInfo(outFiles);
1194 
1195  for(OutFile* outFile : outFiles) {
1196  if (!outFile->open()) {
1197  printf("-E- Could not open ofile=\"%s\".\n",
1198  outFile->getFileName().c_str());
1199  exit(EXIT_FAILURE);
1200  }
1201  }
1202 
1203  if (outFile2) {
1204  if (!outFile2->open()) {
1205  printf("-E- Could not open ofile2=\"%s\".\n",
1206  outFile2->getFileName().c_str());
1207  exit(EXIT_FAILURE);
1208  }
1209  }
1210 
1212  float fudge = clo_getFloat(optionList, "fudge");
1213 
1214  // loop through output pixels
1215  double *tmpX = (double*) allocateMemory(imageWidth * sizeof (double), "tmpX");
1216  double *tmpY = (double*) allocateMemory(imageWidth * sizeof (double), "tmpY");
1217  inBox = (bool*) allocateMemory(imageWidth * sizeof (bool), "inBox");
1218 
1219  deltaLon = widthInDeg / imageWidth;
1220  deltaLat = heightInDeg / imageHeight;
1221  double startX = minX + resolution / 2;
1222  double startY = maxY - resolution / 2;
1223  y = startY;
1224  L3Bin* l3Bin;
1225 
1226  for (int row = 0; row < imageHeight; row++) {
1227  printPercentDone((float) row / (float) imageHeight);
1228  x = startX;
1229 
1230  for (int col = 0; col < imageWidth; col++) {
1231  c.xy.x = x;
1232  c.xy.y = y;
1233  c_out = proj_trans(pj_new, PJ_INV, c);
1234  tmpX[col] = c_out.xy.x;
1235  tmpY[col] = c_out.xy.y;
1236 
1237  if(!isfinite(tmpX[col]) || !isfinite(tmpY[col])) {
1238  tmpX[col] = -999.0; // set to fill value
1239  tmpY[col] = -999.0; // set to fill value
1240  }
1241  x += resolution;
1242  }
1243 
1244  // find line start and end points
1245  int startPoint = 0;
1246  int endPoint = imageWidth;
1247  if (trimNSEW) {
1248  std::fill(inBox, inBox + imageWidth, false);
1249 
1250  float west = constrainLon(metaData->west);
1251 
1252  Point_t pMin(0, metaData->south);
1253  Point_t pMax(widthInDeg, metaData->north);
1254  Box_t box(pMin, pMax);
1255 
1256  for (startPoint = imageWidth / 2; startPoint >= 0; startPoint--) {
1257  lon = constrainLon(tmpX[startPoint] - west);
1258  if (lon < 0)
1259  lon += 180;
1260  lat = tmpY[startPoint];
1261  if (isnormal(lon) && isnormal(lat)) {
1262  Point_t pixel(lon, lat);
1263 
1264  if (!boost::geometry::within(pixel, box)) {
1265  break;
1266  } else {
1267  inBox[startPoint] = true;
1268  }
1269  }
1270  }
1271  startPoint++;
1272  for (endPoint = imageWidth / 2; endPoint < imageWidth; endPoint++) {
1273  lon = constrainLon(tmpX[endPoint] - west);
1274  if (lon < 0)
1275  lon += 180;
1276  lat = tmpY[endPoint];
1277  if (isnormal(lon) && isnormal(lat)) {
1278  Point_t pixel(lon, lat);
1279 
1280  if (!boost::geometry::within(pixel, box)) {
1281  break;
1282  } else {
1283  inBox[endPoint] = true;
1284  }
1285  }
1286  }
1287  endPoint--;
1288  }
1289 
1290  // loop through each pixel in this row
1291  for (int col = 0; col < imageWidth; col++) {
1292  lon = tmpX[col];
1293  lat = tmpY[col];
1294  if (col < startPoint || col > endPoint) {
1295  for(OutFile* outFile : outFiles)
1296  outFile->fillPixel(col);
1297  if (outFile2)
1298  outFile2->fillPixel(col);
1299  } else if (!isnormal(lon) || !isnormal(lat)) {
1300  for(OutFile* outFile : outFiles)
1301  outFile->fillPixel(col);
1302  if (outFile2)
1303  outFile2->fillPixel(col);
1304  } else if (trimNSEW && inBox[col] == false) {
1305  for(OutFile* outFile : outFiles)
1306  outFile->fillPixel(col);
1307  if (outFile2)
1308  outFile2->fillPixel(col);
1309  } else if (applyMask && isLand(lat, lon)) {
1310  for(OutFile* outFile : outFiles)
1311  outFile->landPixel(col);
1312  if (outFile2)
1313  outFile2->landPixel(col);
1314 
1315  } else {
1316  switch (interp) {
1317  case Interp_Nearest:
1318  l3Bin = l3File->getClosestBin(lat, lon);
1319  break;
1320  case Interp_Bin:
1321  case Interp_Area:
1322  {
1323  bool areaWeighted;
1324 
1325  if (interp == Interp_Area)
1326  areaWeighted = true;
1327  else
1328  areaWeighted = false;
1329 
1330  if (checkDateLineCrossed(lon, deltaLon)) {
1331  // East
1332  l3Bin = getBoxBins(l3File, lat, lon, deltaLat, deltaLon, fudge, areaWeighted, IsEast);
1333 
1334  // West
1335  L3Bin* tmpBin = getBoxBins(l3File, lat, lon, deltaLat, deltaLon, fudge, areaWeighted, IsWest);
1336  if (tmpBin) {
1337  *l3Bin += *tmpBin;
1338  }
1339 
1340  } else {
1341  l3Bin = getBoxBins(l3File, lat, lon, deltaLat, deltaLon, fudge, areaWeighted);
1342  }
1343  break;
1344  }
1345  default:
1346  printf("-E- interp = %s is not implemented.",
1348  exit(EXIT_FAILURE);
1349  }
1350 
1351  if (l3Bin) {
1352  numFilledPixels++;
1353  if (doingRGB) {
1354  outFiles[0]->setPixelRGB(col, l3Bin->getMean(0),
1355  l3Bin->getMean(1), l3Bin->getMean(2));
1356  if (outFile2)
1357  outFile2->setPixelRGB(col, l3Bin->getMean(0),
1358  l3Bin->getMean(1), l3Bin->getMean(2));
1359  } else {
1360  for (size_t prod = 0; prod < prodNameList.size();
1361  prod++) {
1362  float val;
1363  switch (prodMeasurementList[prod]) {
1364  case Avg:
1365  val = l3Bin->getMean(prod);
1366  break;
1367  case Stdev:
1368  val = l3Bin->getStdev(prod);
1369  break;
1370  case Variance:
1371  val = l3Bin->getVariance(prod);
1372  break;
1373  case Nobs:
1374  val = l3Bin->getNobs();
1375  break;
1376  case Nscenes:
1377  val = l3Bin->getNscenes();
1378  break;
1379  case ObsTime:
1380  val = l3Bin->getObsTime();
1381  break;
1382  case BinNum:
1383  val = l3Bin->getBinNum();
1384  break;
1385  default:
1386  val = l3Bin->getMean(prod);
1387  }
1388  if(outFiles.size() == 1)
1389  outFiles[0]->setPixel(col, val, prod);
1390  else
1391  outFiles[prod]->setPixel(col, val, 0);
1392  if (outFile2)
1393  outFile2->setPixel(col, val, prod);
1394  }
1395  }
1396  if (doingQuality) {
1397  for(OutFile* outFile : outFiles)
1398  outFile->setQuality(col, l3Bin->getQuality());
1399  if (outFile2)
1400  outFile2->setQuality(col, l3Bin->getQuality());
1401  }
1402  } else {
1403  for(OutFile* outFile : outFiles)
1404  outFile->missingPixel(col);
1405  if (outFile2)
1406  outFile2->missingPixel(col);
1407  }
1408  }
1409  } // for col
1410  for(OutFile* outFile : outFiles) {
1411  outFile->setLatLon(tmpY,tmpX);
1412  outFile->writeLine();
1413  }
1414  if (outFile2) {
1415  outFile2->setLatLon(tmpY,tmpX);
1416  outFile2->writeLine();
1417  }
1418  y -= resolution;
1419  } // for row
1420 
1421  free(tmpX);
1422  free(tmpY);
1423  free(inBox);
1424 
1425  proj_destroy(pj_new);
1426 
1427  for(OutFile* outFile : outFiles) {
1428  if (write_projtext) {
1429  string projtxtfilename;
1430  projtxtfilename = outFile->getFileName();
1431  projtxtfilename += ".projtxt";
1432  ofstream projtxtfile (projtxtfilename);
1433  if (projtxtfile.is_open())
1434  {
1435  projtxtfile << "# Projection information for " << outFile->getFileName() << "\n";
1436  projtxtfile << "proj=" << projStr << "\n";
1437  projtxtfile << "minX=" << std::setprecision(11) << minX << "\n";
1438  projtxtfile << "maxX=" << std::setprecision(11) << maxX << "\n";
1439  projtxtfile << "minY=" << std::setprecision(11) << minY << "\n";
1440  projtxtfile << "maxY=" << std::setprecision(11) << maxY << "\n";
1441  projtxtfile << "north=" << std::setprecision(11) << metaData->north << "\n";
1442  projtxtfile << "south=" << std::setprecision(11) << metaData->south << "\n";
1443  projtxtfile << "east=" << std::setprecision(11) << metaData->east << "\n";
1444  projtxtfile << "west=" << std::setprecision(11) << metaData->west << "\n";
1445 
1446  projtxtfile << "scale_type=" << outFile->getScaleTypeString() << "\n";
1447  projtxtfile << "datamin=" << std::setprecision(11) << outFile->getMinValue() << "\n";
1448  projtxtfile << "datamax=" << std::setprecision(11) << outFile->getMaxValue() << "\n";
1449 
1450  projtxtfile.close();
1451  }
1452  }
1453 
1454  outFile->setNumFilledPixels(numFilledPixels);
1455  outFile->close();
1456  }
1457  if (outFile2) {
1458  outFile2->setNumFilledPixels(numFilledPixels);
1459  outFile2->close();
1460  }
1461 }
1462 
1463 OutFile* makeOutputFile(const char* oformatStr, bool useColor) {
1464  OutFile* outFile = NULL;
1465 
1466  const char* oformatStr2 = getFileFormatName(oformatStr);
1467 
1468  if (oformatStr2 == NULL) {
1469  printf("-E- Unknown output file format \"%s\"\n", oformatStr);
1470  exit(EXIT_FAILURE);
1471  }
1472 
1473  string oformat = oformatStr2;
1474  if (oformat.compare("PPM") == 0) {
1475  if (doingRGB) {
1476  outFile = new OutFile_ppm_rgb();
1477  } else {
1478  if (useColor) {
1479  outFile = new OutFile_ppm();
1480  } else {
1481  outFile = new OutFile_pgm();
1482  }
1483  }
1484  } else if (oformat.compare("PNG") == 0) {
1485  if (doingRGB) {
1486  outFile = new OutFile_png_rgb();
1487  } else {
1488  outFile = new OutFile_png(useColor);
1489  }
1490  } else if (oformat.compare("TIFF") == 0) {
1491  if (doingRGB) {
1492  outFile = new OutFile_tiff_rgb();
1493  } else {
1494  if (useColor) {
1495  outFile = new OutFile_tiff_color();
1496  } else {
1497  outFile = new OutFile_tiff_gray();
1498  }
1499  }
1500  } else if (oformat.compare("HDF4") == 0) {
1501  outFile = new OutFile_hdf4();
1502  } else if (oformat.compare("netCDF4") == 0) {
1503  outFile = new OutFile_netcdf4();
1504  } else {
1505  printf("-E- Output file type %s not implemented\n", oformat.c_str());
1506  exit(EXIT_FAILURE);
1507  }
1508  if(doingTransparency)
1509  outFile->setTransparency();
1510 
1511  return outFile;
1512 }
1513 
1515  vector<OutFile*> outFiles;
1516  OutFile* outFile;
1517  string oformatStr = getFileFormatName(clo_getString(optionList, "oformat"));
1518  string originalOfile = clo_getString(optionList, "ofile");
1519  string tag = clo_getString(optionList, "ofile_product_tag");
1520 
1521  if (oformatStr.compare("netCDF4") == 0 ||
1522  prodNameList.size() == 1 || doingRGB) {
1523  outFile = makeOutputFile(clo_getString(optionList, "oformat"),
1524  clo_getBool(optionList, "apply_pal"));
1525  outFile->setFileName(originalOfile);
1526  outFiles.push_back(outFile);
1527  } else {
1528  size_t pos = originalOfile.find(tag);
1529  if(pos == string::npos) {
1530  printf("Error: ofile_product_tag=%s, not found in ofile=%s\n",
1531  tag.c_str(), originalOfile.c_str());
1532  printf(" and you asked for multiple products with image oformat\n");
1533  exit(EXIT_FAILURE);
1534  }
1535 
1536  for(string &prodName : prodNameList) {
1537  string newName = originalOfile;
1538  newName.replace(pos, tag.size(), prodName);
1539  outFile = makeOutputFile(clo_getString(optionList, "oformat"),
1540  clo_getBool(optionList, "apply_pal"));
1541  outFile->setFileName(newName);
1542  outFiles.push_back(outFile);
1543  } // loop products
1544  }
1545 
1546  return outFiles;
1547 }
1548 
1549 
1550 
1551 
1552 
1553 
1554 //------------------------------------------------------------------------------
1555 // main
1556 //------------------------------------------------------------------------------
1557 
1558 int main(int argc, char* argv[]) {
1559  vector<OutFile*> outFiles;
1560  OutFile* outFile2 = NULL;
1561  char* ifileName;
1562  string oformat;
1563  int i;
1564  char* tmpStr;
1565 
1566  char softwareVersion[200];
1567  sprintf(softwareVersion, "%d.%d.%d-%s", VERSION_MAJOR, VERSION_MINOR,
1569 
1571 
1572  l3mapgen_init_options(optionList, softwareVersion);
1573  if (argc == 1) {
1575  exit(EXIT_FAILURE);
1576  }
1577  l3mapgen_read_options(optionList, argc, argv);
1578 
1579  if (clo_getBool(optionList, "quiet")) {
1580  want_verbose = 0;
1581  }
1582 
1583  ifileName = clo_getString(optionList, "ifile");
1584 
1585  // try SMI input file
1586  int oldVerbose = want_verbose;
1587  want_verbose = 0;
1588  L3File* l3File = new L3FileSMI();
1589  if (!l3File->open(ifileName)) {
1590 
1591  // try real L3 bin format
1592  delete l3File;
1593  l3File = new L3File();
1594  if (!l3File->open(ifileName)) {
1595  printf("-E- Could not open ifile=\"%s\".\n", ifileName);
1596  exit(EXIT_FAILURE);
1597  }
1598  }
1599  want_verbose = oldVerbose;
1600 
1601  if (clo_getBool(optionList, "use_transparency")) {
1602  doingTransparency = true;
1603  }
1604  if (clo_getBool(optionList, "use_rgb")) {
1605  doingRGB = true;
1606  prodName = clo_getRawString(optionList, "product_rgb");
1607  } else {
1608  doingRGB = false;
1609  if (clo_isSet(optionList, "product")) {
1610  prodName = clo_getRawString(optionList, "product");
1611  } else {
1612  prodName.clear();
1613  for (int i = 0; i < l3File->getNumProducts(); i++) {
1614  string tmpName = l3File->getProductName(i);
1615  if (tmpName != "qual_l3") {
1616  if (!prodName.empty())
1617  prodName += ",";
1618  prodName += tmpName;
1619  }
1620  }
1621  }
1622  }
1623  trimNSEW = clo_getBool(optionList, "trimNSEW");
1624  write_projtext = clo_getBool(optionList, "write_projtext");
1625 
1626  boost::split(prodNameList, prodName, boost::is_any_of(","));
1627  string cleanProdName;
1628  vector<string> parts;
1629  for (size_t i = 0; i < prodNameList.size(); i++) {
1630  if (i != 0)
1631  cleanProdName += ",";
1632  boost::split(parts, prodNameList[i], boost::is_any_of(":"));
1633  if (parts.size() == 1) {
1634  cleanProdName += parts[0];
1635  prodMeasurementList.push_back(Avg);
1636  } else if (parts.size() == 2) {
1637  prodNameList[i] = parts[0]; // get rid of the modifier
1638  cleanProdName += parts[0];
1639  if (parts[1].compare("avg") == 0)
1640  prodMeasurementList.push_back(Avg);
1641  else if (parts[1].compare("stdev") == 0)
1642  prodMeasurementList.push_back(Stdev);
1643  else if (parts[1].compare("var") == 0)
1644  prodMeasurementList.push_back(Variance);
1645  else if (parts[1].compare("nobs") == 0)
1646  prodMeasurementList.push_back(Nobs);
1647  else if (parts[1].compare("nscenes") == 0)
1648  prodMeasurementList.push_back(Nscenes);
1649  else if (parts[1].compare("obs_time") == 0)
1650  prodMeasurementList.push_back(ObsTime);
1651  else if (parts[1].compare("bin_num") == 0)
1652  prodMeasurementList.push_back(BinNum);
1653  else {
1654  printf("-E- measurement type \"%s\" "
1655  "not understood for product \"%s\".\n",
1656  parts[1].c_str(), parts[0].c_str());
1657  exit(EXIT_FAILURE);
1658  }
1659  } else {
1660  printf("-E- product name not understood \"%s\".\n",
1661  prodNameList[i].c_str());
1662  exit(EXIT_FAILURE);
1663  }
1664  }
1665 
1666  if (!l3File->setActiveProductList(cleanProdName.c_str())) {
1667  printf("-E- Could not find product=\"%s\" in file=\"%s\".\n",
1668  cleanProdName.c_str(), ifileName);
1669  exit(EXIT_FAILURE);
1670  }
1671 
1672  l3File->setNumCacheRows(clo_getInt(optionList, "num_cache"));
1673 
1674  // copy the L3 meta data since we will modify it a bit for the output file.
1675  meta_l3bType metaData = *l3File->getMetaData();
1676 
1677  outFiles = makeOutputFileList(optionList);
1678 
1679  if (clo_isSet(optionList, "ofile2")) {
1680  outFile2 = makeOutputFile(clo_getString(optionList, "oformat2"),
1681  clo_getBool(optionList, "apply_pal"));
1682  outFile2->setFileName(clo_getString(optionList, "ofile2"));
1683  }
1684 
1685  // resolution = # of meters across 1 pixel in the center of the scene
1686  double res;
1687  if (clo_isSet(optionList, "resolution")) {
1688  outFiles[0]->setResolution(clo_getString(optionList, "resolution"));
1689  res = outFiles[0]->getResolution();
1690  } else {
1691  res = l3File->getMetaData()->resolution; // in meters
1692  if(res < 0) {
1693  outFiles[0]->setResolution("9km");
1694  res = outFiles[0]->getResolution();
1695  }
1696  }
1697 
1698  for(OutFile* outFile : outFiles) {
1699  outFile->setResolution(res);
1700  }
1701 
1702  if (outFile2)
1703  outFile2->setResolution(res);
1704 
1705  // get imageWidth, if specified
1706  if (clo_isSet(optionList, "width"))
1707  imageWidth = clo_getInt(optionList, "width");
1708 
1709  // projection
1710  clo_option_t* projectionOption = clo_findOption(optionList, "projection");
1711  char* projectionStr = clo_getOptionRawString(projectionOption);
1712 
1713  // check the metadata of the bin file
1714  if (metaData.north == metaData.south) {
1715  printf("-E- north and south metadata are equal.\n");
1716  exit(110);
1717  }
1718  if (metaData.east == metaData.west) {
1719  printf("-E- east and west metadata are equal.\n");
1720  exit(110);
1721  }
1722 
1723  // default to whole globe for SMI files
1724  if ((strcmp(projectionStr, "smi") == 0)
1725  || (strcmp(projectionStr, "raw") == 0)) {
1726  metaData.north = 90.0;
1727  metaData.south = -90.0;
1728  metaData.east = 180.0;
1729  metaData.west = -180.0;
1730  }
1731  // read in north, south, east, west from command line
1732  float tmpf = clo_getFloat(optionList, "north");
1733  if (tmpf > -900.0) {
1734  metaData.north = tmpf;
1735  }
1736  tmpf = clo_getFloat(optionList, "south");
1737  if (tmpf > -900.0) {
1738  metaData.south = tmpf;
1739  }
1740  tmpf = clo_getFloat(optionList, "east");
1741  if (tmpf > -900.0) {
1742  metaData.east = tmpf;
1743  }
1744  tmpf = clo_getFloat(optionList, "west");
1745  if (tmpf > -900.0) {
1746  metaData.west = tmpf;
1747  }
1748 
1749  if (metaData.north <= metaData.south) {
1750  printf("-E- north must be greater than south.\n");
1751  exit(EXIT_FAILURE);
1752  }
1753  heightInDeg = metaData.north - metaData.south;
1754  if (heightInDeg > 180.0) {
1755  printf("-E- height in degrees must be less than or equal to 180.\n");
1756  exit(EXIT_FAILURE);
1757  }
1758  mapEast = metaData.east;
1759  mapWest = metaData.west;
1760  if (mapEast < mapWest)
1761  mapEast += 360;
1763 
1764  if (widthInDeg > 360.0) {
1765  printf("-E- width in degrees must be less than or equal to 360.\n");
1766  exit(EXIT_FAILURE);
1767  }
1768 
1769  // set other fields in the metadata
1770  strcpy(metaData.soft_name, "l3mapgen");
1771  strcpy(metaData.soft_ver, softwareVersion);
1772  if ((tmpStr = strrchr(ifileName, '/')) != NULL)
1773  tmpStr++;
1774  else
1775  tmpStr = ifileName;
1776  strcpy(metaData.infiles, tmpStr);
1777  metaData.proc_con[0] = 0;
1778  for (i = 0; i < argc; i++) {
1779  strcat(metaData.proc_con, argv[i]);
1780  strcat(metaData.proc_con, " ");
1781  }
1782  strcpy(metaData.pversion, clo_getString(optionList, "pversion"));
1783 
1784  // set input parameters
1785  metaData.input_parms[0] = 0;
1786  int numOptions = clo_getNumOptions(optionList);
1787  for (int i = 0; i < numOptions; i++) {
1788  clo_option_t* option = clo_getOption(optionList, i);
1789  if (option) {
1790  if (strcmp(option->key, "help") == 0)
1791  continue;
1792  if (strcmp(option->key, "version") == 0)
1793  continue;
1794  if (strstr(option->key, "dump_options"))
1795  continue;
1796  char* val = option->valStr;
1797  if (val == NULL)
1798  val = option->defaultVal;
1799  if(val == NULL)
1800  val = "";
1801  strcat(metaData.input_parms, option->key);
1802  strcat(metaData.input_parms, "=");
1803  strcat(metaData.input_parms, val);
1804  strcat(metaData.input_parms, "|");
1805  }
1806  }
1807 
1808  // set processing time
1809  get_time(metaData.ptime);
1810 
1811  for(OutFile* outFile : outFiles) {
1812  outFile->setMetaData(&metaData);
1813  outFile->setDeflate(clo_getInt(optionList, "deflate"));
1814  outFile->setFullLatLon(clo_getBool(optionList, "full_latlon"));
1815  }
1816  if (outFile2) {
1817  outFile2->setMetaData(&metaData);
1818  outFile2->setDeflate(clo_getInt(optionList, "deflate"));
1819  outFile2->setFullLatLon(clo_getBool(optionList, "full_latlon"));
1820  }
1821 
1822  if (strcasecmp(projectionStr, "raw") == 0) {
1823  writeRawFile(l3File, outFiles, outFile2);
1824  } else if (strcasecmp(projectionStr, "smi") == 0) {
1825  writeSmiFile(l3File, outFiles, outFile2);
1826  } else {
1827  writeProj4File(l3File, projectionStr, outFiles, outFile2, trimNSEW);
1828  }
1829 
1830  // check if no pixels are filled
1831  if (outFiles[0]->getNumFilledPixels() == 0) {
1832  printf("\nThere are no filled pixels\n");
1833  printf("Deleting output file.\n");
1834 
1835  string cmd;
1836  for(OutFile* outFile : outFiles) {
1837  cmd = "rm -f ";
1838  cmd += outFile->getFileName();
1839  system(cmd.c_str());
1840  }
1841 
1842  if (outFile2) {
1843  cmd = "rm -f ";
1844  cmd += outFile2->getFileName();
1845  system(cmd.c_str());
1846  }
1847  exit(110);
1848  }
1849 
1850  // check the % filled threshold
1851  float threshold = clo_getFloat(optionList, "threshold");
1852  if (threshold > 0.0) {
1853  if (outFiles[0]->getPercentFilledPixels() < threshold) {
1854  printf("\nPercent filled pixels (%.1f) "
1855  "is below the threshold (%.1f)\n",
1856  outFiles[0]->getPercentFilledPixels(), threshold);
1857  printf("Deleting output file.\n");
1858 
1859  string cmd;
1860  for(OutFile* outFile : outFiles) {
1861  cmd = "rm -f ";
1862  cmd += outFile->getFileName();
1863  system(cmd.c_str());
1864  }
1865 
1866  if (outFile2) {
1867  cmd = "rm -f ";
1868  cmd += outFile2->getFileName();
1869  system(cmd.c_str());
1870  }
1871  exit(110);
1872  }
1873  }
1874 
1875  printEndInfo(outFiles[0]);
1876 
1877  for(OutFile* outFile : outFiles) {
1878  delete outFile;
1879  }
1880  if (outFile2)
1881  delete outFile2;
1882  delete l3File;
1883 
1884  return EXIT_SUCCESS;
1885 }
virtual void setMetaData(meta_l3bType *metaData)
Definition: OutFile.cpp:477
void interp(double *ephemPtr, int startLoc, double *inTime, int numCoefs, int numCom, int numSets, int velFlag, double *posvel)
int32 value
Definition: Granule.c:1235
char * defaultVal
Definition: clo.h:106
virtual void setPixel(int32_t x, double val, int32_t prod=0)
Definition: OutFile.cpp:345
#define NUM_SEARCH_POINTS
Definition: l3mapgen.cpp:29
virtual void writeLine()=0
#define EXIT_SUCCESS
Definition: GEO_basic.h:72
virtual L3Bin * getClosestBin(float lat, float lon)
Definition: L3File.cpp:739
void freeProductInfo(productInfo_t *info)
int j
Definition: decode_rs.h:73
char * clo_getString(clo_optionList_t *list, const char *key)
Definition: clo.c:1357
int status
Definition: l1_czcs_hdf.c:32
virtual bool hasQuality()
Definition: L3File.cpp:788
@ Avg
Definition: l3mapgen.cpp:32
virtual int32_t getNumCols(int32_t row) const =0
virtual void landPixel(int32_t x)
Definition: OutFile.cpp:383
virtual void setPixelRGB(int32_t x, float red, float green, float blue)
Definition: OutFile.cpp:359
@ IsWest
Definition: l3mapgen.cpp:38
char infiles[LG_ATTRSZ]
Definition: meta_l3b.h:38
void * allocateMemory(size_t numBytes, const char *name)
Definition: allocateMemory.c:7
vector< OutFile * > makeOutputFileList(clo_optionList_t *optionList)
Definition: l3mapgen.cpp:1514
float getCentralMeridian()
Definition: l3mapgen.cpp:151
virtual void missingPixel(int32_t x)
Definition: OutFile.cpp:409
#define VERSION_MINOR
Definition: version.h:2
#define NULL
Definition: decode_rs.h:63
L3Bin * getBin(int64_t binNum)
Definition: L3File.cpp:335
string qualName
Definition: l3mapgen.cpp:58
char * key
Definition: clo.h:104
this program makes no use of any feature of the SDP Toolkit that could generate such a then geolocation is calculated at that resolution
Definition: HISTORY.txt:188
virtual bool open(const char *fileName)
Definition: L3File.cpp:430
char * clo_getOptionRawString(clo_option_t *option)
Definition: clo.c:1030
char input_parms[LG_ATTRSZ]
Definition: meta_l3b.h:36
int sensorName2SensorId(const char *name)
Definition: sensorInfo.c:268
vector< string > prodNameList
Definition: l3mapgen.cpp:56
int clo_isSet(clo_optionList_t *list, const char *key)
Definition: clo.c:2270
#define GITSHA
Definition: version.h:4
clo_option_t * clo_findOption(clo_optionList_t *list, const char *key)
Definition: clo.c:967
float32 * pos
Definition: l1_czcs_hdf.c:35
float * lat
InterpType
Definition: l3mapgen.cpp:34
#define VERSION_PATCH
Definition: version.h:3
EastWest
Definition: l3mapgen.cpp:37
string prodName
Definition: l3mapgen.cpp:55
void setFullLatLon(bool val)
Definition: OutFile.h:233
double constrainLon(double lon)
Definition: L3Shape.cpp:26
virtual void setNumCacheRows(int32_t numRows)
Definition: L3File.cpp:420
virtual L3Shape * getShape() const
Definition: L3File.h:317
bool applyMask
Definition: l3mapgen.cpp:63
int clo_getInt(clo_optionList_t *list, const char *key)
Definition: clo.c:1393
virtual void fillPixel(int32_t x)
Definition: OutFile.cpp:396
int clo_isOptionSet(clo_option_t *option)
Definition: clo.c:2257
grid_info_t * allocate_gridinfo()
Definition: nc_gridutils.c:107
#define VERSION_MAJOR
Definition: version.h:1
double heightInDeg
Definition: l3mapgen.cpp:43
virtual int32_t getNumRows()
Definition: L3File.cpp:726
virtual void setMapProjection(std::string projection)
Definition: OutFile.cpp:558
@ Nobs
Definition: l3mapgen.cpp:32
#define PRODUCT_DEFAULT_fillValue
Definition: productInfo.h:28
bool doingQuality
Definition: l3mapgen.cpp:49
virtual bool setActiveProductList(const char *prodStr)
Definition: L3File.cpp:591
@ Interp_Nearest
Definition: l3mapgen.cpp:35
InterpType interpStr2Type(const char *str)
Definition: l3mapgen.cpp:179
virtual void setLandRGB(const char *rgb_land_string)
Definition: OutFile.cpp:468
virtual void setSize(int32_t width, int32_t height)
Definition: OutFile.cpp:318
bool setupQualityProcessing(L3File *l3File, vector< OutFile * > outFiles, OutFile *outFile2)
Definition: l3mapgen.cpp:265
@ Interp_Bin
Definition: l3mapgen.cpp:35
OutFile * makeOutputFile(const char *oformatStr, bool useColor)
Definition: l3mapgen.cpp:1463
clo_optionList_t * clo_createList()
Definition: clo.c:532
virtual void setQualityName(std::string qualName)
Definition: OutFile.h:217
virtual int32_t getNumProducts()
Definition: L3File.cpp:581
virtual std::string getProductName(size_t index=0)
Definition: L3File.cpp:587
virtual void setDeflate(int val)
Definition: OutFile.h:227
virtual void setQualityProcessing(bool val)
Definition: L3File.cpp:795
virtual L3Row * getRow(int32_t row)
Definition: L3File.cpp:695
productInfo_t * allocateProductInfo()
void get_time(char *pr_time)
Definition: get_time.c:28
bool write_projtext
Definition: l3mapgen.cpp:53
const char * getFileFormatName(const char *str)
char * valStr
Definition: clo.h:108
char * strdup(const char *)
float clo_getFloat(clo_optionList_t *list, const char *key)
Definition: clo.c:1429
virtual void setResolution(std::string resolutionStr)
char * clo_getOptionString(clo_option_t *option)
Definition: clo.c:1050
virtual bool setPalette(const char *paletteName, bool applyMask)
Definition: OutFile.cpp:432
virtual meta_l3bType * getMetadata()
Definition: OutFile.h:186
#define PRODUCT_DEFAULT_palette
Definition: productInfo.h:14
@ Nscenes
Definition: l3mapgen.cpp:32
const char * interpType2Str(InterpType interp)
Definition: l3mapgen.cpp:194
double mapEast
Definition: l3mapgen.cpp:44
bool doingTransparency
Definition: l3mapgen.cpp:51
void clo_printUsage(clo_optionList_t *list)
Definition: clo.c:1988
#define PRODUCT_DEFAULT_displayMin
Definition: productInfo.h:36
uint8_t getQuality() const
Definition: L3File.cpp:234
bg::model::point< double, 2, bg::cs::spherical_equatorial< bg::degree > > Point_t
Definition: get_dataday.cpp:23
vector< MeasurementType > prodMeasurementList
Definition: l3mapgen.cpp:57
#define PRODUCT_DEFAULT_displayMax
Definition: productInfo.h:37
virtual float getPercentFilledPixels()
Definition: OutFile.cpp:588
virtual int64_t getBaseBin(int32_t row) const =0
L3Bin * getBinsInside(Geometry geo, bool areaWeighted=false)
Definition: L3File.h:266
@ notEastOrWest
Definition: l3mapgen.cpp:38
double resolution
Definition: meta_l3b.h:53
void setupProduct(string &prodName, MeasurementType measure, OutFile *outFile, OutFile *outFile2)
Definition: l3mapgen.cpp:305
virtual meta_l3bType * getMetaData()
Definition: L3File.cpp:475
virtual double getFileMinVal()
Definition: OutFile.h:200
clo_optionList_t * optionList
Definition: l3mapgen.cpp:60
int want_verbose
virtual int32_t getNumFilledPixels()
Definition: OutFile.cpp:581
MeasurementType
Definition: l3mapgen.cpp:31
int imageHeight
Definition: l3mapgen.cpp:48
L3Bin * getBoxBins(L3File *l3File, float lat, float lon, float deltaLat, float deltaLon, float fudge, bool areaWeighted, int eastwest=notEastOrWest)
Definition: l3mapgen.cpp:246
bool doingRGB
Definition: l3mapgen.cpp:50
@ ObsTime
Definition: l3mapgen.cpp:32
float getObsTime() const
Definition: L3File.cpp:218
bool checkDateLineCrossed(double lon, double deltaLon)
Definition: l3mapgen.cpp:209
clo_option_t * clo_getOption(clo_optionList_t *list, int i)
Definition: clo.c:908
float north
Definition: meta_l3b.h:49
#define EARTH_CIRCUMFERENCE
Definition: genutils.h:10
virtual void setQuality(int32_t x, uint8_t val)
Definition: OutFile.cpp:369
int isLand(float lat, float lon)
Definition: l3mapgen.cpp:66
int64_t getBinNum() const
Definition: L3File.cpp:186
this program makes no use of any feature of the SDP Toolkit that could generate such a then geolocation is calculated at that and then aggregated up to Resolved feature request Bug by adding three new int8 SDSs for each high resolution pixel
Definition: HISTORY.txt:192
string & trim(string &s, const string &delimiters)
Definition: EnvsatUtil.cpp:29
char title[SM_ATTRSZ]
Definition: meta_l3b.h:17
bool trimNSEW
Definition: l3mapgen.cpp:52
int clo_getNumOptions(clo_optionList_t *list)
Definition: clo.c:1017
double mapWest
Definition: l3mapgen.cpp:45
int l3mapgen_read_options(clo_optionList_t *list, int argc, char *argv[])
void parse_file_name(const char *inpath, char *outpath)
@ IsEast
Definition: l3mapgen.cpp:38
float west
Definition: meta_l3b.h:52
int findProductInfo(const char *productName, int sensorId, productInfo_t *info)
int get_bylatlon(grid_info_t *grid, float lat, float lon, double *value)
Definition: nc_gridutils.c:368
int32_t getNobs() const
Definition: L3File.cpp:194
const char * str
Definition: l1c_msi.cpp:35
virtual void setTransparency()
Definition: OutFile.cpp:365
float getMean(int32_t prodId=0) const
Definition: L3File.cpp:263
int l3mapgen_init_options(clo_optionList_t *list, const char *softwareVersion)
virtual void setLatLon(double *lat, double *lon)
Definition: OutFile.cpp:422
float south
Definition: meta_l3b.h:50
char proc_con[MD_ATTRSZ]
Definition: meta_l3b.h:35
void writeRawFile(L3File *l3File, vector< OutFile * > outFiles, OutFile *outFile2)
Definition: l3mapgen.cpp:536
float getStdev(int32_t prodId=0) const
Definition: L3File.cpp:288
Box_t getBox(float lat, float lon, float deltaLat, float deltaLon, int eastwest=notEastOrWest)
Definition: l3mapgen.cpp:222
char soft_ver[SM_ATTRSZ]
Definition: meta_l3b.h:33
double widthInDeg
Definition: l3mapgen.cpp:42
virtual void setQualityProcessing(bool val)
Definition: OutFile.cpp:605
@ Interp_Area
Definition: l3mapgen.cpp:35
#define PRODUCT_DEFAULT_validMin
Definition: productInfo.h:33
float getVariance(int32_t prodId=0) const
Definition: L3File.cpp:273
void setProj4Info(std::string projStr, double minX, double maxY)
Definition: OutFile.cpp:562
void writeProj4File(L3File *l3File, char *projectionStr, vector< OutFile * > outFiles, OutFile *outFile2, bool trimNSEW)
Definition: l3mapgen.cpp:902
float * lon
char ptime[SM_ATTRSZ]
Definition: meta_l3b.h:34
data_t s[NROOTS]
Definition: decode_rs.h:75
int imageWidth
Definition: l3mapgen.cpp:47
char * clo_getRawString(clo_optionList_t *list, const char *key)
Definition: clo.c:1339
char pversion[SM_ATTRSZ]
Definition: meta_l3b.h:30
Definition: L3File.cpp:10
@ Variance
Definition: l3mapgen.cpp:32
int clo_getBool(clo_optionList_t *list, const char *key)
Definition: clo.c:1375
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude resolving resolving GSFcd00179 Corrected handling of fill values for[Sensor|Solar][Zenith|Azimuth] resolving MODxl01751 Changed to validate LUT version against a value retrieved from the resolving MODxl02056 Changed to calculate Solar Diffuser angles without adjustment for estimated post launch changes in the MODIS orientation relative to incidentally resolving defects MODxl01766 Also resolves MODxl01947 Changed to ignore fill values in SCI_ABNORM and SCI_STATE rather than treating them as resolving MODxl01780 Changed to use spacecraft ancillary data to recognise when the mirror encoder data is being set by side A or side B and to change calculations accordingly This removes the need for seperate LUTs for Side A and Side B data it makes the new LUTs incompatible with older versions of the and vice versa Also resolves MODxl01685 A more robust GRing algorithm is being which will create a non default GRing anytime there s even a single geolocated pixel in a granule Removed obsolete messages from seed as required for compatibility with version of the SDP toolkit Corrected test output file names to end in per delivery and then split off a new MYD_PR03 pcf file for Aqua Added AssociatedPlatformInstrumentSensor to the inventory metadata in MOD01 mcf and MOD03 mcf Created new versions named MYD01 mcf and MYD03 where AssociatedPlatformShortName is rather than Terra The program itself has been changed to read the Satellite Instrument validate it against the input L1A and LUT and to use it determine the correct files to retrieve the ephemeris and attitude data from Changed to produce a LocalGranuleID starting with MYD03 if run on Aqua data Added the Scan Type file attribute to the Geolocation copied from the L1A and attitude_angels to radians rather than degrees The accumulation of Cumulated gflags was moved from GEO_validate_earth_location c to GEO_locate_one_scan c
Definition: HISTORY.txt:464
void printPercentDone(float percentDone)
Definition: l3mapgen.cpp:141
float east
Definition: meta_l3b.h:51
void printEndInfo(OutFile *outFile)
Definition: l3mapgen.cpp:129
@ Interp_Linear
Definition: l3mapgen.cpp:35
char sensor_name[SM_ATTRSZ]
Definition: meta_l3b.h:19
int32_t getNscenes() const
Definition: L3File.cpp:202
int i
Definition: decode_rs.h:71
double rint(double)
virtual void setFileName(std::string fileName)
Definition: OutFile.cpp:341
msiBandIdx val
Definition: l1c_msi.cpp:34
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
int main(int argc, char *argv[])
Definition: l3mapgen.cpp:1558
virtual void setNumFilledPixels(int32_t num)
Definition: OutFile.cpp:575
void clo_printVersion()
Definition: clo.c:1968
char soft_name[SM_ATTRSZ]
Definition: meta_l3b.h:32
int init_gridinfo(char *filename, const char *varnames[], grid_info_t *grid)
Definition: nc_gridutils.c:132
virtual double getFileMaxVal()
Definition: OutFile.h:204
int clo_getOptionBool(clo_option_t *option)
Definition: clo.c:1087
void writeSmiFile(L3File *l3File, vector< OutFile * > outFiles, OutFile *outFile2)
Definition: l3mapgen.cpp:707
virtual bool close()=0
@ BinNum
Definition: l3mapgen.cpp:32
virtual std::string getFileName()
Definition: OutFile.h:152
bg::model::box< Point_t > Box_t
Definition: l1c.cpp:73
@ Stdev
Definition: l3mapgen.cpp:32
virtual bool open()=0
void printStartInfo(vector< OutFile * > outFiles)
Definition: l3mapgen.cpp:76
virtual int32_t addProduct(productInfo_t *productInfo)
Definition: OutFile.cpp:486