/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright (C) 2011-2015 by The HDF Group. * * All rights reserved. * * * * This file is part of the H4CF conversion toolkit. The full H4CF conversion* * toolkit copyright notice including terms governing use, modification, and * * redistribution, is contained in the files COPYING and Copyright.html. * * COPYING and Copyright.html can be found at the root of the source code * * distribution tree. * * For questions contact eoshelp@hdfgroup.org or help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /***************************************************************************** Category: Header file for the EOS2 module under the eoslib namespace Description: This file includes a definition of an HDF-EOS2 grid geo-location field(eos2_var_gd_ll) class. It also includes related method declarations. *****************************************************************************/ #ifndef EOS2_VAR_GD_LL_H #define EOS2_VAR_GD_LL_H #include "eos2_file.h" #include "eos2_group.h" #ifdef _MSC_VER #define isnan(x) _isnan(x) #define isinf(x) (!_finite(x)) #define fpu_error(x) (isinf(x) || isnan(x)) #endif namespace eoslib { class eos2_var_gd_ll: public var { public: typedef enum {LATITUDE, LONGITUDE} type_t; eos2_var_gd_ll( group *g, file_info *f, eos2_handle *handle, const std::string& nickname, type_t type, std::list& dims); eos2_var_gd_ll(const eos2_var_gd_ll& r); virtual ~eos2_var_gd_ll(); virtual value_type_t get_type() const; virtual void get_value(int32 start[], int32 stride[], int32 edge[], void *buf) const; virtual var *_clone() const; virtual bool same_obj_test(var*) const; /* Test for undefined values returned by longitude-latitude calculation */ bool isundef_lat(double value) const { if(isinf(value)) return(true); if(isnan(value)) return(true); /* GCTP_LAMAZ returns "1e+51" for values at the opposite poles */ if(value < -90.0 || value > 90.0) return(true); return(false); } /* end bool isundef_lat(double value) */ bool isundef_lon(double value) const { if(isinf(value)) return(true); if(isnan(value)) return(true); /* GCTP_LAMAZ returns "1e+51" for values at the opposite poles */ if(value < -180.0 || value > 180.0) return(true); return(false); } /* end bool isundef_lat(double value) */ /** * Given rol, col address in double array of dimension YDim x XDim * return value of nearest neighbor to (row,col) which is not * undefined */ double nearestNeighborLatVal(double *array, int row, int col, int YDim, int XDim) const { /* test valid row, col address range */ if(row < 0 || row > YDim || col < 0 || col > XDim) { std::cerr << "nearestNeighborLatVal("< XDim/2) { /* search by incrementing row and decrementing col */ if(!isundef_lat(array[(row+1)*XDim+col])) return(array[(row+1)*XDim+col]); if(!isundef_lat(array[row*XDim+col-1])) return(array[row*XDim+col-1]); if(!isundef_lat(array[(row+1)*XDim+col-1])) return(array[(row+1)*XDim+col-1]); /* recurse on the diagonal */ return(nearestNeighborLatVal(array, row+1, col-1, YDim, XDim)); } if(row > YDim/2 && col < XDim/2) { /* search by incrementing col and decrementing row */ if(!isundef_lat(array[(row-1)*XDim+col])) return(array[(row-1)*XDim+col]); if(!isundef_lat(array[row*XDim+col+1])) return(array[row*XDim+col+1]); if(!isundef_lat(array[(row-1)*XDim+col+1])) return(array[(row-1)*XDim+col+1]); /* recurse on the diagonal */ return(nearestNeighborLatVal(array, row-1, col+1, YDim, XDim)); } if(row > YDim/2 && col > XDim/2) { /* search by decrementing both row and col */ if(!isundef_lat(array[(row-1)*XDim+col])) return(array[(row-1)*XDim+col]); if(!isundef_lat(array[row*XDim+col-1])) return(array[row*XDim+col-1]); if(!isundef_lat(array[(row-1)*XDim+col-1])) return(array[(row-1)*XDim+col-1]); /* recurse on the diagonal */ return(nearestNeighborLatVal(array, row-1, col-1, YDim, XDim)); } return 0.0; } // end double nearestNeighborLonVal(double *array, int row, int col, int YDim, int XDim) const { // test valid row, col address range if(row < 0 || row > YDim || col < 0 || col > XDim) { std::cerr << "nearestNeighborLonVal("< XDim/2) { /* search by incrementing row and decrementing col */ if(!isundef_lon(array[(row+1)*XDim+col])) return(array[(row+1)*XDim+col]); if(!isundef_lon(array[row*XDim+col-1])) return(array[row*XDim+col-1]); if(!isundef_lon(array[(row+1)*XDim+col-1])) return(array[(row+1)*XDim+col-1]); /* recurse on the diagonal */ return(nearestNeighborLonVal(array, row+1, col-1, YDim, XDim)); } if(row > YDim/2 && col < XDim/2) { /* search by incrementing col and decrementing row */ if(!isundef_lon(array[(row-1)*XDim+col])) return(array[(row-1)*XDim+col]); if(!isundef_lon(array[row*XDim+col+1])) return(array[row*XDim+col+1]); if(!isundef_lon(array[(row-1)*XDim+col+1])) return(array[(row-1)*XDim+col+1]); /* recurse on the diagonal */ return(nearestNeighborLonVal(array, row-1, col+1, YDim, XDim)); } if(row > YDim/2 && col > XDim/2) { /* search by decrementing both row and col */ if(!isundef_lon(array[(row-1)*XDim+col])) return(array[(row-1)*XDim+col]); if(!isundef_lon(array[row*XDim+col-1])) return(array[row*XDim+col-1]); if(!isundef_lon(array[(row-1)*XDim+col-1])) return(array[(row-1)*XDim+col-1]); /* recurse on the diagonal */ return(nearestNeighborLonVal(array, row-1, col-1, YDim, XDim)); } return 0.0; } // end protected: file_info *m_file_info; eos2_handle *m_handle; type_t m_type; mutable float64 *m_lat; mutable float64 *m_lon; mutable int32 m_ydim; mutable int32 m_xdim; std::string m_eos2varname; private: eos2_var_gd_ll(); }; } // namespace #endif