int return_product_area(fmgeopos gpos, PRODhead header, float *data, s_data *a) { char *where="return_product_area"; int dx, dy, i, j, k; long l, maxsize; int nodata = 1; fmucsref uref; fmucspos upos; fmindex xyp; uref.Bx = header.Bx; uref.By = header.By; uref.Ax = header.Ax; uref.Ay = header.Ay; uref.iw = header.iw; uref.ih = header.ih; maxsize = header.iw*header.ih; upos = fmgeo2ucs(gpos, MI); xyp = fmucs2ind(uref, upos); /* printf("%.2f %.2f\n", gpos.lat, gpos.lon); printf("%.2f %.2f %.2f %.2f\n", uref.Bx, uref.By, uref.Ax, uref.Ay); printf("%4d %4d\n", uref.iw, uref.ih); printf("%.2f %.2f\n", upos.eastings, upos.northings); */ if ((*a).iw == 1 && (*a).ih == 1) { *((*a).data) = data[fmivec(xyp.col,xyp.row,header.iw)]; return(FM_OK); } if ((*a).iw%2 == 0 || (*a).ih%2 == 0) { fmerrmsg(where, "The area specified must contain an odd number of pixels."); return(FM_IO_ERR); } dx = (int) floorf((float) (*a).iw/2.); dy = (int) floorf((float) (*a).ih/2.); /* printf("dy: %4d dx: %4d\n", dy, dx); */ k = 0; for (i=(xyp.row-dy); i<=(xyp.row+dy); i++) { for (j=(xyp.col-dx); j<=(xyp.col+dx); j++) { l = (int) fmivec(j,i,header.iw); if (l >= maxsize) { fmerrmsg(where, "Image size (%d) exceeded when subsetting image (%d)", maxsize, l); return(FM_IO_ERR); } /* printf("%4d %4d %3d %3d %.2f\n", k, l, i, j, data[l]); */ if ((int) (floorf (data[l]*100.)) != OUTOFIMAGE && (int) (floorf (data[l]*100.)) != MISVAL) { nodata = 0; } (*a).data[k] = data[l]; k++; } } if (nodata) { fmerrmsg(where,"No data were found."); return(FM_IO_ERR); } return(FM_OK); }
int safssi_stdat(fmgeopos gpos, fmprojspec myproj, osihdf *safssi, safssi_data *ssi) { char *where="safssi_stdat"; int dx, dy, i, j, k, l, m; int nodata = 0; fmtime timeid; fmindex xyp, tgin; fmucspos tgxy; fmgeopos tgll; fmucsref rim; /* * Convert from image header to useable data structures, first * satellite id. */ sprintf((*ssi).source,"%s", safssi->h.source); /* * The UCS info is converted */ rim.Ax = safssi->h.Ax; rim.Ay = safssi->h.Ay; rim.Bx = safssi->h.Bx; rim.By = safssi->h.By; rim.iw = safssi->h.iw; rim.ih = safssi->h.ih; /* printf(" lat: %.2f lon: %.2f\n",gpos.lat,gpos.lon); printf(" Bx: %.2f By: %.2f Ax: %.2f Ay: %.2f\n", rim.Bx,rim.By,rim.Ax,rim.Ay); */ (*ssi).nav.Ax = rim.Ax; (*ssi).nav.Ay = rim.Ay; /* * Set UNIX time for product */ timeid.fm_min = safssi->h.minute; timeid.fm_hour = safssi->h.hour; timeid.fm_mday = safssi->h.day; timeid.fm_mon = safssi->h.month; timeid.fm_year = safssi->h.year; (*ssi).vtime = tofmsec1970(timeid);; /* * Get UCS position of the requested geographical position within the * image. */ tgxy = fmgeo2ucs(gpos, myproj); tgin = fmucs2ind(rim,tgxy); if (tgin.col < 0 || tgin.row < 0) { fmerrmsg(where, "This is out of image..."); fprintf(stdout," lat: %.2f lon: %.2f\n",tgll.lat,tgll.lon); fprintf(stdout," northings: %d eastings: %d\n",tgxy.northings,tgxy.eastings); fprintf(stdout," myproj: %d\n", myproj); return(FM_SYNTAX_ERR); } (*ssi).nav.Bx = (float) tgxy.eastings; (*ssi).nav.By = (float) tgxy.northings; /* * Check bounding box size, these parameters are set by the init * function... */ if ((*ssi).nav.iw%2 == 0 || (*ssi).nav.ih%2 == 0) { fmerrmsg("avhrr_stdat","area required must be odd\n"); return(FM_SYNTAX_ERR); } /* * Collect the actual data, l is used for pixel count within the * actual image, and k within the storage tile. */ dx = (int) floorf((float) (*ssi).nav.iw/2.); dy = (int) floorf((float) (*ssi).nav.ih/2.); k = 0; for (i=(tgin.row-dy); i<=(tgin.row+dy); i++) { for (j=(tgin.col-dx); j<=(tgin.col+dx); j++) { /* * Check if within image coverage... */ if (i < 0 || j < 0 || i >= rim.ih || j >= rim.iw) continue; /* * Navigation is performed in 2D while data is stored in 1D... */ l = fmivec(j,i,rim.iw); /* * Collect data... */ (*ssi).data[k] = ((float *) safssi->d[0].data)[l]; (*ssi).qflg[k] = ((unsigned short *) safssi->d[1].data)[l]; /* * Check number of unprocessed pixels */ if ((*ssi).data[k] < -100.) nodata++; k++; } } /* * If all pixels are unprocessed this is likely to be out of coverage, * return code to indicate this... */ if (nodata == k) { fmlogmsg(where,"This request contains all unprocessed pixels."); return(FM_OTHER_ERR); } return(FM_OK); }
/* * Convert METSAT values to HDF storage values. */ int calc_avhrr_channels(fmio_img img, float *ch1, float *ch2, float *ch3b, float *ch4, float *ch5, float *ch3a, float *soz, float *saz) { char *where="calc_avhrr_channels"; long i, j; int xc, yc, ret, angarrX, angarrY; float A1, A2, A3, T3, T4, T5; float sozval, sazval; fmscale cal; fmtime date; fmsec1970 utctime, tst; fmucsref ucsref; fmucspos upos; fmgeopos gpos; fmindex xypos; fmio_subtrack subt; fmangreq angreq; fmangles *angarr; fm_img2slopes(img, &cal); fm_img2fmucsref(img, &ucsref); upos.eastings = img.Bx; upos.northings = img.By; fm_img2fmtime(img, &date); angreq.ref = ucsref; angreq.date = date; angreq.myproj = MI; angreq.subtrack.gpos = (fmgeopos *) malloc(img.numtrack*sizeof(fmgeopos)); for (i=0;i<img.numtrack;i++) { angreq.subtrack.gpos[i].lat = img.track[i].latitude; angreq.subtrack.gpos[i].lon = img.track[i].longitude; } angreq.subtrack.npoints = img.numtrack; fmlogmsg(where,"Unpacking AVHRR channels and estimating observation geometry."); /* Calculate angles for each ANGPIXDIST'th column and row */ angarrX = img.iw/ANGPIXDIST; angarrY = img.ih/ANGPIXDIST; angarr = (fmangles *) malloc(angarrX*angarrY*sizeof(fmangles)); for (yc=0;yc<img.ih;yc++) { for (xc=0;xc<img.iw;xc++) { if (xc%ANGPIXDIST == 0 && yc%ANGPIXDIST == 0) { xypos.col = xc; xypos.row = yc; gpos=fmucs2geo(upos,MI); j = fmivec((int)(xc/ANGPIXDIST),(int)(yc/ANGPIXDIST),(int)(img.iw/ANGPIXDIST)); angreq.ll = gpos; angreq.ind = xypos; if (! fmangest(angreq,&angarr[j])) { fmerrmsg(where, "Observation geometry estimation failed for pixel %d, %d", xc, yc); } } } } for (yc=0;yc<img.ih;yc++) { for (xc=0;xc<img.iw;xc++) { i = fmivec(xc,yc,img.iw); if (img.image[4][i] > 0 || img.image[0][i] > 0) { j = fmivec(mini(xc/ANGPIXDIST,angarrX),mini(yc/ANGPIXDIST,angarrY),angarrX); sozval = (angarr[j]).soz; sazval = (angarr[j]).saz; } else { sozval = -999.9; sazval = -999.9; } /*if (img.image[0][i] > 0) { A1 = calib(img.image[0][i], 1, cal); * }*/ if (img.image[0][i] > 0) { A1 = unpack_fmimage_ushort(img.image[0][i], cal, 1); } else { A1 = -999.9; } /*if (img.image[1][i] > 0) { A2 = calib(img.image[1][i], 2, cal); * }*/ if (img.image[1][i] > 0) { A2 = unpack_fmimage_ushort(img.image[1][i], cal, 1); } else { A2 = -999.9; } /*if (img.image[2][i] > 0) { T3 = calib(img.image[2][i], 3, cal); * }*/ if (img.image[2][i] > 0) { T3 = unpack_fmimage_ushort(img.image[2][i], cal, 2); } else { T3 = -999.9; } /*if (img.image[3][i] > 0) { T4 = calib(img.image[3][i], 4, cal); * }*/ if (img.image[3][i] > 0) { T4 = unpack_fmimage_ushort(img.image[3][i], cal, 2); } else { T4 = -999.9; } /*if (img.image[4][i] > 0) { T5 = calib(img.image[4][i], 5, cal); * }*/ if (img.image[4][i] > 0) { T5 = unpack_fmimage_ushort(img.image[4][i], cal, 2); } else { T5 = -999.9; } /*if (img.image[5][i] > 0) { A3 = calib(img.image[5][i], 6, cal); * }*/ if (img.image[5][i] > 0) { A3 = unpack_fmimage_ushort(img.image[5][i], cal, 1); } else { A3 = -999.9; } ch1[i] = A1; ch2[i] = A2; ch3b[i] = T3; ch4[i] = T4; ch5[i] = T5; ch3a[i] = A3; soz[i] = sozval; saz[i] = sazval; } } return(FM_OK); }
int safcm_stdat(fmgeopos gpos, fmprojspec myproj, CTy_t *ctype, safcm_data *cm) { char *where = "safcm_stdat"; char what[FMSTRING256]; int dx, dy, i, j, k, l, m, in, jn; int nodata = 1; int notprocessed = 0; /* struct clb c; */ fmucspos tgxy; fmindex tgin; fmgeopos tgll; fmucsref rim; if (FMCOL_NO_CLOUDTYPE_VALUES != SM_NUMBER_OF_CLOUDTYPE_VALUES) { sprintf(what,"The number of cloud types seem to have changed %d->%d",FMCOL_NO_CLOUDTYPE_VALUES,SM_NUMBER_OF_CLOUDTYPE_VALUES); fmerrmsg(where, what); return(FM_IO_ERR); } /* * Convert from image header to useable data structures, first * satellite id. */ sprintf((*cm).source,"%s", ctype->satellite_id); /* * The UCS info is converted, remember that SAFNWC use meter unit * while DNMI use kilometer... */ rim.Ax = M2KM(fabs(ctype->reg->area_extent[2]-ctype->reg->area_extent[0])/ (double) ctype->reg->xsize); rim.Ay = M2KM(fabs(ctype->reg->area_extent[3]-ctype->reg->area_extent[1])/ (double) ctype->reg->ysize); rim.Bx = M2KM(ctype->reg->area_extent[0]); rim.By = M2KM(ctype->reg->area_extent[3]); rim.iw = ctype->reg->xsize; rim.ih = ctype->reg->ysize; (*cm).nav.Ax = (float) rim.Ax; (*cm).nav.Ay = (float) rim.Ay; /* * Set UNIX time for product */ (*cm).vtime = ctype->sec_1970; /* * Get UCS position of the requested geographical position within the * image. */ tgll.lat = (double) gpos.lat; tgll.lon = (double) gpos.lon; tgxy = fmgeo2ucs(tgll, myproj) ; tgin = fmucs2ind(rim, tgxy); if (tgin.col < 0 || tgin.row < 0) return(FM_SYNTAX_ERR); (*cm).nav.Bx = (float) tgxy.eastings; (*cm).nav.By = (float) tgxy.northings; /* * Check bounding box size, these parameters are set by the init * function... */ if ((*cm).nav.iw%2 == 0 || (*cm).nav.ih%2 == 0) { fmerrmsg("avhrr_stdat","area required must be odd\n"); return(FM_SYNTAX_ERR); } /* * Transfer decoding information for cloudmask/type to storage tile * structure... */ for (i=0; i<FMCOL_NO_CLOUDTYPE_VALUES; i++) { /* printf(" Lengde: %d\n", strlen(ctype->cloudtype_lut[i])); */ if (ctype->cloudtype_lut[i]) { /* strncpy((*cm).description[i], ctype->cloudtype_lut[i],MAX_LENGTH_STRING); */ strncpy((*cm).description[i], ctype->cloudtype_lut[i],50); } else { sprintf((*cm).description[i],"NA"); } } /* * Collect the actual data, l is used for pixel count within the * actual image, and k within the storage tile. */ dx = (int) floorf((float) (*cm).nav.iw/2.); dy = (int) floorf((float) (*cm).nav.ih/2.); k = 0; for (i=(tgin.row-dy); i<=(tgin.row+dy); i++) { for (j=(tgin.col-dx); j<=(tgin.col+dx); j++) { /* * Check if within image coverage... */ if (i < 0 || j < 0 || i >= rim.ih || j >= rim.iw) continue; /* * Navigation is performed in 2D while data is stored in 1D... */ l = fmivec(j,i,rim.iw); /* * Collect data... */ (*cm).data[k] = (unsigned char) ctype->cloudtype[l]; /* * Check number of unprocessed pixels */ if (ctype->cloudtype[l] == 0) notprocessed++; k++; } } /* * If all pixels are unprocessed this is likely to be out of coverage, * return code to indicate this... */ if (notprocessed == k) { fmlogmsg(where,"This request contains all unprocessed pixels."); return(FM_OTHER_ERR); } return(FM_OK); }