24 #include <boost/algorithm/string.hpp>
25 #include <boost/lexical_cast.hpp>
26 #include <unordered_map>
27 #include <unordered_set>
28 #include <boost/algorithm/string.hpp>
29 #define EXIT_LOG(...) \
32 std::cerr << "Exiting. See line " << __LINE__ << " in " << __FILE__ << std::endl; \
39 #define NUM_SEARCH_POINTS 51
108 static grid_info_t* landmaskGrid = {0};
111 if (landmaskGrid !=
NULL) {
115 return ((
short)
value != 1);
127 for (
OutFile* outFile : outFiles) {
128 if (outFile == outFiles[0])
129 printf(
"%s", outFile->getFileName().c_str());
131 printf(
",%s", outFile->getFileName().c_str());
141 printf(
"resolution : %.3fm\n", outFiles[0]->getResolution());
145 printf(
"product_rgb: %s\n",
prodName.c_str());
147 printf(
"product : %s\n",
prodName.c_str());
149 printf(
"qual_prod : %s\n",
qualName.c_str());
150 printf(
"north : %8.3f\n", metaData->
north);
151 printf(
"south : %8.3f\n", metaData->
south);
152 printf(
"east : %8.3f\n", metaData->
east);
153 printf(
"west : %8.3f\n", metaData->
west);
156 printf(
"central_meridian : %8.3f\n", tmpf);
185 static float percentPrev = 0.0;
186 static const float percentDelta = 0.01;
187 if (
want_verbose && (percentDone - percentPrev > percentDelta)) {
188 percentPrev = percentDone;
189 printf(
"\r%2d%% complete", (
int)(percentDone * 100));
197 if (centralMeridian > -900.0) {
199 while (centralMeridian < -180.0) {
200 centralMeridian += 360.0;
203 printf(
"-E- central meridian is way off\n");
208 while (centralMeridian > 180.0) {
209 centralMeridian -= 360.0;
212 printf(
"-E- central meridian is way off\n");
227 if (
s.compare(
"bin") == 0)
229 if (
s.compare(
"linear") == 0)
231 if (
s.compare(
"area") == 0)
253 bool crossed =
false;
258 if (minlon > 0 && maxlon < 0)
270 pMin.set<1>(
lat - (deltaLat / 2.0));
271 pMax.set<0>(
lon + (deltaLon / 2.0));
272 pMax.set<1>(
lat + (deltaLat / 2.0));
273 }
else if (eastwest ==
IsWest) {
274 pMin.set<0>(
lon - (deltaLon / 2.0));
275 pMin.set<1>(
lat - (deltaLat / 2.0));
277 pMax.set<1>(
lat + (deltaLat / 2.0));
279 pMin.set<0>(
lon - (deltaLon / 2.0));
280 pMin.set<1>(
lat - (deltaLat / 2.0));
281 pMax.set<0>(
lon + (deltaLon / 2.0));
282 pMax.set<1>(
lat + (deltaLat / 2.0));
284 Box_t box(pMin, pMax);
294 if (!l3Bin && fudge > 1) {
315 "-E- Quality processing was requested, "
316 "but the input file does not have quality data.\n");
335 for (
OutFile* outFile : outFiles) {
348 productInfo_t* p_info;
352 if (sensorId == -1) {
358 printf(
"-E- product %s not found in XML product table\n",
prodName.c_str());
369 tmpStr = p_info->description;
370 free(p_info->description);
371 tmpStr +=
" (Standard Deviation)";
372 p_info->description =
strdup(tmpStr.c_str());
373 free(p_info->palette);
375 free(p_info->dataType);
376 p_info->dataType =
strdup(
"float");
377 tmpStr = p_info->suffix;
378 free(p_info->suffix);
380 p_info->suffix =
strdup(tmpStr.c_str());
381 free(p_info->displayScale);
382 p_info->displayScale =
strdup(
"linear");
383 p_info->addOffset = 0.0;
384 p_info->scaleFactor = 1.0;
387 tmpStr = p_info->description;
388 free(p_info->description);
389 tmpStr +=
" (Variance)";
390 p_info->description =
strdup(tmpStr.c_str());
391 free(p_info->palette);
393 free(p_info->dataType);
394 p_info->dataType =
strdup(
"float");
395 tmpStr = p_info->suffix;
396 free(p_info->suffix);
398 p_info->suffix =
strdup(tmpStr.c_str());
399 free(p_info->displayScale);
400 p_info->displayScale =
strdup(
"linear");
401 p_info->addOffset = 0.0;
402 p_info->scaleFactor = 1.0;
405 tmpStr = p_info->description;
406 free(p_info->description);
407 tmpStr +=
" (number of observations)";
408 p_info->description =
strdup(tmpStr.c_str());
410 p_info->units =
strdup(
"counts");
411 free(p_info->palette);
413 free(p_info->dataType);
414 p_info->dataType =
strdup(
"short");
415 tmpStr = p_info->suffix;
416 free(p_info->suffix);
418 p_info->suffix =
strdup(tmpStr.c_str());
420 p_info->validMin = 0;
421 p_info->validMax = 32767;
422 free(p_info->displayScale);
423 p_info->displayScale =
strdup(
"linear");
426 p_info->addOffset = 0.0;
427 p_info->scaleFactor = 1.0;
430 tmpStr = p_info->description;
431 free(p_info->description);
432 tmpStr +=
" (number of scenes)";
433 p_info->description =
strdup(tmpStr.c_str());
435 p_info->units =
strdup(
"counts");
436 free(p_info->palette);
438 free(p_info->dataType);
439 p_info->dataType =
strdup(
"short");
440 tmpStr = p_info->suffix;
441 free(p_info->suffix);
442 tmpStr +=
"_nscenes";
443 p_info->suffix =
strdup(tmpStr.c_str());
445 p_info->validMin = 0;
446 p_info->validMax = 32767;
447 free(p_info->displayScale);
448 p_info->displayScale =
strdup(
"linear");
451 p_info->addOffset = 0.0;
452 p_info->scaleFactor = 1.0;
455 tmpStr = p_info->description;
456 free(p_info->description);
457 tmpStr +=
" (observation time, TAI93)";
458 p_info->description =
strdup(tmpStr.c_str());
460 p_info->units =
strdup(
"counts");
461 free(p_info->palette);
463 free(p_info->dataType);
464 p_info->dataType =
strdup(
"float");
465 tmpStr = p_info->suffix;
466 free(p_info->suffix);
467 tmpStr +=
"_obs_time";
468 p_info->suffix =
strdup(tmpStr.c_str());
472 free(p_info->displayScale);
473 p_info->displayScale =
strdup(
"linear");
476 p_info->addOffset = 0.0;
477 p_info->scaleFactor = 1.0;
480 tmpStr = p_info->description;
481 free(p_info->description);
482 tmpStr +=
" (bin ID number)";
483 p_info->description =
strdup(tmpStr.c_str());
485 p_info->units =
strdup(
"dimensionless");
486 free(p_info->palette);
488 free(p_info->dataType);
489 p_info->dataType =
strdup(
"int");
490 tmpStr = p_info->suffix;
491 free(p_info->suffix);
492 tmpStr +=
"_bin_num";
493 p_info->suffix =
strdup(tmpStr.c_str());
497 free(p_info->displayScale);
498 p_info->displayScale =
strdup(
"linear");
501 p_info->addOffset = 0.0;
502 p_info->scaleFactor = 1.0;
510 char landmaskFile[FILENAME_MAX];
512 static const char* landmaskVars[] = {
"watermask",
"landmask",
"z",
NULL};
518 cerr <<
"Error reading file " << landmaskFile <<
": " << nc_strerror(
status) <<
"\n"
519 <<
"Land mask will not be applied.\n";
545 p_info->displayMin = 0.01;
546 p_info->displayMax = 0.9;
547 if (p_info->displayScale)
548 free(p_info->displayScale);
549 p_info->displayScale =
strdup(
"log");
560 if (p_info->displayScale)
561 free(p_info->displayScale);
585 int32_t numFilledPixels = 0;
588 string mapDesc =
"Bin";
589 string projName =
"Integerized Sinusoidal";
594 sprintf(metaData->
title,
"%s Level-3 %s Mapped Image", metaData->
sensor_name, mapDesc.c_str());
595 for (
OutFile* outFile : outFiles) {
596 strcpy(outFile->getMetadata()->title, metaData->
title);
597 outFile->setFullLatLon(
false);
598 outFile->setMapProjection(projName);
613 if (outFiles.size() == 1)
614 outFile = outFiles[0];
616 outFile = outFiles[
i];
622 for (
OutFile* outFile : outFiles) {
623 if (!outFile->open()) {
624 printf(
"-E- Could not open ofile=\"%s\".\n", outFile->getFileName().c_str());
629 if (!outFile2->
open()) {
630 printf(
"-E- Could not open ofile2=\"%s\".\n", outFile2->
getFileName().c_str());
640 l3Row = l3File->
getRow(row);
643 endBin = baseBin + numBins;
644 if (centralMeridian < 0)
645 binNum = baseBin + numBins * (centralMeridian + 360.0) / 360.0;
647 binNum = baseBin + numBins * centralMeridian / 360.0;
651 for (col = 0; col <
start; col++) {
652 for (
OutFile* outFile : outFiles)
653 outFile->fillPixel(col);
659 for (
int i = 0;
i < numBins;
i++) {
660 l3Bin = l3Row->
getBin(binNum);
667 for (
size_t prod = 0; prod <
prodNameList.size(); prod++) {
694 if (outFiles.size() == 1)
695 outFiles[0]->setPixel(col,
val, prod);
697 outFiles[prod]->setPixel(col,
val, 0);
704 for (
OutFile* outFile : outFiles)
705 outFile->missingPixel(col);
711 if (binNum >= endBin)
717 for (
OutFile* outFile : outFiles)
718 outFile->fillPixel(col);
723 for (
OutFile* outFile : outFiles)
724 outFile->writeLine();
729 for (
OutFile* outFile : outFiles) {
730 outFile->setNumFilledPixels(numFilledPixels);
740 int32_t numFilledPixels = 0;
742 double resolution = outFiles[0]->getResolution();
744 string mapDesc =
"Standard";
745 string projName =
"Equidistant Cylindrical";
747 sprintf(metaData->
title,
"%s Level-3 %s Mapped Image", metaData->
sensor_name, mapDesc.c_str());
756 for (
OutFile* outFile : outFiles)
767 for (
OutFile* outFile : outFiles) {
768 strcpy(outFile->getMetadata()->title, metaData->
title);
770 outFile->setMapProjection(projName);
783 if (outFiles.size() == 1)
784 outFile = outFiles[0];
786 outFile = outFiles[
i];
794 for (
OutFile* outFile : outFiles) {
795 if (!outFile->open()) {
796 printf(
"-E- Could not open ofile=\"%s\".\n", outFile->getFileName().c_str());
802 if (!outFile2->
open()) {
803 printf(
"-E- Could not open ofile2=\"%s\".\n", outFile2->
getFileName().c_str());
812 double lat = metaData->
north - (deltaLat / 2.0);
817 double lon = metaData->
west + (deltaLon / 2.0);
821 for (
OutFile* outFile : outFiles)
822 outFile->landPixel(col);
838 areaWeighted =
false;
840 l3Bin =
getBoxBins(l3File,
lat,
lon, deltaLat, deltaLon, fudge, areaWeighted);
852 outFiles[0]->setPixelRGB(col, l3Bin->
getMean(0), l3Bin->
getMean(1),
858 for (
size_t prod = 0; prod <
prodNameList.size(); prod++) {
885 if (outFiles.size() == 1)
886 outFiles[0]->setPixel(col,
val, prod);
888 outFiles[prod]->setPixel(col,
val, 0);
894 for (
OutFile* outFile : outFiles)
895 outFile->setQuality(col, l3Bin->
getQuality());
900 for (
OutFile* outFile : outFiles)
901 outFile->missingPixel(col);
908 for (
OutFile* outFile : outFiles)
909 outFile->writeLine();
915 for (
OutFile* outFile : outFiles) {
916 outFile->setNumFilledPixels(numFilledPixels);
929 int32_t numFilledPixels = 0;
931 double resolution = outFiles[0]->getResolution();
939 double minX = limitMax;
940 double minY = limitMax;
941 double maxX = limitMin;
942 double maxY = limitMin;
951 string cmStr =
" +lon_0=" + to_string(centralMeridian);
957 float lat0 = (metaData->
north + metaData->
south) / 2.0;
962 lat0Str =
" +lat_0=" + to_string(lat0);
968 lat1Str =
" +lat_1=" + to_string(metaData->
south);
974 lat2Str =
" +lat_2=" + to_string(metaData->
north);
985 if (utmStr.find(
'S') != std::string::npos) {
996 if (strcasecmp(projectionStr,
"mollweide") == 0) {
997 mapDesc =
"Mollweide";
998 projName =
"Mollweide";
999 projStr =
"+proj=moll +ellps=WGS84 +datum=WGS84";
1002 }
else if (strcasecmp(projectionStr,
"lambert") == 0) {
1003 mapDesc =
"Lambert";
1004 projName =
"Lambert";
1005 projStr =
"+proj=lcc +ellps=WGS84 +datum=WGS84";
1006 projStr += cmStr + lat0Str + lat1Str + lat2Str;
1008 }
else if (strcasecmp(projectionStr,
"albersconic") == 0) {
1009 mapDesc =
"Albers Equal Area Conic";
1010 projName =
"Albersconic";
1011 projStr =
"+proj=aea +ellps=WGS84 +datum=WGS84";
1012 projStr += cmStr + lat0Str + lat1Str + lat2Str;
1014 }
else if (strcasecmp(projectionStr,
"aeqd") == 0) {
1015 mapDesc =
"Azimuthal Equidistant";
1016 projName =
"AzimuthalEquidistant";
1017 projStr =
"+proj=aeqd +ellps=WGS84 +datum=WGS84";
1018 projStr += cmStr + lat0Str;
1020 }
else if (strcasecmp(projectionStr,
"mercator") == 0) {
1021 mapDesc =
"Mercator";
1022 projName =
"Mercator";
1023 projStr =
"+proj=merc +ellps=WGS84 +datum=WGS84";
1026 }
else if (strcasecmp(projectionStr,
"tmerc") == 0) {
1027 mapDesc =
"Transverse Mercator";
1028 projName =
"TransverseMercator";
1029 projStr =
"+proj=tmerc +ellps=WGS84 +datum=WGS84";
1030 projStr += cmStr + lat0Str;
1032 }
else if (strcasecmp(projectionStr,
"utm") == 0) {
1033 mapDesc =
"Universal Transverse Mercator";
1035 projStr =
"+proj=utm";
1038 }
else if (strcasecmp(projectionStr,
"obliquemerc") == 0) {
1040 printf(
"-E- lat_0 and azimuth need to be defined for obliquemerc projection");
1043 mapDesc =
"Oblique Mercator";
1044 projName =
"ObliqueMercator";
1045 projStr =
"+proj=omerc +gamma=0 +k_0=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84";
1047 projStr +=
" +lonc=" + to_string(centralMeridian);
1050 }
else if (strcasecmp(projectionStr,
"ease2") == 0) {
1051 mapDesc =
"Ease Grid 2";
1053 projStr =
"EPSG:6933";
1055 }
else if (strcasecmp(projectionStr,
"stere") == 0) {
1057 printf(
"-E- lat_0 and lat_ts need to be defined for stere projection");
1060 mapDesc =
"Stereographic";
1061 projName =
"Stereo";
1064 " +ellps=WGS84 +datum=WGS84 +units=m +no_defs";
1065 projStr += cmStr + tsStr + lat0Str;
1067 }
else if (strcasecmp(projectionStr,
"ortho") == 0) {
1068 mapDesc =
"Orthographic";
1072 " +ellps=GRS80 +units=m +no_defs";
1073 projStr += cmStr + lat0Str;
1075 }
else if (strcasecmp(projectionStr,
"conus") == 0) {
1076 mapDesc =
"USA Contiguous Albers Equal Area Conic USGS version";
1079 "+proj=aea +lat_1=29.5 +lat_2=45.5"
1080 " +lat_0=23.0 +lon_0=-96 +x_0=0 +y_0=0"
1081 " +ellps=GRS80 +datum=NAD83 +units=m +no_defs";
1083 }
else if (strcasecmp(projectionStr,
"alaska") == 0) {
1084 mapDesc =
"Alaska Albers Equal Area Conic USGS version";
1085 projName =
"Alaska";
1086 projStr =
"EPSG:3338";
1088 }
else if (strcasecmp(projectionStr,
"gibs") == 0) {
1089 if (((metaData->
north + metaData->
south) / 2.) > 60.) {
1090 mapDesc =
"Stereographic";
1091 projName =
"GIBS Stereo";
1092 projStr =
"EPSG:3413";
1094 }
else if (((metaData->
north + metaData->
south) / 2.) < -60.) {
1095 mapDesc =
"Stereographic";
1096 projName =
"GIBS Stereo";
1097 projStr =
"EPSG:3031";
1100 mapDesc =
"Equidistant Cylindrical";
1101 projName =
"PlateCarree";
1104 " +lat_ts=0 +lat_0=0 +x_0=0 +y_0=0"
1105 " +ellps=WGS84 +datum=WGS84 +units=m +no_defs";
1109 }
else if (strcasecmp(projectionStr,
"platecarree") == 0) {
1110 mapDesc =
"Equidistant Cylindrical";
1111 projName =
"PlateCarree";
1114 " +lat_ts=0 +lat_0=0 +x_0=0 +y_0=0"
1115 " +ellps=WGS84 +datum=WGS84 +units=m +no_defs";
1120 projName = projectionStr;
1121 projStr = projectionStr;
1125 sprintf(metaData->
title,
"%s Level-3 %s Mapped Image", metaData->
sensor_name, mapDesc.c_str());
1126 for (
OutFile* outFile : outFiles) {
1127 if (outFile->getMetadata() != metaData)
1128 strcpy(outFile->getMetadata()->title, metaData->
title);
1129 outFile->setMapProjection(projName);
1144 pj = proj_create_crs_to_crs(PJ_DEFAULT_CTX,
"EPSG:4326", projStr.c_str(),
NULL);
1146 printf(
"Error - l3mapgen first PROJ projection failed to init\n");
1149 pj_new = proj_normalize_for_visualization(PJ_DEFAULT_CTX, pj);
1150 if (pj_new ==
NULL) {
1151 printf(
"Error - l3mapgen visualization PROJ projection failed to init\n");
1168 std::array<double, 9>
lons{{metaData->
west, (metaData->
east + metaData->
west) / 2., metaData->
east,
1171 std::vector<Point_t>
points;
1172 for (int32_t
i = 0;
i < 9;
i++) {
1175 c_out = proj_trans(pj_new, PJ_FWD,
c);
1177 if (isfinite(c_out.xy.x) && isfinite(c_out.xy.y)) {
1178 Point_t point(c_out.xy.x, c_out.xy.y);
1185 boost::geometry::assign_points(NSEW,
points);
1195 c_out = proj_trans(pj_new, PJ_FWD,
c);
1198 if (isfinite(
x) && isfinite(
y)) {
1199 if (x < limitMax && x > limitMin) {
1205 if (y < limitMax && y > limitMin) {
1220 double latmin = 999., latmax = -999., lonmin = 999., lonmax = -999.;
1221 double lonmin360 = 999., lonmax360 = -999.;
1223 for (
int row = 0; row < l3File->
getNumRows(); row++) {
1226 x = std::numeric_limits<double>::quiet_NaN();
1227 y = std::numeric_limits<double>::quiet_NaN();
1228 int32_t binindex = 0;
1231 while ((!isfinite(
x) || !(isfinite(
y))) && binindex < l3row->getNumBins()) {
1237 c_out = proj_trans(pj_new, PJ_FWD,
c);
1243 if (isfinite(
x) && isfinite(
y)) {
1251 lon360 =
lon + 360.0;
1254 if (lon360 < lonmin360)
1256 if (lon360 > lonmax360)
1264 if (x < limitMax && x > limitMin) {
1272 if (y < limitMax && y > limitMin) {
1285 x = std::numeric_limits<double>::quiet_NaN();
1286 y = std::numeric_limits<double>::quiet_NaN();
1289 while ((!isfinite(
x) || !(isfinite(
y))) && (binindex > 0)) {
1295 c_out = proj_trans(pj_new, PJ_FWD,
c);
1301 if (isfinite(
x) && isfinite(
y)) {
1309 lon360 =
lon + 360.0;
1312 if (lon360 < lonmin360)
1314 if (lon360 > lonmax360)
1322 if (x < limitMax && x > limitMin) {
1330 if (y < limitMax && y > limitMin) {
1348 metaData->
north = latmax;
1349 metaData->
south = latmin;
1351 double delta = lonmax - lonmin;
1352 lonmax360 = fmod(lonmax + 360.0, 360.0);
1353 lonmin360 = fmod(lonmin + 360.0, 360.0);
1354 double delta360 = lonmax360 - lonmin360;
1356 if (delta360 <
delta) {
1357 if (lonmin360 > 180.0)
1358 metaData->
west = lonmin360 - 360.0;
1360 metaData->
west = lonmin360;
1361 if (lonmax360 > 180.0)
1362 metaData->
east = lonmax360 - 360.0;
1364 metaData->
east = lonmax360;
1366 metaData->
west = lonmin;
1367 metaData->
east = lonmax;
1386 for (
OutFile* outFile : outFiles)
1394 for (
OutFile* outFile : outFiles)
1399 for (
OutFile* outFile : outFiles) {
1400 outFile->setProj4Info(projStr, minX, maxY);
1410 if (outFiles.size() == 1)
1411 outFile = outFiles[0];
1413 outFile = outFiles[
i];
1422 for (
OutFile* outFile : outFiles) {
1423 if (!outFile->open()) {
1424 printf(
"-E- Could not open ofile=\"%s\".\n", outFile->getFileName().c_str());
1430 if (!outFile2->
open()) {
1431 printf(
"-E- Could not open ofile2=\"%s\".\n", outFile2->
getFileName().c_str());
1457 c_out = proj_trans(pj_new, PJ_INV,
c);
1458 tmpX[col] = c_out.xy.x;
1459 tmpY[col] = c_out.xy.y;
1460 if (!isfinite(tmpX[col]) || !isfinite(tmpY[col])) {
1466 if (boost::geometry::within(
pixel, NSEW)) {
1476 if (!isfinite(
lon) || !isfinite(
lat)) {
1477 for (
OutFile* outFile : outFiles)
1478 outFile->fillPixel(col);
1481 }
else if (
trimNSEW && inBox[col] ==
false) {
1482 for (
OutFile* outFile : outFiles)
1483 outFile->fillPixel(col);
1487 for (
OutFile* outFile : outFiles)
1488 outFile->landPixel(col);
1502 areaWeighted =
true;
1504 areaWeighted =
false;
1519 l3Bin =
getBoxBins(l3File,
lat,
lon, deltaLat, deltaLon, fudge, areaWeighted);
1531 outFiles[0]->setPixelRGB(col, l3Bin->
getMean(0), l3Bin->
getMean(1),
1538 for (
size_t prod = 0; prod <
prodNameList.size(); prod++) {
1565 if (outFiles.size() == 1)
1566 outFiles[0]->setPixel(col,
val, prod);
1568 outFiles[prod]->setPixel(col,
val, 0);
1574 for (
OutFile* outFile : outFiles)
1575 outFile->setQuality(col, l3Bin->
getQuality());
1580 for (
OutFile* outFile : outFiles)
1581 outFile->missingPixel(col);
1587 for (
OutFile* outFile : outFiles) {
1588 outFile->setLatLon(tmpY, tmpX);
1589 outFile->writeLine();
1602 proj_destroy(pj_new);
1604 for (
OutFile* outFile : outFiles) {
1606 string projtxtfilename;
1607 projtxtfilename = outFile->getFileName();
1608 projtxtfilename +=
".projtxt";
1609 ofstream projtxtfile(projtxtfilename);
1610 if (projtxtfile.is_open()) {
1611 projtxtfile <<
"# Projection information for " << outFile->getFileName() <<
"\n";
1612 projtxtfile <<
"proj=" << projStr <<
"\n";
1613 projtxtfile <<
"minX=" << std::setprecision(11) << minX <<
"\n";
1614 projtxtfile <<
"maxX=" << std::setprecision(11) << maxX <<
"\n";
1615 projtxtfile <<
"minY=" << std::setprecision(11) << minY <<
"\n";
1616 projtxtfile <<
"maxY=" << std::setprecision(11) << maxY <<
"\n";
1617 projtxtfile <<
"north=" << std::setprecision(11) << metaData->
north <<
"\n";
1618 projtxtfile <<
"south=" << std::setprecision(11) << metaData->
south <<
"\n";
1619 projtxtfile <<
"east=" << std::setprecision(11) << metaData->
east <<
"\n";
1620 projtxtfile <<
"west=" << std::setprecision(11) << metaData->
west <<
"\n";
1622 projtxtfile <<
"scale_type=" << outFile->getScaleTypeString() <<
"\n";
1623 projtxtfile <<
"datamin=" << std::setprecision(11) << outFile->getMinValue() <<
"\n";
1624 projtxtfile <<
"datamax=" << std::setprecision(11) << outFile->getMaxValue() <<
"\n";
1625 projtxtfile <<
"width=" <<
imageWidth <<
"\n";
1628 projtxtfile.close();
1632 outFile->setNumFilledPixels(numFilledPixels);
1646 if (oformatStr2 ==
NULL) {
1647 printf(
"-E- Unknown output file format \"%s\"\n", oformatStr);
1651 string oformat = oformatStr2;
1652 if (oformat.compare(
"PPM") == 0) {
1662 }
else if (oformat.compare(
"PNG") == 0) {
1668 }
else if (oformat.compare(
"TIFF") == 0) {
1678 }
else if (oformat.compare(
"HDF4") == 0) {
1680 }
else if (oformat.compare(
"netCDF4") == 0) {
1683 printf(
"-E- Output file type %s not implemented\n", oformat.c_str());
1693 vector<OutFile*> outFiles;
1703 outFiles.push_back(outFile);
1705 size_t pos = originalOfile.find(tag);
1706 if (
pos == string::npos) {
1707 printf(
"Error: ofile_product_tag=%s, not found in ofile=%s\n", tag.c_str(),
1708 originalOfile.c_str());
1710 " and you asked for multiple products with image "
1719 newName.replace(
pos, tag.size(), prodName_clean + modifier);
1723 outFiles.push_back(outFile);
1735 vector<OutFile*> outFiles;
1742 char softwareVersion[200];
1767 if (!l3File->
open(ifileName)) {
1771 if (!l3File->
open(ifileName)) {
1772 printf(
"-E- Could not open ifile=\"%s\".\n", ifileName);
1792 if (tmpName !=
"qual_l3") {
1804 string cleanProdName;
1805 vector<string>
parts;
1808 int32_t* wave_array_of_the_sensor;
1810 std::unordered_set<int32_t> look_up_for_wv;
1812 const auto total_num_bands =
1815 productInfo_t* p_info;
1818 for (
int i = 0;
i < total_num_bands;
i++) {
1819 look_up_for_wv.insert(wave_array_of_the_sensor[
i]);
1824 boost::algorithm::token_compress_on);
1826 std::vector<std::string> colon_expanded_list;
1828 if (boost::contains(wv_par,
":")) {
1829 std::vector<std::string> pars;
1830 boost::split(pars, wv_par, boost::is_any_of(
":"));
1831 if (pars.size() != 2) {
1832 EXIT_LOG(std::cerr <<
"--Error-: Wrong range specifier: " << wv_par << std::endl;)
1835 int wav_st = boost::lexical_cast<int32_t>(pars.at(0));
1836 int wav_end = boost::lexical_cast<int32_t>(pars.at(1));
1837 if (look_up_for_wv.count(wav_st) == 0) {
1838 EXIT_LOG(std::cerr <<
"--Error--: The start wavelength " << wav_st
1839 <<
" is not found in sensor wv list.\n Check "
1841 << wv_par << std::endl);
1843 if (look_up_for_wv.count(wav_end) == 0) {
1844 EXIT_LOG(std::cerr <<
"--Error--: The end wavelength " << wav_end
1845 <<
" is not found in sensor wv list.\n Check "
1847 << wv_par << std::endl);
1849 for (int32_t
i = wav_st;
i <= wav_end;
i++) {
1850 if (look_up_for_wv.count(
i) == 0)
1852 colon_expanded_list.push_back(boost::lexical_cast<std::string>(
i));
1854 }
catch (
const boost::bad_lexical_cast& e) {
1855 EXIT_LOG(std::cerr << e.what() <<
'\n'; std::cerr
1856 <<
"--Error--: Provided wavelength are not valid "
1858 << wv_par << std::endl;)
1861 colon_expanded_list.push_back(wv_par);
1868 std::unordered_set<std::string> look_up_table_product_availiable_list;
1870 for (
int i = 0;
i < number_of_products;
i++) {
1872 look_up_table_product_availiable_list.insert(
name);
1874 std::vector<std::string> temp_prod_name_list;
1875 std::unordered_set<std::string> already_set_wv;
1878 if (already_set_wv.count(wv) == 0) {
1879 already_set_wv.insert(wv);
1881 EXIT_LOG(std::cerr <<
"--Error--: A duplicate found in the wavelength_3d list " << wv
1886 std::vector<std::string>
names;
1891 EXIT_LOG(std::cerr <<
"--Error--: Could not find the product: " << clean_name << std::endl);
1893 int prod_rank = p_info->rank;
1897 if (look_up_table_product_availiable_list.count(clean_name) == 0) {
1898 if (prod_rank != 3) {
1899 EXIT_LOG(std::cerr <<
"--Error--: Non-3D Product " << clean_name
1900 <<
" is not found in the bin l3 file\n");
1904 for (
const auto& product_in_l3in : look_up_table_product_availiable_list) {
1908 EXIT_LOG(std::cerr <<
"--Error--: Could not read the product info " << product_in_l3in
1912 const std::string local_name = p_info->productName;
1913 if (boost::contains(clean_name, local_name)) {
1914 if (!local_suffix.empty()) {
1915 if (!boost::contains(clean_name, local_suffix))
1918 if (clean_name != local_name)
1922 const std::string wave_length = boost::lexical_cast<std::string>(p_info->prod_ix);
1923 if (wave_length.empty()) {
1924 EXIT_LOG(std::cerr <<
"--Error--: Not valid 2D slice of " << clean_name
1925 <<
"in the l3bin file " << std::endl);
1933 bool prod_3d_expand_found =
false;
1937 if (look_up_table_product_availiable_list.count(prod_3d_name) == 0) {
1938 EXIT_LOG(std::cerr <<
"--Error--: Neither product " << clean_name
1939 <<
" or its wavelength 3d slice " << prod_3d_name
1940 <<
" are found. \nExiting ... " << std::endl);
1942 prod_3d_expand_found =
true;
1943 names.at(0) = prod_3d_name;
1946 wavelength = boost::lexical_cast<int32_t>(wv);
1947 }
catch (
const boost::bad_lexical_cast& e) {
1948 EXIT_LOG(std::cerr << e.what() <<
'\n';
1949 std::cerr <<
"--Error--: Provided wavelength are not valid "
1950 "numbers. \nExiting...");
1957 if (!temp_prod_3d_name.empty())
1958 temp_prod_3d_name +=
":";
1959 temp_prod_3d_name +=
name;
1961 temp_prod_name_list.push_back(temp_prod_3d_name);
1964 if (!prod_3d_expand_found) {
1965 EXIT_LOG(std::cerr <<
"--Error--: Product not found : " << clean_name << std::endl);
1969 if (prod_rank != 2) {
1970 EXIT_LOG(std::cerr <<
"--Error--: The product in the bin file " << clean_name
1971 <<
" is not a 2D prodcut" << std::endl);
1983 if (oformatStr2.compare(
"netCDF4") != 0) {
1984 EXIT_LOG(std::cerr <<
"The user supplied a 3D product "
1985 <<
" and the output format for ofile2 is not netCDF4.\n"
1986 <<
"Exiting ... " << std::endl);
1994 cleanProdName +=
",";
1996 if (
parts.size() == 1) {
1997 cleanProdName +=
parts[0];
1999 }
else if (
parts.size() == 2) {
2001 cleanProdName +=
parts[0];
2002 if (
parts[1].compare(
"avg") == 0)
2004 else if (
parts[1].compare(
"stdev") == 0)
2006 else if (
parts[1].compare(
"var") == 0)
2008 else if (
parts[1].compare(
"nobs") == 0)
2010 else if (
parts[1].compare(
"nscenes") == 0)
2012 else if (
parts[1].compare(
"obs_time") == 0)
2014 else if (
parts[1].compare(
"bin_num") == 0)
2018 printf(
"-E- measurement type \"%s\" "
2019 "not understood for product \"%s\".\n",
2028 printf(
"-E- Could not find product=\"%s\" in file=\"%s\".\n", cleanProdName.c_str(), ifileName));
2049 res = outFiles[0]->getResolution();
2053 outFiles[0]->setResolution(
"9km");
2054 res = outFiles[0]->getResolution();
2058 for (
OutFile* outFile : outFiles) {
2059 outFile->setResolution(
res);
2075 printf(
"-E- north and south metadata are equal.\n");
2078 if (metaData.
east == metaData.
west) {
2079 printf(
"-E- east and west metadata are equal.\n");
2084 if ((strcmp(projectionStr,
"smi") == 0) || (strcmp(projectionStr,
"raw") == 0)) {
2085 metaData.
north = 90.0;
2086 metaData.
south = -90.0;
2087 metaData.
east = 180.0;
2088 metaData.
west = -180.0;
2093 if (north > -90.0 && north <= 90.0) {
2094 metaData.
north = north;
2098 if (south < 90.0 && south >= -90) {
2099 metaData.
south = south;
2103 if (east > -180.0 && east <= 180.0) {
2104 metaData.
east = east;
2108 if (west < 180.0 && west >= -180.) {
2109 metaData.
west = west;
2112 if ((nsew > 0) && (nsew < 4)) {
2113 printf(
"-E- If any of north, south, east or west are provided, ALL need to be provided.\n");
2117 printf(
"-E- north must be greater than south.\n");
2122 printf(
"-E- height in degrees must be less than or equal to 180.\n");
2132 printf(
"-E- width in degrees must be less than or equal to 360.\n");
2139 if ((tmpStr = strrchr(ifileName,
'/')) !=
NULL)
2154 for (
int i = 0;
i < numOptions;
i++) {
2157 if (strcmp(option->
key,
"help") == 0)
2159 if (strcmp(option->
key,
"version") == 0)
2161 if (strstr(option->
key,
"dump_options"))
2178 for (
OutFile* outFile : outFiles) {
2179 outFile->setMetaData(&metaData);
2189 if (strcasecmp(projectionStr,
"raw") == 0) {
2191 }
else if (strcasecmp(projectionStr,
"smi") == 0) {
2198 if (outFiles[0]->getNumFilledPixels() == 0) {
2199 printf(
"\nThere are no filled pixels\n");
2200 printf(
"Deleting output file.\n");
2203 for (
OutFile* outFile : outFiles) {
2205 cmd += outFile->getFileName();
2206 system(
cmd.c_str());
2212 system(
cmd.c_str());
2219 if (threshold > 0.0) {
2220 if (outFiles[0]->getPercentFilledPixels() < threshold) {
2222 "\nPercent filled pixels (%.1f) "
2223 "is below the threshold (%.1f)\n",
2224 outFiles[0]->getPercentFilledPixels(), threshold);
2225 printf(
"Deleting output file.\n");
2228 for (
OutFile* outFile : outFiles) {
2230 cmd += outFile->getFileName();
2231 system(
cmd.c_str());
2237 system(
cmd.c_str());
2244 for (
OutFile* outFile : outFiles) {