CPLErr ZMapRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff, void * pImage ) { int i; ZMapDataset *poGDS = (ZMapDataset *) poDS; if (poGDS->fp == NULL) return CE_Failure; if (nBlockXOff < poGDS->nColNum + 1) { VSIFSeekL(poGDS->fp, poGDS->nDataStartOff, SEEK_SET); poGDS->nColNum = -1; } if (nBlockXOff > poGDS->nColNum + 1) { for(i=poGDS->nColNum + 1;i<nBlockXOff;i++) { if (IReadBlock(i,0,pImage) != CE_None) return CE_Failure; } } char* pszLine; i = 0; double dfExp = pow(10.0, poGDS->nDecimalCount); while(i<nRasterYSize) { pszLine = (char*)CPLReadLineL(poGDS->fp); if (pszLine == NULL) return CE_Failure; int nExpected = nRasterYSize - i; if (nExpected > poGDS->nValuesPerLine) nExpected = poGDS->nValuesPerLine; if ((int)strlen(pszLine) != nExpected * poGDS->nFieldSize) return CE_Failure; for(int j=0;j<nExpected;j++) { char* pszValue = pszLine + j * poGDS->nFieldSize; char chSaved = pszValue[poGDS->nFieldSize]; pszValue[poGDS->nFieldSize] = 0; if (strchr(pszValue, '.') != NULL) ((double*)pImage)[i+j] = CPLAtofM(pszValue); else ((double*)pImage)[i+j] = atoi(pszValue) * dfExp; pszValue[poGDS->nFieldSize] = chSaved; } i += nExpected; } poGDS->nColNum ++; return CE_None; }
CPLErr ZMapRasterBand::IReadBlock( int nBlockXOff, CPL_UNUSED int nBlockYOff, void * pImage ) { ZMapDataset *poGDS = reinterpret_cast<ZMapDataset *>( poDS ); if (poGDS->fp == NULL) return CE_Failure; if (nBlockXOff < poGDS->nColNum + 1) { VSIFSeekL(poGDS->fp, poGDS->nDataStartOff, SEEK_SET); poGDS->nColNum = -1; } if (nBlockXOff > poGDS->nColNum + 1) { for( int i = poGDS->nColNum + 1; i < nBlockXOff; i++ ) { if (IReadBlock(i,0,pImage) != CE_None) return CE_Failure; } } int i = 0; const double dfExp = std::pow(10.0, poGDS->nDecimalCount); while(i<nRasterYSize) { char* pszLine = const_cast<char *>( CPLReadLineL(poGDS->fp) ); if (pszLine == NULL) return CE_Failure; int nExpected = nRasterYSize - i; if (nExpected > poGDS->nValuesPerLine) nExpected = poGDS->nValuesPerLine; if( static_cast<int>( strlen(pszLine) ) != nExpected * poGDS->nFieldSize ) return CE_Failure; for( int j = 0; j < nExpected; j++ ) { char* pszValue = pszLine + j * poGDS->nFieldSize; const char chSaved = pszValue[poGDS->nFieldSize]; pszValue[poGDS->nFieldSize] = 0; if (strchr(pszValue, '.') != NULL) reinterpret_cast<double *>( pImage )[i+j] = CPLAtofM(pszValue); else reinterpret_cast<double *>( pImage )[i+j] = atoi(pszValue) * dfExp; pszValue[poGDS->nFieldSize] = chSaved; } i += nExpected; } poGDS->nColNum ++; return CE_None; }
CPLErr AAIGRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff, void *pImage ) { AAIGDataset *poODS = static_cast<AAIGDataset *>(poDS); if( nBlockYOff < 0 || nBlockYOff > poODS->nRasterYSize - 1 || nBlockXOff != 0 || panLineOffset == nullptr || poODS->fp == nullptr ) return CE_Failure; if( panLineOffset[nBlockYOff] == 0 ) { for( int iPrevLine = 1; iPrevLine <= nBlockYOff; iPrevLine++ ) if( panLineOffset[iPrevLine] == 0 ) IReadBlock(nBlockXOff, iPrevLine - 1, nullptr); } if( panLineOffset[nBlockYOff] == 0 ) return CE_Failure; if( poODS->Seek(panLineOffset[nBlockYOff]) != 0 ) { CPLError(CE_Failure, CPLE_FileIO, "Can't seek to offset %lu in input file to read data.", static_cast<long unsigned int>(panLineOffset[nBlockYOff])); return CE_Failure; } for( int iPixel = 0; iPixel < poODS->nRasterXSize; ) { // Suck up any pre-white space. char chNext = '\0'; do { chNext = poODS->Getc(); } while( isspace(static_cast<unsigned char>(chNext)) ); char szToken[500] = { '\0' }; int iTokenChar = 0; while( chNext != '\0' && !isspace((unsigned char)chNext) ) { if( iTokenChar == sizeof(szToken) - 2 ) { CPLError(CE_Failure, CPLE_FileIO, "Token too long at scanline %d.", nBlockYOff); return CE_Failure; } szToken[iTokenChar++] = chNext; chNext = poODS->Getc(); } if( chNext == '\0' && (iPixel != poODS->nRasterXSize - 1 || nBlockYOff != poODS->nRasterYSize - 1) ) { CPLError(CE_Failure, CPLE_FileIO, "File short, can't read line %d.", nBlockYOff); return CE_Failure; } szToken[iTokenChar] = '\0'; if( pImage != nullptr ) { if( eDataType == GDT_Float64 ) reinterpret_cast<double *>(pImage)[iPixel] = CPLAtofM(szToken); else if( eDataType == GDT_Float32 ) reinterpret_cast<float *>(pImage)[iPixel] = DoubleToFloatClamp(CPLAtofM(szToken)); else reinterpret_cast<GInt32 *>(pImage)[iPixel] = static_cast<GInt32>(atoi(szToken)); } iPixel++; } if( nBlockYOff < poODS->nRasterYSize - 1 ) panLineOffset[nBlockYOff + 1] = poODS->Tell(); return CE_None; }
CPLErr E00GRIDRasterBand::IReadBlock( CPL_UNUSED int nBlockXOff, int nBlockYOff, void * pImage ) { E00GRIDDataset *poGDS = (E00GRIDDataset *) poDS; char szVal[E00_FLOAT_SIZE+1]; szVal[E00_FLOAT_SIZE] = 0; float* pafImage = (float*)pImage; int* panImage = (int*)pImage; const float fNoData = static_cast<float>(poGDS->dfNoData); /* A new data line begins on a new text line. So if the xsize */ /* is not a multiple of VALS_PER_LINE, there are padding values */ /* that must be ignored */ const int nRoundedBlockXSize = ((nBlockXSize + VALS_PER_LINE - 1) / VALS_PER_LINE) * VALS_PER_LINE; if (poGDS->e00ReadPtr) { if (poGDS->nLastYOff < 0) { E00ReadRewind(poGDS->e00ReadPtr); for(int i=0;i<6;i++) E00ReadNextLine(poGDS->e00ReadPtr); } if (nBlockYOff == poGDS->nLastYOff + 1) { } else if (nBlockYOff <= poGDS->nMaxYOffset) { //CPLDebug("E00GRID", "Skip to %d from %d", nBlockYOff, poGDS->nLastYOff); VSIFSeekL(poGDS->fp, poGDS->panOffsets[nBlockYOff], SEEK_SET); poGDS->nPosBeforeReadLine = poGDS->panOffsets[nBlockYOff]; poGDS->e00ReadPtr->iInBufPtr = 0; poGDS->e00ReadPtr->szInBuf[0] = '\0'; } else if (nBlockYOff > poGDS->nLastYOff + 1) { //CPLDebug("E00GRID", "Forward skip to %d from %d", nBlockYOff, poGDS->nLastYOff); for(int i=poGDS->nLastYOff + 1; i < nBlockYOff;i++) IReadBlock(0, i, pImage); } if (nBlockYOff > poGDS->nMaxYOffset) { poGDS->panOffsets[nBlockYOff] = poGDS->nPosBeforeReadLine + poGDS->e00ReadPtr->iInBufPtr; poGDS->nMaxYOffset = nBlockYOff; } const char* pszLine = NULL; for(int i=0;i<nBlockXSize;i++) { if ((i % VALS_PER_LINE) == 0) { pszLine = E00ReadNextLine(poGDS->e00ReadPtr); if (pszLine == NULL || strlen(pszLine) < 5 * E00_FLOAT_SIZE) return CE_Failure; } if (eDataType == GDT_Float32) { pafImage[i] = (float) CPLAtof(pszLine + (i%VALS_PER_LINE) * E00_FLOAT_SIZE); /* Workaround single vs double precision problems */ if (fNoData != 0 && fabs((pafImage[i] - fNoData)/fNoData) < 1e-6) pafImage[i] = fNoData; } else { panImage[i] = atoi(pszLine + (i%VALS_PER_LINE) * E00_FLOAT_SIZE); } } poGDS->nLastYOff = nBlockYOff; return CE_None; } vsi_l_offset nValsToSkip = (vsi_l_offset)nBlockYOff * nRoundedBlockXSize; vsi_l_offset nLinesToSkip = nValsToSkip / VALS_PER_LINE; int nBytesPerLine = VALS_PER_LINE * E00_FLOAT_SIZE + poGDS->nBytesEOL; vsi_l_offset nPos = poGDS->nDataStart + nLinesToSkip * nBytesPerLine; VSIFSeekL(poGDS->fp, nPos, SEEK_SET); for(int i=0;i<nBlockXSize;i++) { if (VSIFReadL(szVal, E00_FLOAT_SIZE, 1, poGDS->fp) != 1) return CE_Failure; if (eDataType == GDT_Float32) { pafImage[i] = (float) CPLAtof(szVal); /* Workaround single vs double precision problems */ if (fNoData != 0 && fabs((pafImage[i] - fNoData)/fNoData) < 1e-6) pafImage[i] = fNoData; } else { panImage[i] = atoi(szVal); } if (((i+1) % VALS_PER_LINE) == 0) VSIFReadL(szVal, poGDS->nBytesEOL, 1, poGDS->fp); } return CE_None; }
CPLErr GS7BGRasterBand::ScanForMinMaxZ() { GS7BGDataset* poGDS = reinterpret_cast<GS7BGDataset*>(poDS); double *pafRowVals = (double *)VSI_MALLOC2_VERBOSE( nRasterXSize, sizeof(double)); if( pafRowVals == NULL ) { return CE_Failure; } double dfNewMinZ = DBL_MAX; double dfNewMaxZ = -DBL_MAX; int nNewMinZRow = 0; int nNewMaxZRow = 0; /* Since we have to scan, lets calc. statistics too */ double dfSum = 0.0; double dfSum2 = 0.0; unsigned long nValuesRead = 0; for( int iRow=0; iRow<nRasterYSize; iRow++ ) { CPLErr eErr = IReadBlock( 0, iRow, pafRowVals ); if( eErr != CE_None ) { VSIFree( pafRowVals ); return CE_Failure; } pafRowMinZ[iRow] = FLT_MAX; pafRowMaxZ[iRow] = -FLT_MAX; for( int iCol=0; iCol<nRasterXSize; iCol++ ) { if( pafRowVals[iCol] == poGDS->dfNoData_Value ) continue; if( pafRowVals[iCol] < pafRowMinZ[iRow] ) pafRowMinZ[iRow] = pafRowVals[iCol]; if( pafRowVals[iCol] > pafRowMinZ[iRow] ) pafRowMaxZ[iRow] = pafRowVals[iCol]; dfSum += pafRowVals[iCol]; dfSum2 += pafRowVals[iCol] * pafRowVals[iCol]; nValuesRead++; } if( pafRowMinZ[iRow] < dfNewMinZ ) { dfNewMinZ = pafRowMinZ[iRow]; nNewMinZRow = iRow; } if( pafRowMaxZ[iRow] > dfNewMaxZ ) { dfNewMaxZ = pafRowMaxZ[iRow]; nNewMaxZRow = iRow; } } VSIFree( pafRowVals ); if( nValuesRead == 0 ) { dfMinZ = 0.0; dfMaxZ = 0.0; nMinZRow = 0; nMaxZRow = 0; return CE_None; } dfMinZ = dfNewMinZ; dfMaxZ = dfNewMaxZ; nMinZRow = nNewMinZRow; nMaxZRow = nNewMaxZRow; double dfMean = dfSum / nValuesRead; double dfStdDev = sqrt((dfSum2 / nValuesRead) - (dfMean * dfMean)); SetStatistics( dfMinZ, dfMaxZ, dfMean, dfStdDev ); return CE_None; }
CPLErr XYZRasterBand::IReadBlock( CPL_UNUSED int nBlockXOff, int nBlockYOff, void * pImage ) { XYZDataset *poGDS = (XYZDataset *) poDS; if (poGDS->fp == NULL) return CE_Failure; if( pImage ) { int bSuccess = FALSE; double dfNoDataValue = GetNoDataValue(&bSuccess); if( !bSuccess ) dfNoDataValue = 0.0; GDALCopyWords(&dfNoDataValue, GDT_Float64, 0, pImage, eDataType, GDALGetDataTypeSize(eDataType) / 8, nRasterXSize); } int nLineInFile = nBlockYOff * nBlockXSize; // only valid if bSameNumberOfValuesPerLine if ( (poGDS->bSameNumberOfValuesPerLine && poGDS->nDataLineNum > nLineInFile) || (!poGDS->bSameNumberOfValuesPerLine && (nLastYOff == -1 || nBlockYOff == 0)) ) { poGDS->nDataLineNum = 0; poGDS->nLineNum = 0; VSIFSeekL(poGDS->fp, 0, SEEK_SET); for(int i=0;i<poGDS->nCommentLineCount;i++) { CPLReadLine2L(poGDS->fp, 100, NULL); poGDS->nLineNum ++; } if (poGDS->bHasHeaderLine) { const char* pszLine = CPLReadLine2L(poGDS->fp, 100, 0); if (pszLine == NULL) return CE_Failure; poGDS->nLineNum ++; } } if( !poGDS->bSameNumberOfValuesPerLine && nBlockYOff != nLastYOff + 1 ) { int iY; if( nBlockYOff < nLastYOff ) { nLastYOff = -1; for(iY = 0; iY < nBlockYOff; iY++) { if( IReadBlock(0, iY, NULL) != CE_None ) return CE_Failure; } } else { for(iY = nLastYOff + 1; iY < nBlockYOff; iY++) { if( IReadBlock(0, iY, NULL) != CE_None ) return CE_Failure; } } } else if( poGDS->bSameNumberOfValuesPerLine ) { while(poGDS->nDataLineNum < nLineInFile) { const char* pszLine = CPLReadLine2L(poGDS->fp, 100, 0); if (pszLine == NULL) return CE_Failure; poGDS->nLineNum ++; const char* pszPtr = pszLine; char ch; int nCol = 0; int bLastWasSep = TRUE; while((ch = *pszPtr) != '\0') { if (ch == ' ') { if (!bLastWasSep) nCol ++; bLastWasSep = TRUE; } else if ((ch == ',' && poGDS->chDecimalSep != ',') || ch == '\t' || ch == ';') { nCol ++; bLastWasSep = TRUE; } else { bLastWasSep = FALSE; } pszPtr ++; } /* Skip empty line */ if (nCol == 0 && bLastWasSep) continue; poGDS->nDataLineNum ++; } } double dfExpectedY = poGDS->adfGeoTransform[3] + (0.5 + nBlockYOff) * poGDS->adfGeoTransform[5]; int idx = -1; while(TRUE) { int nCol; int bLastWasSep; do { vsi_l_offset nOffsetBefore = VSIFTellL(poGDS->fp); const char* pszLine = CPLReadLine2L(poGDS->fp, 100, 0); if (pszLine == NULL) { if( poGDS->bSameNumberOfValuesPerLine ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot read line %d", poGDS->nLineNum + 1); return CE_Failure; } else { nLastYOff = nBlockYOff; return CE_None; } } poGDS->nLineNum ++; const char* pszPtr = pszLine; char ch; nCol = 0; bLastWasSep = TRUE; double dfX = 0.0, dfY = 0.0, dfZ = 0.0; int bUsefulColsFound = 0; while((ch = *pszPtr) != '\0') { if (ch == ' ') { if (!bLastWasSep) nCol ++; bLastWasSep = TRUE; } else if ((ch == ',' && poGDS->chDecimalSep != ',') || ch == '\t' || ch == ';') { nCol ++; bLastWasSep = TRUE; } else { if (bLastWasSep) { if (nCol == poGDS->nXIndex) { bUsefulColsFound ++; if( !poGDS->bSameNumberOfValuesPerLine ) dfX = CPLAtofDelim(pszPtr, poGDS->chDecimalSep); } else if (nCol == poGDS->nYIndex) { bUsefulColsFound ++; if( !poGDS->bSameNumberOfValuesPerLine ) dfY = CPLAtofDelim(pszPtr, poGDS->chDecimalSep); } else if( nCol == poGDS->nZIndex) { bUsefulColsFound ++; dfZ = CPLAtofDelim(pszPtr, poGDS->chDecimalSep); } } bLastWasSep = FALSE; } pszPtr ++; } nCol ++; if( bUsefulColsFound == 3 ) { if( poGDS->bSameNumberOfValuesPerLine ) { idx ++; } else { if( fabs(dfY - dfExpectedY) > 1e-8 ) { if( idx < 0 ) { CPLError(CE_Failure, CPLE_AppDefined, "At line %d, found %f instead of %f for nBlockYOff = %d", poGDS->nLineNum, dfY, dfExpectedY, nBlockYOff); return CE_Failure; } VSIFSeekL(poGDS->fp, nOffsetBefore, SEEK_SET); nLastYOff = nBlockYOff; poGDS->nLineNum --; return CE_None; } idx = (int)((dfX - 0.5 * poGDS->adfGeoTransform[1] - poGDS->adfGeoTransform[0]) / poGDS->adfGeoTransform[1] + 0.5); } CPLAssert(idx >= 0 && idx < nRasterXSize); if( pImage ) { if (eDataType == GDT_Float32) { ((float*)pImage)[idx] = (float)dfZ; } else if (eDataType == GDT_Int32) { ((GInt32*)pImage)[idx] = (GInt32)dfZ; } else if (eDataType == GDT_Int16) { ((GInt16*)pImage)[idx] = (GInt16)dfZ; } else { ((GByte*)pImage)[idx] = (GByte)dfZ; } } } /* Skip empty line */ } while (nCol == 1 && bLastWasSep); poGDS->nDataLineNum ++; if (nCol < poGDS->nMinTokens) return CE_Failure; if( idx + 1 == nRasterXSize ) break; } if( poGDS->bSameNumberOfValuesPerLine ) { CPLAssert(poGDS->nDataLineNum == (nBlockYOff + 1) * nBlockXSize); } nLastYOff = nBlockYOff; return CE_None; }
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 GSAGRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff, void * pImage ) { static size_t nMaxLineSize = 128; double *pdfImage = (double *)pImage; GSAGDataset *poGDS = (GSAGDataset *)poDS; assert( poGDS != NULL ); if( nBlockYOff < 0 || nBlockYOff > nRasterYSize - 1 || nBlockXOff != 0 ) return CE_Failure; if( panLineOffset[nBlockYOff] == 0 ) { // Discover the last read block for ( int iFoundLine = nLastReadLine - 1; iFoundLine > nBlockYOff; iFoundLine--) { IReadBlock( nBlockXOff, iFoundLine, NULL); } } if( panLineOffset[nBlockYOff] == 0 ) return CE_Failure; if( VSIFSeekL( poGDS->fp, panLineOffset[nBlockYOff], SEEK_SET ) != 0 ) { CPLError( CE_Failure, CPLE_FileIO, "Can't seek to offset %ld to read grid row %d.", (long) panLineOffset[nBlockYOff], nBlockYOff ); return CE_Failure; } size_t nLineBufSize; char *szLineBuf = NULL; size_t nCharsRead; size_t nCharsExamined = 0; /* If we know the offsets, we can just read line directly */ if( (nBlockYOff > 0) && ( panLineOffset[nBlockYOff-1] != 0 ) ) { assert(panLineOffset[nBlockYOff-1] > panLineOffset[nBlockYOff]); nLineBufSize = (size_t) (panLineOffset[nBlockYOff-1] - panLineOffset[nBlockYOff] + 1); } else { nLineBufSize = nMaxLineSize; } szLineBuf = (char *)VSIMalloc( nLineBufSize ); if( szLineBuf == NULL ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to read block, unable to allocate line buffer.\n" ); return CE_Failure; } nCharsRead = VSIFReadL( szLineBuf, 1, nLineBufSize - 1, poGDS->fp ); if( nCharsRead == 0 ) { VSIFree( szLineBuf ); CPLError( CE_Failure, CPLE_FileIO, "Can't read grid row %d at offset %ld.\n", nBlockYOff, (long) panLineOffset[nBlockYOff] ); return CE_Failure; } szLineBuf[nCharsRead] = '\0'; char *szStart = szLineBuf; char *szEnd = szStart; for( int iCell=0; iCell<nBlockXSize; szStart = szEnd ) { double dfValue = CPLStrtod( szStart, &szEnd ); if( szStart == szEnd ) { /* No number found */ /* Check if this was an expected failure */ while( isspace( (unsigned char)*szStart ) ) szStart++; /* Found sign at end of input, seek back to re-read it */ if ( (*szStart == '-' || *szStart == '+') && *(szStart+1) == '\0' ) { if( VSIFSeekL( poGDS->fp, VSIFTellL( poGDS->fp)-1, SEEK_SET ) != 0 ) { VSIFree( szLineBuf ); CPLError( CE_Failure, CPLE_FileIO, "Unable to seek in grid row %d " "(offset %ld, seek %d).\n", nBlockYOff, (long) VSIFTellL(poGDS->fp), -1 ); return CE_Failure; } } else if( *szStart != '\0' ) { szEnd = szStart; while( !isspace( (unsigned char)*szEnd ) && *szEnd != '\0' ) szEnd++; char cOldEnd = *szEnd; *szEnd = '\0'; CPLError( CE_Warning, CPLE_FileIO, "Unexpected value in grid row %d (expected floating " "point value, found \"%s\").\n", nBlockYOff, szStart ); *szEnd = cOldEnd; szEnd = szStart; while( !isdigit( *szEnd ) && *szEnd != '.' && *szEnd != '\0' ) szEnd++; continue; } else if( static_cast<size_t>(szStart - szLineBuf) != nCharsRead ) { CPLError( CE_Warning, CPLE_FileIO, "Unexpected ASCII null-character in grid row %d at " "offset %ld.\n", nBlockYOff, (long) (szStart - szLineBuf) ); while( *szStart == '\0' && static_cast<size_t>(szStart - szLineBuf) < nCharsRead ) szStart++; szEnd = szStart; continue; } nCharsExamined += szStart - szLineBuf; nCharsRead = VSIFReadL( szLineBuf, 1, nLineBufSize - 1, poGDS->fp ); if( nCharsRead == 0 ) { VSIFree( szLineBuf ); CPLError( CE_Failure, CPLE_FileIO, "Can't read portion of grid row %d at offset %ld.", nBlockYOff, (long) panLineOffset[nBlockYOff] ); return CE_Failure; } szLineBuf[nCharsRead] = '\0'; szStart = szEnd = szLineBuf; continue; } else if( *szEnd == '\0' || (*szEnd == '.' && *(szEnd+1) == '\0') || (*szEnd == '-' && *(szEnd+1) == '\0') || (*szEnd == '+' && *(szEnd+1) == '\0') || (*szEnd == 'E' && *(szEnd+1) == '\0') || (*szEnd == 'E' && *(szEnd+1) == '-' && *(szEnd+2) == '\0') || (*szEnd == 'E' && *(szEnd+1) == '+' && *(szEnd+2) == '\0') || (*szEnd == 'e' && *(szEnd+1) == '\0') || (*szEnd == 'e' && *(szEnd+1) == '-' && *(szEnd+2) == '\0') || (*szEnd == 'e' && *(szEnd+1) == '+' && *(szEnd+2) == '\0')) { /* Number was interrupted by a nul character */ while( *szEnd != '\0' ) szEnd++; if( static_cast<size_t>(szEnd - szLineBuf) != nCharsRead ) { CPLError( CE_Warning, CPLE_FileIO, "Unexpected ASCII null-character in grid row %d at " "offset %ld.\n", nBlockYOff, (long) (szStart - szLineBuf) ); while( *szEnd == '\0' && static_cast<size_t>(szStart - szLineBuf) < nCharsRead ) szEnd++; continue; } /* End of buffer, could be interrupting a number */ if( VSIFSeekL( poGDS->fp, szStart - szEnd, SEEK_CUR ) != 0 ) { VSIFree( szLineBuf ); CPLError( CE_Failure, CPLE_FileIO, "Unable to seek in grid row %d (offset %ld, seek %d)" ".\n", nBlockYOff, (long) VSIFTellL(poGDS->fp), (int) (szStart - szEnd) ); return CE_Failure; } nCharsExamined += szStart - szLineBuf; nCharsRead = VSIFReadL( szLineBuf, 1, nLineBufSize - 1, poGDS->fp ); szLineBuf[nCharsRead] = '\0'; if( nCharsRead == 0 ) { VSIFree( szLineBuf ); CPLError( CE_Failure, CPLE_FileIO, "Can't read portion of grid row %d at offset %ld.", nBlockYOff, (long) panLineOffset[nBlockYOff] ); return CE_Failure; } else if( nCharsRead > static_cast<size_t>(szEnd - szStart) ) { /* Read new data, this was not really the end */ szEnd = szStart = szLineBuf; continue; } /* This is really the last value and has no tailing newline */ szStart = szLineBuf; szEnd = szLineBuf + nCharsRead; } if( pdfImage != NULL ) { *(pdfImage+iCell) = dfValue; } iCell++; } while( *szEnd == ' ' ) szEnd++; if( *szEnd != '\0' && *szEnd != poGDS->szEOL[0] ) CPLDebug( "GSAG", "Grid row %d does not end with a newline. " "Possible skew.\n", nBlockYOff ); while( isspace( (unsigned char)*szEnd ) ) szEnd++; nCharsExamined += szEnd - szLineBuf; if( nCharsExamined >= nMaxLineSize ) nMaxLineSize = nCharsExamined + 1; if( nBlockYOff > 0 ) panLineOffset[nBlockYOff - 1] = panLineOffset[nBlockYOff] + nCharsExamined; nLastReadLine = nBlockYOff; VSIFree( szLineBuf ); return CE_None; }
CPLErr GSAGRasterBand::ScanForMinMaxZ() { double *padfRowValues = (double *)VSIMalloc2( nBlockXSize, sizeof(double) ); if( padfRowValues == NULL ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to allocate memory for grid row values.\n" ); return CE_Failure; } double dfNewMinZ = DBL_MAX; double dfNewMaxZ = -DBL_MAX; int nNewMinZRow = 0; int nNewMaxZRow = 0; /* Since we have to scan, lets calc. statistics too */ double dfSum = 0.0; double dfSum2 = 0.0; unsigned long nValuesRead = 0; for( int iRow=0; iRow<nRasterYSize; iRow++ ) { CPLErr eErr = IReadBlock( 0, iRow, padfRowValues ); if( eErr != CE_None ) { VSIFree( padfRowValues ); return eErr; } padfRowMinZ[iRow] = DBL_MAX; padfRowMaxZ[iRow] = -DBL_MAX; for( int iCell=0; iCell<nRasterXSize; iCell++ ) { if( AlmostEqual(padfRowValues[iCell], GSAGDataset::dfNODATA_VALUE) ) continue; if( padfRowValues[iCell] < padfRowMinZ[iRow] ) padfRowMinZ[iRow] = padfRowValues[iCell]; if( padfRowValues[iCell] > padfRowMaxZ[iRow] ) padfRowMaxZ[iRow] = padfRowValues[iCell]; dfSum += padfRowValues[iCell]; dfSum2 += padfRowValues[iCell] * padfRowValues[iCell]; nValuesRead++; } if( padfRowMinZ[iRow] < dfNewMinZ ) { dfNewMinZ = padfRowMinZ[iRow]; nNewMinZRow = iRow; } if( padfRowMaxZ[iRow] > dfNewMaxZ ) { dfNewMaxZ = padfRowMaxZ[iRow]; nNewMaxZRow = iRow; } } VSIFree( padfRowValues ); if( nValuesRead == 0 ) { dfMinZ = 0.0; dfMaxZ = 0.0; nMinZRow = 0; nMaxZRow = 0; return CE_None; } dfMinZ = dfNewMinZ; dfMaxZ = dfNewMaxZ; nMinZRow = nNewMinZRow; nMaxZRow = nNewMaxZRow; double dfMean = dfSum / nValuesRead; double dfStdDev = sqrt((dfSum2 / nValuesRead) - (dfMean * dfMean)); SetStatistics( dfMinZ, dfMaxZ, dfMean, dfStdDev ); return CE_None; }
CPLErr GSBGRasterBand::ScanForMinMaxZ() { float *pafRowVals = (float *)VSIMalloc2( nRasterXSize, 4 ); if( pafRowVals == NULL ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to allocate row buffer to scan grid file.\n" ); return CE_Failure; } double dfNewMinZ = DBL_MAX; double dfNewMaxZ = -DBL_MAX; int nNewMinZRow = 0; int nNewMaxZRow = 0; /* Since we have to scan, lets calc. statistics too */ double dfSum = 0.0; double dfSum2 = 0.0; unsigned long nValuesRead = 0; for( int iRow=0; iRow<nRasterYSize; iRow++ ) { CPLErr eErr = IReadBlock( 0, iRow, pafRowVals ); if( eErr != CE_None ) { VSIFree( pafRowVals ); return CE_Failure; } pafRowMinZ[iRow] = FLT_MAX; pafRowMaxZ[iRow] = -FLT_MAX; for( int iCol=0; iCol<nRasterXSize; iCol++ ) { if( pafRowVals[iCol] == GSBGDataset::fNODATA_VALUE ) continue; if( pafRowVals[iCol] < pafRowMinZ[iRow] ) pafRowMinZ[iRow] = pafRowVals[iCol]; if( pafRowVals[iCol] > pafRowMinZ[iRow] ) pafRowMaxZ[iRow] = pafRowVals[iCol]; dfSum += pafRowVals[iCol]; dfSum2 += pafRowVals[iCol] * pafRowVals[iCol]; nValuesRead++; } if( pafRowMinZ[iRow] < dfNewMinZ ) { dfNewMinZ = pafRowMinZ[iRow]; nNewMinZRow = iRow; } if( pafRowMaxZ[iRow] > dfNewMaxZ ) { dfNewMaxZ = pafRowMaxZ[iRow]; nNewMaxZRow = iRow; } } VSIFree( pafRowVals ); if( nValuesRead == 0 ) { dfMinZ = 0.0; dfMaxZ = 0.0; nMinZRow = 0; nMaxZRow = 0; return CE_None; } dfMinZ = dfNewMinZ; dfMaxZ = dfNewMaxZ; nMinZRow = nNewMinZRow; nMaxZRow = nNewMaxZRow; double dfMean = dfSum / nValuesRead; double dfStdDev = sqrt((dfSum2 / nValuesRead) - (dfMean * dfMean)); SetStatistics( dfMinZ, dfMaxZ, dfMean, dfStdDev ); return CE_None; }
CPLErr XYZRasterBand::IReadBlock( CPL_UNUSED int nBlockXOff, int nBlockYOff, void * pImage ) { XYZDataset *poGDS = reinterpret_cast<XYZDataset *>( poDS ); if (poGDS->fp == NULL) return CE_Failure; if( pImage ) { int bSuccess = FALSE; double dfNoDataValue = GetNoDataValue(&bSuccess); if( !bSuccess ) dfNoDataValue = 0.0; GDALCopyWords(&dfNoDataValue, GDT_Float64, 0, pImage, eDataType, GDALGetDataTypeSize(eDataType) / 8, nRasterXSize); } // Only valid if bSameNumberOfValuesPerLine. const GIntBig nLineInFile = static_cast<GIntBig>(nBlockYOff) * nBlockXSize; if ( (poGDS->bSameNumberOfValuesPerLine && poGDS->nDataLineNum > nLineInFile) || (!poGDS->bSameNumberOfValuesPerLine && (nLastYOff == -1 || nBlockYOff == 0)) ) { poGDS->nDataLineNum = 0; poGDS->nLineNum = 0; poGDS->bEOF = false; VSIFSeekL(poGDS->fp, 0, SEEK_SET); for(int i=0;i<poGDS->nCommentLineCount;i++) { if( CPLReadLine2L(poGDS->fp, 100, NULL) == NULL ) { poGDS->bEOF = true; return CE_Failure; } poGDS->nLineNum ++; } if (poGDS->bHasHeaderLine) { const char* pszLine = CPLReadLine2L(poGDS->fp, 100, NULL); if (pszLine == NULL) { poGDS->bEOF = true; return CE_Failure; } poGDS->nLineNum ++; } } if( !poGDS->bSameNumberOfValuesPerLine ) { if( nBlockYOff < nLastYOff ) { nLastYOff = -1; for( int iY = 0; iY < nBlockYOff; iY++ ) { if( IReadBlock(0, iY, NULL) != CE_None ) return CE_Failure; } } else { if( poGDS->bEOF ) { return CE_Failure; } for( int iY = nLastYOff + 1; iY < nBlockYOff; iY++ ) { if( IReadBlock(0, iY, NULL) != CE_None ) return CE_Failure; } } } else { if( poGDS->bEOF ) { return CE_Failure; } while(poGDS->nDataLineNum < nLineInFile) { const char* pszLine = CPLReadLine2L(poGDS->fp, 100, NULL); if (pszLine == NULL) { poGDS->bEOF = true; return CE_Failure; } poGDS->nLineNum ++; const char* pszPtr = pszLine; char ch; int nCol = 0; bool bLastWasSep = true; while((ch = *pszPtr) != '\0') { if (ch == ' ') { if (!bLastWasSep) nCol ++; bLastWasSep = true; } else if ((ch == ',' && poGDS->chDecimalSep != ',') || ch == '\t' || ch == ';') { nCol ++; bLastWasSep = true; } else { bLastWasSep = false; } pszPtr ++; } /* Skip empty line */ if (nCol == 0 && bLastWasSep) continue; poGDS->nDataLineNum ++; } } const double dfExpectedY = poGDS->adfGeoTransform[3] + (0.5 + nBlockYOff) * poGDS->adfGeoTransform[5]; int idx = -1; while(true) { int nCol; bool bLastWasSep; do { const vsi_l_offset nOffsetBefore = VSIFTellL(poGDS->fp); const char* pszLine = CPLReadLine2L(poGDS->fp, 100, NULL); if (pszLine == NULL) { poGDS->bEOF = true; if( poGDS->bSameNumberOfValuesPerLine ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot read line " CPL_FRMT_GIB, poGDS->nLineNum + 1); return CE_Failure; } else { nLastYOff = nBlockYOff; return CE_None; } } poGDS->nLineNum ++; const char* pszPtr = pszLine; char ch; nCol = 0; bLastWasSep = true; double dfX = 0.0; double dfY = 0.0; double dfZ = 0.0; int nUsefulColsFound = 0; while((ch = *pszPtr) != '\0') { if (ch == ' ') { if (!bLastWasSep) nCol ++; bLastWasSep = true; } else if ( ( ch == ',' && poGDS->chDecimalSep != ',' ) || ch == '\t' || ch == ';' ) { nCol ++; bLastWasSep = true; } else { if (bLastWasSep) { if (nCol == poGDS->nXIndex) { nUsefulColsFound ++; if( !poGDS->bSameNumberOfValuesPerLine ) dfX = CPLAtofDelim(pszPtr, poGDS->chDecimalSep); } else if (nCol == poGDS->nYIndex) { nUsefulColsFound ++; if( !poGDS->bSameNumberOfValuesPerLine ) dfY = CPLAtofDelim(pszPtr, poGDS->chDecimalSep); } else if( nCol == poGDS->nZIndex) { nUsefulColsFound ++; dfZ = CPLAtofDelim(pszPtr, poGDS->chDecimalSep); } } bLastWasSep = false; } pszPtr ++; } nCol ++; if( nUsefulColsFound == 3 ) { if( poGDS->bSameNumberOfValuesPerLine ) { idx ++; } else { if( fabs( (dfY - dfExpectedY) / poGDS->adfGeoTransform[5] ) > RELATIVE_ERROR ) { if( idx < 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "At line " CPL_FRMT_GIB", found %f instead of %f " "for nBlockYOff = %d", poGDS->nLineNum, dfY, dfExpectedY, nBlockYOff); return CE_Failure; } VSIFSeekL(poGDS->fp, nOffsetBefore, SEEK_SET); nLastYOff = nBlockYOff; poGDS->nLineNum --; return CE_None; } idx = static_cast<int>( ( dfX - 0.5 * poGDS->adfGeoTransform[1] - poGDS->adfGeoTransform[0] ) / poGDS->adfGeoTransform[1] + 0.5 ); } CPLAssert(idx >= 0 && idx < nRasterXSize); if( pImage ) { if (eDataType == GDT_Float32) { reinterpret_cast<float *>( pImage )[idx] = static_cast<float>(dfZ); } else if (eDataType == GDT_Int32) { reinterpret_cast<GInt32 *>( pImage )[idx] = static_cast<GInt32>( dfZ ); } else if (eDataType == GDT_Int16) { reinterpret_cast<GInt16 *>( pImage )[idx] = static_cast<GInt16>( dfZ ); } else { reinterpret_cast<GByte *>( pImage )[idx] = static_cast<GByte>( dfZ ); } } } /* Skip empty line */ } while (nCol == 1 && bLastWasSep); poGDS->nDataLineNum ++; if (nCol < poGDS->nMinTokens) return CE_Failure; if( idx + 1 == nRasterXSize ) break; } if( poGDS->bSameNumberOfValuesPerLine ) { if( poGDS->nDataLineNum != static_cast<GIntBig>(nBlockYOff + 1) * nBlockXSize ) { CPLError(CE_Failure, CPLE_AssertionFailed, "The file has not the same number of values per " "line as initialy thought. It must be somehow corrupted"); return CE_Failure; } } nLastYOff = nBlockYOff; return CE_None; }