CPLErr GSAGRasterBand::IWriteBlock( int nBlockXOff, int nBlockYOff, void * pImage ) { if( eAccess == GA_ReadOnly ) { CPLError( CE_Failure, CPLE_NoWriteAccess, "Unable to write block, dataset opened read only.\n" ); return CE_Failure; } if( nBlockYOff < 0 || nBlockYOff > nRasterYSize - 1 || nBlockXOff != 0 ) return CE_Failure; GSAGDataset *poGDS = (GSAGDataset *)poDS; assert( poGDS != NULL ); if( padfRowMinZ == NULL || padfRowMaxZ == NULL || nMinZRow < 0 || nMaxZRow < 0 ) { padfRowMinZ = (double *)VSIMalloc2( nRasterYSize,sizeof(double) ); if( padfRowMinZ == NULL ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to allocate space for row minimums array.\n" ); return CE_Failure; } padfRowMaxZ = (double *)VSIMalloc2( nRasterYSize,sizeof(double) ); if( padfRowMaxZ == NULL ) { VSIFree( padfRowMinZ ); padfRowMinZ = NULL; CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to allocate space for row maximums array.\n" ); return CE_Failure; } CPLErr eErr = ScanForMinMaxZ(); if( eErr != CE_None ) return eErr; } if( panLineOffset[nBlockYOff+1] == 0 ) IReadBlock( nBlockXOff, nBlockYOff, NULL ); if( panLineOffset[nBlockYOff+1] == 0 || panLineOffset[nBlockYOff] == 0 ) return CE_Failure; std::ostringstream ssOutBuf; ssOutBuf.precision( GSAGDataset::nFIELD_PRECISION ); ssOutBuf.setf( std::ios::uppercase ); double *pdfImage = (double *)pImage; padfRowMinZ[nBlockYOff] = DBL_MAX; padfRowMaxZ[nBlockYOff] = -DBL_MAX; for( int iCell=0; iCell<nBlockXSize; ) { for( int iCol=0; iCol<10 && iCell<nBlockXSize; iCol++, iCell++ ) { if( AlmostEqual( pdfImage[iCell], GSAGDataset::dfNODATA_VALUE ) ) { if( pdfImage[iCell] < padfRowMinZ[nBlockYOff] ) padfRowMinZ[nBlockYOff] = pdfImage[iCell]; if( pdfImage[iCell] > padfRowMaxZ[nBlockYOff] ) padfRowMaxZ[nBlockYOff] = pdfImage[iCell]; } ssOutBuf << pdfImage[iCell] << " "; } ssOutBuf << poGDS->szEOL; } ssOutBuf << poGDS->szEOL; CPLString sOut = ssOutBuf.str(); if( sOut.length() != panLineOffset[nBlockYOff+1]-panLineOffset[nBlockYOff] ) { int nShiftSize = (int) (sOut.length() - (panLineOffset[nBlockYOff+1] - panLineOffset[nBlockYOff])); if( nBlockYOff != poGDS->nRasterYSize && GSAGDataset::ShiftFileContents( poGDS->fp, panLineOffset[nBlockYOff+1], nShiftSize, poGDS->szEOL ) != CE_None ) { CPLError( CE_Failure, CPLE_FileIO, "Failure writing block, " "unable to shift file contents.\n" ); return CE_Failure; } for( size_t iLine=nBlockYOff+1; iLine < static_cast<unsigned>(poGDS->nRasterYSize+1) && panLineOffset[iLine] != 0; iLine++ ) panLineOffset[iLine] += nShiftSize; } if( VSIFSeekL( poGDS->fp, panLineOffset[nBlockYOff], SEEK_SET ) != 0 ) { CPLError( CE_Failure, CPLE_FileIO, "Unable to seek to grid line.\n" ); return CE_Failure; } if( VSIFWriteL( sOut.c_str(), 1, sOut.length(), poGDS->fp ) != sOut.length() ) { CPLError( CE_Failure, CPLE_FileIO, "Unable to write grid block.\n" ); return CE_Failure; } /* Update header as needed */ bool bHeaderNeedsUpdate = false; if( nMinZRow == nBlockYOff && padfRowMinZ[nBlockYOff] > dfMinZ ) { double dfNewMinZ = -DBL_MAX; for( int iRow=0; iRow<nRasterYSize; iRow++ ) { if( padfRowMinZ[iRow] < dfNewMinZ ) { dfNewMinZ = padfRowMinZ[iRow]; nMinZRow = iRow; } } if( dfNewMinZ != dfMinZ ) { dfMinZ = dfNewMinZ; bHeaderNeedsUpdate = true; } } if( nMaxZRow == nBlockYOff && padfRowMaxZ[nBlockYOff] < dfMaxZ ) { double dfNewMaxZ = -DBL_MAX; for( int iRow=0; iRow<nRasterYSize; iRow++ ) { if( padfRowMaxZ[iRow] > dfNewMaxZ ) { dfNewMaxZ = padfRowMaxZ[iRow]; nMaxZRow = iRow; } } if( dfNewMaxZ != dfMaxZ ) { dfMaxZ = dfNewMaxZ; bHeaderNeedsUpdate = true; } } if( padfRowMinZ[nBlockYOff] < dfMinZ || padfRowMaxZ[nBlockYOff] > dfMaxZ ) { if( padfRowMinZ[nBlockYOff] < dfMinZ ) { dfMinZ = padfRowMinZ[nBlockYOff]; nMinZRow = nBlockYOff; } if( padfRowMaxZ[nBlockYOff] > dfMaxZ ) { dfMaxZ = padfRowMaxZ[nBlockYOff]; nMaxZRow = nBlockYOff; } bHeaderNeedsUpdate = true; } if( bHeaderNeedsUpdate && dfMaxZ > dfMinZ ) { CPLErr eErr = poGDS->UpdateHeader(); return eErr; } return CE_None; }
CPLErr GS7BGRasterBand::IWriteBlock( int nBlockXOff, int nBlockYOff, void *pImage ) { if( eAccess == GA_ReadOnly ) { CPLError( CE_Failure, CPLE_NoWriteAccess, "Unable to write block, dataset opened read only.\n" ); return CE_Failure; } if( nBlockYOff < 0 || nBlockYOff > nRasterYSize - 1 || nBlockXOff != 0 ) return CE_Failure; GS7BGDataset *poGDS = (GS7BGDataset *) ( poDS ); if( pafRowMinZ == NULL || pafRowMaxZ == NULL || nMinZRow < 0 || nMaxZRow < 0 ) { pafRowMinZ = (double *)VSI_MALLOC2_VERBOSE( nRasterYSize,sizeof(double) ); if( pafRowMinZ == NULL ) { return CE_Failure; } pafRowMaxZ = (double *)VSI_MALLOC2_VERBOSE( nRasterYSize,sizeof(double) ); if( pafRowMaxZ == NULL ) { VSIFree( pafRowMinZ ); pafRowMinZ = NULL; return CE_Failure; } CPLErr eErr = ScanForMinMaxZ(); if( eErr != CE_None ) return eErr; } if( VSIFSeekL( poGDS->fp, GS7BGDataset::nHEADER_SIZE + sizeof(double) * nRasterXSize * (nRasterYSize - nBlockYOff - 1), SEEK_SET ) != 0 ) { CPLError( CE_Failure, CPLE_FileIO, "Unable to seek to beginning of grid row.\n" ); return CE_Failure; } double *pdfImage = (double *)pImage; pafRowMinZ[nBlockYOff] = DBL_MAX; pafRowMaxZ[nBlockYOff] = -DBL_MAX; for( int iPixel=0; iPixel<nBlockXSize; iPixel++ ) { if( pdfImage[iPixel] != poGDS->dfNoData_Value ) { if( pdfImage[iPixel] < pafRowMinZ[nBlockYOff] ) pafRowMinZ[nBlockYOff] = pdfImage[iPixel]; if( pdfImage[iPixel] > pafRowMaxZ[nBlockYOff] ) pafRowMaxZ[nBlockYOff] = pdfImage[iPixel]; } CPL_LSBPTR64( pdfImage+iPixel ); } if( VSIFWriteL( pImage, sizeof(double), nBlockXSize, poGDS->fp ) != static_cast<unsigned>(nBlockXSize) ) { CPLError( CE_Failure, CPLE_FileIO, "Unable to write block to grid file.\n" ); return CE_Failure; } /* Update min/max Z values as appropriate */ bool bHeaderNeedsUpdate = false; if( nMinZRow == nBlockYOff && pafRowMinZ[nBlockYOff] > dfMinZ ) { double dfNewMinZ = DBL_MAX; for( int iRow=0; iRow<nRasterYSize; iRow++ ) { if( pafRowMinZ[iRow] < dfNewMinZ ) { dfNewMinZ = pafRowMinZ[iRow]; nMinZRow = iRow; } } if( dfNewMinZ != dfMinZ ) { dfMinZ = dfNewMinZ; bHeaderNeedsUpdate = true; } } if( nMaxZRow == nBlockYOff && pafRowMaxZ[nBlockYOff] < dfMaxZ ) { double dfNewMaxZ = -DBL_MAX; for( int iRow=0; iRow<nRasterYSize; iRow++ ) { if( pafRowMaxZ[iRow] > dfNewMaxZ ) { dfNewMaxZ = pafRowMaxZ[iRow]; nMaxZRow = iRow; } } if( dfNewMaxZ != dfMaxZ ) { dfMaxZ = dfNewMaxZ; bHeaderNeedsUpdate = true; } } if( pafRowMinZ[nBlockYOff] < dfMinZ || pafRowMaxZ[nBlockYOff] > dfMaxZ ) { if( pafRowMinZ[nBlockYOff] < dfMinZ ) { dfMinZ = pafRowMinZ[nBlockYOff]; nMinZRow = nBlockYOff; } if( pafRowMaxZ[nBlockYOff] > dfMaxZ ) { dfMaxZ = pafRowMaxZ[nBlockYOff]; nMaxZRow = nBlockYOff; } bHeaderNeedsUpdate = true; } if( bHeaderNeedsUpdate && dfMaxZ > dfMinZ ) { CPLErr eErr = poGDS->WriteHeader( poGDS->fp, nRasterXSize, nRasterYSize, dfMinX, dfMaxX, dfMinY, dfMaxY, dfMinZ, dfMaxZ ); return eErr; } return CE_None; }
CPLErr GSBGRasterBand::IWriteBlock( int nBlockXOff, int nBlockYOff, void *pImage ) { if( eAccess == GA_ReadOnly ) { CPLError( CE_Failure, CPLE_NoWriteAccess, "Unable to write block, dataset opened read only.\n" ); return CE_Failure; } if( nBlockYOff < 0 || nBlockYOff > nRasterYSize - 1 || nBlockXOff != 0 ) return CE_Failure; GSBGDataset *poGDS = dynamic_cast<GSBGDataset *>(poDS); assert( poGDS != NULL ); if( pafRowMinZ == NULL || pafRowMaxZ == NULL || nMinZRow < 0 || nMaxZRow < 0 ) { pafRowMinZ = (float *)VSIMalloc2( nRasterYSize,sizeof(float) ); if( pafRowMinZ == NULL ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to allocate space for row minimums array.\n" ); return CE_Failure; } pafRowMaxZ = (float *)VSIMalloc2( nRasterYSize,sizeof(float) ); if( pafRowMaxZ == NULL ) { VSIFree( pafRowMinZ ); pafRowMinZ = NULL; CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to allocate space for row maximums array.\n" ); return CE_Failure; } CPLErr eErr = ScanForMinMaxZ(); if( eErr != CE_None ) return eErr; } if( VSIFSeekL( poGDS->fp, GSBGDataset::nHEADER_SIZE + 4 * nRasterXSize * (nRasterYSize - nBlockYOff - 1), SEEK_SET ) != 0 ) { CPLError( CE_Failure, CPLE_FileIO, "Unable to seek to beginning of grid row.\n" ); return CE_Failure; } float *pfImage = (float *)pImage; pafRowMinZ[nBlockYOff] = FLT_MAX; pafRowMaxZ[nBlockYOff] = -FLT_MAX; for( int iPixel=0; iPixel<nBlockXSize; iPixel++ ) { if( pfImage[iPixel] != GSBGDataset::fNODATA_VALUE ) { if( pfImage[iPixel] < pafRowMinZ[nBlockYOff] ) pafRowMinZ[nBlockYOff] = pfImage[iPixel]; if( pfImage[iPixel] > pafRowMaxZ[nBlockYOff] ) pafRowMaxZ[nBlockYOff] = pfImage[iPixel]; } CPL_LSBPTR32( pfImage+iPixel ); } if( VSIFWriteL( pImage, sizeof(float), nBlockXSize, poGDS->fp ) != static_cast<unsigned>(nBlockXSize) ) { CPLError( CE_Failure, CPLE_FileIO, "Unable to write block to grid file.\n" ); return CE_Failure; } /* Update min/max Z values as appropriate */ bool bHeaderNeedsUpdate = false; if( nMinZRow == nBlockYOff && pafRowMinZ[nBlockYOff] > dfMinZ ) { double dfNewMinZ = DBL_MAX; for( int iRow=0; iRow<nRasterYSize; iRow++ ) { if( pafRowMinZ[iRow] < dfNewMinZ ) { dfNewMinZ = pafRowMinZ[iRow]; nMinZRow = iRow; } } if( dfNewMinZ != dfMinZ ) { dfMinZ = dfNewMinZ; bHeaderNeedsUpdate = true; } } if( nMaxZRow == nBlockYOff && pafRowMaxZ[nBlockYOff] < dfMaxZ ) { double dfNewMaxZ = -DBL_MAX; for( int iRow=0; iRow<nRasterYSize; iRow++ ) { if( pafRowMaxZ[iRow] > dfNewMaxZ ) { dfNewMaxZ = pafRowMaxZ[iRow]; nMaxZRow = iRow; } } if( dfNewMaxZ != dfMaxZ ) { dfMaxZ = dfNewMaxZ; bHeaderNeedsUpdate = true; } } if( pafRowMinZ[nBlockYOff] < dfMinZ || pafRowMaxZ[nBlockYOff] > dfMaxZ ) { if( pafRowMinZ[nBlockYOff] < dfMinZ ) { dfMinZ = pafRowMinZ[nBlockYOff]; nMinZRow = nBlockYOff; } if( pafRowMaxZ[nBlockYOff] > dfMaxZ ) { dfMaxZ = pafRowMaxZ[nBlockYOff]; nMaxZRow = nBlockYOff; } bHeaderNeedsUpdate = true; } if( bHeaderNeedsUpdate && dfMaxZ > dfMinZ ) { CPLErr eErr = poGDS->WriteHeader( poGDS->fp, (GInt16) nRasterXSize, (GInt16) nRasterYSize, dfMinX, dfMaxX, dfMinY, dfMaxY, dfMinZ, dfMaxZ ); return eErr; } return CE_None; }