float* get_tif_data(char* tif_file, int* tif_width, int* tif_height) { GDALDatasetH hDataset; hDataset = GDALOpen(tif_file, GA_ReadOnly); if (hDataset == NULL ) { fprintf(stderr, "ERROR: Failed to open the file %s\n", tif_file); return NULL ; } GDALRasterBandH hBand; hBand = GDALGetRasterBand(hDataset, 1); int width1 = GDALGetRasterXSize(hDataset); int height1 = GDALGetRasterYSize(hDataset); double nodata1 = GDALGetRasterNoDataValue(hBand, NULL ); float* data = (float *) CPLMalloc(sizeof(float) * width1 * height1); if (!data) { fprintf(stderr, "ERROR: Failed to allocate data of size %d \n", width1 * height1); return NULL; } GDALRasterIO(hBand, GF_Read, 0, 0, width1, height1, data, width1, height1, GDT_Float32, 0, 0); *tif_width = width1; *tif_height = height1; return data; }
void MDAL::DriverGdal::addDataToOutput( GDALRasterBandH raster_band, std::shared_ptr<MemoryDataset> tos, bool is_vector, bool is_x ) { assert( raster_band ); double nodata = GDALGetRasterNoDataValue( raster_band, nullptr ); unsigned int mXSize = meshGDALDataset()->mXSize; unsigned int mYSize = meshGDALDataset()->mYSize; double *values = tos->values(); for ( unsigned int y = 0; y < mYSize; ++y ) { // buffering per-line CPLErr err = GDALRasterIO( raster_band, GF_Read, 0, //nXOff static_cast<int>( y ), //nYOff static_cast<int>( mXSize ), //nXSize 1, //nYSize mPafScanline, //pData static_cast<int>( mXSize ), //nBufXSize 1, //nBufYSize GDT_Float64, //eBufType 0, //nPixelSpace 0 //nLineSpace ); if ( err != CE_None ) { throw MDAL_Status::Err_InvalidData; } for ( unsigned int x = 0; x < mXSize; ++x ) { unsigned int idx = x + mXSize * y; double val = mPafScanline[x]; if ( !MDAL::equals( val, nodata ) ) { // values is prepolulated with NODATA values, so store only legal values if ( is_vector ) { if ( is_x ) { values[2 * idx] = val; } else { values[2 * idx + 1] = val; } } else { values[idx] = val; } } } } }
void object::test<6>() { // Index of test file being tested const std::size_t fileIdx = 1; std::string file(data_ + SEP); file += grids_.at(fileIdx).file_; GDALDatasetH ds = GDALOpen(file.c_str(), GA_ReadOnly); ensure("Can't open dataset: " + file, nullptr != ds); GDALRasterBandH band = GDALGetRasterBand(ds, grids_.at(fileIdx).band_); ensure("Can't get raster band", nullptr != band); const double noData = GDALGetRasterNoDataValue(band, nullptr); ensure_equals("Grid NODATA value wrong or missing", noData, -99999); ensure_equals("Data type is not GDT_Float32", GDALGetRasterDataType(band), GDT_Float32); GDALClose(ds); }
int QgsRasterCalculator::processCalculation( QProgressDialog* p ) { //prepare search string / tree QString errorString; QgsRasterCalcNode* calcNode = QgsRasterCalcNode::parseRasterCalcString( mFormulaString, errorString ); if ( !calcNode ) { //error } double targetGeoTransform[6]; outputGeoTransform( targetGeoTransform ); //open all input rasters for reading QMap< QString, GDALRasterBandH > mInputRasterBands; //raster references and corresponding scanline data QMap< QString, QgsRasterMatrix* > inputScanLineData; //stores raster references and corresponding scanline data QVector< GDALDatasetH > mInputDatasets; //raster references and corresponding dataset QVector<QgsRasterCalculatorEntry>::const_iterator it = mRasterEntries.constBegin(); for ( ; it != mRasterEntries.constEnd(); ++it ) { if ( !it->raster ) // no raster layer in entry { return 2; } GDALDatasetH inputDataset = GDALOpen( it->raster->source().toLocal8Bit().data(), GA_ReadOnly ); if ( inputDataset == NULL ) { return 2; } //check if the input dataset is south up or rotated. If yes, use GDALAutoCreateWarpedVRT to create a north up raster double inputGeoTransform[6]; if ( GDALGetGeoTransform( inputDataset, inputGeoTransform ) == CE_None && ( inputGeoTransform[1] < 0.0 || inputGeoTransform[2] != 0.0 || inputGeoTransform[4] != 0.0 || inputGeoTransform[5] > 0.0 ) ) { GDALDatasetH vDataset = GDALAutoCreateWarpedVRT( inputDataset, NULL, NULL, GRA_NearestNeighbour, 0.2, NULL ); mInputDatasets.push_back( vDataset ); mInputDatasets.push_back( inputDataset ); inputDataset = vDataset; } else { mInputDatasets.push_back( inputDataset ); } GDALRasterBandH inputRasterBand = GDALGetRasterBand( inputDataset, it->bandNumber ); if ( inputRasterBand == NULL ) { return 2; } int nodataSuccess; double nodataValue = GDALGetRasterNoDataValue( inputRasterBand, &nodataSuccess ); mInputRasterBands.insert( it->ref, inputRasterBand ); inputScanLineData.insert( it->ref, new QgsRasterMatrix( mNumOutputColumns, 1, new float[mNumOutputColumns], nodataValue ) ); } //open output dataset for writing GDALDriverH outputDriver = openOutputDriver(); if ( outputDriver == NULL ) { return 1; } GDALDatasetH outputDataset = openOutputFile( outputDriver ); GDALRasterBandH outputRasterBand = GDALGetRasterBand( outputDataset, 1 ); float outputNodataValue = -FLT_MAX; GDALSetRasterNoDataValue( outputRasterBand, outputNodataValue ); float* resultScanLine = ( float * ) CPLMalloc( sizeof( float ) * mNumOutputColumns ); if ( p ) { p->setMaximum( mNumOutputRows ); } QgsRasterMatrix resultMatrix; //read / write line by line for ( int i = 0; i < mNumOutputRows; ++i ) { if ( p ) { p->setValue( i ); } if ( p && p->wasCanceled() ) { break; } //fill buffers QMap< QString, QgsRasterMatrix* >::iterator bufferIt = inputScanLineData.begin(); for ( ; bufferIt != inputScanLineData.end(); ++bufferIt ) { double sourceTransformation[6]; GDALRasterBandH sourceRasterBand = mInputRasterBands[bufferIt.key()]; GDALGetGeoTransform( GDALGetBandDataset( sourceRasterBand ), sourceTransformation ); //the function readRasterPart calls GDALRasterIO (and ev. does some conversion if raster transformations are not the same) readRasterPart( targetGeoTransform, 0, i, mNumOutputColumns, 1, sourceTransformation, sourceRasterBand, bufferIt.value()->data() ); } if ( calcNode->calculate( inputScanLineData, resultMatrix ) ) { bool resultIsNumber = resultMatrix.isNumber(); float* calcData; if ( resultIsNumber ) //scalar result. Insert number for every pixel { calcData = new float[mNumOutputColumns]; for ( int j = 0; j < mNumOutputColumns; ++j ) { calcData[j] = resultMatrix.number(); } } else //result is real matrix { calcData = resultMatrix.data(); } //replace all matrix nodata values with output nodatas for ( int j = 0; j < mNumOutputColumns; ++j ) { if ( calcData[j] == resultMatrix.nodataValue() ) { calcData[j] = outputNodataValue; } } //write scanline to the dataset if ( GDALRasterIO( outputRasterBand, GF_Write, 0, i, mNumOutputColumns, 1, calcData, mNumOutputColumns, 1, GDT_Float32, 0, 0 ) != CE_None ) { qWarning( "RasterIO error!" ); } if ( resultIsNumber ) { delete[] calcData; } } } if ( p ) { p->setValue( mNumOutputRows ); } //close datasets and release memory delete calcNode; QMap< QString, QgsRasterMatrix* >::iterator bufferIt = inputScanLineData.begin(); for ( ; bufferIt != inputScanLineData.end(); ++bufferIt ) { delete bufferIt.value(); } inputScanLineData.clear(); QVector< GDALDatasetH >::iterator datasetIt = mInputDatasets.begin(); for ( ; datasetIt != mInputDatasets.end(); ++ datasetIt ) { GDALClose( *datasetIt ); } if ( p && p->wasCanceled() ) { //delete the dataset without closing (because it is faster) GDALDeleteDataset( outputDriver, mOutputFile.toLocal8Bit().data() ); return 3; } GDALClose( outputDataset ); CPLFree( resultScanLine ); return 0; }
void QgsRasterCalculator::readRasterPart( double* targetGeotransform, int xOffset, int yOffset, int nCols, int nRows, double* sourceTransform, GDALRasterBandH sourceBand, float* rasterBuffer ) { //If dataset transform is the same as the requested transform, do a normal GDAL raster io if ( transformationsEqual( targetGeotransform, sourceTransform ) ) { GDALRasterIO( sourceBand, GF_Read, xOffset, yOffset, nCols, nRows, rasterBuffer, nCols, nRows, GDT_Float32, 0, 0 ); return; } //pixel calculation needed because of different raster position / resolution int nodataSuccess; double nodataValue = GDALGetRasterNoDataValue( sourceBand, &nodataSuccess ); QgsRectangle targetRect( targetGeotransform[0] + targetGeotransform[1] * xOffset, targetGeotransform[3] + yOffset * targetGeotransform[5] + nRows * targetGeotransform[5] , targetGeotransform[0] + targetGeotransform[1] * xOffset + targetGeotransform[1] * nCols, targetGeotransform[3] + yOffset * targetGeotransform[5] ); QgsRectangle sourceRect( sourceTransform[0], sourceTransform[3] + GDALGetRasterBandYSize( sourceBand ) * sourceTransform[5], sourceTransform[0] + GDALGetRasterBandXSize( sourceBand )* sourceTransform[1], sourceTransform[3] ); QgsRectangle intersection = targetRect.intersect( &sourceRect ); //no intersection, fill all the pixels with nodata values if ( intersection.isEmpty() ) { int nPixels = nCols * nRows; for ( int i = 0; i < nPixels; ++i ) { rasterBuffer[i] = nodataValue; } return; } //do raster io in source resolution int sourcePixelOffsetXMin = floor(( intersection.xMinimum() - sourceTransform[0] ) / sourceTransform[1] ); int sourcePixelOffsetXMax = ceil(( intersection.xMaximum() - sourceTransform[0] ) / sourceTransform[1] ); int nSourcePixelsX = sourcePixelOffsetXMax - sourcePixelOffsetXMin; int sourcePixelOffsetYMax = floor(( intersection.yMaximum() - sourceTransform[3] ) / sourceTransform[5] ); int sourcePixelOffsetYMin = ceil(( intersection.yMinimum() - sourceTransform[3] ) / sourceTransform[5] ); int nSourcePixelsY = sourcePixelOffsetYMin - sourcePixelOffsetYMax; float* sourceRaster = ( float * ) CPLMalloc( sizeof( float ) * nSourcePixelsX * nSourcePixelsY ); double sourceRasterXMin = sourceRect.xMinimum() + sourcePixelOffsetXMin * sourceTransform[1]; double sourceRasterYMax = sourceRect.yMaximum() + sourcePixelOffsetYMax * sourceTransform[5]; GDALRasterIO( sourceBand, GF_Read, sourcePixelOffsetXMin, sourcePixelOffsetYMax, nSourcePixelsX, nSourcePixelsY, sourceRaster, nSourcePixelsX, nSourcePixelsY, GDT_Float32, 0, 0 ); double targetPixelX; double targetPixelXMin = targetGeotransform[0] + targetGeotransform[1] * xOffset + targetGeotransform[1] / 2.0; double targetPixelY = targetGeotransform[3] + targetGeotransform[5] * yOffset + targetGeotransform[5] / 2.0; //coordinates of current target pixel int sourceIndexX, sourceIndexY; //current raster index in source pixels double sx, sy; for ( int i = 0; i < nRows; ++i ) { targetPixelX = targetPixelXMin; for ( int j = 0; j < nCols; ++j ) { sx = ( targetPixelX - sourceRasterXMin ) / sourceTransform[1]; sourceIndexX = sx > 0 ? sx : floor( sx ); sy = ( targetPixelY - sourceRasterYMax ) / sourceTransform[5]; sourceIndexY = sy > 0 ? sy : floor( sy ); if ( sourceIndexX >= 0 && sourceIndexX < nSourcePixelsX && sourceIndexY >= 0 && sourceIndexY < nSourcePixelsY ) { rasterBuffer[j + i*nRows] = sourceRaster[ sourceIndexX + nSourcePixelsX * sourceIndexY ]; } else { rasterBuffer[j + i*j] = nodataValue; } targetPixelX += targetGeotransform[1]; } targetPixelY += targetGeotransform[5]; } CPLFree( sourceRaster ); return; }
/** Apply a vertical shift grid to a source (DEM typically) dataset. * * hGridDataset will typically use WGS84 as horizontal datum (but this is * not a requirement) and its values are the values to add to go from geoid * elevations to WGS84 ellipsoidal heights. * * hGridDataset will be on-the-fly reprojected and resampled to the projection * and resolution of hSrcDataset, using bilinear resampling by default. * * Both hSrcDataset and hGridDataset must be single band datasets, and have * a valid geotransform and projection. * * On success, a reference will be taken on hSrcDataset and hGridDataset. * Reference counting semantics on the source and grid datasets should be * honoured. That is, don't just GDALClose() it, unless it was opened with * GDALOpenShared(), but rather use GDALReleaseDataset() if wanting to * immediately release the reference(s) and make the returned dataset the * owner of them. * * Valid use cases: * * \code * hSrcDataset = GDALOpen(...) * hGridDataset = GDALOpen(...) * hDstDataset = GDALApplyVerticalShiftGrid(hSrcDataset, hGridDataset, ...) * GDALReleaseDataset(hSrcDataset); * GDALReleaseDataset(hGridDataset); * if( hDstDataset ) * { * // Do things with hDstDataset * GDALClose(hDstDataset) // will close hSrcDataset and hGridDataset * } * \endcode * * @param hSrcDataset source (DEM) dataset. Must not be NULL. * @param hGridDataset vertical grid shift dataset. Must not be NULL. * @param bInverse if set to FALSE, hGridDataset values will be added to * hSrcDataset. If set to TRUE, they will be subtracted. * @param dfSrcUnitToMeter the factor to convert values from hSrcDataset to * meters (1.0 if source values are in meter). * @param dfDstUnitToMeter the factor to convert shifted values from meter * (1.0 if output values must be in meter). * @param papszOptions list of options, or NULL. Supported options are: * <ul> * <li>RESAMPLING=NEAREST/BILINEAR/CUBIC. Defaults to BILINEAR.</li> * <li>MAX_ERROR=val. Maximum error measured in input pixels that is allowed in * approximating the transformation (0.0 for exact calculations). Defaults * to 0.125</li> * <li>DATATYPE=Byte/UInt16/Int16/Float32/Float64. Output data type. If not * specified will be the same as the one of hSrcDataset. * <li>ERROR_ON_MISSING_VERT_SHIFT=YES/NO. Whether a missing/nodata value in * hGridDataset should cause I/O requests to fail. Default is NO (in which case * 0 will be used) * <li>SRC_SRS=srs_def. Override projection on hSrcDataset; * </ul> * * @return a new dataset corresponding to hSrcDataset adjusted with * hGridDataset, or NULL. If not NULL, it must be closed with GDALClose(). * * @since GDAL 2.2 */ GDALDatasetH GDALApplyVerticalShiftGrid( GDALDatasetH hSrcDataset, GDALDatasetH hGridDataset, int bInverse, double dfSrcUnitToMeter, double dfDstUnitToMeter, const char* const* papszOptions ) { VALIDATE_POINTER1( hSrcDataset, "GDALApplyVerticalShiftGrid", nullptr ); VALIDATE_POINTER1( hGridDataset, "GDALApplyVerticalShiftGrid", nullptr ); double adfSrcGT[6]; if( GDALGetGeoTransform(hSrcDataset, adfSrcGT) != CE_None ) { CPLError(CE_Failure, CPLE_NotSupported, "Source dataset has no geotransform."); return nullptr; } const char* pszSrcProjection = CSLFetchNameValueDef(papszOptions, "SRC_SRS", GDALGetProjectionRef(hSrcDataset)); if( pszSrcProjection == nullptr || pszSrcProjection[0] == '\0' ) { CPLError(CE_Failure, CPLE_NotSupported, "Source dataset has no projection."); return nullptr; } if( GDALGetRasterCount(hSrcDataset) != 1 ) { CPLError(CE_Failure, CPLE_NotSupported, "Only single band source dataset is supported."); return nullptr; } double adfGridGT[6]; if( GDALGetGeoTransform(hGridDataset, adfGridGT) != CE_None ) { CPLError(CE_Failure, CPLE_NotSupported, "Grid dataset has no geotransform."); return nullptr; } const char* pszGridProjection = GDALGetProjectionRef(hGridDataset); if( pszGridProjection == nullptr || pszGridProjection[0] == '\0' ) { CPLError(CE_Failure, CPLE_NotSupported, "Grid dataset has no projection."); return nullptr; } if( GDALGetRasterCount(hGridDataset) != 1 ) { CPLError(CE_Failure, CPLE_NotSupported, "Only single band grid dataset is supported."); return nullptr; } GDALDataType eDT = GDALGetRasterDataType(GDALGetRasterBand(hSrcDataset,1)); const char* pszDataType = CSLFetchNameValue(papszOptions, "DATATYPE"); if( pszDataType ) eDT = GDALGetDataTypeByName(pszDataType); if( eDT == GDT_Unknown ) { CPLError(CE_Failure, CPLE_NotSupported, "Invalid DATATYPE=%s", pszDataType); return nullptr; } const int nSrcXSize = GDALGetRasterXSize(hSrcDataset); const int nSrcYSize = GDALGetRasterYSize(hSrcDataset); OGRSpatialReference oSRS; CPLString osSrcProjection(pszSrcProjection); oSRS.SetFromUserInput(osSrcProjection); if( oSRS.IsCompound() ) { OGR_SRSNode* poNode = oSRS.GetRoot()->GetChild(1); if( poNode != nullptr ) { char* pszWKT = nullptr; poNode->exportToWkt(&pszWKT); osSrcProjection = pszWKT; CPLFree(pszWKT); } } void* hTransform = GDALCreateGenImgProjTransformer3( pszGridProjection, adfGridGT, osSrcProjection, adfSrcGT ); if( hTransform == nullptr ) return nullptr; GDALWarpOptions* psWO = GDALCreateWarpOptions(); psWO->hSrcDS = hGridDataset; psWO->eResampleAlg = GRA_Bilinear; const char* pszResampling = CSLFetchNameValue(papszOptions, "RESAMPLING"); if( pszResampling ) { if( EQUAL(pszResampling, "NEAREST") ) psWO->eResampleAlg = GRA_NearestNeighbour; else if( EQUAL(pszResampling, "BILINEAR") ) psWO->eResampleAlg = GRA_Bilinear; else if( EQUAL(pszResampling, "CUBIC") ) psWO->eResampleAlg = GRA_Cubic; } psWO->eWorkingDataType = GDT_Float32; int bHasNoData = FALSE; const double dfSrcNoData = GDALGetRasterNoDataValue( GDALGetRasterBand(hGridDataset, 1), &bHasNoData ); if( bHasNoData ) { psWO->padfSrcNoDataReal = static_cast<double*>(CPLMalloc(sizeof(double))); psWO->padfSrcNoDataReal[0] = dfSrcNoData; } psWO->padfDstNoDataReal = static_cast<double*>(CPLMalloc(sizeof(double))); const bool bErrorOnMissingShift = CPLFetchBool( papszOptions, "ERROR_ON_MISSING_VERT_SHIFT", false ); psWO->padfDstNoDataReal[0] = (bErrorOnMissingShift) ? -std::numeric_limits<float>::infinity() : 0.0; psWO->papszWarpOptions = CSLSetNameValue(psWO->papszWarpOptions, "INIT_DEST", "NO_DATA"); psWO->pfnTransformer = GDALGenImgProjTransform; psWO->pTransformerArg = hTransform; const double dfMaxError = CPLAtof(CSLFetchNameValueDef(papszOptions, "MAX_ERROR", "0.125")); if( dfMaxError > 0.0 ) { psWO->pTransformerArg = GDALCreateApproxTransformer( psWO->pfnTransformer, psWO->pTransformerArg, dfMaxError ); psWO->pfnTransformer = GDALApproxTransform; GDALApproxTransformerOwnsSubtransformer(psWO->pTransformerArg, TRUE); } psWO->nBandCount = 1; psWO->panSrcBands = static_cast<int *>(CPLMalloc(sizeof(int))); psWO->panSrcBands[0] = 1; psWO->panDstBands = static_cast<int *>(CPLMalloc(sizeof(int))); psWO->panDstBands[0] = 1; VRTWarpedDataset* poReprojectedGrid = new VRTWarpedDataset(nSrcXSize, nSrcYSize); // This takes a reference on hGridDataset CPLErr eErr = poReprojectedGrid->Initialize(psWO); CPLAssert(eErr == CE_None); CPL_IGNORE_RET_VAL(eErr); GDALDestroyWarpOptions(psWO); poReprojectedGrid->SetGeoTransform(adfSrcGT); poReprojectedGrid->AddBand(GDT_Float32, nullptr); GDALApplyVSGDataset* poOutDS = new GDALApplyVSGDataset( reinterpret_cast<GDALDataset*>(hSrcDataset), poReprojectedGrid, eDT, CPL_TO_BOOL(bInverse), dfSrcUnitToMeter, dfDstUnitToMeter, // Undocumented option. For testing only atoi(CSLFetchNameValueDef(papszOptions, "BLOCKSIZE", "256")) ); poReprojectedGrid->ReleaseRef(); if( !poOutDS->IsInitOK() ) { delete poOutDS; return nullptr; } poOutDS->SetDescription( GDALGetDescription( hSrcDataset ) ); return reinterpret_cast<GDALDatasetH>(poOutDS); }
int main( int argc, char ** argv ) { GDALDatasetH hSrcDS; int iY, iX, nOutLevel=0, nXSize, nYSize, iArg, nFillDist=0; void *pStream; GInt16 *panData; const char *pszFilename = NULL; GDALRasterBandH hSrcBand; double adfGeoTransform[6]; int bEnableTrim = FALSE; GInt16 noDataValue = 0; int bHasNoData; /* -------------------------------------------------------------------- */ /* Identify arguments. */ /* -------------------------------------------------------------------- */ for( iArg = 1; iArg < argc; iArg++ ) { if( EQUAL(argv[iArg],"-trim") ) bEnableTrim = TRUE; else if( EQUAL(argv[iArg],"-fill") ) nFillDist = atoi(argv[++iArg]); else if( EQUAL(argv[iArg],"-level") ) nOutLevel = atoi(argv[++iArg]); else { if( pszFilename != NULL ) Usage(); pszFilename = argv[iArg]; } } if( pszFilename == NULL ) Usage(); /* -------------------------------------------------------------------- */ /* Open input file. */ /* -------------------------------------------------------------------- */ GDALAllRegister(); hSrcDS = GDALOpen( pszFilename, GA_ReadOnly ); if( hSrcDS == NULL ) exit(1); hSrcBand = GDALGetRasterBand( hSrcDS, 1 ); noDataValue = (GInt16)GDALGetRasterNoDataValue(hSrcBand, &bHasNoData); nXSize = GDALGetRasterXSize( hSrcDS ); nYSize = GDALGetRasterYSize( hSrcDS ); GDALGetGeoTransform( hSrcDS, adfGeoTransform ); /* -------------------------------------------------------------------- */ /* Create output stream. */ /* -------------------------------------------------------------------- */ pStream = DTEDCreatePtStream( ".", nOutLevel ); if( pStream == NULL ) exit( 1 ); /* -------------------------------------------------------------------- */ /* Process all the profiles. */ /* -------------------------------------------------------------------- */ panData = (GInt16 *) malloc(sizeof(GInt16) * nXSize); for( iY = 0; iY < nYSize; iY++ ) { GDALRasterIO( hSrcBand, GF_Read, 0, iY, nXSize, 1, panData, nXSize, 1, GDT_Int16, 0, 0 ); if (bHasNoData) { for( iX = 0; iX < nXSize; iX++ ) { if (panData[iX] == noDataValue) panData[iX] = DTED_NODATA_VALUE; } } for( iX = 0; iX < nXSize; iX++ ) { DTEDWritePt( pStream, adfGeoTransform[0] + adfGeoTransform[1] * (iX + 0.5) + adfGeoTransform[2] * (iY + 0.5), adfGeoTransform[3] + adfGeoTransform[4] * (iX + 0.5) + adfGeoTransform[5] * (iY + 0.5), panData[iX] ); } } free( panData ); /* -------------------------------------------------------------------- */ /* Cleanup. */ /* -------------------------------------------------------------------- */ if( bEnableTrim ) DTEDPtStreamTrimEdgeOnlyTiles( pStream ); if( nFillDist > 0 ) DTEDFillPtStream( pStream, nFillDist ); DTEDClosePtStream( pStream ); GDALClose( hSrcDS ); exit( 0 ); }
int QgsZonalStatistics::calculateStatistics( QProgressDialog* p ) { if ( !mPolygonLayer || mPolygonLayer->geometryType() != QGis::Polygon ) { return 1; } QgsVectorDataProvider* vectorProvider = mPolygonLayer->dataProvider(); if ( !vectorProvider ) { return 2; } //open the raster layer and the raster band GDALAllRegister(); GDALDatasetH inputDataset = GDALOpen( mRasterFilePath.toLocal8Bit().data(), GA_ReadOnly ); if ( inputDataset == NULL ) { return 3; } if ( GDALGetRasterCount( inputDataset ) < ( mRasterBand - 1 ) ) { GDALClose( inputDataset ); return 4; } GDALRasterBandH rasterBand = GDALGetRasterBand( inputDataset, mRasterBand ); if ( rasterBand == NULL ) { GDALClose( inputDataset ); return 5; } mInputNodataValue = GDALGetRasterNoDataValue( rasterBand, NULL ); //get geometry info about raster layer int nCellsX = GDALGetRasterXSize( inputDataset ); int nCellsY = GDALGetRasterYSize( inputDataset ); double geoTransform[6]; if ( GDALGetGeoTransform( inputDataset, geoTransform ) != CE_None ) { GDALClose( inputDataset ); return 6; } double cellsizeX = geoTransform[1]; if ( cellsizeX < 0 ) { cellsizeX = -cellsizeX; } double cellsizeY = geoTransform[5]; if ( cellsizeY < 0 ) { cellsizeY = -cellsizeY; } QgsRectangle rasterBBox( geoTransform[0], geoTransform[3] - ( nCellsY * cellsizeY ), geoTransform[0] + ( nCellsX * cellsizeX ), geoTransform[3] ); //add the new count, sum, mean fields to the provider QList<QgsField> newFieldList; QgsField countField( mAttributePrefix + "count", QVariant::Double ); QgsField sumField( mAttributePrefix + "sum", QVariant::Double ); QgsField meanField( mAttributePrefix + "mean", QVariant::Double ); newFieldList.push_back( countField ); newFieldList.push_back( sumField ); newFieldList.push_back( meanField ); if ( !vectorProvider->addAttributes( newFieldList ) ) { return 7; } //index of the new fields int countIndex = vectorProvider->fieldNameIndex( mAttributePrefix + "count" ); int sumIndex = vectorProvider->fieldNameIndex( mAttributePrefix + "sum" ); int meanIndex = vectorProvider->fieldNameIndex( mAttributePrefix + "mean" ); if ( countIndex == -1 || sumIndex == -1 || meanIndex == -1 ) { return 8; } //progress dialog long featureCount = vectorProvider->featureCount(); if ( p ) { p->setMaximum( featureCount ); } //iterate over each polygon vectorProvider->select( QgsAttributeList(), QgsRectangle(), true, false ); vectorProvider->rewind(); QgsFeature f; double count = 0; double sum = 0; double mean = 0; int featureCounter = 0; while ( vectorProvider->nextFeature( f ) ) { qWarning( "%d", featureCounter ); if ( p ) { p->setValue( featureCounter ); } if ( p && p->wasCanceled() ) { break; } QgsGeometry* featureGeometry = f.geometry(); if ( !featureGeometry ) { ++featureCounter; continue; } int offsetX, offsetY, nCellsX, nCellsY; if ( cellInfoForBBox( rasterBBox, featureGeometry->boundingBox(), cellsizeX, cellsizeY, offsetX, offsetY, nCellsX, nCellsY ) != 0 ) { ++featureCounter; continue; } statisticsFromMiddlePointTest_improved( rasterBand, featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY, rasterBBox, sum, count ); if ( count <= 1 ) { //the cell resolution is probably larger than the polygon area. We switch to precise pixel - polygon intersection in this case statisticsFromPreciseIntersection( rasterBand, featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY, rasterBBox, sum, count ); } if ( count == 0 ) { mean = 0; } else { mean = sum / count; } //write the statistics value to the vector data provider QgsChangedAttributesMap changeMap; QgsAttributeMap changeAttributeMap; changeAttributeMap.insert( countIndex, QVariant( count ) ); changeAttributeMap.insert( sumIndex, QVariant( sum ) ); changeAttributeMap.insert( meanIndex, QVariant( mean ) ); changeMap.insert( f.id(), changeAttributeMap ); vectorProvider->changeAttributeValues( changeMap ); ++featureCounter; } if ( p ) { p->setValue( featureCount ); } GDALClose( inputDataset ); return 0; }
CPLErr CPL_STDCALL GDALComputeProximity(GDALRasterBandH hSrcBand, GDALRasterBandH hProximityBand, char **papszOptions, GDALProgressFunc pfnProgress, void *pProgressArg) { int nXSize, nYSize, i, bFixedBufVal = FALSE; const char *pszOpt; double dfMaxDist; double dfFixedBufVal = 0.0; VALIDATE_POINTER1(hSrcBand, "GDALComputeProximity", CE_Failure); VALIDATE_POINTER1(hProximityBand, "GDALComputeProximity", CE_Failure); if (pfnProgress == NULL) pfnProgress = GDALDummyProgress; /* -------------------------------------------------------------------- */ /* Are we using pixels or georeferenced coordinates for distances? */ /* -------------------------------------------------------------------- */ double dfDistMult = 1.0; pszOpt = CSLFetchNameValue(papszOptions, "DISTUNITS"); if (pszOpt) { if (EQUAL(pszOpt, "GEO")) { GDALDatasetH hSrcDS = GDALGetBandDataset(hSrcBand); if (hSrcDS) { double adfGeoTransform[6]; GDALGetGeoTransform(hSrcDS, adfGeoTransform); if (ABS(adfGeoTransform[1]) != ABS(adfGeoTransform[5])) CPLError(CE_Warning, CPLE_AppDefined, "Pixels not square, distances will be inaccurate."); dfDistMult = ABS(adfGeoTransform[1]); } } else if (!EQUAL(pszOpt, "PIXEL")) { CPLError(CE_Failure, CPLE_AppDefined, "Unrecognised DISTUNITS value '%s', should be GEO or PIXEL.", pszOpt); return CE_Failure; } } /* -------------------------------------------------------------------- */ /* What is our maxdist value? */ /* -------------------------------------------------------------------- */ pszOpt = CSLFetchNameValue(papszOptions, "MAXDIST"); if (pszOpt) dfMaxDist = atof(pszOpt) / dfDistMult; else dfMaxDist = GDALGetRasterBandXSize(hSrcBand) + GDALGetRasterBandYSize(hSrcBand); CPLDebug("GDAL", "MAXDIST=%g, DISTMULT=%g", dfMaxDist, dfDistMult); /* -------------------------------------------------------------------- */ /* Verify the source and destination are compatible. */ /* -------------------------------------------------------------------- */ nXSize = GDALGetRasterBandXSize(hSrcBand); nYSize = GDALGetRasterBandYSize(hSrcBand); if (nXSize != GDALGetRasterBandXSize(hProximityBand) || nYSize != GDALGetRasterBandYSize(hProximityBand)) { CPLError(CE_Failure, CPLE_AppDefined, "Source and proximity bands are not the same size."); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Get output NODATA value. */ /* -------------------------------------------------------------------- */ float fNoDataValue; pszOpt = CSLFetchNameValue(papszOptions, "NODATA"); if (pszOpt != NULL) fNoDataValue = (float) atof(pszOpt); else { int bSuccess; fNoDataValue = (float) GDALGetRasterNoDataValue(hProximityBand, &bSuccess); if (!bSuccess) fNoDataValue = 65535.0; } /* -------------------------------------------------------------------- */ /* Is there a fixed value we wish to force the buffer area to? */ /* -------------------------------------------------------------------- */ pszOpt = CSLFetchNameValue(papszOptions, "FIXED_BUF_VAL"); if (pszOpt) { dfFixedBufVal = atof(pszOpt); bFixedBufVal = TRUE; } /* -------------------------------------------------------------------- */ /* Get the target value(s). */ /* -------------------------------------------------------------------- */ int *panTargetValues = NULL; int nTargetValues = 0; pszOpt = CSLFetchNameValue(papszOptions, "VALUES"); if (pszOpt != NULL) { char **papszValuesTokens; papszValuesTokens = CSLTokenizeStringComplex(pszOpt, ",", FALSE, FALSE); nTargetValues = CSLCount(papszValuesTokens); panTargetValues = (int*) CPLCalloc(sizeof(int), nTargetValues); for (i = 0; i < nTargetValues; i++) panTargetValues[i] = atoi(papszValuesTokens[i]); CSLDestroy(papszValuesTokens); } /* -------------------------------------------------------------------- */ /* Initialize progress counter. */ /* -------------------------------------------------------------------- */ if (!pfnProgress(0.0, "", pProgressArg)) { CPLError(CE_Failure, CPLE_UserInterrupt, "User terminated"); CPLFree(panTargetValues); return CE_Failure; } /* -------------------------------------------------------------------- */ /* We need a signed type for the working proximity values kept */ /* on disk. If our proximity band is not signed, then create a */ /* temporary file for this purpose. */ /* -------------------------------------------------------------------- */ GDALRasterBandH hWorkProximityBand = hProximityBand; GDALDatasetH hWorkProximityDS = NULL; GDALDataType eProxType = GDALGetRasterDataType(hProximityBand); int *panNearX = NULL, *panNearY = NULL; float *pafProximity = NULL; GInt32 *panSrcScanline = NULL; int iLine; CPLErr eErr = CE_None; if (eProxType == GDT_Byte || eProxType == GDT_UInt16 || eProxType == GDT_UInt32) { GDALDriverH hDriver = GDALGetDriverByName("GTiff"); if (hDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "GDALComputeProximity needs GTiff driver"); eErr = CE_Failure; goto end; } CPLString osTmpFile = CPLGenerateTempFilename("proximity"); hWorkProximityDS = GDALCreate(hDriver, osTmpFile, nXSize, nYSize, 1, GDT_Float32, NULL); if (hWorkProximityDS == NULL) { eErr = CE_Failure; goto end; } hWorkProximityBand = GDALGetRasterBand(hWorkProximityDS, 1); } /* -------------------------------------------------------------------- */ /* Allocate buffer for two scanlines of distances as floats */ /* (the current and last line). */ /* -------------------------------------------------------------------- */ pafProximity = (float*) VSIMalloc2(sizeof(float), nXSize); panNearX = (int*) VSIMalloc2(sizeof(int), nXSize); panNearY = (int*) VSIMalloc2(sizeof(int), nXSize); panSrcScanline = (GInt32*) VSIMalloc2(sizeof(GInt32), nXSize); if (pafProximity == NULL || panNearX == NULL || panNearY == NULL || panSrcScanline == NULL) { CPLError(CE_Failure, CPLE_OutOfMemory, "Out of memory allocating working buffers."); eErr = CE_Failure; goto end; } /* -------------------------------------------------------------------- */ /* Loop from top to bottom of the image. */ /* -------------------------------------------------------------------- */ for (i = 0; i < nXSize; i++) panNearX[i] = panNearY[i] = -1; for (iLine = 0; eErr == CE_None && iLine < nYSize; iLine++) { // Read for target values. eErr = GDALRasterIO(hSrcBand, GF_Read, 0, iLine, nXSize, 1, panSrcScanline, nXSize, 1, GDT_Int32, 0, 0); if (eErr != CE_None) break; for (i = 0; i < nXSize; i++) pafProximity[i] = -1.0; // Left to right ProcessProximityLine(panSrcScanline, panNearX, panNearY, TRUE, iLine, nXSize, dfMaxDist, pafProximity, nTargetValues, panTargetValues); // Right to Left ProcessProximityLine(panSrcScanline, panNearX, panNearY, FALSE, iLine, nXSize, dfMaxDist, pafProximity, nTargetValues, panTargetValues); // Write out results. eErr = GDALRasterIO(hWorkProximityBand, GF_Write, 0, iLine, nXSize, 1, pafProximity, nXSize, 1, GDT_Float32, 0, 0); if (eErr != CE_None) break; if (!pfnProgress(0.5 * (iLine + 1) / (double) nYSize, "", pProgressArg)) { CPLError(CE_Failure, CPLE_UserInterrupt, "User terminated"); eErr = CE_Failure; } } /* -------------------------------------------------------------------- */ /* Loop from bottom to top of the image. */ /* -------------------------------------------------------------------- */ for (i = 0; i < nXSize; i++) panNearX[i] = panNearY[i] = -1; for (iLine = nYSize - 1; eErr == CE_None && iLine >= 0; iLine--) { // Read first pass proximity eErr = GDALRasterIO(hWorkProximityBand, GF_Read, 0, iLine, nXSize, 1, pafProximity, nXSize, 1, GDT_Float32, 0, 0); if (eErr != CE_None) break; // Read pixel values. eErr = GDALRasterIO(hSrcBand, GF_Read, 0, iLine, nXSize, 1, panSrcScanline, nXSize, 1, GDT_Int32, 0, 0); if (eErr != CE_None) break; // Right to left ProcessProximityLine(panSrcScanline, panNearX, panNearY, FALSE, iLine, nXSize, dfMaxDist, pafProximity, nTargetValues, panTargetValues); // Left to right ProcessProximityLine(panSrcScanline, panNearX, panNearY, TRUE, iLine, nXSize, dfMaxDist, pafProximity, nTargetValues, panTargetValues); // Final post processing of distances. for (i = 0; i < nXSize; i++) { if (pafProximity[i] < 0.0) pafProximity[i] = fNoDataValue; else if (pafProximity[i] > 0.0) { if (bFixedBufVal) pafProximity[i] = (float) dfFixedBufVal; else pafProximity[i] = (float)(pafProximity[i] * dfDistMult); } } // Write out results. eErr = GDALRasterIO(hProximityBand, GF_Write, 0, iLine, nXSize, 1, pafProximity, nXSize, 1, GDT_Float32, 0, 0); if (eErr != CE_None) break; if (!pfnProgress(0.5 + 0.5 * (nYSize - iLine) / (double) nYSize, "", pProgressArg)) { CPLError(CE_Failure, CPLE_UserInterrupt, "User terminated"); eErr = CE_Failure; } } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ end: CPLFree(panNearX); CPLFree(panNearY); CPLFree(panSrcScanline); CPLFree(pafProximity); CPLFree(panTargetValues); if (hWorkProximityDS != NULL) { CPLString osProxFile = GDALGetDescription(hWorkProximityDS); GDALClose(hWorkProximityDS); GDALDeleteDataset(GDALGetDriverByName("GTiff"), osProxFile); } return eErr; }
QgsVectorLayer* QgsSLDConfigParser::contourLayerFromRaster( const QDomElement& userStyleElem, QgsRasterLayer* rasterLayer ) const { QgsDebugMsg( "Entering." ); if ( !rasterLayer ) { return nullptr; } //get <ContourSymbolizer> element QDomNodeList contourNodeList = userStyleElem.elementsByTagName( QStringLiteral( "ContourSymbolizer" ) ); if ( contourNodeList.size() < 1 ) { return nullptr; } QDomElement contourSymbolizerElem = contourNodeList.item( 0 ).toElement(); if ( contourSymbolizerElem.isNull() ) { return nullptr; } double equidistance, minValue, maxValue, offset; QString propertyName; equidistance = contourSymbolizerElem.attribute( QStringLiteral( "equidistance" ) ).toDouble(); minValue = contourSymbolizerElem.attribute( QStringLiteral( "minValue" ) ).toDouble(); maxValue = contourSymbolizerElem.attribute( QStringLiteral( "maxValue" ) ).toDouble(); offset = contourSymbolizerElem.attribute( QStringLiteral( "offset" ) ).toDouble(); propertyName = contourSymbolizerElem.attribute( QStringLiteral( "propertyName" ) ); if ( equidistance <= 0.0 ) { return nullptr; } QTemporaryFile* tmpFile1 = new QTemporaryFile(); tmpFile1->open(); mFilesToRemove.push_back( tmpFile1 ); QString tmpBaseName = tmpFile1->fileName(); QString tmpFileName = tmpBaseName + ".shp"; //hack: use gdal_contour first to write into a temporary file /* todo: use GDALContourGenerate( hBand, dfInterval, dfOffset, nFixedLevelCount, adfFixedLevels, bNoDataSet, dfNoData, hLayer, 0, nElevField, GDALTermProgress, nullptr );*/ //do the stuff that is also done in the main method of gdal_contour... /* -------------------------------------------------------------------- */ /* Open source raster file. */ /* -------------------------------------------------------------------- */ GDALRasterBandH hBand; GDALDatasetH hSrcDS; int numberOfLevels = 0; double currentLevel = 0.0; if ( maxValue > minValue ) { //find first level currentLevel = ( int )(( minValue - offset ) / equidistance + 0.5 ) * equidistance + offset; while ( currentLevel <= maxValue ) { ++numberOfLevels; currentLevel += equidistance; } } double *adfFixedLevels = new double[numberOfLevels]; int nFixedLevelCount = numberOfLevels; currentLevel = ( int )(( minValue - offset ) / equidistance + 0.5 ) * equidistance + offset; for ( int i = 0; i < numberOfLevels; ++i ) { adfFixedLevels[i] = currentLevel; currentLevel += equidistance; } int nBandIn = 1; double dfInterval = equidistance, dfNoData = 0.0, dfOffset = offset; int /* b3D = FALSE, */ bNoDataSet = FALSE, bIgnoreNoData = FALSE; hSrcDS = GDALOpen( rasterLayer->source().toUtf8().constData(), GA_ReadOnly ); if ( !hSrcDS ) { delete [] adfFixedLevels; throw QgsMapServiceException( QStringLiteral( "LayerNotDefined" ), QStringLiteral( "Operation request is for a file not available on the server." ) ); } hBand = GDALGetRasterBand( hSrcDS, nBandIn ); if ( !hBand ) { CPLError( CE_Failure, CPLE_AppDefined, "Band %d does not exist on dataset.", nBandIn ); } if ( !bNoDataSet && !bIgnoreNoData ) dfNoData = GDALGetRasterNoDataValue( hBand, &bNoDataSet ); /* -------------------------------------------------------------------- */ /* Try to get a coordinate system from the raster. */ /* -------------------------------------------------------------------- */ OGRSpatialReferenceH hSRS = nullptr; const char *pszWKT = GDALGetProjectionRef( hBand ); if ( pszWKT && strlen( pszWKT ) != 0 ) hSRS = OSRNewSpatialReference( pszWKT ); /* -------------------------------------------------------------------- */ /* Create the outputfile. */ /* -------------------------------------------------------------------- */ OGRDataSourceH hDS; OGRSFDriverH hDriver = OGRGetDriverByName( "ESRI Shapefile" ); OGRFieldDefnH hFld; OGRLayerH hLayer; int nElevField = -1; if ( !hDriver ) { //fprintf( FCGI_stderr, "Unable to find format driver named 'ESRI Shapefile'.\n" ); delete [] adfFixedLevels; throw QgsMapServiceException( QStringLiteral( "LayerNotDefined" ), QStringLiteral( "Operation request is for a file not available on the server." ) ); } hDS = OGR_Dr_CreateDataSource( hDriver, tmpFileName.toUtf8().constData(), nullptr ); if ( !hDS ) { delete [] adfFixedLevels; throw QgsMapServiceException( QStringLiteral( "LayerNotDefined" ), QStringLiteral( "Operation request cannot create data source." ) ); } hLayer = OGR_DS_CreateLayer( hDS, "contour", hSRS, /* b3D ? wkbLineString25D : */ wkbLineString, nullptr ); if ( !hLayer ) { delete [] adfFixedLevels; throw QgsMapServiceException( QStringLiteral( "LayerNotDefined" ), QStringLiteral( "Operation request could not create contour file." ) ); } hFld = OGR_Fld_Create( "ID", OFTInteger ); OGR_Fld_SetWidth( hFld, 8 ); OGR_L_CreateField( hLayer, hFld, FALSE ); OGR_Fld_Destroy( hFld ); if ( !propertyName.isEmpty() ) { hFld = OGR_Fld_Create( propertyName.toUtf8().constData(), OFTReal ); OGR_Fld_SetWidth( hFld, 12 ); OGR_Fld_SetPrecision( hFld, 3 ); OGR_L_CreateField( hLayer, hFld, FALSE ); OGR_Fld_Destroy( hFld ); nElevField = 1; } /* -------------------------------------------------------------------- */ /* Invoke. */ /* -------------------------------------------------------------------- */ GDALContourGenerate( hBand, dfInterval, dfOffset, nFixedLevelCount, adfFixedLevels, bNoDataSet, dfNoData, hLayer, 0, nElevField, GDALTermProgress, nullptr ); delete [] adfFixedLevels; OGR_DS_Destroy( hDS ); GDALClose( hSrcDS ); //todo: store those three files elsewhere... //mark shp, dbf and shx to delete after the request mFilePathsToRemove.push_back( tmpBaseName + ".shp" ); mFilePathsToRemove.push_back( tmpBaseName + ".dbf" ); mFilePathsToRemove.push_back( tmpBaseName + ".shx" ); QgsVectorLayer* contourLayer = new QgsVectorLayer( tmpFileName, QStringLiteral( "layer" ), QStringLiteral( "ogr" ) ); //create renderer QgsFeatureRenderer* theRenderer = rendererFromUserStyle( userStyleElem, contourLayer ); contourLayer->setRenderer( theRenderer ); //add labeling if requested labelSettingsFromUserStyle( userStyleElem, contourLayer ); QgsDebugMsg( "Returning the contour layer" ); return contourLayer; }
int main(int argc, char *argv[]) { const char *pszInputfile = NULL; const char *pszOutputfile = NULL; const char *pszFormat = "GTiff"; int bProgress = FALSE; int bMaskNoData = FALSE; GDALDatasetH hSrcDS; GDALDatasetH hMaskDS; GDALDriverH hDriver; double adfGeoTransform[6]; const char *pszWkt; int nXSize, nYSize; int nMaskCount = 0; int nPixelsMasked = 0; double adfMaskValues[1024]; int anMaskFound[1024]; int bMaskProvided = FALSE; double dfNoData; int i, j, k; GDALRasterBandH hSrcBand, hMaskBand; double *padfScanline; unsigned char *pabyScanline; int nHasNoData; char** papszCreationOptions = NULL; i = 1; while( i < argc ) { if( EQUAL( argv[i], "-p" ) ) { bProgress = TRUE; } else if( EQUAL( argv[i], "-mask_nodata" ) ) { bMaskNoData = TRUE; bMaskProvided = TRUE; } else if( EQUAL( argv[i], "-of" ) ) { pszFormat = argv[++i]; } else if( EQUAL( argv[i], "-co" ) ) { papszCreationOptions = CSLAddString(papszCreationOptions, argv[++i]); } else if( EQUAL( argv[i], "-h" ) ) { Usage(); } else if( pszInputfile == NULL ) { pszInputfile = argv[i]; } else if( pszOutputfile == NULL ) { pszOutputfile = argv[i]; } else { adfMaskValues[nMaskCount++] = atof(argv[i]); bMaskProvided = TRUE; } //else //{ // Usage(); //} i++; } if( pszInputfile == NULL ) { fprintf( stderr, "No input file provided\n"); Usage(); } if( pszOutputfile == NULL ) { fprintf( stderr, "No output file provided\n" ); Usage(); } GDALAllRegister(); hSrcDS = GDALOpen(pszInputfile, GA_ReadOnly); if(hSrcDS == NULL) { CPLError(CE_Fatal, CPLE_OpenFailed, "Failed to open source dataset"); } hDriver = GDALGetDriverByName(pszFormat); if(hDriver == NULL) { CPLError(CE_Fatal, CPLE_NotSupported, "Failed to load output driver"); } nXSize = GDALGetRasterXSize(hSrcDS); nYSize = GDALGetRasterYSize(hSrcDS); hMaskDS = GDALCreate(hDriver, pszOutputfile, nXSize, nYSize, 1, GDT_Byte, papszCreationOptions); pszWkt = GDALGetProjectionRef(hSrcDS); if(pszWkt != NULL) { GDALSetProjection(hMaskDS, pszWkt); } if(GDALGetGeoTransform(hSrcDS, adfGeoTransform) == CE_None) { GDALSetGeoTransform(hMaskDS, adfGeoTransform); } hSrcBand = GDALGetRasterBand(hSrcDS, 1); hMaskBand = GDALGetRasterBand(hMaskDS, 1); nHasNoData = FALSE; if(bMaskNoData) { dfNoData = GDALGetRasterNoDataValue(hSrcBand, &nHasNoData); if(nHasNoData) { adfMaskValues[nMaskCount++] = dfNoData; } } for(i = 0;i < nMaskCount;i++) { anMaskFound[i] = 0; } padfScanline = (double*)CPLMalloc(nXSize * sizeof(double)); pabyScanline = (unsigned char*)CPLMalloc(nXSize * sizeof(unsigned char)); if(bProgress) { GDALTermProgress(0.0, NULL, NULL); } for(i = 0;i < nYSize;i++) { GDALRasterIO(hSrcBand, GF_Read, 0, i, nXSize, 1, padfScanline, nXSize, 1, GDT_Float64, 0, 0); for(j = 0; j < nXSize;j++) { pabyScanline[j] = 255; for(k = 0; k < nMaskCount; k++) { if(CPLIsEqual(padfScanline[j], adfMaskValues[k])) { pabyScanline[j] = 0; anMaskFound[k]++; nPixelsMasked++; break; } } } GDALRasterIO(hMaskBand, GF_Write, 0, i, nXSize, 1, pabyScanline, nXSize, 1, GDT_Byte, 0, 0); if(bProgress) { GDALTermProgress((double)i / (double)nYSize, NULL, NULL); } } if(bProgress) { GDALTermProgress(1.0, NULL, NULL); } for(i = 0; i < nMaskCount;i++) { CPLDebug("addmask", "%d pixels were masked for value: %lf", anMaskFound[i], adfMaskValues[i]); } CPLDebug("addmask", "%d pixels were masked total", nPixelsMasked); CPLFree(padfScanline); CPLFree(pabyScanline); GDALClose(hSrcDS); GDALClose(hMaskDS); }
int Gdal_Contour(maps*& conf,maps*& inputs,maps*& outputs) #endif { fprintf(stderr,"DEBUG HELLO %f %d\n",__FILE__,__LINE__); fflush(stderr); GDALDatasetH hSrcDS; int i, b3D = FALSE, bNoDataSet = FALSE, bIgnoreNoData = FALSE; int nBandIn = 1; double dfInterval = 0.0, dfNoData = 0.0, dfOffset = 0.0; const char *pszSrcFilename = NULL; const char *pszDstFilename = NULL; const char *pszElevAttrib = NULL; const char *pszFormat = "ESRI Shapefile"; char **papszDSCO = NULL, **papszLCO = NULL; double adfFixedLevels[1000]; int nFixedLevelCount = 0; const char *pszNewLayerName = "contour"; int bQuiet = FALSE; GDALProgressFunc pfnProgress = NULL; fprintf(stderr,"DEBUG HELLO %f %d\n",__FILE__,__LINE__); fflush(stderr); #ifndef ZOO_SERVICE /* Check that we are running against at least GDAL 1.4 */ /* Note to developers : if we use newer API, please change the requirement */ if (atoi(GDALVersionInfo("VERSION_NUM")) < 1400) { fprintf(stderr, "At least, GDAL >= 1.4.0 is required for this version of %s, " "which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME); exit(1); } #endif GDALAllRegister(); OGRRegisterAll(); #ifndef ZOO_SERVICE argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); /* -------------------------------------------------------------------- */ /* Parse arguments. */ /* -------------------------------------------------------------------- */ for( i = 1; i < argc; i++ ) { if( EQUAL(argv[i], "--utility_version") ) { printf("%s was compiled against GDAL %s and is running against GDAL %s\n", argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); return 0; } else if( EQUAL(argv[i], "--help") ) Usage(); else if( EQUAL(argv[i],"-a") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszElevAttrib = argv[++i]; } else if( EQUAL(argv[i],"-off") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); dfOffset = atof(argv[++i]); } else if( EQUAL(argv[i],"-i") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); dfInterval = atof(argv[++i]); } else if( EQUAL(argv[i],"-fl") ) { if( i >= argc-1 ) Usage(CPLSPrintf("%s option requires at least 1 argument", argv[i])); while( i < argc-1 && nFixedLevelCount < (int)(sizeof(adfFixedLevels)/sizeof(double)) && ArgIsNumeric(argv[i+1]) ) adfFixedLevels[nFixedLevelCount++] = atof(argv[++i]); } else if( EQUAL(argv[i],"-b") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); nBandIn = atoi(argv[++i]); } else if( EQUAL(argv[i],"-f") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszFormat = argv[++i]; } else if( EQUAL(argv[i],"-dsco") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); papszDSCO = CSLAddString(papszDSCO, argv[++i] ); } else if( EQUAL(argv[i],"-lco") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); papszLCO = CSLAddString(papszLCO, argv[++i] ); } else if( EQUAL(argv[i],"-3d") ) { b3D = TRUE; } else if( EQUAL(argv[i],"-snodata") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); bNoDataSet = TRUE; dfNoData = atof(argv[++i]); } else if( EQUAL(argv[i],"-nln") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszNewLayerName = argv[++i]; } else if( EQUAL(argv[i],"-inodata") ) { bIgnoreNoData = TRUE; } else if ( EQUAL(argv[i],"-q") || EQUAL(argv[i],"-quiet") ) { bQuiet = TRUE; } else if( pszSrcFilename == NULL ) { pszSrcFilename = argv[i]; } else if( pszDstFilename == NULL ) { pszDstFilename = argv[i]; } else Usage("Too many command options."); } #else bQuiet = TRUE; bIgnoreNoData = TRUE; map* tmpMap=NULL; tmpMap=NULL; tmpMap=getMapFromMaps(inputs,"a","value"); if(tmpMap!=NULL && strncmp(tmpMap->value,"NULL",4)!=0){ pszElevAttrib = strdup(tmpMap->value); } tmpMap=getMapFromMaps(inputs,"off","value"); if(tmpMap!=NULL && strncmp(tmpMap->value,"NULL",4)!=0){ dfOffset = atof(tmpMap->value); } tmpMap=getMapFromMaps(inputs,"i","value"); if(tmpMap!=NULL && strncmp(tmpMap->value,"NULL",4)!=0){ dfInterval = atof(tmpMap->value); } tmpMap=getMapFromMaps(inputs,"b","value"); if(tmpMap!=NULL && strncmp(tmpMap->value,"NULL",4)!=0){ nBandIn = atoi(tmpMap->value); } tmpMap=getMapFromMaps(inputs,"InputDSN","value"); if(tmpMap!=NULL && strncmp(tmpMap->value,"NULL",4)!=0){ pszSrcFilename = strdup(tmpMap->value); } tmpMap=getMapFromMaps(inputs,"OutputDSN","value"); if(tmpMap!=NULL && strncmp(tmpMap->value,"NULL",4)!=0){ pszDstFilename = strdup(tmpMap->value); } #endif if( dfInterval == 0.0 && nFixedLevelCount == 0 ) { Usage("Neither -i nor -fl are specified."); } if (pszSrcFilename == NULL) { Usage("Missing source filename."); } if (pszDstFilename == NULL) { Usage("Missing destination filename."); } if (!bQuiet) pfnProgress = GDALTermProgress; /* -------------------------------------------------------------------- */ /* Open source raster file. */ /* -------------------------------------------------------------------- */ GDALRasterBandH hBand; hSrcDS = GDALOpen( pszSrcFilename, GA_ReadOnly ); if( hSrcDS == NULL ){ #ifndef ZOO_SERVICE exit( 2 ); #else setMapInMaps(conf,"lenv","message","Unable to open the file"); #endif } hBand = GDALGetRasterBand( hSrcDS, nBandIn ); if( hBand == NULL ) { #ifndef ZOO_SERVICE CPLError( CE_Failure, CPLE_AppDefined, "Band %d does not exist on dataset.", nBandIn ); exit(2); #else char tmp[1024]; sprintf(tmp,"Band %d does not exist on dataset.",nBandIn); setMapInMaps(conf,"lenv","message",tmp); return SERVICE_FAILED; #endif } if( !bNoDataSet && !bIgnoreNoData ) dfNoData = GDALGetRasterNoDataValue( hBand, &bNoDataSet ); /* -------------------------------------------------------------------- */ /* Try to get a coordinate system from the raster. */ /* -------------------------------------------------------------------- */ OGRSpatialReferenceH hSRS = NULL; const char *pszWKT = GDALGetProjectionRef( hSrcDS ); if( pszWKT != NULL && strlen(pszWKT) != 0 ) hSRS = OSRNewSpatialReference( pszWKT ); /* -------------------------------------------------------------------- */ /* Create the outputfile. */ /* -------------------------------------------------------------------- */ OGRDataSourceH hDS; OGRSFDriverH hDriver = OGRGetDriverByName( pszFormat ); OGRFieldDefnH hFld; OGRLayerH hLayer; if( hDriver == NULL ) { #ifndef ZOO_SERVICE fprintf( stderr, "Unable to find format driver named %s.\n", pszFormat ); exit( 10 ); #else char tmp[1024]; sprintf( tmp, "Unable to find format driver named %s.\n", pszFormat ); setMapInMaps(conf,"lenv","message",tmp); return SERVICE_FAILED; #endif } hDS = OGR_Dr_CreateDataSource( hDriver, pszDstFilename, papszDSCO ); if( hDS == NULL ){ #ifndef ZOO_SERVICE exit( 1 ); #else setMapInMaps(conf,"lenv","message","Unable to create the file"); return SERVICE_FAILED; #endif } hLayer = OGR_DS_CreateLayer( hDS, pszNewLayerName, hSRS, b3D ? wkbLineString25D : wkbLineString, papszLCO ); if( hLayer == NULL ) exit( 1 ); hFld = OGR_Fld_Create( "ID", OFTInteger ); OGR_Fld_SetWidth( hFld, 8 ); OGR_L_CreateField( hLayer, hFld, FALSE ); OGR_Fld_Destroy( hFld ); if( pszElevAttrib ) { hFld = OGR_Fld_Create( pszElevAttrib, OFTReal ); OGR_Fld_SetWidth( hFld, 12 ); OGR_Fld_SetPrecision( hFld, 3 ); OGR_L_CreateField( hLayer, hFld, FALSE ); OGR_Fld_Destroy( hFld ); } /* -------------------------------------------------------------------- */ /* Invoke. */ /* -------------------------------------------------------------------- */ CPLErr eErr; eErr = GDALContourGenerate( hBand, dfInterval, dfOffset, nFixedLevelCount, adfFixedLevels, bNoDataSet, dfNoData, hLayer, OGR_FD_GetFieldIndex( OGR_L_GetLayerDefn( hLayer ), "ID" ), (pszElevAttrib == NULL) ? -1 : OGR_FD_GetFieldIndex( OGR_L_GetLayerDefn( hLayer ), pszElevAttrib ), pfnProgress, NULL ); OGR_DS_Destroy( hDS ); GDALClose( hSrcDS ); if (hSRS) OSRDestroySpatialReference( hSRS ); #ifndef ZOO_SERVICE CSLDestroy( argv ); CSLDestroy( papszDSCO ); CSLDestroy( papszLCO ); GDALDestroyDriverManager(); OGRCleanupAll(); return 0; #else GDALDestroyDriverManager(); OGRCleanupAll(); char tmp[1024]; sprintf(tmp,"File %s successfully created.",pszDstFilename); setMapInMaps(outputs,"Result","value",tmp); return SERVICE_SUCCEEDED; #endif }
void QgsImageWarper::warp( const QString& input, const QString& output, double& xOffset, double& yOffset, ResamplingMethod resampling, bool useZeroAsTrans, const QString& compression ) { // Open input file GDALAllRegister(); GDALDatasetH hSrcDS = GDALOpen( QFile::encodeName( input ).constData(), GA_ReadOnly ); // Setup warp options. GDALWarpOptions *psWarpOptions = GDALCreateWarpOptions(); psWarpOptions->hSrcDS = hSrcDS; psWarpOptions->nBandCount = GDALGetRasterCount( hSrcDS ); psWarpOptions->panSrcBands = ( int * ) CPLMalloc( sizeof( int ) * psWarpOptions->nBandCount ); psWarpOptions->panDstBands = ( int * ) CPLMalloc( sizeof( int ) * psWarpOptions->nBandCount ); for ( int i = 0; i < psWarpOptions->nBandCount; ++i ) { psWarpOptions->panSrcBands[i] = i + 1; psWarpOptions->panDstBands[i] = i + 1; } psWarpOptions->pfnProgress = GDALTermProgress; psWarpOptions->pfnTransformer = &QgsImageWarper::transform; psWarpOptions->eResampleAlg = GDALResampleAlg( resampling ); // check the bounds for the warped raster // order: upper right, lower right, lower left (y points down) double x[] = { GDALGetRasterXSize( hSrcDS ), GDALGetRasterXSize( hSrcDS ), 0 }; double y[] = { 0, GDALGetRasterYSize( hSrcDS ), GDALGetRasterYSize( hSrcDS ) }; int s[] = { 0, 0, 0 }; TransformParameters tParam = { mAngle, 0, 0 }; transform( &tParam, FALSE, 3, x, y, NULL, s ); double minX = 0, minY = 0, maxX = 0, maxY = 0; for ( int i = 0; i < 3; ++i ) { minX = minX < x[i] ? minX : x[i]; minY = minY < y[i] ? minY : y[i]; maxX = maxX > x[i] ? maxX : x[i]; maxY = maxY > y[i] ? maxY : y[i]; } int newXSize = int( maxX - minX ) + 1; int newYSize = int( maxY - minY ) + 1; xOffset = -minX; yOffset = -minY; tParam.x0 = xOffset; tParam.y0 = yOffset; psWarpOptions->pTransformerArg = &tParam; // create the output file GDALDriverH driver = GDALGetDriverByName( "GTiff" ); char **papszOptions = NULL; papszOptions = CSLSetNameValue( papszOptions, "INIT_DEST", "NO_DATA" ); papszOptions = CSLSetNameValue( papszOptions, "COMPRESS", compression.toAscii() ); GDALDatasetH hDstDS = GDALCreate( driver, QFile::encodeName( output ).constData(), newXSize, newYSize, GDALGetRasterCount( hSrcDS ), GDALGetRasterDataType( GDALGetRasterBand( hSrcDS, 1 ) ), papszOptions ); for ( int i = 0; i < GDALGetRasterCount( hSrcDS ); ++i ) { GDALRasterBandH hSrcBand = GDALGetRasterBand( hSrcDS, i + 1 ); GDALRasterBandH hDstBand = GDALGetRasterBand( hDstDS, i + 1 ); GDALColorTableH cTable = GDALGetRasterColorTable( hSrcBand ); GDALSetRasterColorInterpretation( hDstBand, GDALGetRasterColorInterpretation( hSrcBand ) ); if ( cTable ) { GDALSetRasterColorTable( hDstBand, cTable ); } double noData = GDALGetRasterNoDataValue( hSrcBand, NULL ); if ( noData == -1e10 && useZeroAsTrans ) { GDALSetRasterNoDataValue( hDstBand, 0 ); } else { GDALSetRasterNoDataValue( hDstBand, noData ); } } psWarpOptions->hDstDS = hDstDS; // Initialize and execute the warp operation. GDALWarpOperation oOperation; oOperation.Initialize( psWarpOptions ); oOperation.ChunkAndWarpImage( 0, 0, GDALGetRasterXSize( hDstDS ), GDALGetRasterYSize( hDstDS ) ); GDALDestroyWarpOptions( psWarpOptions ); GDALClose( hSrcDS ); GDALClose( hDstDS ); }
static int GeoLocLoadFullData( GDALGeoLocTransformInfo *psTransform ) { int nXSize, nYSize; int nXSize_XBand = GDALGetRasterXSize( psTransform->hDS_X ); int nYSize_XBand = GDALGetRasterYSize( psTransform->hDS_X ); int nXSize_YBand = GDALGetRasterXSize( psTransform->hDS_Y ); int nYSize_YBand = GDALGetRasterYSize( psTransform->hDS_Y ); if (nYSize_XBand == 1 && nYSize_YBand == 1) { nXSize = nXSize_XBand; nYSize = nXSize_YBand; } else { nXSize = nXSize_XBand; nYSize = nYSize_XBand; } psTransform->nGeoLocXSize = nXSize; psTransform->nGeoLocYSize = nYSize; psTransform->padfGeoLocY = (double *) VSIMalloc3(sizeof(double), nXSize, nYSize); psTransform->padfGeoLocX = (double *) VSIMalloc3(sizeof(double), nXSize, nYSize); if( psTransform->padfGeoLocX == NULL || psTransform->padfGeoLocY == NULL ) { CPLError(CE_Failure, CPLE_OutOfMemory, "GeoLocLoadFullData : Out of memory"); return FALSE; } if (nYSize_XBand == 1 && nYSize_YBand == 1) { /* Case of regular grid */ /* The XBAND contains the x coordinates for all lines */ /* The YBAND contains the y coordinates for all columns */ double* padfTempX = (double*)VSIMalloc2(nXSize, sizeof(double)); double* padfTempY = (double*)VSIMalloc2(nYSize, sizeof(double)); if (padfTempX == NULL || padfTempY == NULL) { CPLFree(padfTempX); CPLFree(padfTempY); CPLError(CE_Failure, CPLE_OutOfMemory, "GeoLocLoadFullData : Out of memory"); return FALSE; } CPLErr eErr = CE_None; eErr = GDALRasterIO( psTransform->hBand_X, GF_Read, 0, 0, nXSize, 1, padfTempX, nXSize, 1, GDT_Float64, 0, 0 ); int i,j; for(j=0;j<nYSize;j++) { memcpy( psTransform->padfGeoLocX + j * nXSize, padfTempX, nXSize * sizeof(double) ); } if (eErr == CE_None) { eErr = GDALRasterIO( psTransform->hBand_Y, GF_Read, 0, 0, nYSize, 1, padfTempY, nYSize, 1, GDT_Float64, 0, 0 ); for(j=0;j<nYSize;j++) { for(i=0;i<nXSize;i++) { psTransform->padfGeoLocY[j * nXSize + i] = padfTempY[j]; } } } CPLFree(padfTempX); CPLFree(padfTempY); if (eErr != CE_None) return FALSE; } else { if( GDALRasterIO( psTransform->hBand_X, GF_Read, 0, 0, nXSize, nYSize, psTransform->padfGeoLocX, nXSize, nYSize, GDT_Float64, 0, 0 ) != CE_None || GDALRasterIO( psTransform->hBand_Y, GF_Read, 0, 0, nXSize, nYSize, psTransform->padfGeoLocY, nXSize, nYSize, GDT_Float64, 0, 0 ) != CE_None ) return FALSE; } psTransform->dfNoDataX = GDALGetRasterNoDataValue( psTransform->hBand_X, &(psTransform->bHasNoData) ); return TRUE; }
int QgsNineCellFilter::processRaster( QProgressDialog* p ) { GDALAllRegister(); //open input file int xSize, ySize; GDALDatasetH inputDataset = openInputFile( xSize, ySize ); if ( inputDataset == NULL ) { return 1; //opening of input file failed } //output driver GDALDriverH outputDriver = openOutputDriver(); if ( outputDriver == 0 ) { return 2; } GDALDatasetH outputDataset = openOutputFile( inputDataset, outputDriver ); if ( outputDataset == NULL ) { return 3; //create operation on output file failed } //open first raster band for reading (operation is only for single band raster) GDALRasterBandH rasterBand = GDALGetRasterBand( inputDataset, 1 ); if ( rasterBand == NULL ) { GDALClose( inputDataset ); GDALClose( outputDataset ); return 4; } mInputNodataValue = GDALGetRasterNoDataValue( rasterBand, NULL ); GDALRasterBandH outputRasterBand = GDALGetRasterBand( outputDataset, 1 ); if ( outputRasterBand == NULL ) { GDALClose( inputDataset ); GDALClose( outputDataset ); return 5; } //try to set -9999 as nodata value GDALSetRasterNoDataValue( outputRasterBand, -9999 ); mOutputNodataValue = GDALGetRasterNoDataValue( outputRasterBand, NULL ); if ( ySize < 3 ) //we require at least three rows (should be true for most datasets) { GDALClose( inputDataset ); GDALClose( outputDataset ); return 6; } //keep only three scanlines in memory at a time float* scanLine1 = ( float * ) CPLMalloc( sizeof( float ) * xSize ); float* scanLine2 = ( float * ) CPLMalloc( sizeof( float ) * xSize ); float* scanLine3 = ( float * ) CPLMalloc( sizeof( float ) * xSize ); float* resultLine = ( float * ) CPLMalloc( sizeof( float ) * xSize ); if ( p ) { p->setMaximum( ySize ); } //values outside the layer extent (if the 3x3 window is on the border) are sent to the processing method as (input) nodata values for ( int i = 0; i < ySize; ++i ) { if ( p ) { p->setValue( i ); } if ( p && p->wasCanceled() ) { break; } if ( i == 0 ) { //fill scanline 1 with (input) nodata for the values above the first row and feed scanline2 with the first row for ( int a = 0; a < xSize; ++a ) { scanLine1[a] = mInputNodataValue; } GDALRasterIO( rasterBand, GF_Read, 0, 0, xSize, 1, scanLine2, xSize, 1, GDT_Float32, 0, 0 ); } else { //normally fetch only scanLine3 and release scanline 1 if we move forward one row CPLFree( scanLine1 ); scanLine1 = scanLine2; scanLine2 = scanLine3; scanLine3 = ( float * ) CPLMalloc( sizeof( float ) * xSize ); } if ( i == ySize - 1 ) //fill the row below the bottom with nodata values { for ( int a = 0; a < xSize; ++a ) { scanLine3[a] = mInputNodataValue; } } else { GDALRasterIO( rasterBand, GF_Read, 0, i + 1, xSize, 1, scanLine3, xSize, 1, GDT_Float32, 0, 0 ); } for ( int j = 0; j < xSize; ++j ) { if ( j == 0 ) { resultLine[j] = processNineCellWindow( &mInputNodataValue, &scanLine1[j], &scanLine1[j+1], &mInputNodataValue, &scanLine2[j], \ &scanLine2[j+1], &mInputNodataValue, &scanLine3[j], &scanLine3[j+1] ); } else if ( j == xSize - 1 ) { resultLine[j] = processNineCellWindow( &scanLine1[j-1], &scanLine1[j], &mInputNodataValue, &scanLine2[j-1], &scanLine2[j], \ &mInputNodataValue, &scanLine3[j-1], &scanLine3[j], &mInputNodataValue ); } else { resultLine[j] = processNineCellWindow( &scanLine1[j-1], &scanLine1[j], &scanLine1[j+1], &scanLine2[j-1], &scanLine2[j], \ &scanLine2[j+1], &scanLine3[j-1], &scanLine3[j], &scanLine3[j+1] ); } } GDALRasterIO( outputRasterBand, GF_Write, 0, i, xSize, 1, resultLine, xSize, 1, GDT_Float32, 0, 0 ); } if ( p ) { p->setValue( ySize ); } CPLFree( resultLine ); CPLFree( scanLine1 ); CPLFree( scanLine2 ); CPLFree( scanLine3 ); GDALClose( inputDataset ); if ( p && p->wasCanceled() ) { //delete the dataset without closing (because it is faster) GDALDeleteDataset( outputDriver, mOutputFile.toLocal8Bit().data() ); return 7; } GDALClose( outputDataset ); return 0; }
int QgsZonalStatistics::calculateStatistics( QProgressDialog* p ) { if ( !mPolygonLayer || mPolygonLayer->geometryType() != QGis::Polygon ) { return 1; } QgsVectorDataProvider* vectorProvider = mPolygonLayer->dataProvider(); if ( !vectorProvider ) { return 2; } //open the raster layer and the raster band GDALAllRegister(); GDALDatasetH inputDataset = GDALOpen( TO8F( mRasterFilePath ), GA_ReadOnly ); if ( !inputDataset ) { return 3; } if ( GDALGetRasterCount( inputDataset ) < ( mRasterBand - 1 ) ) { GDALClose( inputDataset ); return 4; } GDALRasterBandH rasterBand = GDALGetRasterBand( inputDataset, mRasterBand ); if ( !rasterBand ) { GDALClose( inputDataset ); return 5; } mInputNodataValue = GDALGetRasterNoDataValue( rasterBand, nullptr ); //get geometry info about raster layer int nCellsXGDAL = GDALGetRasterXSize( inputDataset ); int nCellsYGDAL = GDALGetRasterYSize( inputDataset ); double geoTransform[6]; if ( GDALGetGeoTransform( inputDataset, geoTransform ) != CE_None ) { GDALClose( inputDataset ); return 6; } double cellsizeX = geoTransform[1]; if ( cellsizeX < 0 ) { cellsizeX = -cellsizeX; } double cellsizeY = geoTransform[5]; if ( cellsizeY < 0 ) { cellsizeY = -cellsizeY; } QgsRectangle rasterBBox( geoTransform[0], geoTransform[3] - ( nCellsYGDAL * cellsizeY ), geoTransform[0] + ( nCellsXGDAL * cellsizeX ), geoTransform[3] ); //add the new fields to the provider QList<QgsField> newFieldList; QString countFieldName; if ( mStatistics & QgsZonalStatistics::Count ) { countFieldName = getUniqueFieldName( mAttributePrefix + "count" ); QgsField countField( countFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( countField ); } QString sumFieldName; if ( mStatistics & QgsZonalStatistics::Sum ) { sumFieldName = getUniqueFieldName( mAttributePrefix + "sum" ); QgsField sumField( sumFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( sumField ); } QString meanFieldName; if ( mStatistics & QgsZonalStatistics::Mean ) { meanFieldName = getUniqueFieldName( mAttributePrefix + "mean" ); QgsField meanField( meanFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( meanField ); } QString medianFieldName; if ( mStatistics & QgsZonalStatistics::Median ) { medianFieldName = getUniqueFieldName( mAttributePrefix + "median" ); QgsField medianField( medianFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( medianField ); } QString stdevFieldName; if ( mStatistics & QgsZonalStatistics::StDev ) { stdevFieldName = getUniqueFieldName( mAttributePrefix + "stdev" ); QgsField stdField( stdevFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( stdField ); } QString minFieldName; if ( mStatistics & QgsZonalStatistics::Min ) { minFieldName = getUniqueFieldName( mAttributePrefix + "min" ); QgsField minField( minFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( minField ); } QString maxFieldName; if ( mStatistics & QgsZonalStatistics::Max ) { maxFieldName = getUniqueFieldName( mAttributePrefix + "max" ); QgsField maxField( maxFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( maxField ); } QString rangeFieldName; if ( mStatistics & QgsZonalStatistics::Range ) { rangeFieldName = getUniqueFieldName( mAttributePrefix + "range" ); QgsField rangeField( rangeFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( rangeField ); } QString minorityFieldName; if ( mStatistics & QgsZonalStatistics::Minority ) { minorityFieldName = getUniqueFieldName( mAttributePrefix + "minority" ); QgsField minorityField( minorityFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( minorityField ); } QString majorityFieldName; if ( mStatistics & QgsZonalStatistics::Majority ) { majorityFieldName = getUniqueFieldName( mAttributePrefix + "majority" ); QgsField majField( majorityFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( majField ); } QString varietyFieldName; if ( mStatistics & QgsZonalStatistics::Variety ) { varietyFieldName = getUniqueFieldName( mAttributePrefix + "variety" ); QgsField varietyField( varietyFieldName, QVariant::Int, "int" ); newFieldList.push_back( varietyField ); } vectorProvider->addAttributes( newFieldList ); //index of the new fields int countIndex = mStatistics & QgsZonalStatistics::Count ? vectorProvider->fieldNameIndex( countFieldName ) : -1; int sumIndex = mStatistics & QgsZonalStatistics::Sum ? vectorProvider->fieldNameIndex( sumFieldName ) : -1; int meanIndex = mStatistics & QgsZonalStatistics::Mean ? vectorProvider->fieldNameIndex( meanFieldName ) : -1; int medianIndex = mStatistics & QgsZonalStatistics::Median ? vectorProvider->fieldNameIndex( medianFieldName ) : -1; int stdevIndex = mStatistics & QgsZonalStatistics::StDev ? vectorProvider->fieldNameIndex( stdevFieldName ) : -1; int minIndex = mStatistics & QgsZonalStatistics::Min ? vectorProvider->fieldNameIndex( minFieldName ) : -1; int maxIndex = mStatistics & QgsZonalStatistics::Max ? vectorProvider->fieldNameIndex( maxFieldName ) : -1; int rangeIndex = mStatistics & QgsZonalStatistics::Range ? vectorProvider->fieldNameIndex( rangeFieldName ) : -1; int minorityIndex = mStatistics & QgsZonalStatistics::Minority ? vectorProvider->fieldNameIndex( minorityFieldName ) : -1; int majorityIndex = mStatistics & QgsZonalStatistics::Majority ? vectorProvider->fieldNameIndex( majorityFieldName ) : -1; int varietyIndex = mStatistics & QgsZonalStatistics::Variety ? vectorProvider->fieldNameIndex( varietyFieldName ) : -1; if (( mStatistics & QgsZonalStatistics::Count && countIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Sum && sumIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Mean && meanIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Median && medianIndex == -1 ) || ( mStatistics & QgsZonalStatistics::StDev && stdevIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Min && minIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Max && maxIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Range && rangeIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Minority && minorityIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Majority && majorityIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Variety && varietyIndex == -1 ) ) { //failed to create a required field return 8; } //progress dialog long featureCount = vectorProvider->featureCount(); if ( p ) { p->setMaximum( featureCount ); } //iterate over each polygon QgsFeatureRequest request; request.setSubsetOfAttributes( QgsAttributeList() ); QgsFeatureIterator fi = vectorProvider->getFeatures( request ); QgsFeature f; bool statsStoreValues = ( mStatistics & QgsZonalStatistics::Median ) || ( mStatistics & QgsZonalStatistics::StDev ); bool statsStoreValueCount = ( mStatistics & QgsZonalStatistics::Minority ) || ( mStatistics & QgsZonalStatistics::Majority ); FeatureStats featureStats( statsStoreValues, statsStoreValueCount ); int featureCounter = 0; QgsChangedAttributesMap changeMap; while ( fi.nextFeature( f ) ) { if ( p ) { p->setValue( featureCounter ); } if ( p && p->wasCanceled() ) { break; } if ( !f.constGeometry() ) { ++featureCounter; continue; } const QgsGeometry* featureGeometry = f.constGeometry(); QgsRectangle featureRect = featureGeometry->boundingBox().intersect( &rasterBBox ); if ( featureRect.isEmpty() ) { ++featureCounter; continue; } int offsetX, offsetY, nCellsX, nCellsY; if ( cellInfoForBBox( rasterBBox, featureRect, cellsizeX, cellsizeY, offsetX, offsetY, nCellsX, nCellsY ) != 0 ) { ++featureCounter; continue; } //avoid access to cells outside of the raster (may occur because of rounding) if (( offsetX + nCellsX ) > nCellsXGDAL ) { nCellsX = nCellsXGDAL - offsetX; } if (( offsetY + nCellsY ) > nCellsYGDAL ) { nCellsY = nCellsYGDAL - offsetY; } statisticsFromMiddlePointTest( rasterBand, featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY, rasterBBox, featureStats ); if ( featureStats.count <= 1 ) { //the cell resolution is probably larger than the polygon area. We switch to precise pixel - polygon intersection in this case statisticsFromPreciseIntersection( rasterBand, featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY, rasterBBox, featureStats ); } //write the statistics value to the vector data provider QgsAttributeMap changeAttributeMap; if ( mStatistics & QgsZonalStatistics::Count ) changeAttributeMap.insert( countIndex, QVariant( featureStats.count ) ); if ( mStatistics & QgsZonalStatistics::Sum ) changeAttributeMap.insert( sumIndex, QVariant( featureStats.sum ) ); if ( featureStats.count > 0 ) { double mean = featureStats.sum / featureStats.count; if ( mStatistics & QgsZonalStatistics::Mean ) changeAttributeMap.insert( meanIndex, QVariant( mean ) ); if ( mStatistics & QgsZonalStatistics::Median ) { qSort( featureStats.values.begin(), featureStats.values.end() ); int size = featureStats.values.count(); bool even = ( size % 2 ) < 1; double medianValue; if ( even ) { medianValue = ( featureStats.values.at( size / 2 - 1 ) + featureStats.values.at( size / 2 ) ) / 2; } else //odd { medianValue = featureStats.values.at(( size + 1 ) / 2 - 1 ); } changeAttributeMap.insert( medianIndex, QVariant( medianValue ) ); } if ( mStatistics & QgsZonalStatistics::StDev ) { double sumSquared = 0; for ( int i = 0; i < featureStats.values.count(); ++i ) { double diff = featureStats.values.at( i ) - mean; sumSquared += diff * diff; } double stdev = qPow( sumSquared / featureStats.values.count(), 0.5 ); changeAttributeMap.insert( stdevIndex, QVariant( stdev ) ); } if ( mStatistics & QgsZonalStatistics::Min ) changeAttributeMap.insert( minIndex, QVariant( featureStats.min ) ); if ( mStatistics & QgsZonalStatistics::Max ) changeAttributeMap.insert( maxIndex, QVariant( featureStats.max ) ); if ( mStatistics & QgsZonalStatistics::Range ) changeAttributeMap.insert( rangeIndex, QVariant( featureStats.max - featureStats.min ) ); if ( mStatistics & QgsZonalStatistics::Minority || mStatistics & QgsZonalStatistics::Majority ) { QList<int> vals = featureStats.valueCount.values(); qSort( vals.begin(), vals.end() ); if ( mStatistics & QgsZonalStatistics::Minority ) { float minorityKey = featureStats.valueCount.key( vals.first() ); changeAttributeMap.insert( minorityIndex, QVariant( minorityKey ) ); } if ( mStatistics & QgsZonalStatistics::Majority ) { float majKey = featureStats.valueCount.key( vals.last() ); changeAttributeMap.insert( majorityIndex, QVariant( majKey ) ); } } if ( mStatistics & QgsZonalStatistics::Variety ) changeAttributeMap.insert( varietyIndex, QVariant( featureStats.valueCount.count() ) ); } changeMap.insert( f.id(), changeAttributeMap ); ++featureCounter; } vectorProvider->changeAttributeValues( changeMap ); if ( p ) { p->setValue( featureCount ); } GDALClose( inputDataset ); mPolygonLayer->updateFields(); if ( p && p->wasCanceled() ) { return 9; } return 0; }
bool QgsImageWarper::createDestinationDataset( const QString &outputName, GDALDatasetH hSrcDS, GDALDatasetH &hDstDS, uint resX, uint resY, double *adfGeoTransform, bool useZeroAsTrans, const QString& compression, const QString &projection ) { // create the output file GDALDriverH driver = GDALGetDriverByName( "GTiff" ); if ( !driver ) { return false; } char **papszOptions = NULL; papszOptions = CSLSetNameValue( papszOptions, "COMPRESS", compression.toAscii() ); hDstDS = GDALCreate( driver, QFile::encodeName( outputName ).constData(), resX, resY, GDALGetRasterCount( hSrcDS ), GDALGetRasterDataType( GDALGetRasterBand( hSrcDS, 1 ) ), papszOptions ); if ( !hDstDS ) { return false; } if ( CE_None != GDALSetGeoTransform( hDstDS, adfGeoTransform ) ) { return false; } if ( !projection.isEmpty() ) { OGRSpatialReference oTargetSRS; if ( projection.startsWith( "EPSG", Qt::CaseInsensitive ) ) { QString epsg = projection.mid( projection.indexOf( ":" ) + 1 ); oTargetSRS.importFromEPSG( epsg.toInt() ); } else { oTargetSRS.importFromProj4( projection.toLatin1().data() ); } char *wkt = NULL; OGRErr err = oTargetSRS.exportToWkt( &wkt ); if ( err != CE_None || GDALSetProjection( hDstDS, wkt ) != CE_None ) { OGRFree( wkt ); return false; } OGRFree( wkt ); } for ( int i = 0; i < GDALGetRasterCount( hSrcDS ); ++i ) { GDALRasterBandH hSrcBand = GDALGetRasterBand( hSrcDS, i + 1 ); GDALRasterBandH hDstBand = GDALGetRasterBand( hDstDS, i + 1 ); GDALColorTableH cTable = GDALGetRasterColorTable( hSrcBand ); GDALSetRasterColorInterpretation( hDstBand, GDALGetRasterColorInterpretation( hSrcBand ) ); if ( cTable ) { GDALSetRasterColorTable( hDstBand, cTable ); } int success; double noData = GDALGetRasterNoDataValue( hSrcBand, &success ); if ( success ) { GDALSetRasterNoDataValue( hDstBand, noData ); } else if ( useZeroAsTrans ) { GDALSetRasterNoDataValue( hDstBand, 0 ); } } return true; }
int main( int argc, char ** argv ) { GDALDatasetH hDataset; GDALRasterBandH hBand; int i, iBand; double adfGeoTransform[6]; GDALDriverH hDriver; char **papszMetadata; int bComputeMinMax = FALSE, bSample = FALSE; int bShowGCPs = TRUE, bShowMetadata = TRUE, bShowRAT=TRUE; int bStats = FALSE, bApproxStats = TRUE, iMDD; int bShowColorTable = TRUE, bComputeChecksum = FALSE; int bReportHistograms = FALSE; const char *pszFilename = NULL; char **papszExtraMDDomains = NULL, **papszFileList; const char *pszProjection = NULL; OGRCoordinateTransformationH hTransform = NULL; /* Check that we are running against at least GDAL 1.5 */ /* Note to developers : if we use newer API, please change the requirement */ if (atoi(GDALVersionInfo("VERSION_NUM")) < 1500) { fprintf(stderr, "At least, GDAL >= 1.5.0 is required for this version of %s, " "which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME); exit(1); } /* Must process GDAL_SKIP before GDALAllRegister(), but we can't call */ /* GDALGeneralCmdLineProcessor before it needs the drivers to be registered */ /* for the --format or --formats options */ for( i = 1; i < argc; i++ ) { if( EQUAL(argv[i],"--config") && i + 2 < argc && EQUAL(argv[i + 1], "GDAL_SKIP") ) { CPLSetConfigOption( argv[i+1], argv[i+2] ); i += 2; } } GDALAllRegister(); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); /* -------------------------------------------------------------------- */ /* Parse arguments. */ /* -------------------------------------------------------------------- */ for( i = 1; i < argc; i++ ) { if( EQUAL(argv[i], "--utility_version") ) { printf("%s was compiled against GDAL %s and is running against GDAL %s\n", argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); return 0; } else if( EQUAL(argv[i], "-mm") ) bComputeMinMax = TRUE; else if( EQUAL(argv[i], "-hist") ) bReportHistograms = TRUE; else if( EQUAL(argv[i], "-stats") ) { bStats = TRUE; bApproxStats = FALSE; } else if( EQUAL(argv[i], "-approx_stats") ) { bStats = TRUE; bApproxStats = TRUE; } else if( EQUAL(argv[i], "-sample") ) bSample = TRUE; else if( EQUAL(argv[i], "-checksum") ) bComputeChecksum = TRUE; else if( EQUAL(argv[i], "-nogcp") ) bShowGCPs = FALSE; else if( EQUAL(argv[i], "-nomd") ) bShowMetadata = FALSE; else if( EQUAL(argv[i], "-norat") ) bShowRAT = FALSE; else if( EQUAL(argv[i], "-noct") ) bShowColorTable = FALSE; else if( EQUAL(argv[i], "-mdd") && i < argc-1 ) papszExtraMDDomains = CSLAddString( papszExtraMDDomains, argv[++i] ); else if( argv[i][0] == '-' ) Usage(); else if( pszFilename == NULL ) pszFilename = argv[i]; else Usage(); } if( pszFilename == NULL ) Usage(); /* -------------------------------------------------------------------- */ /* Open dataset. */ /* -------------------------------------------------------------------- */ hDataset = GDALOpen( pszFilename, GA_ReadOnly ); if( hDataset == NULL ) { fprintf( stderr, "gdalinfo failed - unable to open '%s'.\n", pszFilename ); CSLDestroy( argv ); GDALDumpOpenDatasets( stderr ); GDALDestroyDriverManager(); CPLDumpSharedList( NULL ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Report general info. */ /* -------------------------------------------------------------------- */ hDriver = GDALGetDatasetDriver( hDataset ); printf( "Driver: %s/%s\n", GDALGetDriverShortName( hDriver ), GDALGetDriverLongName( hDriver ) ); papszFileList = GDALGetFileList( hDataset ); if( CSLCount(papszFileList) == 0 ) { printf( "Files: none associated\n" ); } else { printf( "Files: %s\n", papszFileList[0] ); for( i = 1; papszFileList[i] != NULL; i++ ) printf( " %s\n", papszFileList[i] ); } CSLDestroy( papszFileList ); printf( "Size is %d, %d\n", GDALGetRasterXSize( hDataset ), GDALGetRasterYSize( hDataset ) ); /* -------------------------------------------------------------------- */ /* Report projection. */ /* -------------------------------------------------------------------- */ if( GDALGetProjectionRef( hDataset ) != NULL ) { OGRSpatialReferenceH hSRS; char *pszProjection; pszProjection = (char *) GDALGetProjectionRef( hDataset ); hSRS = OSRNewSpatialReference(NULL); if( OSRImportFromWkt( hSRS, &pszProjection ) == CE_None ) { char *pszPrettyWkt = NULL; OSRExportToPrettyWkt( hSRS, &pszPrettyWkt, FALSE ); printf( "Coordinate System is:\n%s\n", pszPrettyWkt ); CPLFree( pszPrettyWkt ); } else printf( "Coordinate System is `%s'\n", GDALGetProjectionRef( hDataset ) ); OSRDestroySpatialReference( hSRS ); } /* -------------------------------------------------------------------- */ /* Report Geotransform. */ /* -------------------------------------------------------------------- */ if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None ) { if( adfGeoTransform[2] == 0.0 && adfGeoTransform[4] == 0.0 ) { printf( "Origin = (%.15f,%.15f)\n", adfGeoTransform[0], adfGeoTransform[3] ); printf( "Pixel Size = (%.15f,%.15f)\n", adfGeoTransform[1], adfGeoTransform[5] ); } else printf( "GeoTransform =\n" " %.16g, %.16g, %.16g\n" " %.16g, %.16g, %.16g\n", adfGeoTransform[0], adfGeoTransform[1], adfGeoTransform[2], adfGeoTransform[3], adfGeoTransform[4], adfGeoTransform[5] ); } /* -------------------------------------------------------------------- */ /* Report GCPs. */ /* -------------------------------------------------------------------- */ if( bShowGCPs && GDALGetGCPCount( hDataset ) > 0 ) { if (GDALGetGCPProjection(hDataset) != NULL) { OGRSpatialReferenceH hSRS; char *pszProjection; pszProjection = (char *) GDALGetGCPProjection( hDataset ); hSRS = OSRNewSpatialReference(NULL); if( OSRImportFromWkt( hSRS, &pszProjection ) == CE_None ) { char *pszPrettyWkt = NULL; OSRExportToPrettyWkt( hSRS, &pszPrettyWkt, FALSE ); printf( "GCP Projection = \n%s\n", pszPrettyWkt ); CPLFree( pszPrettyWkt ); } else printf( "GCP Projection = %s\n", GDALGetGCPProjection( hDataset ) ); OSRDestroySpatialReference( hSRS ); } for( i = 0; i < GDALGetGCPCount(hDataset); i++ ) { const GDAL_GCP *psGCP; psGCP = GDALGetGCPs( hDataset ) + i; printf( "GCP[%3d]: Id=%s, Info=%s\n" " (%.15g,%.15g) -> (%.15g,%.15g,%.15g)\n", i, psGCP->pszId, psGCP->pszInfo, psGCP->dfGCPPixel, psGCP->dfGCPLine, psGCP->dfGCPX, psGCP->dfGCPY, psGCP->dfGCPZ ); } } /* -------------------------------------------------------------------- */ /* Report metadata. */ /* -------------------------------------------------------------------- */ papszMetadata = (bShowMetadata) ? GDALGetMetadata( hDataset, NULL ) : NULL; if( bShowMetadata && CSLCount(papszMetadata) > 0 ) { printf( "Metadata:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } for( iMDD = 0; bShowMetadata && iMDD < CSLCount(papszExtraMDDomains); iMDD++ ) { papszMetadata = GDALGetMetadata( hDataset, papszExtraMDDomains[iMDD] ); if( CSLCount(papszMetadata) > 0 ) { printf( "Metadata (%s):\n", papszExtraMDDomains[iMDD]); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } } /* -------------------------------------------------------------------- */ /* Report "IMAGE_STRUCTURE" metadata. */ /* -------------------------------------------------------------------- */ papszMetadata = (bShowMetadata) ? GDALGetMetadata( hDataset, "IMAGE_STRUCTURE" ) : NULL; if( bShowMetadata && CSLCount(papszMetadata) > 0 ) { printf( "Image Structure Metadata:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } /* -------------------------------------------------------------------- */ /* Report subdatasets. */ /* -------------------------------------------------------------------- */ papszMetadata = GDALGetMetadata( hDataset, "SUBDATASETS" ); if( CSLCount(papszMetadata) > 0 ) { printf( "Subdatasets:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } /* -------------------------------------------------------------------- */ /* Report geolocation. */ /* -------------------------------------------------------------------- */ papszMetadata = (bShowMetadata) ? GDALGetMetadata( hDataset, "GEOLOCATION" ) : NULL; if( bShowMetadata && CSLCount(papszMetadata) > 0 ) { printf( "Geolocation:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } /* -------------------------------------------------------------------- */ /* Report RPCs */ /* -------------------------------------------------------------------- */ papszMetadata = (bShowMetadata) ? GDALGetMetadata( hDataset, "RPC" ) : NULL; if( bShowMetadata && CSLCount(papszMetadata) > 0 ) { printf( "RPC Metadata:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } /* -------------------------------------------------------------------- */ /* Setup projected to lat/long transform if appropriate. */ /* -------------------------------------------------------------------- */ if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None ) pszProjection = GDALGetProjectionRef(hDataset); if( pszProjection != NULL && strlen(pszProjection) > 0 ) { OGRSpatialReferenceH hProj, hLatLong = NULL; hProj = OSRNewSpatialReference( pszProjection ); if( hProj != NULL ) hLatLong = OSRCloneGeogCS( hProj ); if( hLatLong != NULL ) { CPLPushErrorHandler( CPLQuietErrorHandler ); hTransform = OCTNewCoordinateTransformation( hProj, hLatLong ); CPLPopErrorHandler(); OSRDestroySpatialReference( hLatLong ); } if( hProj != NULL ) OSRDestroySpatialReference( hProj ); } /* -------------------------------------------------------------------- */ /* Report corners. */ /* -------------------------------------------------------------------- */ printf( "Corner Coordinates:\n" ); GDALInfoReportCorner( hDataset, hTransform, "Upper Left", 0.0, 0.0 ); GDALInfoReportCorner( hDataset, hTransform, "Lower Left", 0.0, GDALGetRasterYSize(hDataset)); GDALInfoReportCorner( hDataset, hTransform, "Upper Right", GDALGetRasterXSize(hDataset), 0.0 ); GDALInfoReportCorner( hDataset, hTransform, "Lower Right", GDALGetRasterXSize(hDataset), GDALGetRasterYSize(hDataset) ); GDALInfoReportCorner( hDataset, hTransform, "Center", GDALGetRasterXSize(hDataset)/2.0, GDALGetRasterYSize(hDataset)/2.0 ); if( hTransform != NULL ) { OCTDestroyCoordinateTransformation( hTransform ); hTransform = NULL; } /* ==================================================================== */ /* Loop over bands. */ /* ==================================================================== */ for( iBand = 0; iBand < GDALGetRasterCount( hDataset ); iBand++ ) { double dfMin, dfMax, adfCMinMax[2], dfNoData; int bGotMin, bGotMax, bGotNodata, bSuccess; int nBlockXSize, nBlockYSize, nMaskFlags; double dfMean, dfStdDev; GDALColorTableH hTable; CPLErr eErr; hBand = GDALGetRasterBand( hDataset, iBand+1 ); if( bSample ) { float afSample[10000]; int nCount; nCount = GDALGetRandomRasterSample( hBand, 10000, afSample ); printf( "Got %d samples.\n", nCount ); } GDALGetBlockSize( hBand, &nBlockXSize, &nBlockYSize ); printf( "Band %d Block=%dx%d Type=%s, ColorInterp=%s\n", iBand+1, nBlockXSize, nBlockYSize, GDALGetDataTypeName( GDALGetRasterDataType(hBand)), GDALGetColorInterpretationName( GDALGetRasterColorInterpretation(hBand)) ); if( GDALGetDescription( hBand ) != NULL && strlen(GDALGetDescription( hBand )) > 0 ) printf( " Description = %s\n", GDALGetDescription(hBand) ); dfMin = GDALGetRasterMinimum( hBand, &bGotMin ); dfMax = GDALGetRasterMaximum( hBand, &bGotMax ); if( bGotMin || bGotMax || bComputeMinMax ) { printf( " " ); if( bGotMin ) printf( "Min=%.3f ", dfMin ); if( bGotMax ) printf( "Max=%.3f ", dfMax ); if( bComputeMinMax ) { CPLErrorReset(); GDALComputeRasterMinMax( hBand, FALSE, adfCMinMax ); if (CPLGetLastErrorType() == CE_None) { printf( " Computed Min/Max=%.3f,%.3f", adfCMinMax[0], adfCMinMax[1] ); } } printf( "\n" ); } eErr = GDALGetRasterStatistics( hBand, bApproxStats, bStats, &dfMin, &dfMax, &dfMean, &dfStdDev ); if( eErr == CE_None ) { printf( " Minimum=%.3f, Maximum=%.3f, Mean=%.3f, StdDev=%.3f\n", dfMin, dfMax, dfMean, dfStdDev ); } if( bReportHistograms ) { int nBucketCount, *panHistogram = NULL; eErr = GDALGetDefaultHistogram( hBand, &dfMin, &dfMax, &nBucketCount, &panHistogram, TRUE, GDALTermProgress, NULL ); if( eErr == CE_None ) { int iBucket; printf( " %d buckets from %g to %g:\n ", nBucketCount, dfMin, dfMax ); for( iBucket = 0; iBucket < nBucketCount; iBucket++ ) printf( "%d ", panHistogram[iBucket] ); printf( "\n" ); CPLFree( panHistogram ); } } if ( bComputeChecksum) { printf( " Checksum=%d\n", GDALChecksumImage(hBand, 0, 0, GDALGetRasterXSize(hDataset), GDALGetRasterYSize(hDataset))); } dfNoData = GDALGetRasterNoDataValue( hBand, &bGotNodata ); if( bGotNodata ) { printf( " NoData Value=%.18g\n", dfNoData ); } if( GDALGetOverviewCount(hBand) > 0 ) { int iOverview; printf( " Overviews: " ); for( iOverview = 0; iOverview < GDALGetOverviewCount(hBand); iOverview++ ) { GDALRasterBandH hOverview; const char *pszResampling = NULL; if( iOverview != 0 ) printf( ", " ); hOverview = GDALGetOverview( hBand, iOverview ); printf( "%dx%d", GDALGetRasterBandXSize( hOverview ), GDALGetRasterBandYSize( hOverview ) ); pszResampling = GDALGetMetadataItem( hOverview, "RESAMPLING", "" ); if( pszResampling != NULL && EQUALN(pszResampling,"AVERAGE_BIT2",12) ) printf( "*" ); } printf( "\n" ); if ( bComputeChecksum) { printf( " Overviews checksum: " ); for( iOverview = 0; iOverview < GDALGetOverviewCount(hBand); iOverview++ ) { GDALRasterBandH hOverview; if( iOverview != 0 ) printf( ", " ); hOverview = GDALGetOverview( hBand, iOverview ); printf( "%d", GDALChecksumImage(hOverview, 0, 0, GDALGetRasterBandXSize(hOverview), GDALGetRasterBandYSize(hOverview))); } printf( "\n" ); } } if( GDALHasArbitraryOverviews( hBand ) ) { printf( " Overviews: arbitrary\n" ); } nMaskFlags = GDALGetMaskFlags( hBand ); if( (nMaskFlags & (GMF_NODATA|GMF_ALL_VALID)) == 0 ) { GDALRasterBandH hMaskBand = GDALGetMaskBand(hBand) ; printf( " Mask Flags: " ); if( nMaskFlags & GMF_PER_DATASET ) printf( "PER_DATASET " ); if( nMaskFlags & GMF_ALPHA ) printf( "ALPHA " ); if( nMaskFlags & GMF_NODATA ) printf( "NODATA " ); if( nMaskFlags & GMF_ALL_VALID ) printf( "ALL_VALID " ); printf( "\n" ); if( hMaskBand != NULL && GDALGetOverviewCount(hMaskBand) > 0 ) { int iOverview; printf( " Overviews of mask band: " ); for( iOverview = 0; iOverview < GDALGetOverviewCount(hMaskBand); iOverview++ ) { GDALRasterBandH hOverview; if( iOverview != 0 ) printf( ", " ); hOverview = GDALGetOverview( hMaskBand, iOverview ); printf( "%dx%d", GDALGetRasterBandXSize( hOverview ), GDALGetRasterBandYSize( hOverview ) ); } printf( "\n" ); } } if( strlen(GDALGetRasterUnitType(hBand)) > 0 ) { printf( " Unit Type: %s\n", GDALGetRasterUnitType(hBand) ); } if( GDALGetRasterCategoryNames(hBand) != NULL ) { char **papszCategories = GDALGetRasterCategoryNames(hBand); int i; printf( " Categories:\n" ); for( i = 0; papszCategories[i] != NULL; i++ ) printf( " %3d: %s\n", i, papszCategories[i] ); } if( GDALGetRasterScale( hBand, &bSuccess ) != 1.0 || GDALGetRasterOffset( hBand, &bSuccess ) != 0.0 ) printf( " Offset: %.15g, Scale:%.15g\n", GDALGetRasterOffset( hBand, &bSuccess ), GDALGetRasterScale( hBand, &bSuccess ) ); papszMetadata = (bShowMetadata) ? GDALGetMetadata( hBand, NULL ) : NULL; if( bShowMetadata && CSLCount(papszMetadata) > 0 ) { printf( " Metadata:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } papszMetadata = (bShowMetadata) ? GDALGetMetadata( hBand, "IMAGE_STRUCTURE" ) : NULL; if( bShowMetadata && CSLCount(papszMetadata) > 0 ) { printf( " Image Structure Metadata:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } if( GDALGetRasterColorInterpretation(hBand) == GCI_PaletteIndex && (hTable = GDALGetRasterColorTable( hBand )) != NULL ) { int i; printf( " Color Table (%s with %d entries)\n", GDALGetPaletteInterpretationName( GDALGetPaletteInterpretation( hTable )), GDALGetColorEntryCount( hTable ) ); if (bShowColorTable) { for( i = 0; i < GDALGetColorEntryCount( hTable ); i++ ) { GDALColorEntry sEntry; GDALGetColorEntryAsRGB( hTable, i, &sEntry ); printf( " %3d: %d,%d,%d,%d\n", i, sEntry.c1, sEntry.c2, sEntry.c3, sEntry.c4 ); } } } if( bShowRAT && GDALGetDefaultRAT( hBand ) != NULL ) { GDALRasterAttributeTableH hRAT = GDALGetDefaultRAT( hBand ); GDALRATDumpReadable( hRAT, NULL ); } } GDALClose( hDataset ); CSLDestroy( papszExtraMDDomains ); CSLDestroy( argv ); GDALDumpOpenDatasets( stderr ); GDALDestroyDriverManager(); CPLDumpSharedList( NULL ); CPLCleanupTLS(); exit( 0 ); }
void toprsGadlReader::computeMinMax() { toprs_uint32 bands = GDALGetRasterCount(theDataset); if(theMinPixValues) { delete [] theMinPixValues; theMinPixValues = 0; } if(theMaxPixValues) { delete [] theMaxPixValues; theMaxPixValues = 0; } if(theNullPixValues) { delete [] theNullPixValues; theNullPixValues = 0; } if(isIndexTo3Band()) { int i = 0; theMinPixValues = new double[3]; theMaxPixValues = new double[3]; theNullPixValues = new double[3]; for(i = 0; i < 3; ++i) { theMinPixValues[i] = 1; theMaxPixValues[i] = 255; theNullPixValues[i] = 0; } } else if(isIndexTo1Band()) { theMinPixValues = new double[1]; theMaxPixValues = new double[1]; theNullPixValues = new double[1]; *theNullPixValues = 0; *theMaxPixValues = 255; *theMinPixValues = 1; } else { if(!theMinPixValues && !theMaxPixValues&&bands) { theMinPixValues = new double[bands]; theMaxPixValues = new double[bands]; theNullPixValues = new double[bands]; } for(toprs_int32 band = 0; band < (toprs_int32)bands; ++band) { GDALRasterBandH aBand=0; aBand = GDALGetRasterBand(theDataset, band+1); int minOk=1; int maxOk=1; int nullOk=1; if(aBand) { if(hasData()) { theMinPixValues[band] = theData.getMinPix(band); theMaxPixValues[band] = theData.getMaxPix(band); theNullPixValues[band] = theData.getNullPix(band); } else { std::string driverName = theDriver ? GDALGetDriverShortName( theDriver ) : ""; // Allow to rescale the image data // to the min/max values found in the raster data only // if it was not acquired with the following drivers: if ( driverName.find("JP2KAK") != std::string::npos || driverName.find("JPEG2000") != std::string::npos|| driverName.find("NITF") != std::string::npos) { theMinPixValues[band] = toprs::defaultMin(getOutputScalarType()); theMaxPixValues[band] = toprs::defaultMax(getOutputScalarType()); theNullPixValues[band] = toprs::defaultNull(getOutputScalarType()); } else { theMinPixValues[band] = GDALGetRasterMinimum(aBand, &minOk); theMaxPixValues[band] = GDALGetRasterMaximum(aBand, &maxOk); theNullPixValues[band] = GDALGetRasterNoDataValue(aBand, &nullOk); } if((!nullOk)||(theNullPixValues[band] < toprs::defaultNull(getOutputScalarType()))) { theNullPixValues[band] = toprs::defaultNull(getOutputScalarType()); } } if(!minOk||!maxOk) { theMinPixValues[band] = toprs::defaultMin(getOutputScalarType()); theMaxPixValues[band] = toprs::defaultMax(getOutputScalarType()); } } else { theMinPixValues[band] = toprs::defaultMin(getOutputScalarType()); theMaxPixValues[band] = toprs::defaultMax(getOutputScalarType()); } } } }
/** * GDALReprojectImage() method with a ChunkAndWarpImage replaced with ChunkAndWarpMulti */ CPLErr GDALReprojectImageMulti( GDALDatasetH hSrcDS, const char *pszSrcWKT, GDALDatasetH hDstDS, const char *pszDstWKT, GDALResampleAlg eResampleAlg, double dfWarpMemoryLimit, double dfMaxError, GDALProgressFunc pfnProgress, void *pProgressArg, GDALWarpOptions *psOptions ) { GDALWarpOptions *psWOptions; /* -------------------------------------------------------------------- */ /* Setup a reprojection based transformer. */ /* -------------------------------------------------------------------- */ void *hTransformArg; hTransformArg = GDALCreateGenImgProjTransformer( hSrcDS, pszSrcWKT, hDstDS, pszDstWKT, TRUE, 1000.0, 0 ); if( hTransformArg == NULL ) return CE_Failure; /* -------------------------------------------------------------------- */ /* Create a copy of the user provided options, or a defaulted */ /* options structure. */ /* -------------------------------------------------------------------- */ if( psOptions == NULL ) psWOptions = GDALCreateWarpOptions(); else psWOptions = GDALCloneWarpOptions( psOptions ); psWOptions->eResampleAlg = eResampleAlg; /* -------------------------------------------------------------------- */ /* Set transform. */ /* -------------------------------------------------------------------- */ if( dfMaxError > 0.0 ) { psWOptions->pTransformerArg = GDALCreateApproxTransformer( GDALGenImgProjTransform, hTransformArg, dfMaxError ); psWOptions->pfnTransformer = GDALApproxTransform; } else { psWOptions->pfnTransformer = GDALGenImgProjTransform; psWOptions->pTransformerArg = hTransformArg; } /* -------------------------------------------------------------------- */ /* Set file and band mapping. */ /* -------------------------------------------------------------------- */ int iBand; psWOptions->hSrcDS = hSrcDS; psWOptions->hDstDS = hDstDS; if( psWOptions->nBandCount == 0 ) { psWOptions->nBandCount = MIN(GDALGetRasterCount(hSrcDS), GDALGetRasterCount(hDstDS)); psWOptions->panSrcBands = (int *) CPLMalloc(sizeof(int) * psWOptions->nBandCount); psWOptions->panDstBands = (int *) CPLMalloc(sizeof(int) * psWOptions->nBandCount); for( iBand = 0; iBand < psWOptions->nBandCount; iBand++ ) { psWOptions->panSrcBands[iBand] = iBand+1; psWOptions->panDstBands[iBand] = iBand+1; } } /* -------------------------------------------------------------------- */ /* Set source nodata values if the source dataset seems to have */ /* any. Same for target nodata values */ /* -------------------------------------------------------------------- */ for( iBand = 0; iBand < psWOptions->nBandCount; iBand++ ) { GDALRasterBandH hBand = GDALGetRasterBand( hSrcDS, iBand+1 ); int bGotNoData = FALSE; double dfNoDataValue; if (GDALGetRasterColorInterpretation(hBand) == GCI_AlphaBand) { psWOptions->nSrcAlphaBand = iBand + 1; } dfNoDataValue = GDALGetRasterNoDataValue( hBand, &bGotNoData ); if( bGotNoData ) { if( psWOptions->padfSrcNoDataReal == NULL ) { int ii; psWOptions->padfSrcNoDataReal = (double *) CPLMalloc(sizeof(double) * psWOptions->nBandCount); psWOptions->padfSrcNoDataImag = (double *) CPLMalloc(sizeof(double) * psWOptions->nBandCount); for( ii = 0; ii < psWOptions->nBandCount; ii++ ) { psWOptions->padfSrcNoDataReal[ii] = -1.1e20; psWOptions->padfSrcNoDataImag[ii] = 0.0; } } psWOptions->padfSrcNoDataReal[iBand] = dfNoDataValue; } // Deal with target band hBand = GDALGetRasterBand( hDstDS, iBand+1 ); if (hBand && GDALGetRasterColorInterpretation(hBand) == GCI_AlphaBand) { psWOptions->nDstAlphaBand = iBand + 1; } dfNoDataValue = GDALGetRasterNoDataValue( hBand, &bGotNoData ); if( bGotNoData ) { if( psWOptions->padfDstNoDataReal == NULL ) { int ii; psWOptions->padfDstNoDataReal = (double *) CPLMalloc(sizeof(double) * psWOptions->nBandCount); psWOptions->padfDstNoDataImag = (double *) CPLMalloc(sizeof(double) * psWOptions->nBandCount); for( ii = 0; ii < psWOptions->nBandCount; ii++ ) { psWOptions->padfDstNoDataReal[ii] = -1.1e20; psWOptions->padfDstNoDataImag[ii] = 0.0; } } psWOptions->padfDstNoDataReal[iBand] = dfNoDataValue; } } /* -------------------------------------------------------------------- */ /* Set the progress function. */ /* -------------------------------------------------------------------- */ if( pfnProgress != NULL ) { psWOptions->pfnProgress = pfnProgress; psWOptions->pProgressArg = pProgressArg; } /* -------------------------------------------------------------------- */ /* Create a warp options based on the options. */ /* -------------------------------------------------------------------- */ GDALWarpOperation oWarper; CPLErr eErr; eErr = oWarper.Initialize( psWOptions ); if( eErr == CE_None ) eErr = oWarper.ChunkAndWarpMulti( 0, 0, GDALGetRasterXSize(hDstDS), GDALGetRasterYSize(hDstDS) ); /* -------------------------------------------------------------------- */ /* Cleanup. */ /* -------------------------------------------------------------------- */ GDALDestroyGenImgProjTransformer( hTransformArg ); if( dfMaxError > 0.0 ) GDALDestroyApproxTransformer( psWOptions->pTransformerArg ); GDALDestroyWarpOptions( psWOptions ); return eErr; }
ral_grid_handle RAL_CALL ral_grid_create_using_GDAL(GDALDatasetH dataset, int band, ral_rectangle clip_region, double cell_size) { GDALRasterBandH hBand; GDALDataType datatype; int M, N, gd_datatype; int W, H; /* size of the full GDAL raster */ int north_up, east_up, i0, j0, i1, j1, w, h; /* the clip region (P) */ int ws, hs; /* the size of the buffer into which to rasterIO to */ CPLErr err; ral_grid *gd_s = NULL, *gd_t = NULL; double t[6] = {0,1,0,0,0,1}; /* the geotransformation P -> G */ double tx[6]; /* the inverse geotransformation G -> P */ ral_rectangle GDAL; /* boundaries of the GDAL raster */ ral_point p0, p1, p2, p3; /* locations of corners of clip region: top left, top right, bottom right, bottom left, i.e, 0,0 W',0 W',H' 0,H' */ CPLPushErrorHandler(ral_cpl_error); GDALGetGeoTransform(dataset, t); north_up = (t[2] == 0) AND (t[4] == 0); east_up = (t[1] == 0) AND (t[5] == 0); /*fprintf(stderr, "\nt is\n%f %f %f\n%f %f %f\n", t[0],t[1],t[2],t[3],t[4],t[5]);*/ W = GDALGetRasterXSize(dataset); H = GDALGetRasterYSize(dataset); /*fprintf(stderr, "cell size is %f, raster size is %i %i\n", cell_size, W, H);*/ /* test all corners to find the min & max xg and yg */ { double x, y; P2G(0, 0, t, GDAL.min.x, GDAL.min.y); GDAL.max.x = GDAL.min.x; GDAL.max.y = GDAL.min.y; P2G(0, H, t, x, y); GDAL.min.x = MIN(x, GDAL.min.x); GDAL.min.y = MIN(y, GDAL.min.y); GDAL.max.x = MAX(x, GDAL.max.x); GDAL.max.y = MAX(y, GDAL.max.y); P2G(W, H, t, x, y); GDAL.min.x = MIN(x, GDAL.min.x); GDAL.min.y = MIN(y, GDAL.min.y); GDAL.max.x = MAX(x, GDAL.max.x); GDAL.max.y = MAX(y, GDAL.max.y); P2G(W, 0, t, x, y); GDAL.min.x = MIN(x, GDAL.min.x); GDAL.min.y = MIN(y, GDAL.min.y); GDAL.max.x = MAX(x, GDAL.max.x); GDAL.max.y = MAX(y, GDAL.max.y); } /*fprintf(stderr, "clip region is %f %f %f %f\n", clip_region.min.x, clip_region.min.y, clip_region.max.x, clip_region.max.y); fprintf(stderr, "GDAL raster is %f %f %f %f\n", GDAL.min.x, GDAL.min.y, GDAL.max.x, GDAL.max.y);*/ clip_region.min.x = MAX(clip_region.min.x, GDAL.min.x); clip_region.min.y = MAX(clip_region.min.y, GDAL.min.y); clip_region.max.x = MIN(clip_region.max.x, GDAL.max.x); clip_region.max.y = MIN(clip_region.max.y, GDAL.max.y); /*fprintf(stderr, "visible region is %f %f %f %f\n", clip_region.min.x, clip_region.min.y, clip_region.max.x, clip_region.max.y);*/ RAL_CHECK((clip_region.min.x < clip_region.max.x) AND (clip_region.min.y < clip_region.max.y)); /* the inverse transformation, from georeferenced space to pixel space */ { double tmp = t[2]*t[4] - t[1]*t[5]; tx[0] = (t[0]*t[5] - t[2]*t[3])/tmp; tx[1] = -t[5]/tmp; tx[2] = t[2]/tmp; tx[3] = (t[1]*t[3] - t[0]*t[4])/tmp; tx[4] = t[4]/tmp; tx[5] = -t[1]/tmp; } /* the clip region in pixel space */ /* test all corners to find the min & max xp and yp (j0..j1, i0..i1) */ { int i, j; G2P(clip_region.min.x, clip_region.min.y, tx, j0, i0); j1 = j0; i1 = i0; G2P(clip_region.min.x, clip_region.max.y, tx, j, i); j0 = MIN(j, j0); i0 = MIN(i, i0); j1 = MAX(j, j1); i1 = MAX(i, i1); G2P(clip_region.max.x, clip_region.max.y, tx, j, i); j0 = MIN(j, j0); i0 = MIN(i, i0); j1 = MAX(j, j1); i1 = MAX(i, i1); G2P(clip_region.max.x, clip_region.min.y, tx, j, i); j0 = MIN(j, j0); i0 = MIN(i, i0); j1 = MAX(j, j1); i1 = MAX(i, i1); j0 = MAX(j0, 0); j0 = MIN(j0, W-1); j1 = MAX(j1, 0); j1 = MIN(j1, W-1); i0 = MAX(i0, 0); i0 = MIN(i0, H-1); i1 = MAX(i1, 0); i1 = MIN(i1, H-1); } w = j1 - j0 + 1; h = i1 - i0 + 1; /*fprintf(stderr, "visible region in raster is %i %i %i %i\n", j0, i0, j1, i1);*/ RAL_CHECK(w > 0 AND h > 0); /* the corners of the raster clip */ P2G(j0, i0, t, p0.x, p0.y); P2G(j1+1, i0, t, p1.x, p1.y); P2G(j1+1, i1+1, t, p2.x, p2.y); P2G(j0, i1+1, t, p3.x, p3.y); /*fprintf(stderr, "source corners: (%f,%f %f,%f %f,%f %f,%f)\n", p0.x, p0.y, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);*/ /* the width and height of the resized raster clip */ /* the resized clip has the same corner coordinates as the clip */ ws = round(sqrt((p1.x-p0.x)*(p1.x-p0.x)+(p1.y-p0.y)*(p1.y-p0.y))/cell_size); hs = round(sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y))/cell_size); /*fprintf(stderr, "clipped source size is %i, %i\n", ws, hs);*/ hBand = GDALGetRasterBand(dataset, band); RAL_CHECK(hBand); switch (GDALGetRasterDataType(hBand)) { case GDT_Byte: case GDT_UInt16: case GDT_Int16: case GDT_UInt32: case GDT_Int32: gd_datatype = RAL_INTEGER_GRID; switch (sizeof(RAL_INTEGER)) { /* hmm.. this breaks if INTEGER is unsigned */ case 1: datatype = GDT_Byte; break; case 2: datatype = GDT_Int16; break; case 4: datatype = GDT_Int32; break; default: RAL_CHECKM(0, ral_msg("Strange sizeof(INTEGER): %i",sizeof(RAL_INTEGER))); } break; case GDT_Float32: case GDT_Float64: gd_datatype = RAL_REAL_GRID; switch (sizeof(RAL_REAL)) { case 4: datatype = GDT_Float32; break; case 8: datatype = GDT_Float64; break; default: RAL_CHECKM(0, ral_msg("Strange sizeof(REAL): %i", sizeof(RAL_REAL))); } break; default: RAL_CHECKM(0, "complex data type not supported"); } /* size of the grid in display */ M = ceil(fabs(clip_region.max.y - clip_region.min.y)/cell_size); N = ceil(fabs(clip_region.max.x - clip_region.min.x)/cell_size); /*fprintf(stderr, "display size is %i, %i\n", N, M);*/ RAL_CHECK(gd_s = ral_grid_create(gd_datatype, hs, ws)); RAL_CHECK(gd_t = ral_grid_create(gd_datatype, M, N)); ral_grid_set_bounds_csnx(gd_t, cell_size, clip_region.min.x, clip_region.max.y); err = GDALRasterIO(hBand, GF_Read, j0, i0, w, h, gd_s->data, ws, hs, datatype, 0, 0); RAL_CHECK(err == CE_None); { int success; double nodata_value = GDALGetRasterNoDataValue(hBand, &success); if (success) { RAL_CHECK(ral_grid_set_real_nodata_value(gd_t, nodata_value)); RAL_CHECK(ral_grid_set_all_nodata(gd_t)); } else { RAL_CHECK(ral_grid_set_real_nodata_value(gd_t, -9999)); /* change this! */ RAL_CHECK(ral_grid_set_all_nodata(gd_t)); } } /* from source to target */ { /* b = from p0 to p1 */ double bx = p1.x - p0.x; double by = p1.y - p0.y; double b = east_up ? 0 : bx/by; double b2 = east_up ? 1 : sqrt(1+1/b/b); /*fprintf(stderr, "b = %f %f (%f)\n", bx, by, b);*/ /* c = from p0 to p3 */ double cx = p3.x - p0.x; double cy = p3.y - p0.y; double c = north_up ? 0 : cx/cy; double c2 = north_up ? 1 : sqrt(1+1/c/c); /*fprintf(stderr, "c = %f %f (%f)\n", cx, cy, c);*/ ral_cell cs, ct; switch (gd_t->datatype) { case RAL_REAL_GRID: RAL_FOR(ct, gd_t) { /* p = the location of the center of the target pixel in georeferenced coordinates */ double px = clip_region.min.x + cell_size*(ct.j+0.5); double py = clip_region.max.y - cell_size*(ct.i+0.5); /* vector a = from p0 to p */ double ax = px - p0.x; double ay = py - p0.y; /* x = the vector from p0 to the beginning of y */ double x = east_up ? ay : (north_up ? ax : (ax-c*ay)/(1-c/b)); if (!east_up AND !north_up AND (x/b > 0)) continue; /* the length */ x = fabs(x)*b2; /* y = length of the parallel to c vector from b to p */ double y = east_up ? ax : (north_up ? ay : (ax-b*ay)/(1-b/c)); if (!east_up AND !north_up AND (y/c < 0)) continue; /* the length */ y = fabs(y)*c2; ral_cell cs; /* the coordinates in the clipped raster */ cs.j = floor(x/cell_size); cs.i = floor(y/cell_size); if (RAL_GRID_CELL_IN(gd_s, cs)) RAL_REAL_GRID_CELL(gd_t, ct) = RAL_REAL_GRID_CELL(gd_s, cs); } break; case RAL_INTEGER_GRID: RAL_FOR(ct, gd_t) { /* p = the location of the center of the target pixel in georeferenced coordinates */ double px = clip_region.min.x + cell_size*(ct.j+0.5); double py = clip_region.max.y - cell_size*(ct.i+0.5); /* vector a = from p0 to p */ double ax = px - p0.x; double ay = py - p0.y; /* x = the vector from p0 to the beginning of y */ double x = east_up ? ay : (north_up ? ax : (ax-c*ay)/(1-c/b)); if (!east_up AND !north_up AND (x/b > 0)) continue; /* the length */ x = fabs(x)*b2; /* y = length of the parallel to c vector from b to p */ double y = east_up ? ax : (north_up ? ay : (ax-b*ay)/(1-b/c)); if (!east_up AND !north_up AND (y/c < 0)) continue; /* the length */ y = fabs(y)*c2; ral_cell cs; /* the coordinates in the clipped raster */ cs.j = floor(x/cell_size); cs.i = floor(y/cell_size); /* if ((cs.i == 0 AND cs.j == 0) OR (cs.i == hs-1 AND cs.j == 0) OR (cs.i == 0 AND cs.j == ws-1) OR (cs.i == hs-1 AND cs.j == ws-1) OR (ct.i == 0 AND ct.j == 0) OR (ct.i == M-1 AND ct.j == N-1)) { fprintf(stderr, "p = %f %f\n", px, py); fprintf(stderr, "a = %f %f\n", ax, ay); fprintf(stderr, "x = %f\n", x); fprintf(stderr, "y = %f\n", y); fprintf(stderr, "copy %i, %i -> %i, %i\n", cs.j, cs.i, ct.j, ct.i); } */ if (RAL_GRID_CELL_IN(gd_s, cs)) { RAL_INTEGER_GRID_CELL(gd_t, ct) = RAL_INTEGER_GRID_CELL(gd_s, cs); } } }
int main( int argc, char ** argv ) { GDALDatasetH hDataset; GDALRasterBandH hBand; int i, iBand; double adfGeoTransform[6]; GDALDriverH hDriver; char **papszMetadata; int bComputeMinMax = FALSE; if( !GDALBridgeInitialize( "..", stderr ) ) { fprintf( stderr, "Unable to intiailize GDAL bridge.\n" ); exit( 10 ); } if( argc > 1 && strcmp(argv[1],"-mm") == 0 ) { bComputeMinMax = TRUE; argv++; } GDALAllRegister(); hDataset = GDALOpen( argv[1], GA_ReadOnly ); if( hDataset == NULL ) { fprintf( stderr, "GDALOpen failed - %d\n%s\n", CPLGetLastErrorNo(), CPLGetLastErrorMsg() ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Report general info. */ /* -------------------------------------------------------------------- */ hDriver = GDALGetDatasetDriver( hDataset ); printf( "Driver: %s/%s\n", GDALGetDriverShortName( hDriver ), GDALGetDriverLongName( hDriver ) ); printf( "Size is %d, %d\n", GDALGetRasterXSize( hDataset ), GDALGetRasterYSize( hDataset ) ); /* -------------------------------------------------------------------- */ /* Report projection. */ /* -------------------------------------------------------------------- */ if( GDALGetProjectionRef( hDataset ) != NULL ) { OGRSpatialReferenceH hSRS; char *pszProjection; pszProjection = (char *) GDALGetProjectionRef( hDataset ); hSRS = OSRNewSpatialReference(NULL); if( OSRImportFromWkt( hSRS, &pszProjection ) == CE_None ) { char *pszPrettyWkt = NULL; OSRExportToPrettyWkt( hSRS, &pszPrettyWkt, FALSE ); printf( "Coordinate System is:\n%s\n", pszPrettyWkt ); } else printf( "Coordinate System is `%s'\n", GDALGetProjectionRef( hDataset ) ); OSRDestroySpatialReference( hSRS ); } /* -------------------------------------------------------------------- */ /* Report Geotransform. */ /* -------------------------------------------------------------------- */ if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None ) { printf( "Origin = (%.6f,%.6f)\n", adfGeoTransform[0], adfGeoTransform[3] ); printf( "Pixel Size = (%.6f,%.6f)\n", adfGeoTransform[1], adfGeoTransform[5] ); } /* -------------------------------------------------------------------- */ /* Report GCPs. */ /* -------------------------------------------------------------------- */ if( GDALGetGCPCount( hDataset ) > 0 ) { printf( "GCP Projection = %s\n", GDALGetGCPProjection(hDataset) ); for( i = 0; i < GDALGetGCPCount(hDataset); i++ ) { const GDAL_GCP *psGCP; psGCP = GDALGetGCPs( hDataset ) + i; printf( "GCP[%3d]: Id=%s, Info=%s\n" " (%g,%g) -> (%g,%g,%g)\n", i, psGCP->pszId, psGCP->pszInfo, psGCP->dfGCPPixel, psGCP->dfGCPLine, psGCP->dfGCPX, psGCP->dfGCPY, psGCP->dfGCPZ ); } } /* -------------------------------------------------------------------- */ /* Report metadata. */ /* -------------------------------------------------------------------- */ papszMetadata = GDALGetMetadata( hDataset, NULL ); if( papszMetadata != NULL ) { printf( "Metadata:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } /* -------------------------------------------------------------------- */ /* Report subdatasets. */ /* -------------------------------------------------------------------- */ papszMetadata = GDALGetMetadata( hDataset, "SUBDATASETS" ); if( papszMetadata != NULL ) { printf( "Subdatasets:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } /* -------------------------------------------------------------------- */ /* Report corners. */ /* -------------------------------------------------------------------- */ printf( "Corner Coordinates:\n" ); GDALInfoReportCorner( hDataset, "Upper Left", 0.0, 0.0 ); GDALInfoReportCorner( hDataset, "Lower Left", 0.0, GDALGetRasterYSize(hDataset)); GDALInfoReportCorner( hDataset, "Upper Right", GDALGetRasterXSize(hDataset), 0.0 ); GDALInfoReportCorner( hDataset, "Lower Right", GDALGetRasterXSize(hDataset), GDALGetRasterYSize(hDataset) ); GDALInfoReportCorner( hDataset, "Center", GDALGetRasterXSize(hDataset)/2.0, GDALGetRasterYSize(hDataset)/2.0 ); /* ==================================================================== */ /* Loop over bands. */ /* ==================================================================== */ for( iBand = 0; iBand < GDALGetRasterCount( hDataset ); iBand++ ) { double dfMin, dfMax, adfCMinMax[2], dfNoData; int bGotMin, bGotMax, bGotNodata; int nBlockXSize, nBlockYSize; hBand = GDALGetRasterBand( hDataset, iBand+1 ); GDALGetBlockSize( hBand, &nBlockXSize, &nBlockYSize ); printf( "Band %d Block=%dx%d Type=%d, ColorInterp=%d\n", iBand+1, nBlockXSize, nBlockYSize, GDALGetRasterDataType(hBand), GDALGetRasterColorInterpretation(hBand) ); dfMin = GDALGetRasterMinimum( hBand, &bGotMin ); dfMax = GDALGetRasterMaximum( hBand, &bGotMax ); printf( " Min=%.3f/%d, Max=%.3f/%d", dfMin, bGotMin, dfMax, bGotMax); if( bComputeMinMax ) { GDALComputeRasterMinMax( hBand, TRUE, adfCMinMax ); printf( ", Computed Min/Max=%.3f,%.3f", adfCMinMax[0], adfCMinMax[1] ); } printf( "\n" ); dfNoData = GDALGetRasterNoDataValue( hBand, &bGotNodata ); if( bGotNodata ) { printf( " NoData Value=%g\n", dfNoData ); } if( GDALGetOverviewCount(hBand) > 0 ) { int iOverview; printf( " Overviews: " ); for( iOverview = 0; iOverview < GDALGetOverviewCount(hBand); iOverview++ ) { GDALRasterBandH hOverview; if( iOverview != 0 ) printf( ", " ); hOverview = GDALGetOverview( hBand, iOverview ); printf( "%dx%d", GDALGetRasterBandXSize( hOverview ), GDALGetRasterBandYSize( hOverview ) ); } printf( "\n" ); } papszMetadata = GDALGetMetadata( hBand, NULL ); if( papszMetadata != NULL ) { printf( "Metadata:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } if( GDALGetRasterColorInterpretation(hBand) == GCI_PaletteIndex ) { GDALColorTableH hTable; int i; hTable = GDALGetRasterColorTable( hBand ); printf( " Color Table (%s with %d entries)\n", GDALGetPaletteInterpretationName( GDALGetPaletteInterpretation( hTable )), GDALGetColorEntryCount( hTable ) ); for( i = 0; i < GDALGetColorEntryCount( hTable ); i++ ) { GDALColorEntry sEntry; GDALGetColorEntryAsRGB( hTable, i, &sEntry ); printf( " %3d: %d,%d,%d,%d\n", i, sEntry.c1, sEntry.c2, sEntry.c3, sEntry.c4 ); } } } GDALClose( hDataset ); exit( 0 ); }
int QgsRelief::processRaster( QgsFeedback *feedback ) { //open input file int xSize, ySize; GDALDatasetH inputDataset = openInputFile( xSize, ySize ); if ( !inputDataset ) { return 1; //opening of input file failed } //output driver GDALDriverH outputDriver = openOutputDriver(); if ( !outputDriver ) { return 2; } GDALDatasetH outputDataset = openOutputFile( inputDataset, outputDriver ); if ( !outputDataset ) { return 3; //create operation on output file failed } //initialize dependency filters with cell sizes mHillshadeFilter285->setCellSizeX( mCellSizeX ); mHillshadeFilter285->setCellSizeY( mCellSizeY ); mHillshadeFilter285->setZFactor( mZFactor ); mHillshadeFilter300->setCellSizeX( mCellSizeX ); mHillshadeFilter300->setCellSizeY( mCellSizeY ); mHillshadeFilter300->setZFactor( mZFactor ); mHillshadeFilter315->setCellSizeX( mCellSizeX ); mHillshadeFilter315->setCellSizeY( mCellSizeY ); mHillshadeFilter315->setZFactor( mZFactor ); mSlopeFilter->setCellSizeX( mCellSizeX ); mSlopeFilter->setCellSizeY( mCellSizeY ); mSlopeFilter->setZFactor( mZFactor ); mAspectFilter->setCellSizeX( mCellSizeX ); mAspectFilter->setCellSizeY( mCellSizeY ); mAspectFilter->setZFactor( mZFactor ); //open first raster band for reading (operation is only for single band raster) GDALRasterBandH rasterBand = GDALGetRasterBand( inputDataset, 1 ); if ( !rasterBand ) { GDALClose( inputDataset ); GDALClose( outputDataset ); return 4; } mInputNodataValue = GDALGetRasterNoDataValue( rasterBand, nullptr ); mSlopeFilter->setInputNodataValue( mInputNodataValue ); mAspectFilter->setInputNodataValue( mInputNodataValue ); mHillshadeFilter285->setInputNodataValue( mInputNodataValue ); mHillshadeFilter300->setInputNodataValue( mInputNodataValue ); mHillshadeFilter315->setInputNodataValue( mInputNodataValue ); GDALRasterBandH outputRedBand = GDALGetRasterBand( outputDataset, 1 ); GDALRasterBandH outputGreenBand = GDALGetRasterBand( outputDataset, 2 ); GDALRasterBandH outputBlueBand = GDALGetRasterBand( outputDataset, 3 ); if ( !outputRedBand || !outputGreenBand || !outputBlueBand ) { GDALClose( inputDataset ); GDALClose( outputDataset ); return 5; } //try to set -9999 as nodata value GDALSetRasterNoDataValue( outputRedBand, -9999 ); GDALSetRasterNoDataValue( outputGreenBand, -9999 ); GDALSetRasterNoDataValue( outputBlueBand, -9999 ); mOutputNodataValue = GDALGetRasterNoDataValue( outputRedBand, nullptr ); mSlopeFilter->setOutputNodataValue( mOutputNodataValue ); mAspectFilter->setOutputNodataValue( mOutputNodataValue ); mHillshadeFilter285->setOutputNodataValue( mOutputNodataValue ); mHillshadeFilter300->setOutputNodataValue( mOutputNodataValue ); mHillshadeFilter315->setOutputNodataValue( mOutputNodataValue ); if ( ySize < 3 ) //we require at least three rows (should be true for most datasets) { GDALClose( inputDataset ); GDALClose( outputDataset ); return 6; } //keep only three scanlines in memory at a time float *scanLine1 = ( float * ) CPLMalloc( sizeof( float ) * xSize ); float *scanLine2 = ( float * ) CPLMalloc( sizeof( float ) * xSize ); float *scanLine3 = ( float * ) CPLMalloc( sizeof( float ) * xSize ); unsigned char *resultRedLine = ( unsigned char * ) CPLMalloc( sizeof( unsigned char ) * xSize ); unsigned char *resultGreenLine = ( unsigned char * ) CPLMalloc( sizeof( unsigned char ) * xSize ); unsigned char *resultBlueLine = ( unsigned char * ) CPLMalloc( sizeof( unsigned char ) * xSize ); bool resultOk; //values outside the layer extent (if the 3x3 window is on the border) are sent to the processing method as (input) nodata values for ( int i = 0; i < ySize; ++i ) { if ( feedback ) { feedback->setProgress( 100.0 * i / static_cast< double >( ySize ) ); } if ( feedback && feedback->isCanceled() ) { break; } if ( i == 0 ) { //fill scanline 1 with (input) nodata for the values above the first row and feed scanline2 with the first row for ( int a = 0; a < xSize; ++a ) { scanLine1[a] = mInputNodataValue; } if ( GDALRasterIO( rasterBand, GF_Read, 0, 0, xSize, 1, scanLine2, xSize, 1, GDT_Float32, 0, 0 ) != CE_None ) { QgsDebugMsg( "Raster IO Error" ); } } else { //normally fetch only scanLine3 and release scanline 1 if we move forward one row CPLFree( scanLine1 ); scanLine1 = scanLine2; scanLine2 = scanLine3; scanLine3 = ( float * ) CPLMalloc( sizeof( float ) * xSize ); } if ( i == ySize - 1 ) //fill the row below the bottom with nodata values { for ( int a = 0; a < xSize; ++a ) { scanLine3[a] = mInputNodataValue; } } else { if ( GDALRasterIO( rasterBand, GF_Read, 0, i + 1, xSize, 1, scanLine3, xSize, 1, GDT_Float32, 0, 0 ) != CE_None ) { QgsDebugMsg( "Raster IO Error" ); } } for ( int j = 0; j < xSize; ++j ) { if ( j == 0 ) { resultOk = processNineCellWindow( &mInputNodataValue, &scanLine1[j], &scanLine1[j + 1], &mInputNodataValue, &scanLine2[j], \ &scanLine2[j + 1], &mInputNodataValue, &scanLine3[j], &scanLine3[j + 1], \ &resultRedLine[j], &resultGreenLine[j], &resultBlueLine[j] ); } else if ( j == xSize - 1 ) { resultOk = processNineCellWindow( &scanLine1[j - 1], &scanLine1[j], &mInputNodataValue, &scanLine2[j - 1], &scanLine2[j], \ &mInputNodataValue, &scanLine3[j - 1], &scanLine3[j], &mInputNodataValue, \ &resultRedLine[j], &resultGreenLine[j], &resultBlueLine[j] ); } else { resultOk = processNineCellWindow( &scanLine1[j - 1], &scanLine1[j], &scanLine1[j + 1], &scanLine2[j - 1], &scanLine2[j], \ &scanLine2[j + 1], &scanLine3[j - 1], &scanLine3[j], &scanLine3[j + 1], \ &resultRedLine[j], &resultGreenLine[j], &resultBlueLine[j] ); } if ( !resultOk ) { resultRedLine[j] = mOutputNodataValue; resultGreenLine[j] = mOutputNodataValue; resultBlueLine[j] = mOutputNodataValue; } } if ( GDALRasterIO( outputRedBand, GF_Write, 0, i, xSize, 1, resultRedLine, xSize, 1, GDT_Byte, 0, 0 ) != CE_None ) { QgsDebugMsg( "Raster IO Error" ); } if ( GDALRasterIO( outputGreenBand, GF_Write, 0, i, xSize, 1, resultGreenLine, xSize, 1, GDT_Byte, 0, 0 ) != CE_None ) { QgsDebugMsg( "Raster IO Error" ); } if ( GDALRasterIO( outputBlueBand, GF_Write, 0, i, xSize, 1, resultBlueLine, xSize, 1, GDT_Byte, 0, 0 ) != CE_None ) { QgsDebugMsg( "Raster IO Error" ); } } if ( feedback ) { feedback->setProgress( 100 ); } CPLFree( resultRedLine ); CPLFree( resultBlueLine ); CPLFree( resultGreenLine ); CPLFree( scanLine1 ); CPLFree( scanLine2 ); CPLFree( scanLine3 ); GDALClose( inputDataset ); if ( feedback && feedback->isCanceled() ) { //delete the dataset without closing (because it is faster) GDALDeleteDataset( outputDriver, mOutputFile.toUtf8().constData() ); return 7; } GDALClose( outputDataset ); return 0; }
void MDAL::LoaderGdal::addDataToOutput( GDALRasterBandH raster_band, std::shared_ptr<Dataset> tos, bool is_vector, bool is_x ) { assert( raster_band ); double nodata = GDALGetRasterNoDataValue( raster_band, nullptr ); unsigned int mXSize = meshGDALDataset()->mXSize; unsigned int mYSize = meshGDALDataset()->mYSize; for ( unsigned int y = 0; y < mYSize; ++y ) { // buffering per-line CPLErr err = GDALRasterIO( raster_band, GF_Read, 0, //nXOff static_cast<int>( y ), //nYOff static_cast<int>( mXSize ), //nXSize 1, //nYSize mPafScanline, //pData static_cast<int>( mXSize ), //nBufXSize 1, //nBufYSize GDT_Float64, //eBufType 0, //nPixelSpace 0 //nLineSpace ); if ( err != CE_None ) { throw MDAL_Status::Err_InvalidData; } for ( unsigned int x = 0; x < mXSize; ++x ) { unsigned int idx = x + mXSize * y; double val = mPafScanline[x]; bool noData = false; if ( MDAL::equals( val, nodata ) ) { // store all nodata value as this hardcoded number val = MDAL_NODATA; noData = true; } if ( is_vector ) { if ( is_x ) { tos->values[idx].x = val; tos->values[idx].noData = noData; } else { tos->values[idx].y = val; tos->values[idx].noData = noData; } } else { tos->values[idx].x = val; tos->values[idx].noData = noData; } } } }
/* * POPULATE_METADATA_STRUCT * * This routine just queries the GDAL raster file for all the metadata * that can be squeezed out of it. * * The resulting matlab structure is by necessity nested. Each raster * file can have several bands, e.g. PNG files usually have 3, a red, a * blue, and a green channel. Each band can have several overviews (tiffs * come to mind here). * * Fields: * ProjectionRef: a string describing the projection. Not parsed. * GeoTransform: * a 6-tuple. Entries are as follows. * [0] --> top left x * [1] --> w-e pixel resolution * [2] --> rotation, 0 if image is "north up" * [3] --> top left y * [4] --> rotation, 0 if image is "north up" * [5] --> n-s pixel resolution * * DriverShortName: describes the driver used to query *this* raster file * DriverLongName: describes the driver used to query *this* raster file * RasterXSize, RasterYSize: * These are the primary dimensions of the raster. See "Overview", though. * RasterCount: * Number of raster bands present in the file. * Driver: * This itself is a structure array. Each element describes a driver * that the locally compiled GDAL library has available. So you recompile * GDAL with new format support, this structure will change. * * Fields: * DriverShortName, DriverLongName: * Same as fields in top level structure with same name. * * Band: * Also a structure array. One element for each raster band present in * the GDAL file. See "RasterCount". * * Fields: * XSize, YSize: * Dimensions of the current raster band. * Overview: * A structure array, one element for each overview present. If * empty, then there are no overviews. * NoDataValue: * When passed back to MATLAB, one can set pixels with this value to NaN. * ColorMap: * A Mx3 double array with the colormap, or empty if it does not exists * * */ mxArray *populate_metadata_struct (GDALDatasetH hDataset, int correct_bounds) { /* These are used to define the metadata structure about available GDAL drivers. */ mxArray *mxtmp; mxArray *mxProjectionRef; mxArray *mxGeoTransform; mxArray *mxGDALDriverShortName; mxArray *mxGDALDriverLongName; mxArray *mxGDALRasterCount; mxArray *mxGDALRasterXSize; mxArray *mxGDALRasterYSize; mxArray *mxCorners; mxArray *mxGMT_header; /* * These will be matlab structures that hold the metadata. * "metadata_struct" actually encompasses "band_struct", * which encompasses "overview_struct" * */ mxArray *metadata_struct; mxArray *band_struct; mxArray *overview_struct; mxArray *corner_struct; int overview, band_number; /* Loop indices */ double *dptr; /* short cut to the mxArray data */ double *dptr2; /* "" */ GDALDriverH hDriver; /* This is the driver chosen by the GDAL library to query the dataset. */ GDALRasterBandH hBand, overview_hBand; int num_overview_fields; /* Number of metadata items for each overview structure. */ int status; /* success or failure */ double adfGeoTransform[6]; /* bounds on the dataset */ int num_overviews; /* Number of overviews in the current band. */ int num_struct_fields; /* number of fields in the metadata structures. */ int num_band_fields; int num_corner_fields; char *fieldnames[100]; /* this array contains the names of the fields of the metadata structure. */ char *band_fieldnames[100]; char *corner_fieldnames[100]; char *overview_fieldnames[100]; int xSize, ySize, raster_count; /* Dimensions of the dataset */ int gdal_type; /* Datatype of the bands. */ double tmpdble; /* temporary value */ double xy_c[2]; /* Corner coordinates */ int dims[2]; int bGotMin, bGotMax; /* To know if driver transmited Min/Max */ double adfMinMax[2]; /* Dataset Min Max */ double z_min = 1e50, z_max = -1e50; /* Create the metadata structure. Just one element, with XXX fields. */ num_struct_fields = 10; fieldnames[0] = strdup ("ProjectionRef"); fieldnames[1] = strdup ("GeoTransform"); fieldnames[2] = strdup ("DriverShortName"); fieldnames[3] = strdup ("DriverLongName"); fieldnames[4] = strdup ("RasterXSize"); fieldnames[5] = strdup ("RasterYSize"); fieldnames[6] = strdup ("RasterCount"); fieldnames[7] = strdup ("Band"); fieldnames[8] = strdup ("Corners"); fieldnames[9] = strdup("GMT_hdr"); metadata_struct = mxCreateStructMatrix ( 1, 1, num_struct_fields, (const char **)fieldnames ); /* Record the ProjectionRef. */ mxProjectionRef = mxCreateString ( GDALGetProjectionRef( hDataset ) ); mxSetField ( metadata_struct, 0, "ProjectionRef", mxProjectionRef ); /* Record the geotransform. */ mxGeoTransform = mxCreateNumericMatrix ( 6, 1, mxDOUBLE_CLASS, mxREAL ); dptr = mxGetPr ( mxGeoTransform ); if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None ) { dptr[0] = adfGeoTransform[0]; dptr[1] = adfGeoTransform[1]; dptr[2] = adfGeoTransform[2]; dptr[3] = adfGeoTransform[3]; dptr[4] = adfGeoTransform[4]; dptr[5] = adfGeoTransform[5]; mxSetField ( metadata_struct, 0, "GeoTransform", mxGeoTransform ); } /* Get driver information */ hDriver = GDALGetDatasetDriver( hDataset ); mxGDALDriverShortName = mxCreateString ( GDALGetDriverShortName( hDriver ) ); mxSetField ( metadata_struct, 0, (const char *) "DriverShortName", mxGDALDriverShortName ); mxGDALDriverLongName = mxCreateString ( GDALGetDriverLongName( hDriver ) ); mxSetField ( metadata_struct, 0, (const char *) "DriverLongName", mxGDALDriverLongName ); xSize = GDALGetRasterXSize( hDataset ); ySize = GDALGetRasterYSize( hDataset ); mxGDALRasterXSize = mxCreateDoubleScalar ( (double) xSize ); mxSetField ( metadata_struct, 0, (const char *) "RasterXSize", mxGDALRasterXSize ); mxGDALRasterYSize = mxCreateDoubleScalar ( (double) ySize ); mxSetField ( metadata_struct, 0, (const char *) "RasterYSize", mxGDALRasterYSize ); raster_count = GDALGetRasterCount( hDataset ); mxGDALRasterCount = mxCreateDoubleScalar ( (double)raster_count ); mxSetField ( metadata_struct, 0, (const char *) "RasterCount", mxGDALRasterCount ); /* Get the metadata for each band. */ num_band_fields = 5; band_fieldnames[0] = strdup ( "XSize" ); band_fieldnames[1] = strdup ( "YSize" ); band_fieldnames[2] = strdup ( "Overview" ); band_fieldnames[3] = strdup ( "NoDataValue" ); band_fieldnames[4] = strdup ( "DataType" ); band_struct = mxCreateStructMatrix ( raster_count, 1, num_band_fields, (const char **)band_fieldnames ); num_overview_fields = 2; overview_fieldnames[0] = strdup ( "XSize" ); overview_fieldnames[1] = strdup ( "YSize" ); for ( band_number = 1; band_number <= raster_count; ++band_number ) { /* Loop over bands */ hBand = GDALGetRasterBand( hDataset, band_number ); mxtmp = mxCreateDoubleScalar ( (double) GDALGetRasterBandXSize( hBand ) ); mxSetField ( band_struct, 0, "XSize", mxtmp ); mxtmp = mxCreateDoubleScalar ( (double) GDALGetRasterBandYSize( hBand ) ); mxSetField ( band_struct, 0, "YSize", mxtmp ); gdal_type = GDALGetRasterDataType ( hBand ); mxtmp = mxCreateString ( GDALGetDataTypeName ( (GDALDataType)gdal_type ) ); mxSetField ( band_struct, 0, (const char *) "DataType", mxtmp ); tmpdble = GDALGetRasterNoDataValue ( hBand, &status ); mxtmp = mxCreateDoubleScalar ( (double) (GDALGetRasterNoDataValue ( hBand, &status ) ) ); mxSetField ( band_struct, 0, "NoDataValue", mxtmp ); num_overviews = GDALGetOverviewCount( hBand ); /* Can have multiple overviews per band. */ if ( num_overviews > 0 ) { overview_struct = mxCreateStructMatrix ( num_overviews, 1, num_overview_fields, (const char **)overview_fieldnames ); for ( overview = 0; overview < num_overviews; ++overview ) { overview_hBand = GDALGetOverview ( hBand, overview ); xSize = GDALGetRasterBandXSize ( overview_hBand ); mxtmp = mxCreateDoubleScalar ( xSize ); mxSetField ( overview_struct, overview, "XSize", mxtmp ); ySize = GDALGetRasterBandYSize ( overview_hBand ); mxtmp = mxCreateDoubleScalar ( ySize ); mxSetField ( overview_struct, overview, "YSize", mxtmp ); } mxSetField ( band_struct, 0, "Overview", overview_struct ); } } mxSetField ( metadata_struct, 0, "Band", band_struct ); /* Record the GMT header. This will be interleaved with "corners" because they share somes values */ mxGMT_header = mxCreateNumericMatrix(1, 9, mxDOUBLE_CLASS, mxREAL); dptr2 = mxGetPr(mxGMT_header); /* Record corners. */ num_corner_fields = 4; corner_fieldnames[0] = strdup ("LL"); corner_fieldnames[1] = strdup ("UL"); corner_fieldnames[2] = strdup ("UR"); corner_fieldnames[3] = strdup ("LR"); corner_struct = mxCreateStructMatrix(1, 1, num_corner_fields, (const char **)corner_fieldnames); dims[0] = 1; dims[1] = 2; ReportCorner(hDataset, 0.0, GDALGetRasterYSize(hDataset), xy_c); /* Lower Left */ mxCorners = mxCreateNumericArray (2,dims,mxDOUBLE_CLASS, mxREAL); dptr = mxGetPr(mxCorners); dptr[0] = xy_c[0]; dptr[1] = xy_c[1]; dptr2[0] = xy_c[0]; dptr2[2] = xy_c[1]; /* xmin, ymin */ mxSetField(corner_struct, 0, "LL", mxCorners ); ReportCorner(hDataset, 0.0, 0.0, xy_c); /* Upper Left */ mxCorners = mxCreateNumericArray (2,dims,mxDOUBLE_CLASS, mxREAL); dptr = mxGetPr(mxCorners); dptr[0] = xy_c[0]; dptr[1] = xy_c[1]; mxSetField(corner_struct, 0, "UL", mxCorners ); ReportCorner(hDataset, GDALGetRasterXSize(hDataset), 0.0, xy_c); /* Upper Rigt */ mxCorners = mxCreateNumericArray (2,dims,mxDOUBLE_CLASS, mxREAL); dptr = mxGetPr(mxCorners); dptr[0] = xy_c[0]; dptr[1] = xy_c[1]; dptr2[1] = xy_c[0]; dptr2[3] = xy_c[1]; /* xmax, ymax */ mxSetField(corner_struct, 0, "UR", mxCorners ); ReportCorner(hDataset, GDALGetRasterXSize(hDataset), GDALGetRasterYSize(hDataset), xy_c); /* Lower Rigt */ mxCorners = mxCreateNumericArray (2,dims,mxDOUBLE_CLASS, mxREAL); dptr = mxGetPr(mxCorners); dptr[0] = xy_c[0]; dptr[1] = xy_c[1]; mxSetField(corner_struct, 0, "LR", mxCorners ); mxSetField (metadata_struct, 0, "Corners", corner_struct); /* Fill in the rest of the GMT header values */ if (z_min == 1e50) { /* We don't know yet the dataset Min/Max */ adfMinMax[0] = GDALGetRasterMinimum( hBand, &bGotMin ); adfMinMax[1] = GDALGetRasterMaximum( hBand, &bGotMax ); if(!(bGotMin && bGotMax)) GDALComputeRasterMinMax( hBand, TRUE, adfMinMax ); dptr2[4] = adfMinMax[0]; dptr2[5] = adfMinMax[1]; } else { dptr2[4] = z_min; dptr2[5] = z_max; } dptr2[6] = 0; dptr2[7] = adfGeoTransform[1]; dptr2[8] = fabs(adfGeoTransform[5]); if (correct_bounds) { dptr2[0] += dptr2[7] / 2; dptr2[1] -= dptr2[7] / 2; dptr2[2] += dptr2[8] / 2; dptr2[3] -= dptr2[8] / 2; } mxSetField (metadata_struct, 0, "GMT_hdr", mxGMT_header); return ( metadata_struct ); }