bool ossimH5GridModel::setGridNodes( H5::DataSet* latDataSet, H5::DataSet* lonDataSet, const ossimIrect& validRect ) { bool status = false; if ( latDataSet && lonDataSet ) { m_crossesDateline = ossim_hdf5::crossesDateline( *lonDataSet, validRect ); if ( m_crossesDateline ) { theLonGrid.setDomainType(ossimDblGrid::WRAP_360); } else { theLonGrid.setDomainType(ossimDblGrid::WRAP_180); } // Get dataspace of the dataset. H5::DataSpace latDataSpace = latDataSet->getSpace(); H5::DataSpace lonDataSpace = lonDataSet->getSpace(); const ossim_int32 LAT_DIM_COUNT = latDataSpace.getSimpleExtentNdims(); const ossim_int32 LON_DIM_COUNT = lonDataSpace.getSimpleExtentNdims(); // Number of dimensions of the input dataspace: if ( ( LAT_DIM_COUNT == 2 ) && ( LON_DIM_COUNT == 2 ) ) { const ossim_uint32 ROWS = validRect.height(); const ossim_uint32 COLS = validRect.width(); const ossim_uint32 GRID_SIZE = 4; // Only grab every 4th value. //--- // Get the extents: // dimsOut[0] is height, dimsOut[1] is width: //--- std::vector<hsize_t> latDimsOut(LAT_DIM_COUNT); latDataSpace.getSimpleExtentDims( &latDimsOut.front(), 0 ); std::vector<hsize_t> lonDimsOut(LON_DIM_COUNT); lonDataSpace.getSimpleExtentDims( &lonDimsOut.front(), 0 ); // Verify valid rect within our bounds: if ( (ROWS <= latDimsOut[0] ) && (ROWS <= lonDimsOut[0] ) && (COLS <= latDimsOut[1] ) && (COLS <= lonDimsOut[1] ) ) { //---- // Initialize the ossimDblGrids: //--- ossimDpt dspacing (GRID_SIZE, GRID_SIZE); ossim_uint32 gridRows = ROWS / GRID_SIZE + 1; ossim_uint32 gridCols = COLS / GRID_SIZE + 1; // Round up if size doesn't fall on end pixel. if ( ROWS % GRID_SIZE) ++gridRows; if ( COLS % GRID_SIZE) ++gridCols; ossimIpt gridSize (gridCols, gridRows); // The grid as used in base class, has UV-space always at 0,0 origin ossimDpt gridOrigin(0.0,0.0); const ossim_float64 NULL_VALUE = -999.0; theLatGrid.setNullValue(ossim::nan()); theLonGrid.setNullValue(ossim::nan()); theLatGrid.initialize(gridSize, gridOrigin, dspacing); theLonGrid.initialize(gridSize, gridOrigin, dspacing); std::vector<hsize_t> inputCount(LAT_DIM_COUNT); std::vector<hsize_t> inputOffset(LAT_DIM_COUNT); inputOffset[0] = 0; // row is set below. inputOffset[1] = validRect.ul().x; // col inputCount[0] = 1; // row inputCount[1] = (hsize_t)COLS; // col // Output dataspace dimensions. Reading a line at a time. const ossim_int32 OUT_DIM_COUNT = 3; std::vector<hsize_t> outputCount(OUT_DIM_COUNT); outputCount[0] = 1; // band outputCount[1] = 1; // row outputCount[2] = COLS; // col // Output dataspace offset. std::vector<hsize_t> outputOffset(OUT_DIM_COUNT); outputOffset[0] = 0; outputOffset[1] = 0; outputOffset[2] = 0; ossimScalarType scalar = ossim_hdf5::getScalarType( latDataSet ); if ( scalar == OSSIM_FLOAT32 ) { // Set the return status to true if we get here... status = true; // See if we need to swap bytes: ossimEndian* endian = 0; if ( ( ossim::byteOrder() != ossim_hdf5::getByteOrder( latDataSet ) ) ) { endian = new ossimEndian(); } // Native type: H5::DataType latDataType = latDataSet->getDataType(); H5::DataType lonDataType = lonDataSet->getDataType(); // Output dataspace always the same, width of one line. H5::DataSpace bufferDataSpace( OUT_DIM_COUNT, &outputCount.front()); bufferDataSpace.selectHyperslab( H5S_SELECT_SET, &outputCount.front(), &outputOffset.front() ); // Arrays to hold a single line of latitude longitude values. vector<ossim_float32> latValue(COLS); vector<ossim_float32> lonValue(COLS); hsize_t row = 0; // Line loop: for ( ossim_uint32 y = 0; y < gridRows; ++y ) { // row = line in image space row = y*GRID_SIZE; if ( row < ROWS ) { inputOffset[0] = row + validRect.ul().y; latDataSpace.selectHyperslab( H5S_SELECT_SET, &inputCount.front(), &inputOffset.front() ); lonDataSpace.selectHyperslab( H5S_SELECT_SET, &inputCount.front(), &inputOffset.front() ); // Read data from file into the buffer. latDataSet->read( &(latValue.front()), latDataType, bufferDataSpace, latDataSpace ); lonDataSet->read( &(lonValue.front()), lonDataType, bufferDataSpace, lonDataSpace ); if ( endian ) { // If the endian pointer is initialized(not zero) swap the bytes. endian->swap( &(latValue.front()), COLS ); endian->swap( &(lonValue.front()), COLS ); } // Sample loop: hsize_t col = 0; for ( ossim_uint32 x = 0; x < gridCols; ++x ) { ossim_float32 lat = ossim::nan(); ossim_float32 lon = ossim::nan(); // col = sample in image space col = x*GRID_SIZE; if ( col < COLS ) { if ( (latValue[col] > NULL_VALUE)&&(lonValue[col] > NULL_VALUE) ) { lat = latValue[col]; lon = lonValue[col]; if ( m_crossesDateline ) { if ( lon < 0.0 ) lon += 360; } } else // Nulls in grid! { std::string errMsg = "ossimH5GridModel::setGridNodes encountered nans!"; throw ossimException(errMsg); } } else // Last column is outside of image bounds. { // Get the last two latitude values: ossim_float32 lat1 = theLatGrid.getNode( x-2, y ); ossim_float32 lat2 = theLatGrid.getNode( x-1, y ); // Get the last two longitude values ossim_float32 lon1 = theLonGrid.getNode( x-2, y ); ossim_float32 lon2 = theLonGrid.getNode( x-1, y ); if ( ( lat1 > NULL_VALUE ) && ( lat2 > NULL_VALUE ) ) { // Delta between last two latitude grid values. ossim_float32 latSpacing = lat2 - lat1; // Compute: lat = lat2 + latSpacing; } else // Nulls in grid! { std::string errMsg = "ossimH5GridModel::setGridNodes encountered nans!"; throw ossimException(errMsg); } if ( ( lon1 > NULL_VALUE ) && ( lon2 > NULL_VALUE ) ) { // Delta between last two longitude values. ossim_float32 lonSpacing = lon2 - lon1; // Compute: lon = lon2 + lonSpacing; // Check for wrap: if ( !m_crossesDateline && ( lon > 180 ) ) { lon -= 360.0; } } else // Nulls in grid! { std::string errMsg = "ossimH5GridModel::setGridNodes encountered nans!"; throw ossimException(errMsg); } #if 0 /* Please leave for debug. (drb) */ cout << "lat1: " << lat1 << " lat2 " << lat2 << " lon1 " << lon1 << " lon2 " << lon2 << "\n"; #endif } // Assign the latitude and longitude. theLatGrid.setNode( x, y, lat ); theLonGrid.setNode( x, y, lon ); #if 0 /* Please leave for debug. (drb) */ cout << "x,y,col,row,lat,lon:" << x << "," << y << "," << col << "," << row << "," << theLatGrid.getNode(x, y) << "," << theLonGrid.getNode( x, y) << "\n"; #endif } // End sample loop. } else // Row is outside of image bounds: { // Sample loop: for ( ossim_uint32 x = 0; x < gridCols; ++x ) { ossim_float32 lat = ossim::nan(); ossim_float32 lon = ossim::nan(); ossim_float32 lat1 = theLatGrid.getNode( x, y-2 ); ossim_float32 lat2 = theLatGrid.getNode( x, y-1 ); ossim_float32 lon1 = theLonGrid.getNode( x, y-2 ); ossim_float32 lon2 = theLonGrid.getNode( x, y-1 ); if ( ( lon1 > NULL_VALUE ) && ( lon2 > NULL_VALUE ) ) { // Delta between last two longitude values. ossim_float32 lonSpacing = lon2 - lon1; // Compute: lon = lon2 + lonSpacing; // Check for wrap: if ( !m_crossesDateline && ( lon > 180 ) ) { lon -= 360.0; } } else // Nulls in grid! { std::string errMsg = "ossimH5GridModel::setGridNodes encountered nans!"; throw ossimException(errMsg); } if ( ( lat1 > NULL_VALUE ) && ( lat2 > NULL_VALUE ) ) { // Delta between last two latitude values. ossim_float32 latSpacing = lat2 - lat1; lat = lat2 + latSpacing; } else // Nulls in grid! { std::string errMsg = "ossimH5GridModel::setGridNodes encountered nans!"; throw ossimException(errMsg); } #if 0 /* Please leave for debug. (drb) */ hsize_t col = x*GRID_SIZE; // Sample in image space cout << "lat1: " << lat1 << " lat2 " << lat2 << " lon1 " << lon1 << " lon2 " << lon2 << "\nx,y,col,row,lat,lon:" << x << "," << y << "," << col << "," << row << "," << lat << "," << lon << "\n"; #endif // Assign the latitude:: theLatGrid.setNode( x, y, lat ); // Assign the longitude. theLonGrid.setNode( x, y, lon ); } // End sample loop. } // Matches if ( row < imageRows ){...}else{ } // End line loop. latDataSpace.close(); lonDataSpace.close(); if ( status ) { theSeedFunction = ossim_hdf5::getBilinearProjection( *latDataSet,*lonDataSet, validRect ); // Bileaner projection to handle ossimDrect imageRect(validRect); initializeModelParams(imageRect); // debugDump(); } if ( endian ) { delete endian; endian = 0; } } // Matches: if ( scalar == OSSIM_FLOAT32 ) } // Matches: if ( (latDimsOut[0] == imageRows) ... } // Matches: if ( ( LAT_DIM_COUNT == 2 ) ... } // Matches: if ( latDataSet && lonDataSet return status; } // End: bool ossimH5GridModel::setGridNodes( H5::DataSet* latDataSet, ... )
bool ossimHdfGridModel::setGridNodes( H5::DataSet* latDataSet, H5::DataSet* lonDataSet, ossim_uint32 imageRows, ossim_uint32 imageCols ) { bool status = false; if ( latDataSet && lonDataSet ) { const ossim_uint32 GRID_SIZE = 32; // Only grab every 32nd value. // Get dataspace of the dataset. H5::DataSpace latDataSpace = latDataSet->getSpace(); H5::DataSpace lonDataSpace = lonDataSet->getSpace(); const ossim_int32 LAT_DIM_COUNT = latDataSpace.getSimpleExtentNdims(); const ossim_int32 LON_DIM_COUNT = latDataSpace.getSimpleExtentNdims(); // Number of dimensions of the input dataspace: if ( ( LAT_DIM_COUNT == 2 ) && ( LON_DIM_COUNT == 2 ) ) { //--- // Get the extents: // dimsOut[0] is height, dimsOut[1] is width: //--- std::vector<hsize_t> latDimsOut(LAT_DIM_COUNT); latDataSpace.getSimpleExtentDims( &latDimsOut.front(), 0 ); std::vector<hsize_t> lonDimsOut(LON_DIM_COUNT); lonDataSpace.getSimpleExtentDims( &lonDimsOut.front(), 0 ); // Verify same as image: if ( (latDimsOut[0] == imageRows) && (lonDimsOut[0] == imageRows) && (latDimsOut[1] == imageCols) && (lonDimsOut[1] == imageCols) ) { //--- // Capture the rectangle: // dimsOut[0] is height, dimsOut[1] is width: //--- ossimIrect rect = ossimIrect( 0, 0, static_cast<ossim_int32>( latDimsOut[1]-1 ), static_cast<ossim_int32>( latDimsOut[0]-1 ) ); //---- // Initialize the ossimDblGrids: //--- ossimDpt dspacing (GRID_SIZE, GRID_SIZE); ossim_uint32 gridRows = imageRows / GRID_SIZE + 1; ossim_uint32 gridCols = imageCols / GRID_SIZE + 1; // Round up if size doesn't fall on end pixel. if ( imageRows % GRID_SIZE) ++gridRows; if ( imageCols % GRID_SIZE) ++gridCols; ossimIpt gridSize (gridCols, gridRows); // The grid as used in base class, has UV-space always at 0,0 origin ossimDpt gridOrigin(0.0,0.0); const ossim_float64 NULL_VALUE = -999.0; theLatGrid.setNullValue(ossim::nan()); theLonGrid.setNullValue(ossim::nan()); theLatGrid.initialize(gridSize, gridOrigin, dspacing); theLonGrid.initialize(gridSize, gridOrigin, dspacing); std::vector<hsize_t> inputCount(LAT_DIM_COUNT); std::vector<hsize_t> inputOffset(LAT_DIM_COUNT); inputOffset[0] = 0; // row inputOffset[1] = 0; // col inputCount[0] = 1; // row inputCount[1] = (hsize_t)imageCols; // col // Output dataspace dimensions. Reading a line at a time. const ossim_int32 OUT_DIM_COUNT = 3; std::vector<hsize_t> outputCount(OUT_DIM_COUNT); outputCount[0] = 1; // band outputCount[1] = 1; // row outputCount[2] = imageCols; // col // Output dataspace offset. std::vector<hsize_t> outputOffset(OUT_DIM_COUNT); outputOffset[0] = 0; outputOffset[1] = 0; outputOffset[2] = 0; ossimScalarType scalar = ossim_hdf5::getScalarType( latDataSet ); if ( scalar == OSSIM_FLOAT32 ) { // Set the return status to true if we get here... status = true; // See if we need to swap bytes: ossimEndian* endian = 0; if ( ( ossim::byteOrder() != ossim_hdf5::getByteOrder( latDataSet ) ) ) { endian = new ossimEndian(); } // Native type: H5::DataType latDataType = latDataSet->getDataType(); H5::DataType lonDataType = lonDataSet->getDataType(); // Output dataspace always the same, width of one line. H5::DataSpace bufferDataSpace( OUT_DIM_COUNT, &outputCount.front()); bufferDataSpace.selectHyperslab( H5S_SELECT_SET, &outputCount.front(), &outputOffset.front() ); // Arrays to hold a single line of latitude longitude values. vector<ossim_float32> latValue(imageCols); vector<ossim_float32> lonValue(imageCols); hsize_t row = 0; // Line loop: for ( ossim_uint32 y = 0; y < gridRows; ++y ) { // row = line in image space row = y*GRID_SIZE; bool hitNans = false; if ( row < imageRows ) { inputOffset[0] = row; latDataSpace.selectHyperslab( H5S_SELECT_SET, &inputCount.front(), &inputOffset.front() ); lonDataSpace.selectHyperslab( H5S_SELECT_SET, &inputCount.front(), &inputOffset.front() ); // Read data from file into the buffer. latDataSet->read( &(latValue.front()), latDataType, bufferDataSpace, latDataSpace ); lonDataSet->read( &(lonValue.front()), lonDataType, bufferDataSpace, lonDataSpace ); if ( endian ) { // If the endian pointer is initialized(not zero) swap the bytes. endian->swap( &(latValue.front()), imageCols ); endian->swap( &(lonValue.front()), imageCols ); } // Sample loop: hsize_t col = 0; for ( ossim_uint32 x = 0; x < gridCols; ++x ) { ossim_float32 lat = ossim::nan(); ossim_float32 lon = ossim::nan(); // col = sample in image space col = x*GRID_SIZE; if ( col < imageCols ) { if ( (latValue[col] > NULL_VALUE)&&(lonValue[col] > NULL_VALUE) ) { lat = latValue[col]; lon = lonValue[col]; } else { hitNans = true; } } else // Last column is outside of image bounds. { ossim_float32 latSpacing = ossim::nan(); ossim_float32 lonSpacing = ossim::nan(); // Get the last two latitude values: ossim_float32 lat1 = latValue[imageCols-2]; ossim_float32 lat2 = latValue[imageCols-1]; // Get the last two longitude values ossim_float32 lon1 = lonValue[imageCols-2]; ossim_float32 lon2 = lonValue[imageCols-1]; if ( ( lat1 > NULL_VALUE ) && ( lat2 > NULL_VALUE ) ) { // Delta between last two latitude values. latSpacing = lat2 - lat1; // Compute: lat = lat2 + ( col - (imageCols-1) ) * latSpacing; } else { hitNans = true; } if ( ( lon1 > NULL_VALUE ) && ( lon2 > NULL_VALUE ) ) { // Consider dateline crossing. if ( (lon1 > 0.0) && ( lon2 < 0.0 ) ) { lon2 += 360.0; } // Delta between last two longitude values. lonSpacing = lon2 - lon1; // Compute: lon = lon2 + ( col - (imageCols-1) ) * lonSpacing; // Check for wrap: if ( lon > 180 ) { lon -= 360.0; } } else { hitNans = true; } #if 0 /* Please leave for debug. (drb) */ cout << "lat1: " << lat1 << " lat2 " << lat2 << " lon1 " << lon1 << " lon2 " << lon2 << "\n"; #endif } if ( hitNans ) { std::string errMsg = "ossimHdfGridModel::setGridNodes encountered nans!"; throw ossimException(errMsg); } // Assign the latitude and longitude. theLatGrid.setNode( x, y, lat ); theLonGrid.setNode( x, y, lon ); #if 0 /* Please leave for debug. (drb) */ cout << "x,y,col,row,lat,lon:" << x << "," << y << "," << col << "," << row << "," << theLatGrid.getNode(x, y) << "," << theLonGrid.getNode( x, y) << "\n"; #endif } // End sample loop. } else // Row is outside of image bounds: { // Read the last two rows in. vector<ossim_float32> latValue2(imageCols); vector<ossim_float32> lonValue2(imageCols); inputOffset[0] = imageRows-2; // 2nd to last line latDataSpace.selectHyperslab( H5S_SELECT_SET, &inputCount.front(), &inputOffset.front() ); lonDataSpace.selectHyperslab( H5S_SELECT_SET, &inputCount.front(), &inputOffset.front() ); // Read data from file into the buffer. latDataSet->read( &(latValue.front()), latDataType, bufferDataSpace, latDataSpace ); lonDataSet->read( &(lonValue.front()), lonDataType, bufferDataSpace, lonDataSpace ); inputOffset[0] = imageRows-1; // last line latDataSpace.selectHyperslab( H5S_SELECT_SET, &inputCount.front(), &inputOffset.front() ); lonDataSpace.selectHyperslab( H5S_SELECT_SET, &inputCount.front(), &inputOffset.front() ); // Read data from file into the buffer. latDataSet->read( &(latValue2.front()), latDataType, bufferDataSpace, latDataSpace ); lonDataSet->read( &(lonValue2.front()), lonDataType, bufferDataSpace, lonDataSpace ); if ( endian ) { // If the endian pointer is initialized(not zero) swap the bytes. endian->swap( &(latValue.front()), imageCols ); endian->swap( &(lonValue.front()), imageCols ); endian->swap( &(latValue2.front()), imageCols ); endian->swap( &(lonValue2.front()), imageCols ); } // Sample loop: hsize_t col = 0; for ( ossim_uint32 x = 0; x < gridCols; ++x ) { col = x*GRID_SIZE; // Sample in image space. ossim_float32 lat = ossim::nan(); ossim_float32 lat1 = ossim::nan(); ossim_float32 lat2 = ossim::nan(); ossim_float32 latSpacing = ossim::nan(); ossim_float32 lon = ossim::nan(); ossim_float32 lon1 = ossim::nan(); ossim_float32 lon2 = ossim::nan(); ossim_float32 lonSpacing = ossim::nan(); if ( col < imageCols ) { lat1 = latValue[col]; lat2 = latValue2[col]; lon1 = lonValue[col]; lon2 = lonValue2[col]; } else // Very last grid point. { // Compute the missing column for the last two image lines: lat1 = latValue[imageCols-1] + ( col - (imageCols-1)) * ( latValue[imageCols-1] - latValue[imageCols-2] ); lat2 = latValue2[imageCols-1] + ( col - (imageCols-1)) * ( latValue2[imageCols-1] - latValue2[imageCols-2] ); lon1 = lonValue[imageCols-1] + ( col - (imageCols-1)) * ( lonValue[imageCols-1] - lonValue[imageCols-2] ); lon2 = lonValue2[imageCols-1] + ( col - (imageCols-1)) * ( lonValue2[imageCols-1] - lonValue2[imageCols-2] ); } #if 0 /* Please leave for debug. (drb) */ cout << "lat1: " << lat1 << " lat2 " << lat2 << " lon1 " << lon1 << " lon2 " << lon2 << "\n"; #endif if ( ( lon1 > NULL_VALUE ) && ( lon2 > NULL_VALUE ) ) { // Consider dateline crossing. if ( (lon1 > 0.0) && ( lon2 < 0.0 ) ) { lon2 += 360.0; } // Delta between last two longitude values. lonSpacing = lon2 - lon1; // Compute: lon = lon2 + ( row - (imageRows-1) ) * lonSpacing; // Check for wrap: if ( lon > 180 ) { lon -= 360.0; } } else { hitNans = true; } if ( ( lat1 > NULL_VALUE ) && ( lat2 > NULL_VALUE ) ) { // Delta between last two latitude values. latSpacing = lat2 - lat1; // Compute: lat = lat2 + ( row - (imageRows-1) ) * latSpacing; } else { hitNans = true; } if ( hitNans ) { std::string errMsg = "ossimHdfGridModel::setGridNodes encountered nans!"; throw ossimException(errMsg); } // Assign the latitude:: theLatGrid.setNode( x, y, lat ); // Assign the longitude. theLonGrid.setNode( x, y, lon ); #if 0 /* Please leave for debug. (drb) */ cout << "x,y,col,row,lat,lon:" << x << "," << y << "," << col << "," << row << "," << lat << "," << lon << "\n"; #endif } // End sample loop. } // Matches if ( row < imageRows ){...}else{ } // End line loop. latDataSpace.close(); lonDataSpace.close(); if ( status ) { theLatGrid.enableExtrapolation(); theLonGrid.enableExtrapolation(); theHeightEnabledFlag = false; ossimDrect imageRect(rect); initializeModelParams(imageRect); // debugDump(); } } // Matches: if ( scalar == OSSIM_FLOAT32 ) } // Matches: if ( (latDimsOut[0] == imageRows) ... } // Matches: if ( ( LAT_DIM_COUNT == 2 ) ... } // Matches: if ( latDataSet && lonDataSet return status; } // End: bool ossimHdfGridModel::setGridNodes( H5::DataSet* latDataSet, ... )