16 using namespace netCDF;
17 using namespace netCDF::exceptions;
23 static float normalizeLon(
float lon) {
31 static float rotateLon(
float lon,
float ref) {
32 return normalizeLon(
lon -
ref);
35 static void fixModisResolution(lonlat2pixline_t *
params) {
37 if (
params->resolution == 500) {
43 }
else if (
params->resolution == 250) {
60 fprintf(
stderr,
"-E- %s:%d: %s\n",
84 float filelon[2] = {1000, -1000};
85 float filelat[2] = {1000, -1000};
89 l1str *
l1rec =
nullptr;
90 filehandle *
l1file =
nullptr;
91 l1_input_t* input_save =
nullptr;
92 int extra_options_save;
105 float refBoxLon = 0.0;
110 int32_t minScan = 2147483647;
111 int32_t maxScan = -1;
112 int32_t minPix = 2147483647;
117 int32_t extract_pix_off = 0;
120 int32_t percentFloor = 0;
122 static l2_prod l2_str;
129 int32_t sds_id_ll[2];
130 int32_t
start[3] = {0, 0, 0};
134 int grpid, lonid, latid;
135 size_t ncStart[] = {0, 0};
136 size_t ncCount[] = {1, 1};
139 NcVar latVar, lonVar;
140 float latScale, lonScale;
142 float latlon[2][2000];
151 cornerlon[0] =
params->SWlon - 0.025;
152 cornerlon[1] =
params->SWlon + 0.025;
154 cornerlat[0] =
params->SWlat - 0.025;
155 cornerlat[1] =
params->SWlat + 0.025;
156 if (cornerlat[0] < -90) cornerlat[0] = -89.99;
157 if (cornerlat[1] > +90) cornerlat[1] = +89.99;
163 cornerlon[0] =
params->SWlon;
164 cornerlon[1] =
params->NElon;
165 cornerlat[0] =
params->SWlat;
166 cornerlat[1] =
params->NElat;
168 if (cornerlat[0] > cornerlat[1]) {
169 printf(
"-E- lonlat2pixline: SW lat must be south of NE lat\n");
175 cornerlon[0] = normalizeLon(cornerlon[0]);
176 cornerlon[1] = normalizeLon(cornerlon[1]);
177 if (cornerlon[1] < cornerlon[0])
181 refBoxLon = normalizeLon(cornerlon[0] + (cornerlon[1] - cornerlon[0]) / 2);
182 normBoxLon[0] = rotateLon(cornerlon[0], refBoxLon);
183 normBoxLon[1] = rotateLon(cornerlon[1], refBoxLon);
188 printf(
"-E- lonlat2pixline: Can not have resolution of %d with an Ocean Subsetted MODIS file.\n",
198 sd_id = SDstart(
params->input_filename, DFACC_RDONLY);
201 printf(
"-E- lonlat2pixline: Error opening %s for reading.\n",
206 sds_id_ll[0] = SDselect(sd_id, SDnametoindex(sd_id,
"Latitude"));
207 if (sds_id_ll[0] == -1) {
208 printf(
"-E- lonlat2pixline: Error opening Latitude field.\n");
211 status = SDgetinfo(sds_id_ll[0], buffer, &
rank, dims, &
dtype, &nattrs);
216 status = SDreadattr(sd_id, SDfindattr(sd_id,
"Max Earth Frames"), &
epix);
221 sds_id_ll[1] = SDselect(sd_id, SDnametoindex(sd_id,
"Longitude"));
222 if (sds_id_ll[1] == -1) {
223 printf(
"-E- lonlat2pixline: Error opening Longitude field.\n");
228 attrindx = SDfindattr(sd_id,
"Extract Pixel Offset");
230 status = SDreadattr(sd_id, attrindx, &extract_pix_off);
233 int dimids[] = {-1,-1};
237 geoname =
params->input_filename;
239 geoname =
params->geo_filename;
241 if(geoname[0] == 0) {
242 fprintf(
stderr,
"-E- lonlat2pixline: Must supply a geofile for VIIRS.\n");
246 status = nc_open(geoname, NC_NOWRITE, &ncid);
249 "-E- lonlat2pixline: Error opening %s for reading.\n",
254 check_nc(nc_inq_grp_ncid(ncid,
"geolocation_data", &grpid),
256 check_nc(nc_inq_varid(grpid,
"longitude", &lonid),
258 check_nc(nc_inq_varid(grpid,
"latitude", &latid),
261 status = nc_inq_vardimid(grpid, latid, dimids);
262 nc_inq_dimlen(ncid, dimids[0], &dimlen);
265 nc_inq_dimlen(ncid, dimids[1], &dimlen);
269 lonArray = (
float *) malloc(
npix *
sizeof(
float));
270 latArray = (
float *) malloc(
npix *
sizeof(
float));
274 nc_set_chunk_cache(10000000, 23, 1.0);
276 latVar =
ncFile.getVar(
"latitude");
277 lonVar =
ncFile.getVar(
"longitude");
278 latVar.getAtt(
"scale_factor").getValues(&latScale);
279 lonVar.getAtt(
"scale_factor").getValues(&lonScale);
281 std::vector<NcDim> dims = latVar.getDims();
282 nscan = dims[0].getSize();
284 npix = dims[1].getSize();
287 lonArray = (
float *) malloc(
npix *
sizeof(
float));
288 latArray = (
float *) malloc(
npix *
sizeof(
float));
291 catch(NcException& e) {
292 printf(
"-E- %s:%d - Problem reading latitude/longitude from file %s\n",
293 __FILE__, __LINE__,
params->input_filename);
301 printf(
"-E- lonlat2pixline: Error opening %s for reading.\n",
309 printf(
"-E- lonlat2pixline: Error opening %s for reading.\n",
317 filelon[0] = normalizeLon(meta_l2.westlon);
318 filelon[1] = normalizeLon(meta_l2.eastlon);
319 if (filelon[1] < filelon[0])
321 filelat[0] = meta_l2.southlat;
322 filelat[1] = meta_l2.northlat;
328 nscan = escan - sscan + 1;
331 if (normBoxLon[0] <= rotateLon(filelon[0], refBoxLon) &&
332 normBoxLon[1] >= rotateLon(filelon[1], refBoxLon) &&
333 cornerlat[0] <= filelat[0] &&
334 cornerlat[1] >= filelat[1]) {
336 params->eline = escan + 1;
349 }
else if (
type > 0) {
357 l1file = (filehandle*) malloc(
sizeof (filehandle));
358 l1rec = (l1str*) malloc(
sizeof (l1str));
374 printf(
"-E- lonlat2pixline: Error opening %s for reading.\n",
383 printf(
"-E- lonlat2pixline: Unable to allocate L1 record.\n");
391 escan =
l1file->nscan - 1;
398 printf(
"-E- lonlat2pixline: File type not recognized for %s.\n",
425 lonArray = latlon[1];
426 latArray = latlon[0];
433 check_nc(nc_get_vara_float(grpid, lonid, ncStart, ncCount, lonArray),
435 check_nc(nc_get_vara_float(grpid, latid, ncStart, ncCount, latArray),
440 std::vector<size_t> ncStart = {(size_t)
iscan,0};
441 std::vector<size_t> ncCount = {1,(size_t)
npix};
443 latVar.getVar(ncStart, ncCount, latArray);
444 lonVar.getVar(ncStart, ncCount, lonArray);
446 for (ipix = 0; ipix <
npix; ipix++) {
447 latArray[ipix] *= latScale;
448 lonArray[ipix] *= lonScale;
452 catch(NcException& e) {
463 lonArray = l2_str.longitude;
464 latArray = l2_str.latitude;
468 lonArray =
l1rec->lon;
469 latArray =
l1rec->lat;
473 lonMiddle = normalizeLon(lonArray[
npix / 2]);
476 if (filelon[0] == 1000)
477 filelon[0] = lonMiddle;
478 if (filelon[1] == -1000)
479 filelon[1] = lonMiddle;
483 if (!
params->box_failed) {
486 for (ipix = 0; ipix <
npix; ipix++) {
487 if (normBoxLon[0] < rotateLon(lonArray[ipix], refBoxLon) &&
488 normBoxLon[1] > rotateLon(lonArray[ipix], refBoxLon) &&
489 cornerlat[0] < latArray[ipix] &&
490 cornerlat[1] > latArray[ipix]) {
496 if (normBoxLon[0] < rotateLon(lonArray[0], refBoxLon) &&
497 normBoxLon[1] > rotateLon(lonArray[0], refBoxLon) &&
498 cornerlat[0] < latArray[0] &&
499 cornerlat[1] > latArray[0]) {
503 if (normBoxLon[0] < rotateLon(lonArray[
npix - 1], refBoxLon) &&
504 normBoxLon[1] > rotateLon(lonArray[
npix - 1], refBoxLon) &&
505 cornerlat[0] < latArray[
npix - 1] &&
506 cornerlat[1] > latArray[
npix - 1]) {
513 for (ipix = 0; ipix <
npix; ipix++) {
514 lat = latArray[ipix];
515 lon = normalizeLon(lonArray[ipix]);
518 if (rotateLon(
lon, lonMiddle) > 0) {
520 if (rotateLon(
lon, lonMiddle) > rotateLon(filelon[1], lonMiddle)) {
525 if (rotateLon(
lon, lonMiddle) < rotateLon(filelon[0], lonMiddle)) {
530 if (
lat < filelat[0]) filelat[0] =
lat;
531 if (
lat > filelat[1]) filelat[1] =
lat;
533 latTest = (
lat >= cornerlat[0] &&
lat <= cornerlat[1]);
534 lonTest = (rotateLon(
lon, refBoxLon) >= normBoxLon[0] && rotateLon(
lon, refBoxLon) <= normBoxLon[1]);
536 if (lonTest && latTest) {
537 if (ipix < minPix) minPix = ipix;
539 if (ipix > maxPix) maxPix = ipix;
545 if (
params->pix_srch && minPix != 2147483647 && maxPix != -1) {
547 for (ipix = minPix; ipix <= maxPix; ipix++) {
551 uv[0] = cos(
lat) * cos(
lon);
552 uv[1] = cos(
lat) * sin(
lon);
555 dot = uv[0] * uvpix[0] + uv[1] * uvpix[1] + uv[2] * uvpix[2];
570 percentDone = ((
float)
iscan / (
float) escan)*100.0;
571 if (percentDone >= percentFloor) {
573 fprintf(
stderr,
"\rlonlat2pixline %2.0lf%% done.",
574 ((
float)
iscan / (
float) escan)*100.0);
577 if (
iscan % 500 == 0) {
578 fprintf(
stderr,
" Reading scan: %d out of %d",
iscan, escan);
589 if (minScan == 2147483647) minScan = -1;
590 if (minPix == 2147483647) minPix = -1;
593 if (extract_pix_off > 0) {
594 minPix -= extract_pix_off;
595 maxPix -= extract_pix_off;
600 if (
params->want_pixbox == 1) {
604 ((pixsn + 1 -
params->ybox) >= 1) ?
608 ((pixsn + 1 +
params->ybox) <= escan) ?
610 (
params->eline = escan+1);
612 ((pixpx + 1 - extract_pix_off -
params->xbox) >= 1) ?
613 (
params->spixl = pixpx + 1 - extract_pix_off -
params->xbox) :
616 ((pixpx + 1 - extract_pix_off +
params->xbox) <=
epix) ?
617 (
params->epixl = pixpx + 1 - extract_pix_off +
params->xbox) :
623 params->spixl =
params->epixl = pixpx + 1 - extract_pix_off;
634 params->sline = minScan + 1;
635 params->eline = maxScan + 1;
636 params->spixl = minPix + 1;
637 params->epixl = maxPix + 1;
641 SDendaccess(sds_id_ll[0]);
642 SDendaccess(sds_id_ll[1]);
669 if (minScan == -1 || maxScan == -1 || minPix == -1 || maxPix == -1) {
673 normBoxLon[0] >= rotateLon(filelon[0], refBoxLon) &&
674 normBoxLon[1] <= rotateLon(filelon[1], refBoxLon) &&
675 cornerlat[0] >= filelat[0] &&
676 cornerlat[1] <= filelat[1]) {
687 if (
params->want_pixbox) {
689 if ((pixsn + 1 -
params->ybox) < 1)
691 if ((pixpx + 1 - extract_pix_off -
params->xbox) < 1)
693 if ((pixsn + 1 +
params->ybox) > escan)
695 if ((pixpx + 1 - extract_pix_off +
params->xbox) >
epix)
701 if (dx < params->xbox) {
714 if (dy < params->ybox) {
738 if (normBoxLon[0] < rotateLon(filelon[0], refBoxLon) ||
739 normBoxLon[1] > rotateLon(filelon[1], refBoxLon) ||
740 cornerlat[0] < filelat[0] ||
741 cornerlat[1] > filelat[1]) {
753 fixModisResolution(
params);
759 int32_t
resolution,
float SWlon,
float SWlat,
float NElon,
float NElat,
760 int32_t *spixl, int32_t *epixl, int32_t *sline, int32_t * eline) {
786 int32_t *spixl, int32_t *epixl, int32_t *sline, int32_t * eline) {
812 int32_t *pixl, int32_t *
line) {