/** Fetch the min value of a dataset. * Fetch the min value from any valid GDAL dataset * @param poDS a pointer to a valid GDAL Dataset * @return min value */ double GDALGetMin( GDALDataset *poDS ) { GDALRasterBand *poBand = poDS->GetRasterBand( 1 ); double adfMinMax[2]; GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax); return adfMinMax[0]; }
bool getRawValuesFromFile(string fname,vector<vector<float>>& vecs) { //vector<float> temp = vector<float>() GDALDataset *poDataset; GDALAllRegister(); poDataset= (GDALDataset*) GDALOpen(fname.c_str(),GA_ReadOnly); if(poDataset == NULL) { cout << "OUCH!" << endl; return false; } cout << "Data size: " << GDALGetRasterXSize(poDataset) << " " << GDALGetRasterYSize(poDataset) << endl; GDALRasterBand *poBand; int nBlockXSize, nBlockYSize; int bGotMin, bGotMax; double adfMinMax[2]; poBand = poDataset->GetRasterBand( 1 ); poBand->GetBlockSize( &nBlockXSize, &nBlockYSize ); printf( "Block=%dx%d Type=%s, ColorInterp=%s\n", nBlockXSize, nBlockYSize, GDALGetDataTypeName(poBand->GetRasterDataType()), GDALGetColorInterpretationName( poBand->GetColorInterpretation()) ); adfMinMax[0] = poBand->GetMinimum( &bGotMin ); adfMinMax[1] = poBand->GetMaximum( &bGotMax ); if( ! (bGotMin && bGotMax) ) GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax); int width = poBand->GetXSize(); int height = poBand->GetYSize(); int bands = poDataset->GetRasterCount(); float *pafScanline; std::cout << "Before allocation" << adfMinMax[0] << " " << adfMinMax[1] << endl; int dsize = 256; pafScanline = (float *) CPLMalloc(sizeof(float)*width*height); vector<vector<float>> out = vector<vector<float>>(height,vector<float> (width,0)); poBand->RasterIO(GF_Read,0,0,width,height,pafScanline,width,height,GDT_Float32,0,0); cout << "After allocation" << endl; for(int i = 0; i < height; i++) { for(int j = 0; j < width; j++) { //cout << i << j << endl << pafS; out[i][j] = pafScanline[i*width+j]; } } CPLFree(pafScanline); //for(auto i : out) //for(auto j : i) // cout << j << endl; cout << "After allocation" << endl; vecs = out; return true; }
int main() { GDALDataset *poDataset; GDALAllRegister(); poDataset = (GDALDataset *) GDALOpen( "GE01.tif", GA_ReadOnly ); printf("Working! \n"); if( poDataset != NULL ){ //Get Dataset Information double adfGeoTransform[6]; printf( "Driver: %s/%s\n", poDataset->GetDriver()->GetDescription(), poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME ) ); printf( "Size is %dx%dx%d\n", poDataset->GetRasterXSize(), poDataset->GetRasterYSize(), poDataset->GetRasterCount() ); if( poDataset->GetProjectionRef() != NULL ) printf( "Projection is `%s'\n", poDataset->GetProjectionRef() ); if( poDataset->GetGeoTransform( adfGeoTransform ) == CE_None ){ printf( "Origin = (%.6f,%.6f)\n", adfGeoTransform[0], adfGeoTransform[3] ); printf( "Pixel Size = (%.6f,%.6f)\n", adfGeoTransform[1], adfGeoTransform[5] ); } //Fetch Raster Band GDALRasterBand *poBand; int nBlockXSize, nBlockYSize; int bGotMin, bGotMax; double adfMinMax[2]; poBand = poDataset->GetRasterBand( 1 ); poBand->GetBlockSize( &nBlockXSize, &nBlockYSize ); printf( "Block=%dx%d Type=%s, ColorInterp=%s\n", nBlockXSize, nBlockYSize, GDALGetDataTypeName(poBand->GetRasterDataType()), GDALGetColorInterpretationName( poBand->GetColorInterpretation()) ); adfMinMax[0] = poBand->GetMinimum( &bGotMin ); adfMinMax[1] = poBand->GetMaximum( &bGotMax ); if( ! (bGotMin && bGotMax) ) GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax); printf( "Min=%.3fd, Max=%.3f\n", adfMinMax[0], adfMinMax[1] ); if( poBand->GetOverviewCount() > 0 ) printf( "Band has %d overviews.\n", poBand->GetOverviewCount() ); if( poBand->GetColorTable() != NULL ) printf( "Band has a color table with %d entries.\n", poBand->GetColorTable()->GetColorEntryCount() ); //Close Dataset GDALClose(poDataset); //Exit return 0; } }
void HypSpecImage::bounds(int band, float *min, float *max) { GDALRasterBand *raster = m_data->GetRasterBand(band); int bGotMin, bGotMax; *min = raster->GetMinimum(&bGotMin); *max = raster->GetMaximum(&bGotMax); if(!(bGotMin && bGotMax)) { double adfMinMax[2]; GDALComputeRasterMinMax((GDALRasterBandH) raster, TRUE, adfMinMax); *min = adfMinMax[0]; *max = adfMinMax[1]; } }
bool Slic::_InitData() { // Check the params if (_poSrcDS == NULL|| _poDstDS == NULL) { std::cerr<<"Input image or output image invalid !"<<std::endl; return false; } if (_regionSize<0 || _regularizer<0) { std::cerr<<"Parameter regionSize and regularizer must bigger than 0!"<<std::endl; return false; } // Init some vars _M = static_cast<int> (static_cast<double>(_width) / _regionSize + 0.5); _N = static_cast<int> (static_cast<double>(_height) / _regionSize + 0.5); // Init normalization params for (int k=0;k<_bandCount;++k) { GDALRasterBand* poBand = _poSrcDS->GetRasterBand(k+1); int bGotMin, bGotMax; double adfMinMax[2]; adfMinMax[0] = poBand->GetMinimum( &bGotMin ); adfMinMax[1] = poBand->GetMaximum( &bGotMax ); if( ! (bGotMin && bGotMax) ) GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax); std::vector<double> adfNormalizationParam(2); adfNormalizationParam[0] = 1./(adfMinMax[1]-adfMinMax[0]); adfNormalizationParam[1] = adfMinMax[0]/(adfMinMax[1]-adfMinMax[0]); _normalizationParam.push_back(adfNormalizationParam); } // Init centers for (int i=_regionSize/2;i<_height ;i+=_regionSize) { for (int j=_regionSize/2;j<_width ;j += _regionSize) { FeatureVector featureVec; _InitCenterFeature(i,j,featureVec); _centerVector.push_back(featureVec); } } return true; }
void Create8BitImage(const char *srcfile,const char *dstfile) { GDALAllRegister(); CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO"); GDALDataset *pDataset=(GDALDataset *) GDALOpen( srcfile, GA_ReadOnly ); int bandNum=pDataset->GetRasterCount(); GDALDriver *pDriver=GetGDALDriverManager()->GetDriverByName("GTiff"); GDALDataset *dstDataset=pDriver->Create(dstfile,800,800,3,GDT_Byte,NULL); GDALRasterBand *pBand; GDALRasterBand *dstBand; //写入光栅数据 ushort *sbuf= new ushort[800*800]; uchar *cbuf=new uchar[800*800]; for (int i=bandNum,j=1;i>=2;i--,j++) { pBand=pDataset->GetRasterBand(i); pBand->RasterIO(GF_Read,0,0,800,800,sbuf,800,800,GDT_UInt16,0,0); int bGotMin, bGotMax; double adfMinMax[2]; adfMinMax[0] = pBand->GetMinimum( &bGotMin ); adfMinMax[1] = pBand->GetMaximum( &bGotMax ); if( ! (bGotMin && bGotMax) ) GDALComputeRasterMinMax((GDALRasterBandH)pBand, TRUE, adfMinMax); MinMaxStretch(sbuf,cbuf,800,800,adfMinMax[0],adfMinMax[1]); /*double min,max; HistogramAccumlateMinMax16S(sbuf,800,800,&min,&max); MinMaxStretchNew(sbuf,cbuf,800,800,min,max);*/ dstBand=dstDataset->GetRasterBand(j); dstBand->RasterIO(GF_Write,0,0,800,800,cbuf,800,800,GDT_Byte,0,0); } delete []cbuf; delete []sbuf; GDALClose(pDataset); GDALClose(dstDataset); }
static GDALDataset * GMTCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, CPL_UNUSED char ** papszOptions, CPL_UNUSED GDALProgressFunc pfnProgress, CPL_UNUSED void * pProgressData ) { /* -------------------------------------------------------------------- */ /* Figure out general characteristics. */ /* -------------------------------------------------------------------- */ nc_type nc_datatype; GDALRasterBand *poBand; int nXSize, nYSize; CPLMutexHolderD(&hNCMutex); if( poSrcDS->GetRasterCount() != 1 ) { CPLError( CE_Failure, CPLE_AppDefined, "Currently GMT export only supports 1 band datasets." ); return NULL; } poBand = poSrcDS->GetRasterBand(1); nXSize = poSrcDS->GetRasterXSize(); nYSize = poSrcDS->GetRasterYSize(); if( poBand->GetRasterDataType() == GDT_Int16 ) nc_datatype = NC_SHORT; else if( poBand->GetRasterDataType() == GDT_Int32 ) nc_datatype = NC_INT; else if( poBand->GetRasterDataType() == GDT_Float32 ) nc_datatype = NC_FLOAT; else if( poBand->GetRasterDataType() == GDT_Float64 ) nc_datatype = NC_DOUBLE; else if( bStrict ) { CPLError( CE_Failure, CPLE_AppDefined, "Band data type %s not supported in GMT, giving up.", GDALGetDataTypeName( poBand->GetRasterDataType() ) ); return NULL; } else if( poBand->GetRasterDataType() == GDT_Byte ) nc_datatype = NC_SHORT; else if( poBand->GetRasterDataType() == GDT_UInt16 ) nc_datatype = NC_INT; else if( poBand->GetRasterDataType() == GDT_UInt32 ) nc_datatype = NC_INT; else nc_datatype = NC_FLOAT; /* -------------------------------------------------------------------- */ /* Establish bounds from geotransform. */ /* -------------------------------------------------------------------- */ double adfGeoTransform[6]; double dfXMax, dfYMin; poSrcDS->GetGeoTransform( adfGeoTransform ); if( adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0 ) { CPLError( bStrict ? CE_Failure : CE_Warning, CPLE_AppDefined, "Geotransform has rotational coefficients not supported in GMT." ); if( bStrict ) return NULL; } dfXMax = adfGeoTransform[0] + adfGeoTransform[1] * nXSize; dfYMin = adfGeoTransform[3] + adfGeoTransform[5] * nYSize; /* -------------------------------------------------------------------- */ /* Create base file. */ /* -------------------------------------------------------------------- */ int cdfid, err; err = nc_create (pszFilename, NC_CLOBBER,&cdfid); if( err != NC_NOERR ) { CPLError( CE_Failure, CPLE_AppDefined, "nc_create(%s): %s", pszFilename, nc_strerror( err ) ); return NULL; } /* -------------------------------------------------------------------- */ /* Define the dimensions and so forth. */ /* -------------------------------------------------------------------- */ int side_dim, xysize_dim, dims[1]; int x_range_id, y_range_id, z_range_id, inc_id, nm_id, z_id; nc_def_dim(cdfid, "side", 2, &side_dim); nc_def_dim(cdfid, "xysize", (int) (nXSize * nYSize), &xysize_dim); dims[0] = side_dim; nc_def_var (cdfid, "x_range", NC_DOUBLE, 1, dims, &x_range_id); nc_def_var (cdfid, "y_range", NC_DOUBLE, 1, dims, &y_range_id); nc_def_var (cdfid, "z_range", NC_DOUBLE, 1, dims, &z_range_id); nc_def_var (cdfid, "spacing", NC_DOUBLE, 1, dims, &inc_id); nc_def_var (cdfid, "dimension", NC_LONG, 1, dims, &nm_id); dims[0] = xysize_dim; nc_def_var (cdfid, "z", nc_datatype, 1, dims, &z_id); /* -------------------------------------------------------------------- */ /* Assign attributes. */ /* -------------------------------------------------------------------- */ double default_scale = 1.0; double default_offset = 0.0; int default_node_offset = 1; // pixel is area nc_put_att_text (cdfid, x_range_id, "units", 7, "meters"); nc_put_att_text (cdfid, y_range_id, "units", 7, "meters"); nc_put_att_text (cdfid, z_range_id, "units", 7, "meters"); nc_put_att_double (cdfid, z_id, "scale_factor", NC_DOUBLE, 1, &default_scale ); nc_put_att_double (cdfid, z_id, "add_offset", NC_DOUBLE, 1, &default_offset ); nc_put_att_int (cdfid, z_id, "node_offset", NC_LONG, 1, &default_node_offset ); nc_put_att_text (cdfid, NC_GLOBAL, "title", 1, ""); nc_put_att_text (cdfid, NC_GLOBAL, "source", 1, ""); /* leave define mode */ nc_enddef (cdfid); /* -------------------------------------------------------------------- */ /* Get raster min/max. */ /* -------------------------------------------------------------------- */ double adfMinMax[2]; GDALComputeRasterMinMax( (GDALRasterBandH) poBand, FALSE, adfMinMax ); /* -------------------------------------------------------------------- */ /* Set range variables. */ /* -------------------------------------------------------------------- */ size_t start[2], edge[2]; double dummy[2]; int nm[2]; start[0] = 0; edge[0] = 2; dummy[0] = adfGeoTransform[0]; dummy[1] = dfXMax; nc_put_vara_double(cdfid, x_range_id, start, edge, dummy); dummy[0] = dfYMin; dummy[1] = adfGeoTransform[3]; nc_put_vara_double(cdfid, y_range_id, start, edge, dummy); dummy[0] = adfGeoTransform[1]; dummy[1] = -adfGeoTransform[5]; nc_put_vara_double(cdfid, inc_id, start, edge, dummy); nm[0] = nXSize; nm[1] = nYSize; nc_put_vara_int(cdfid, nm_id, start, edge, nm); nc_put_vara_double(cdfid, z_range_id, start, edge, adfMinMax); /* -------------------------------------------------------------------- */ /* Write out the image one scanline at a time. */ /* -------------------------------------------------------------------- */ double *padfData; int iLine; padfData = (double *) CPLMalloc( sizeof(double) * nXSize ); edge[0] = nXSize; for( iLine = 0; iLine < nYSize; iLine++ ) { start[0] = iLine * nXSize; poBand->RasterIO( GF_Read, 0, iLine, nXSize, 1, padfData, nXSize, 1, GDT_Float64, 0, 0, NULL ); err = nc_put_vara_double( cdfid, z_id, start, edge, padfData ); if( err != NC_NOERR ) { CPLError( CE_Failure, CPLE_AppDefined, "nc_put_vara_double(%s): %s", pszFilename, nc_strerror( err ) ); nc_close (cdfid); return( NULL ); } } CPLFree( padfData ); /* -------------------------------------------------------------------- */ /* Close file, and reopen. */ /* -------------------------------------------------------------------- */ nc_close (cdfid); /* -------------------------------------------------------------------- */ /* Re-open dataset, and copy any auxiliary pam information. */ /* -------------------------------------------------------------------- */ GDALPamDataset *poDS = (GDALPamDataset *) GDALOpen( pszFilename, GA_ReadOnly ); if( poDS ) poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT ); return poDS; }
void generateTexture(string fname, GLuint& tex, int bandnum) { if(bandnum <= 0 ) { bandnum = 1; } GDALDataset *poDataset; GDALAllRegister(); poDataset= (GDALDataset*) GDALOpen(fname.c_str(),GA_ReadOnly); if(poDataset == NULL) { cout << "OUCH!" << endl; //exit(0); return; } cout << "Data size: " << GDALGetRasterXSize(poDataset) << " " << GDALGetRasterYSize(poDataset) << endl; GDALRasterBand *poBand; int nBlockXSize, nBlockYSize; int bGotMin, bGotMax; double adfMinMax[2]; int bands = poDataset->GetRasterCount(); bandnum = bandnum % bands + 1; if(bandnum > bands) { bandnum = 1; } poBand = poDataset->GetRasterBand( bandnum ); poBand->GetBlockSize( &nBlockXSize, &nBlockYSize ); printf( "Block=%dx%d Type=%s, ColorInterp=%s\n", nBlockXSize, nBlockYSize, GDALGetDataTypeName(poBand->GetRasterDataType()), GDALGetColorInterpretationName( poBand->GetColorInterpretation()) ); float max = adfMinMax[0] = poBand->GetMinimum( &bGotMin ); float min = adfMinMax[1] = poBand->GetMaximum( &bGotMax ); if( ! (bGotMin && bGotMax) ) GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax); int width = poBand->GetXSize(); int height = poBand->GetYSize(); float *pafScanline; std::cout << "Before allocation" << adfMinMax[0] << " " << adfMinMax[1] << endl; min = adfMinMax[0]; max = adfMinMax[1]; int dsize = 256; pafScanline = (float *) CPLMalloc(sizeof(float)*512*512); vector<vector<float>> out = vector<vector<float>>(height,vector<float> (width,0)); //vector<vector<unsigned char>> texs = vector<vector<unsigned char>>(height,vector<unsigned char> (width,0)); unsigned char texs[512*512]; poBand->RasterIO(GF_Read,0,0,width,height,pafScanline,512,512,GDT_Float32,0,0); float no = poBand->GetNoDataValue(); cout << "After allocation" << endl; for(int i = 0; i < 512; i++) { for(int j = 0; j < 512; j++) { //cout << i << j << endl << pafS; if(pafScanline[i*width+j] != no) { // set tex val texs[i*512+j] = (unsigned char)(255*((pafScanline[i*512+j] - min)/(max-min))); //if((int)texs[i*width] < 0) //cout << (int)texs[i*512 +j] << " " << pafScanline[i*512+j] << " " << no << " " << fname << " " << min << " " << max << endl; } else { // Set zero val texs[i*512+j] = 0; //cout << (int)texs[i*512 +j] << fname << endl; } //texs[i*512+j] = 255; //ut[i][j] = pafScanline[i*width+j]; } } CPLFree(pafScanline); //exit(0); // Create a texture glGenTextures(1,&tex); glBindTexture(GL_TEXTURE_2D,tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 512,512, 0, GL_RED, GL_UNSIGNED_BYTE,texs); GDALClose( (GDALDatasetH) poDataset); return; }
CC_FILE_ERROR RasterGridFilter::loadFile(QString filename, ccHObject& container, bool alwaysDisplayLoadDialog/*=true*/, bool* coordinatesShiftEnabled/*=0*/, CCVector3d* coordinatesShift/*=0*/) { GDALAllRegister(); ccLog::PrintDebug("(GDAL drivers: %i)", GetGDALDriverManager()->GetDriverCount()); GDALDataset* poDataset = static_cast<GDALDataset*>(GDALOpen( qPrintable(filename), GA_ReadOnly )); if( poDataset != NULL ) { ccLog::Print(QString("Raster file: '%1'").arg(filename)); ccLog::Print( "Driver: %s/%s", poDataset->GetDriver()->GetDescription(), poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME ) ); int rasterCount = poDataset->GetRasterCount(); int rasterX = poDataset->GetRasterXSize(); int rasterY = poDataset->GetRasterYSize(); ccLog::Print( "Size is %dx%dx%d", rasterX, rasterY, rasterCount ); ccPointCloud* pc = new ccPointCloud(); if (!pc->reserve(static_cast<unsigned>(rasterX * rasterY))) { delete pc; return CC_FERR_NOT_ENOUGH_MEMORY; } if( poDataset->GetProjectionRef() != NULL ) ccLog::Print( "Projection is `%s'", poDataset->GetProjectionRef() ); double adfGeoTransform[6] = { 0, //top left x 1, //w-e pixel resolution (can be negative) 0, //0 0, //top left y 0, //0 1 //n-s pixel resolution (can be negative) }; if( poDataset->GetGeoTransform( adfGeoTransform ) == CE_None ) { ccLog::Print( "Origin = (%.6f,%.6f)", adfGeoTransform[0], adfGeoTransform[3] ); ccLog::Print( "Pixel Size = (%.6f,%.6f)", adfGeoTransform[1], adfGeoTransform[5] ); } if (adfGeoTransform[1] == 0 || adfGeoTransform[5] == 0) { ccLog::Warning("Invalid pixel size! Forcing it to (1,1)"); adfGeoTransform[1] = adfGeoTransform[5] = 1; } CCVector3d origin( adfGeoTransform[0], adfGeoTransform[3], 0.0 ); CCVector3d Pshift(0,0,0); //check for 'big' coordinates { bool shiftAlreadyEnabled = (coordinatesShiftEnabled && *coordinatesShiftEnabled && coordinatesShift); if (shiftAlreadyEnabled) Pshift = *coordinatesShift; bool applyAll = false; if ( sizeof(PointCoordinateType) < 8 && ccCoordinatesShiftManager::Handle(origin,0,alwaysDisplayLoadDialog,shiftAlreadyEnabled,Pshift,0,&applyAll)) { pc->setGlobalShift(Pshift); ccLog::Warning("[RasterFilter::loadFile] Raster has been recentered! Translation: (%.2f,%.2f,%.2f)",Pshift.x,Pshift.y,Pshift.z); //we save coordinates shift information if (applyAll && coordinatesShiftEnabled && coordinatesShift) { *coordinatesShiftEnabled = true; *coordinatesShift = Pshift; } } } //create blank raster 'grid' { double z = 0.0 /*+ Pshift.z*/; for (int j=0; j<rasterY; ++j) { double y = adfGeoTransform[3] + static_cast<double>(j) * adfGeoTransform[5] + Pshift.y; CCVector3 P( 0, static_cast<PointCoordinateType>(y), static_cast<PointCoordinateType>(z)); for (int i=0; i<rasterX; ++i) { double x = adfGeoTransform[0] + static_cast<double>(i) * adfGeoTransform[1] + Pshift.x; P.x = static_cast<PointCoordinateType>(x); pc->addPoint(P); } } QVariant xVar = QVariant::fromValue<int>(rasterX); QVariant yVar = QVariant::fromValue<int>(rasterY); pc->setMetaData("raster_width",xVar); pc->setMetaData("raster_height",yVar); } //fetch raster bands bool zRasterProcessed = false; unsigned zInvalid = 0; double zMinMax[2] = {0, 0}; for (int i=1; i<=rasterCount; ++i) { ccLog::Print( "Reading band #%i", i); GDALRasterBand* poBand = poDataset->GetRasterBand(i); GDALColorInterp colorInterp = poBand->GetColorInterpretation(); GDALDataType bandType = poBand->GetRasterDataType(); int nBlockXSize, nBlockYSize; poBand->GetBlockSize( &nBlockXSize, &nBlockYSize ); ccLog::Print( "Block=%dx%d Type=%s, ColorInterp=%s", nBlockXSize, nBlockYSize, GDALGetDataTypeName(poBand->GetRasterDataType()), GDALGetColorInterpretationName(colorInterp) ); //fetching raster scan-line int nXSize = poBand->GetXSize(); int nYSize = poBand->GetYSize(); assert(nXSize == rasterX); assert(nYSize == rasterY); int bGotMin, bGotMax; double adfMinMax[2] = {0, 0}; adfMinMax[0] = poBand->GetMinimum( &bGotMin ); adfMinMax[1] = poBand->GetMaximum( &bGotMax ); if (!bGotMin || !bGotMax ) //DGM FIXME: if the file is corrupted (e.g. ASCII ArcGrid with missing rows) this method will enter in a infinite loop! GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax); ccLog::Print( "Min=%.3fd, Max=%.3f", adfMinMax[0], adfMinMax[1] ); GDALColorTable* colTable = poBand->GetColorTable(); if( colTable != NULL ) printf( "Band has a color table with %d entries", colTable->GetColorEntryCount() ); if( poBand->GetOverviewCount() > 0 ) printf( "Band has %d overviews", poBand->GetOverviewCount() ); if (colorInterp == GCI_Undefined && !zRasterProcessed/*&& !colTable*/) //probably heights? { zRasterProcessed = true; zMinMax[0] = adfMinMax[0]; zMinMax[1] = adfMinMax[1]; double* scanline = (double*) CPLMalloc(sizeof(double)*nXSize); //double* scanline = new double[nXSize]; memset(scanline,0,sizeof(double)*nXSize); for (int j=0; j<nYSize; ++j) { if (poBand->RasterIO( GF_Read, /*xOffset=*/0, /*yOffset=*/j, /*xSize=*/nXSize, /*ySize=*/1, /*buffer=*/scanline, /*bufferSizeX=*/nXSize, /*bufferSizeY=*/1, /*bufferType=*/GDT_Float64, /*x_offset=*/0, /*y_offset=*/0 ) != CE_None) { delete pc; CPLFree(scanline); GDALClose(poDataset); return CC_FERR_READING; } for (int k=0; k<nXSize; ++k) { double z = static_cast<double>(scanline[k]) + Pshift[2]; unsigned pointIndex = static_cast<unsigned>(k + j * rasterX); if (pointIndex <= pc->size()) { if (z < zMinMax[0] || z > zMinMax[1]) { z = zMinMax[0] - 1.0; ++zInvalid; } const_cast<CCVector3*>(pc->getPoint(pointIndex))->z = static_cast<PointCoordinateType>(z); } } } //update bounding-box pc->invalidateBoundingBox(); if (scanline) CPLFree(scanline); scanline = 0; } else //colors { bool isRGB = false; bool isScalar = false; bool isPalette = false; switch(colorInterp) { case GCI_Undefined: isScalar = true; break; case GCI_PaletteIndex: isPalette = true; break; case GCI_RedBand: case GCI_GreenBand: case GCI_BlueBand: isRGB = true; break; case GCI_AlphaBand: if (adfMinMax[0] != adfMinMax[1]) isScalar = true; else ccLog::Warning(QString("Alpha band ignored as it has a unique value (%1)").arg(adfMinMax[0])); break; default: isScalar = true; break; } if (isRGB || isPalette) { //first check that a palette exists if the band is a palette index if (isPalette && !colTable) { ccLog::Warning(QString("Band is declared as a '%1' but no palette is associated!").arg(GDALGetColorInterpretationName(colorInterp))); isPalette = false; } else { //instantiate memory for RBG colors if necessary if (!pc->hasColors() && !pc->setRGBColor(MAX_COLOR_COMP,MAX_COLOR_COMP,MAX_COLOR_COMP)) { ccLog::Warning(QString("Failed to instantiate memory for storing color band '%1'!").arg(GDALGetColorInterpretationName(colorInterp))); } else { assert(bandType <= GDT_Int32); int* colIndexes = (int*) CPLMalloc(sizeof(int)*nXSize); //double* scanline = new double[nXSize]; memset(colIndexes,0,sizeof(int)*nXSize); for (int j=0; j<nYSize; ++j) { if (poBand->RasterIO( GF_Read, /*xOffset=*/0, /*yOffset=*/j, /*xSize=*/nXSize, /*ySize=*/1, /*buffer=*/colIndexes, /*bufferSizeX=*/nXSize, /*bufferSizeY=*/1, /*bufferType=*/GDT_Int32, /*x_offset=*/0, /*y_offset=*/0 ) != CE_None) { CPLFree(colIndexes); delete pc; return CC_FERR_READING; } for (int k=0; k<nXSize; ++k) { unsigned pointIndex = static_cast<unsigned>(k + j * rasterX); if (pointIndex <= pc->size()) { colorType* C = const_cast<colorType*>(pc->getPointColor(pointIndex)); switch(colorInterp) { case GCI_PaletteIndex: assert(colTable); { GDALColorEntry col; colTable->GetColorEntryAsRGB(colIndexes[k],&col); C[0] = static_cast<colorType>(col.c1 & MAX_COLOR_COMP); C[1] = static_cast<colorType>(col.c2 & MAX_COLOR_COMP); C[2] = static_cast<colorType>(col.c3 & MAX_COLOR_COMP); } break; case GCI_RedBand: C[0] = static_cast<colorType>(colIndexes[k] & MAX_COLOR_COMP); break; case GCI_GreenBand: C[1] = static_cast<colorType>(colIndexes[k] & MAX_COLOR_COMP); break; case GCI_BlueBand: C[2] = static_cast<colorType>(colIndexes[k] & MAX_COLOR_COMP); break; default: assert(false); break; } } } } if (colIndexes) CPLFree(colIndexes); colIndexes = 0; pc->showColors(true); } } } else if (isScalar) { ccScalarField* sf = new ccScalarField(GDALGetColorInterpretationName(colorInterp)); if (!sf->resize(pc->size(),true,NAN_VALUE)) { ccLog::Warning(QString("Failed to instantiate memory for storing '%1' as a scalar field!").arg(sf->getName())); sf->release(); sf = 0; } else { double* colValues = (double*) CPLMalloc(sizeof(double)*nXSize); //double* scanline = new double[nXSize]; memset(colValues,0,sizeof(double)*nXSize); for (int j=0; j<nYSize; ++j) { if (poBand->RasterIO( GF_Read, /*xOffset=*/0, /*yOffset=*/j, /*xSize=*/nXSize, /*ySize=*/1, /*buffer=*/colValues, /*bufferSizeX=*/nXSize, /*bufferSizeY=*/1, /*bufferType=*/GDT_Float64, /*x_offset=*/0, /*y_offset=*/0 ) != CE_None) { CPLFree(colValues); delete pc; return CC_FERR_READING; } for (int k=0; k<nXSize; ++k) { unsigned pointIndex = static_cast<unsigned>(k + j * rasterX); if (pointIndex <= pc->size()) { ScalarType s = static_cast<ScalarType>(colValues[k]); sf->setValue(pointIndex,s); } } } if (colValues) CPLFree(colValues); colValues = 0; sf->computeMinAndMax(); pc->addScalarField(sf); if (pc->getNumberOfScalarFields() == 1) pc->setCurrentDisplayedScalarField(0); pc->showSF(true); } } } } if (pc) { if (!zRasterProcessed) { ccLog::Warning("Raster has no height (Z) information: you can convert one of its scalar fields to Z with 'Edit > Scalar Fields > Set SF as coordinate(s)'"); } else if (zInvalid != 0 && zInvalid < pc->size()) { //shall we remove the points with invalid heights? if (QMessageBox::question(0,"Remove NaN points?","This raster has pixels with invalid heights. Shall we remove them?",QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) { CCLib::ReferenceCloud validPoints(pc); unsigned count = pc->size(); bool error = true; if (validPoints.reserve(count-zInvalid)) { for (unsigned i=0; i<count; ++i) { if (pc->getPoint(i)->z >= zMinMax[0]) validPoints.addPointIndex(i); } if (validPoints.size() > 0) { validPoints.resize(validPoints.size()); ccPointCloud* newPC = pc->partialClone(&validPoints); if (newPC) { delete pc; pc = newPC; error = false; } } else { assert(false); } } if (error) { ccLog::Error("Not enough memory to remove the points with invalid heights!"); } } } container.addChild(pc); } GDALClose(poDataset); } else { return CC_FERR_UNKNOWN_FILE; } return CC_FERR_NO_ERROR; }
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 Terrain::initTerrainFile() { auto t = map_file.toLatin1(); dataset = (GDALDataset*) GDALOpen(t.constData(), GA_ReadOnly); if(dataset == nullptr) { qDebug() << "Unable to get GDAL Dataset for file: " << map_file; exit(1); } GDALRasterBand *raster = dataset->GetRasterBand(1); int width = raster->GetXSize();//terrain_img.getWidth(); int height = raster->GetYSize();//terrain_img.getHeight(); int gotMin, gotMax; float min = raster->GetMinimum(&gotMin); float max = raster->GetMaximum(&gotMax); double minMax[2] = {min, max}; if(!(gotMin && gotMax)) { GDALComputeRasterMinMax((GDALRasterBandH) raster, TRUE, minMax); min = minMax[0]; max = minMax[1]; } if(engine->getOptions().verbose) qDebug() << "terrain: " << map_file << "x: " << width << " y: " << height << " min: " << min << " max: " << max; int woffset = width / 2; int hoffset = height / 2; Vertex tempVert; tempVert.position[1] = 0; float maxOffset = max - min; float scale = engine->getOptions().map_scalar; float *lineData = (float*) CPLMalloc(sizeof(float) * width); float *lineData2 = (float*) CPLMalloc(sizeof(float) * width); for(int z = -hoffset; z < height - hoffset-1; z++) { raster->RasterIO(GF_Read, 0, z + hoffset, width, 1, lineData, width, 1, GDT_Float32, 0, 0); raster->RasterIO(GF_Read, 0, z + hoffset + 1, width, 1, lineData2, width, 1, GDT_Float32, 0, 0); for(int x = -woffset; x < width - woffset-1; x++) { tempVert.position[0] = x*scale; tempVert.position[1] = (lineData[x+woffset]-min) / maxOffset; tempVert.position[2] = z*scale; geometry.push_back(tempVert); tempVert.position[0] = (x+1) * scale; tempVert.position[1] = (lineData[x+woffset+1]-min) / maxOffset; tempVert.position[2] = z*scale; geometry.push_back(tempVert); tempVert.position[0] = x*scale; tempVert.position[1] = (lineData2[x+woffset]-min) / maxOffset; tempVert.position[2] = (z+1) * scale; geometry.push_back(tempVert); // push bottom row of triangles tempVert.position[0] = x*scale; tempVert.position[1] = (lineData2[x+woffset]-min) / maxOffset; tempVert.position[2] = (z+1) * scale; geometry.push_back(tempVert); tempVert.position[0] = (x+1) * scale; tempVert.position[1] = (lineData2[x+woffset+1]-min) / maxOffset; tempVert.position[2] = (z+1) * scale; geometry.push_back(tempVert); tempVert.position[0] = (x+1) * scale; tempVert.position[1] = (lineData[x+woffset+1]-min) / maxOffset; tempVert.position[2] = z*scale; geometry.push_back(tempVert); } } CPLFree(lineData); CPLFree(lineData2); }
/* * 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 ); }
void GDALBlockAccessor::open(const Char8 *szFilename) { #ifdef OSG_WITH_GDAL _pDataset = static_cast<GDALDataset *>(GDALOpen(szFilename, GA_ReadOnly)); if(_pDataset != NULL) { _pGeoRef = GeoReferenceAttachment::create(); double adfGeoTransform[6]; if(_pDataset->GetGeoTransform(adfGeoTransform) == CE_None) { _pGeoRef->editOrigin().setValues(adfGeoTransform[0], adfGeoTransform[3]); _pGeoRef->editPixelSize().setValues(adfGeoTransform[1], adfGeoTransform[5]); if(GDALGetProjectionRef(_pDataset) != NULL) { OGRSpatialReferenceH hSRS; Char8 *szProjection = const_cast<char *>(GDALGetProjectionRef(_pDataset)); hSRS = OSRNewSpatialReference(NULL); if(OSRImportFromWkt(hSRS, &szProjection) == CE_None) { _pGeoRef->editEllipsoidAxis().setValues( OSRGetSemiMajor(hSRS, NULL), OSRGetSemiMinor(hSRS, NULL)); const Char8 *szDatum = OSRGetAttrValue(hSRS, "DATUM", 0); if(szDatum != NULL && 0 == strcmp(szDatum, "WGS_1984")) { _pGeoRef->editDatum() = GeoReferenceAttachment::WGS84; } else { fprintf(stderr, "Unknow datum %s\n", szDatum); _pGeoRef->editDatum() = GeoReferenceAttachment::UnknownDatum; } } OSRDestroySpatialReference(hSRS); } } int nBlockXSize, nBlockYSize; int bGotMin, bGotMax; double adfMinMax[2]; _pBand = _pDataset->GetRasterBand(1); _pBand->GetBlockSize(&nBlockXSize, &nBlockYSize); adfMinMax[0] = _pBand->GetMinimum(&bGotMin); adfMinMax[1] = _pBand->GetMaximum(&bGotMax); if(!(bGotMin && bGotMax)) { GDALComputeRasterMinMax(GDALRasterBandH(_pBand), TRUE, adfMinMax); } if(_pBand != NULL) { _eImgFormat = Image::OSG_INVALID_PF; switch(_pDataset->GetRasterCount()) { case 1: _eImgFormat = Image::OSG_L_PF; break; case 2: _eImgFormat = Image::OSG_LA_PF; break; case 3: _eImgFormat = Image::OSG_RGB_PF; break; case 4: _eImgFormat = Image::OSG_RGBA_PF; break; } _eImgType = Image::OSG_INVALID_IMAGEDATATYPE; switch(_pBand->GetRasterDataType()) { case GDT_Byte: _eImgType = Image::OSG_UINT8_IMAGEDATA; break; case GDT_UInt16: _eImgType = Image::OSG_UINT16_IMAGEDATA; break; case GDT_Int16: _eImgType = Image::OSG_INT16_IMAGEDATA; break; case GDT_UInt32: _eImgType = Image::OSG_UINT32_IMAGEDATA; break; case GDT_Int32: _eImgType = Image::OSG_INT32_IMAGEDATA; break; case GDT_Float32: _eImgType = Image::OSG_FLOAT32_IMAGEDATA; break; case GDT_Float64: case GDT_CInt16: case GDT_CInt32: case GDT_CFloat32: case GDT_CFloat64: default: GDALClose(_pDataset); _pDataset = NULL; break; } _vSize[0] = _pDataset->GetRasterXSize(); _vSize[1] = _pDataset->GetRasterYSize(); _fNoDataValue = _pBand->GetNoDataValue(); _pGeoRef->setNoDataValue(_fNoDataValue); } } #endif }
bool GdalAdapter::loadImage(const QString& fn) { if (alreadyLoaded(fn)) return true; QFileInfo fi(fn); GdalImage img; QRectF bbox; poDataset = (GDALDataset *) GDALOpen( QDir::toNativeSeparators(fi.absoluteFilePath()).toUtf8().constData(), GA_ReadOnly ); if( poDataset == NULL ) { qDebug() << "GDAL Open failed: " << fn; return false; } bool hasGeo = false; QDir dir(fi.absoluteDir()); QString f = fi.baseName(); QStringList wldFilter; wldFilter << f+".tfw" << f+".tifw" << f+".tiffw" << f+".wld"; QFileInfoList fil = dir.entryInfoList(wldFilter); if (fil.count()) { QFile wld(fil[0].absoluteFilePath()); if (wld.open(QIODevice::ReadOnly)) { int i; for (i=0; i<6; ++i) { if (wld.atEnd()) break; QString l = wld.readLine(); bool ok; double d = l.toDouble(&ok); if (!ok) break; switch (i) { case 0: img.adfGeoTransform[1] = d; break; case 1: img.adfGeoTransform[4] = d; break; case 2: img.adfGeoTransform[2] = d; break; case 3: img.adfGeoTransform[5] = d; break; case 4: img.adfGeoTransform[0] = d; break; case 5: img.adfGeoTransform[3] = d; break; } } if (i == 6) hasGeo = true; } } if(!hasGeo) if ( poDataset->GetGeoTransform( img.adfGeoTransform ) != CE_None ) { GDALClose((GDALDatasetH)poDataset); return false; } qDebug( "Origin = (%.6f,%.6f)\n", img.adfGeoTransform[0], img.adfGeoTransform[3] ); qDebug( "Pixel Size = (%.6f,%.6f)\n", img.adfGeoTransform[1], img.adfGeoTransform[5] ); bbox.setTopLeft(QPointF(img.adfGeoTransform[0], img.adfGeoTransform[3])); bbox.setWidth(img.adfGeoTransform[1]*poDataset->GetRasterXSize()); bbox.setHeight(img.adfGeoTransform[5]*poDataset->GetRasterYSize()); isLatLon = false; if( strlen(poDataset->GetProjectionRef()) != 0 ) { qDebug( "Projection is `%s'\n", poDataset->GetProjectionRef() ); OGRSpatialReference* theSrs = new OGRSpatialReference(poDataset->GetProjectionRef()); if (theSrs && theSrs->Validate() == OGRERR_NONE) { theSrs->morphFromESRI(); char* theProj4; if (theSrs->exportToProj4(&theProj4) == OGRERR_NONE) { qDebug() << "GDAL: to proj4 : " << theProj4; } else { qDebug() << "GDAL: to proj4 error: " << CPLGetLastErrorMsg(); GDALClose((GDALDatasetH)poDataset); return false; } QString srsProj = QString(theProj4); if (!srsProj.isEmpty() && theProjection != srsProj) { cleanup(); theProjection = srsProj; } isLatLon = (theSrs->IsGeographic() == TRUE); } } if (theProjection.isEmpty()) { theProjection = ProjectionChooser::getProjection(QCoreApplication::translate("ImportExportGdal", "Unable to set projection; please specify one")); if (theProjection.isEmpty()) { GDALClose((GDALDatasetH)poDataset); return false; } } qDebug( "Driver: %s/%s\n", poDataset->GetDriver()->GetDescription(), poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME ) ); qDebug( "Size is %dx%dx%d\n", poDataset->GetRasterXSize(), poDataset->GetRasterYSize(), poDataset->GetRasterCount() ); GdalAdapter::ImgType theType = GdalAdapter::Unknown; int bandCount = poDataset->GetRasterCount(); int ixA = -1; int ixR, ixG, ixB; int ixH, ixS, ixL; int ixC, ixM, ixY, ixK; int ixYuvY, ixYuvU, ixYuvV; double adfMinMax[2]; double UnknownUnit; GDALColorTable* colTable = NULL; for (int i=0; i<bandCount; ++i) { GDALRasterBand *poBand = poDataset->GetRasterBand( i+1 ); GDALColorInterp bandtype = poBand->GetColorInterpretation(); qDebug() << "Band " << i+1 << " Color: " << GDALGetColorInterpretationName(poBand->GetColorInterpretation()); switch (bandtype) { case GCI_Undefined: theType = GdalAdapter::Unknown; int bGotMin, bGotMax; adfMinMax[0] = poBand->GetMinimum( &bGotMin ); adfMinMax[1] = poBand->GetMaximum( &bGotMax ); if( ! (bGotMin && bGotMax) ) GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax); UnknownUnit = (adfMinMax[1] - adfMinMax[0]) / 256; break; case GCI_GrayIndex: theType = GdalAdapter::GrayScale; break; case GCI_RedBand: theType = GdalAdapter::Rgb; ixR = i; break; case GCI_GreenBand: theType = GdalAdapter::Rgb; ixG = i; break; case GCI_BlueBand : theType = GdalAdapter::Rgb; ixB = i; break; case GCI_HueBand: theType = GdalAdapter::Hsl; ixH = i; break; case GCI_SaturationBand: theType = GdalAdapter::Hsl; ixS = i; break; case GCI_LightnessBand: theType = GdalAdapter::Hsl; ixL = i; break; case GCI_CyanBand: theType = GdalAdapter::Cmyk; ixC = i; break; case GCI_MagentaBand: theType = GdalAdapter::Cmyk; ixM = i; break; case GCI_YellowBand: theType = GdalAdapter::Cmyk; ixY = i; break; case GCI_BlackBand: theType = GdalAdapter::Cmyk; ixK = i; break; case GCI_YCbCr_YBand: theType = GdalAdapter::YUV; ixYuvY = i; break; case GCI_YCbCr_CbBand: theType = GdalAdapter::YUV; ixYuvU = i; break; case GCI_YCbCr_CrBand: theType = GdalAdapter::YUV; ixYuvV = i; break; case GCI_AlphaBand: ixA = i; break; case GCI_PaletteIndex: colTable = poBand->GetColorTable(); switch (colTable->GetPaletteInterpretation()) { case GPI_Gray : theType = GdalAdapter::Palette_Gray; break; case GPI_RGB : theType = GdalAdapter::Palette_RGBA; break; case GPI_CMYK : theType = GdalAdapter::Palette_CMYK; break; case GPI_HLS : theType = GdalAdapter::Palette_HLS; break; } break; } } QSize theImgSize(poDataset->GetRasterXSize(), poDataset->GetRasterYSize()); QImage theImg = QImage(theImgSize, QImage::Format_ARGB32); // Make sure that lineBuf holds one whole line of data. float *lineBuf; lineBuf = (float *) CPLMalloc(theImgSize.width() * bandCount * sizeof(float)); int px, py; //every row loop for (int row = 0; row < theImgSize.height(); row++) { py = row; poDataset->RasterIO( GF_Read, 0, row, theImgSize.width(), 1, lineBuf, theImgSize.width(), 1, GDT_Float32, bandCount, NULL, sizeof(float) * bandCount, 0, sizeof(float) ); // every pixel in row. for (int col = 0; col < theImgSize.width(); col++){ px = col; switch (theType) { case GdalAdapter::Unknown: { float* v = lineBuf + (col*bandCount); float val = (*v - adfMinMax[0]) / UnknownUnit; theImg.setPixel(px, py, qRgb(val, val, val)); break; } case GdalAdapter::GrayScale: { float* v = lineBuf + (col*bandCount); theImg.setPixel(px, py, qRgb(*v, *v, *v)); break; } case GdalAdapter::Rgb: { float* r = lineBuf + (col*bandCount) + ixR; float* g = lineBuf + (col*bandCount) + ixG; float* b = lineBuf + (col*bandCount) + ixB; int a = 255; if (ixA != -1) { float* fa = lineBuf + (col*bandCount) + ixA; a = *fa; } theImg.setPixel(px, py, qRgba(*r, *g, *b, a)); break; } #if QT_VERSION >= 0x040600 case GdalAdapter::Hsl: { float* h = lineBuf + (col*bandCount) + ixH; float* s = lineBuf + (col*bandCount) + ixS; float* l = lineBuf + (col*bandCount) + ixL; int a = 255; if (ixA != -1) { float* fa = lineBuf + (col*bandCount) + ixA; a = *fa; } QColor C = QColor::fromHsl(*h, *s, *l, a); theImg.setPixel(px, py, C.rgba()); break; } #endif case GdalAdapter::Cmyk: { float* c = lineBuf + (col*bandCount) + ixC; float* m = lineBuf + (col*bandCount) + ixM; float* y = lineBuf + (col*bandCount) + ixY; float* k = lineBuf + (col*bandCount) + ixK; int a = 255; if (ixA != -1) { float* fa = lineBuf + (col*bandCount) + ixA; a = *fa; } QColor C = QColor::fromCmyk(*c, *m, *y, *k, a); theImg.setPixel(px, py, C.rgba()); break; } case GdalAdapter::YUV: { // From http://www.fourcc.org/fccyvrgb.php float* y = lineBuf + (col*bandCount) + ixYuvY; float* u = lineBuf + (col*bandCount) + ixYuvU; float* v = lineBuf + (col*bandCount) + ixYuvV; int a = 255; if (ixA != -1) { float* fa = lineBuf + (col*bandCount) + ixA; a = *fa; } float R = 1.164*(*y - 16) + 1.596*(*v - 128); float G = 1.164*(*y - 16) - 0.813*(*v - 128) - 0.391*(*u - 128); float B = 1.164*(*y - 16) + 2.018*(*u - 128); theImg.setPixel(px, py, qRgba(R, G, B, a)); break; } case GdalAdapter::Palette_Gray: { float* ix = (lineBuf + (col*bandCount)); const GDALColorEntry* color = colTable->GetColorEntry(*ix); theImg.setPixel(px, py, qRgb(color->c1, color->c1, color->c1)); break; } case GdalAdapter::Palette_RGBA: { float* ix = (lineBuf + (col*bandCount)); const GDALColorEntry* color = colTable->GetColorEntry(*ix); theImg.setPixel(px, py, qRgba(color->c1, color->c2, color->c3, color->c4)); break; } #if QT_VERSION >= 0x040600 case GdalAdapter::Palette_HLS: { float* ix = (lineBuf + (col*bandCount)); const GDALColorEntry* color = colTable->GetColorEntry(*ix); QColor C = QColor::fromHsl(color->c1, color->c2, color->c3, color->c4); theImg.setPixel(px, py, C.rgba()); break; } #endif case GdalAdapter::Palette_CMYK: { float* ix = (lineBuf + (col*bandCount)); const GDALColorEntry* color = colTable->GetColorEntry(*ix); QColor C = QColor::fromCmyk(color->c1, color->c2, color->c3, color->c4); theImg.setPixel(px, py, C.rgba()); break; } } } QCoreApplication::processEvents(); } img.theFilename = fn; img.theImg = QPixmap::fromImage(theImg); theImages.push_back(img); theBbox = theBbox.united(bbox); GDALClose((GDALDatasetH)poDataset); return true; }
bool GDALImageFileType::read( Image *OSG_GDAL_ARG(pImage), const Char8 *OSG_GDAL_ARG(fileName)) { #ifdef OSG_WITH_GDAL bool returnValue = false; GDALDataset *pDataset; pDataset = static_cast<GDALDataset *>(GDALOpen(fileName, GA_ReadOnly)); if(pDataset != NULL) { GeoReferenceAttachmentUnrecPtr pGeoRef = GeoReferenceAttachment::create(); pImage->addAttachment(pGeoRef); double adfGeoTransform[6]; if(pDataset->GetGeoTransform(adfGeoTransform) == CE_None) { pGeoRef->editOrigin().setValues(adfGeoTransform[0], adfGeoTransform[3]); pGeoRef->editPixelSize().setValues(adfGeoTransform[1], adfGeoTransform[5]); if(GDALGetProjectionRef(pDataset) != NULL) { OGRSpatialReferenceH hSRS; Char8 *szProjection = const_cast<char *>(GDALGetProjectionRef(pDataset)); hSRS = OSRNewSpatialReference(NULL); if(OSRImportFromWkt(hSRS, &szProjection) == CE_None) { pGeoRef->editEllipsoidAxis().setValues( OSRGetSemiMajor(hSRS, NULL), OSRGetSemiMinor(hSRS, NULL)); const Char8 *szDatum = OSRGetAttrValue(hSRS, "DATUM", 0); if(szDatum != NULL && 0 == strcmp(szDatum, "WGS_1984")) { pGeoRef->editDatum() = GeoReferenceAttachment::WGS84; } else { fprintf(stderr, "Unknow datum %s\n", szDatum); pGeoRef->editDatum() = GeoReferenceAttachment::UnknownDatum; } } OSRDestroySpatialReference(hSRS); } } GDALRasterBand *pBand; int nBlockXSize, nBlockYSize; int bGotMin, bGotMax; double adfMinMax[2]; pBand = pDataset->GetRasterBand( 1 ); pBand->GetBlockSize( &nBlockXSize, &nBlockYSize ); adfMinMax[0] = pBand->GetMinimum( &bGotMin ); adfMinMax[1] = pBand->GetMaximum( &bGotMax ); if(!(bGotMin && bGotMax)) GDALComputeRasterMinMax(GDALRasterBandH(pBand), TRUE, adfMinMax); pBand = pDataset->GetRasterBand(1); if(pBand != NULL) { Image::PixelFormat ePF = Image::OSG_INVALID_PF; switch(pDataset->GetRasterCount()) { case 1: ePF = Image::OSG_L_PF; break; case 2: ePF = Image::OSG_LA_PF; break; case 3: ePF = Image::OSG_RGB_PF; break; case 4: ePF = Image::OSG_RGBA_PF; break; } Image::Type eDT = Image::OSG_INVALID_IMAGEDATATYPE; switch(pBand->GetRasterDataType()) { case GDT_Byte: eDT = Image::OSG_UINT8_IMAGEDATA; break; case GDT_UInt16: eDT = Image::OSG_UINT16_IMAGEDATA; break; case GDT_Int16: eDT = Image::OSG_INT16_IMAGEDATA; break; case GDT_UInt32: eDT = Image::OSG_UINT32_IMAGEDATA; break; case GDT_Int32: eDT = Image::OSG_INT32_IMAGEDATA; break; case GDT_Float32: eDT = Image::OSG_FLOAT32_IMAGEDATA; break; case GDT_Float64: case GDT_CInt16: case GDT_CInt32: case GDT_CFloat32: case GDT_CFloat64: default: GDALClose(pDataset); return returnValue; break; } pImage->set(ePF, pDataset->GetRasterXSize(), pDataset->GetRasterYSize(), 1, 1, 1, 0.0, NULL, eDT); UChar8 *dst = pImage->editData(); pBand->RasterIO(GF_Read, 0, 0, pDataset->GetRasterXSize(), pDataset->GetRasterYSize(), dst, pDataset->GetRasterXSize(), pDataset->GetRasterYSize(), pBand->GetRasterDataType(), 0, 0); pGeoRef->setNoDataValue(pBand->GetNoDataValue()); returnValue = true; } GDALClose(pDataset); } return returnValue; #else SWARNING << getMimeType() << " read is not compiled into the current binary " << std::endl; return false; #endif // OSG_WITH_GDAL }
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 ); }
static int ProxyMain(int argc, char **argv) { GDALDatasetH hDataset, hOutDS; int i; int nRasterXSize, nRasterYSize; const char *pszSource = NULL, *pszDest = NULL, *pszFormat = "GTiff"; GDALDriverH hDriver; int *panBandList = NULL; /* negative value of panBandList[i] means mask band of ABS(panBandList[i]) */ int nBandCount = 0, bDefBands = TRUE; double adfGeoTransform[6]; GDALDataType eOutputType = GDT_Unknown; int nOXSize = 0, nOYSize = 0; char *pszOXSize = NULL, *pszOYSize = NULL; char **papszCreateOptions = NULL; int anSrcWin[4], bStrict = FALSE; const char *pszProjection; int bScale = FALSE, bHaveScaleSrc = FALSE, bUnscale = FALSE; double dfScaleSrcMin = 0.0, dfScaleSrcMax = 255.0; double dfScaleDstMin = 0.0, dfScaleDstMax = 255.0; double dfULX, dfULY, dfLRX, dfLRY; char **papszMetadataOptions = NULL; char *pszOutputSRS = NULL; int bQuiet = FALSE, bGotBounds = FALSE; GDALProgressFunc pfnProgress = GDALTermProgress; int nGCPCount = 0; GDAL_GCP *pasGCPs = NULL; int iSrcFileArg = -1, iDstFileArg = -1; int bCopySubDatasets = FALSE; double adfULLR[4] = { 0, 0, 0, 0 }; int bSetNoData = FALSE; int bUnsetNoData = FALSE; double dfNoDataReal = 0.0; int nRGBExpand = 0; int bParsedMaskArgument = FALSE; int eMaskMode = MASK_AUTO; int nMaskBand = 0; /* negative value means mask band of ABS(nMaskBand) */ int bStats = FALSE, bApproxStats = FALSE; anSrcWin[0] = 0; anSrcWin[1] = 0; anSrcWin[2] = 0; anSrcWin[3] = 0; dfULX = dfULY = dfLRX = dfLRY = 0.0; /* Check strict compilation and runtime library version as we use C++ API */ if (!GDAL_CHECK_VERSION(argv[0])) 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; } } /* -------------------------------------------------------------------- */ /* Register standard GDAL drivers, and process generic GDAL */ /* command options. */ /* -------------------------------------------------------------------- */ GDALAllRegister(); argc = GDALGeneralCmdLineProcessor(argc, &argv, 0); if (argc < 1) exit(-argc); /* -------------------------------------------------------------------- */ /* Handle command line 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], "-of") && i < argc - 1) pszFormat = argv[++i]; else if (EQUAL(argv[i], "-q") || EQUAL(argv[i], "-quiet")) { bQuiet = TRUE; pfnProgress = GDALDummyProgress; } else if (EQUAL(argv[i], "-ot") && i < argc - 1) { int iType; for (iType = 1; iType < GDT_TypeCount; iType++) { if (GDALGetDataTypeName((GDALDataType)iType) != NULL && EQUAL(GDALGetDataTypeName((GDALDataType)iType), argv[i + 1])) { eOutputType = (GDALDataType) iType; } } if (eOutputType == GDT_Unknown) { printf("Unknown output pixel type: %s\n", argv[i + 1]); Usage(); GDALDestroyDriverManager(); exit(2); } i++; } else if (EQUAL(argv[i], "-b") && i < argc - 1) { const char *pszBand = argv[i + 1]; int bMask = FALSE; if (EQUAL(pszBand, "mask")) pszBand = "mask,1"; if (EQUALN(pszBand, "mask,", 5)) { bMask = TRUE; pszBand += 5; /* If we use tha source mask band as a regular band */ /* don't create a target mask band by default */ if (!bParsedMaskArgument) eMaskMode = MASK_DISABLED; } int nBand = atoi(pszBand); if (nBand < 1) { printf("Unrecognizable band number (%s).\n", argv[i + 1]); Usage(); GDALDestroyDriverManager(); exit(2); } i++; nBandCount++; panBandList = (int*) CPLRealloc(panBandList, sizeof(int) * nBandCount); panBandList[nBandCount - 1] = nBand; if (bMask) panBandList[nBandCount - 1] *= -1; if (panBandList[nBandCount - 1] != nBandCount) bDefBands = FALSE; } else if (EQUAL(argv[i], "-mask") && i < argc - 1) { bParsedMaskArgument = TRUE; const char *pszBand = argv[i + 1]; if (EQUAL(pszBand, "none")) { eMaskMode = MASK_DISABLED; } else if (EQUAL(pszBand, "auto")) { eMaskMode = MASK_AUTO; } else { int bMask = FALSE; if (EQUAL(pszBand, "mask")) pszBand = "mask,1"; if (EQUALN(pszBand, "mask,", 5)) { bMask = TRUE; pszBand += 5; } int nBand = atoi(pszBand); if (nBand < 1) { printf("Unrecognizable band number (%s).\n", argv[i + 1]); Usage(); GDALDestroyDriverManager(); exit(2); } eMaskMode = MASK_USER; nMaskBand = nBand; if (bMask) nMaskBand *= -1; } i++; } else if (EQUAL(argv[i], "-not_strict")) bStrict = FALSE; else if (EQUAL(argv[i], "-strict")) bStrict = TRUE; else if (EQUAL(argv[i], "-sds")) bCopySubDatasets = TRUE; else if (EQUAL(argv[i], "-gcp") && i < argc - 4) { char *endptr = NULL; /* -gcp pixel line easting northing [elev] */ nGCPCount++; pasGCPs = (GDAL_GCP*) CPLRealloc(pasGCPs, sizeof(GDAL_GCP) * nGCPCount); GDALInitGCPs(1, pasGCPs + nGCPCount - 1); pasGCPs[nGCPCount - 1].dfGCPPixel = CPLAtofM(argv[++i]); pasGCPs[nGCPCount - 1].dfGCPLine = CPLAtofM(argv[++i]); pasGCPs[nGCPCount - 1].dfGCPX = CPLAtofM(argv[++i]); pasGCPs[nGCPCount - 1].dfGCPY = CPLAtofM(argv[++i]); if (argv[i + 1] != NULL && (CPLStrtod(argv[i + 1], &endptr) != 0.0 || argv[i + 1][0] == '0')) { /* Check that last argument is really a number and not a filename */ /* looking like a number (see ticket #863) */ if (endptr && *endptr == 0) pasGCPs[nGCPCount - 1].dfGCPZ = CPLAtofM(argv[++i]); } /* should set id and info? */ } else if (EQUAL(argv[i], "-a_nodata") && i < argc - 1) { if (EQUAL(argv[i + 1], "none")) { bUnsetNoData = TRUE; } else { bSetNoData = TRUE; dfNoDataReal = CPLAtofM(argv[i + 1]); } i += 1; } else if (EQUAL(argv[i], "-a_ullr") && i < argc - 4) { adfULLR[0] = CPLAtofM(argv[i + 1]); adfULLR[1] = CPLAtofM(argv[i + 2]); adfULLR[2] = CPLAtofM(argv[i + 3]); adfULLR[3] = CPLAtofM(argv[i + 4]); bGotBounds = TRUE; i += 4; } else if (EQUAL(argv[i], "-co") && i < argc - 1) { papszCreateOptions = CSLAddString(papszCreateOptions, argv[++i]); } else if (EQUAL(argv[i], "-scale")) { bScale = TRUE; if (i < argc - 2 && ArgIsNumeric(argv[i + 1])) { bHaveScaleSrc = TRUE; dfScaleSrcMin = CPLAtofM(argv[i + 1]); dfScaleSrcMax = CPLAtofM(argv[i + 2]); i += 2; } if (i < argc - 2 && bHaveScaleSrc && ArgIsNumeric(argv[i + 1])) { dfScaleDstMin = CPLAtofM(argv[i + 1]); dfScaleDstMax = CPLAtofM(argv[i + 2]); i += 2; } else { dfScaleDstMin = 0.0; dfScaleDstMax = 255.999; } } else if (EQUAL(argv[i], "-unscale")) { bUnscale = TRUE; } else if (EQUAL(argv[i], "-mo") && i < argc - 1) { papszMetadataOptions = CSLAddString(papszMetadataOptions, argv[++i]); } else if (EQUAL(argv[i], "-outsize") && i < argc - 2) { pszOXSize = argv[++i]; pszOYSize = argv[++i]; } else if (EQUAL(argv[i], "-srcwin") && i < argc - 4) { anSrcWin[0] = atoi(argv[++i]); anSrcWin[1] = atoi(argv[++i]); anSrcWin[2] = atoi(argv[++i]); anSrcWin[3] = atoi(argv[++i]); } else if (EQUAL(argv[i], "-projwin") && i < argc - 4) { dfULX = CPLAtofM(argv[++i]); dfULY = CPLAtofM(argv[++i]); dfLRX = CPLAtofM(argv[++i]); dfLRY = CPLAtofM(argv[++i]); } else if (EQUAL(argv[i], "-a_srs") && i < argc - 1) { OGRSpatialReference oOutputSRS; if (oOutputSRS.SetFromUserInput(argv[i + 1]) != OGRERR_NONE) { fprintf(stderr, "Failed to process SRS definition: %s\n", argv[i + 1]); GDALDestroyDriverManager(); exit(1); } oOutputSRS.exportToWkt(&pszOutputSRS); i++; } else if (EQUAL(argv[i], "-expand") && i < argc - 1) { if (EQUAL(argv[i + 1], "gray")) nRGBExpand = 1; else if (EQUAL(argv[i + 1], "rgb")) nRGBExpand = 3; else if (EQUAL(argv[i + 1], "rgba")) nRGBExpand = 4; else { printf("Value %s unsupported. Only gray, rgb or rgba are supported.\n\n", argv[i]); Usage(); GDALDestroyDriverManager(); exit(2); } i++; } else if (EQUAL(argv[i], "-stats")) { bStats = TRUE; bApproxStats = FALSE; } else if (EQUAL(argv[i], "-approx_stats")) { bStats = TRUE; bApproxStats = TRUE; } else if (argv[i][0] == '-') { printf("Option %s incomplete, or not recognised.\n\n", argv[i]); Usage(); GDALDestroyDriverManager(); exit(2); } else if (pszSource == NULL) { iSrcFileArg = i; pszSource = argv[i]; } else if (pszDest == NULL) { pszDest = argv[i]; iDstFileArg = i; } else { printf("Too many command options.\n\n"); Usage(); GDALDestroyDriverManager(); exit(2); } } if (pszDest == NULL) { Usage(); GDALDestroyDriverManager(); exit(10); } if (strcmp(pszSource, pszDest) == 0) { fprintf(stderr, "Source and destination datasets must be different.\n"); GDALDestroyDriverManager(); exit(1); } if (strcmp(pszDest, "/vsistdout/") == 0) { bQuiet = TRUE; pfnProgress = GDALDummyProgress; } /* -------------------------------------------------------------------- */ /* Attempt to open source file. */ /* -------------------------------------------------------------------- */ hDataset = GDALOpenShared(pszSource, GA_ReadOnly); if (hDataset == NULL) { fprintf(stderr, "GDALOpen failed - %d\n%s\n", CPLGetLastErrorNo(), CPLGetLastErrorMsg()); GDALDestroyDriverManager(); exit(1); } /* -------------------------------------------------------------------- */ /* Handle subdatasets. */ /* -------------------------------------------------------------------- */ if (!bCopySubDatasets && CSLCount(GDALGetMetadata(hDataset, "SUBDATASETS")) > 0 && GDALGetRasterCount(hDataset) == 0) { fprintf(stderr, "Input file contains subdatasets. Please, select one of them for reading.\n"); GDALClose(hDataset); GDALDestroyDriverManager(); exit(1); } if (CSLCount(GDALGetMetadata(hDataset, "SUBDATASETS")) > 0 && bCopySubDatasets) { char **papszSubdatasets = GDALGetMetadata(hDataset, "SUBDATASETS"); char *pszSubDest = (char*) CPLMalloc(strlen(pszDest) + 32); int i; int bOldSubCall = bSubCall; char **papszDupArgv = CSLDuplicate(argv); int nRet = 0; CPLFree(papszDupArgv[iDstFileArg]); papszDupArgv[iDstFileArg] = pszSubDest; bSubCall = TRUE; for (i = 0; papszSubdatasets[i] != NULL; i += 2) { CPLFree(papszDupArgv[iSrcFileArg]); papszDupArgv[iSrcFileArg] = CPLStrdup(strstr(papszSubdatasets[i], "=") + 1); sprintf(pszSubDest, "%s%d", pszDest, i / 2 + 1); nRet = ProxyMain(argc, papszDupArgv); if (nRet != 0) break; } CSLDestroy(papszDupArgv); bSubCall = bOldSubCall; CSLDestroy(argv); GDALClose(hDataset); if (!bSubCall) { GDALDumpOpenDatasets(stderr); GDALDestroyDriverManager(); } return nRet; } /* -------------------------------------------------------------------- */ /* Collect some information from the source file. */ /* -------------------------------------------------------------------- */ nRasterXSize = GDALGetRasterXSize(hDataset); nRasterYSize = GDALGetRasterYSize(hDataset); if (!bQuiet) printf("Input file size is %d, %d\n", nRasterXSize, nRasterYSize); if (anSrcWin[2] == 0 && anSrcWin[3] == 0) { anSrcWin[2] = nRasterXSize; anSrcWin[3] = nRasterYSize; } /* -------------------------------------------------------------------- */ /* Build band list to translate */ /* -------------------------------------------------------------------- */ if (nBandCount == 0) { nBandCount = GDALGetRasterCount(hDataset); if (nBandCount == 0) { fprintf(stderr, "Input file has no bands, and so cannot be translated.\n"); GDALDestroyDriverManager(); exit(1); } panBandList = (int*) CPLMalloc(sizeof(int) * nBandCount); for (i = 0; i < nBandCount; i++) panBandList[i] = i + 1; } else { for (i = 0; i < nBandCount; i++) { if (ABS(panBandList[i]) > GDALGetRasterCount(hDataset)) { fprintf(stderr, "Band %d requested, but only bands 1 to %d available.\n", ABS(panBandList[i]), GDALGetRasterCount(hDataset)); GDALDestroyDriverManager(); exit(2); } } if (nBandCount != GDALGetRasterCount(hDataset)) bDefBands = FALSE; } /* -------------------------------------------------------------------- */ /* Compute the source window from the projected source window */ /* if the projected coordinates were provided. Note that the */ /* projected coordinates are in ulx, uly, lrx, lry format, */ /* while the anSrcWin is xoff, yoff, xsize, ysize with the */ /* xoff,yoff being the ulx, uly in pixel/line. */ /* -------------------------------------------------------------------- */ if (dfULX != 0.0 || dfULY != 0.0 || dfLRX != 0.0 || dfLRY != 0.0) { double adfGeoTransform[6]; GDALGetGeoTransform(hDataset, adfGeoTransform); if (adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0) { fprintf(stderr, "The -projwin option was used, but the geotransform is\n" "rotated. This configuration is not supported.\n"); GDALClose(hDataset); CPLFree(panBandList); GDALDestroyDriverManager(); exit(1); } anSrcWin[0] = (int) ((dfULX - adfGeoTransform[0]) / adfGeoTransform[1] + 0.001); anSrcWin[1] = (int) ((dfULY - adfGeoTransform[3]) / adfGeoTransform[5] + 0.001); anSrcWin[2] = (int) ((dfLRX - dfULX) / adfGeoTransform[1] + 0.5); anSrcWin[3] = (int) ((dfLRY - dfULY) / adfGeoTransform[5] + 0.5); if (!bQuiet) fprintf(stdout, "Computed -srcwin %d %d %d %d from projected window.\n", anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3]); if (anSrcWin[0] < 0 || anSrcWin[1] < 0 || anSrcWin[0] + anSrcWin[2] > GDALGetRasterXSize(hDataset) || anSrcWin[1] + anSrcWin[3] > GDALGetRasterYSize(hDataset)) { fprintf(stderr, "Computed -srcwin falls outside raster size of %dx%d.\n", GDALGetRasterXSize(hDataset), GDALGetRasterYSize(hDataset)); exit(1); } } /* -------------------------------------------------------------------- */ /* Verify source window. */ /* -------------------------------------------------------------------- */ if (anSrcWin[0] < 0 || anSrcWin[1] < 0 || anSrcWin[2] <= 0 || anSrcWin[3] <= 0 || anSrcWin[0] + anSrcWin[2] > GDALGetRasterXSize(hDataset) || anSrcWin[1] + anSrcWin[3] > GDALGetRasterYSize(hDataset)) { fprintf(stderr, "-srcwin %d %d %d %d falls outside raster size of %dx%d\n" "or is otherwise illegal.\n", anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], GDALGetRasterXSize(hDataset), GDALGetRasterYSize(hDataset)); exit(1); } /* -------------------------------------------------------------------- */ /* Find the output driver. */ /* -------------------------------------------------------------------- */ hDriver = GDALGetDriverByName(pszFormat); if (hDriver == NULL) { int iDr; printf("Output driver `%s' not recognised.\n", pszFormat); printf("The following format drivers are configured and support output:\n"); for (iDr = 0; iDr < GDALGetDriverCount(); iDr++) { GDALDriverH hDriver = GDALGetDriver(iDr); if (GDALGetMetadataItem(hDriver, GDAL_DCAP_CREATE, NULL) != NULL || GDALGetMetadataItem(hDriver, GDAL_DCAP_CREATECOPY, NULL) != NULL) { printf(" %s: %s\n", GDALGetDriverShortName(hDriver), GDALGetDriverLongName(hDriver)); } } printf("\n"); Usage(); GDALClose(hDataset); CPLFree(panBandList); GDALDestroyDriverManager(); CSLDestroy(argv); CSLDestroy(papszCreateOptions); exit(1); } /* -------------------------------------------------------------------- */ /* The short form is to CreateCopy(). We use this if the input */ /* matches the whole dataset. Eventually we should rewrite */ /* this entire program to use virtual datasets to construct a */ /* virtual input source to copy from. */ /* -------------------------------------------------------------------- */ int bSpatialArrangementPreserved = ( anSrcWin[0] == 0 && anSrcWin[1] == 0 && anSrcWin[2] == GDALGetRasterXSize(hDataset) && anSrcWin[3] == GDALGetRasterYSize(hDataset) && pszOXSize == NULL && pszOYSize == NULL); if (eOutputType == GDT_Unknown && !bScale && !bUnscale && CSLCount(papszMetadataOptions) == 0 && bDefBands && eMaskMode == MASK_AUTO && bSpatialArrangementPreserved && nGCPCount == 0 && !bGotBounds && pszOutputSRS == NULL && !bSetNoData && !bUnsetNoData && nRGBExpand == 0 && !bStats) { hOutDS = GDALCreateCopy(hDriver, pszDest, hDataset, bStrict, papszCreateOptions, pfnProgress, NULL); if (hOutDS != NULL) GDALClose(hOutDS); GDALClose(hDataset); CPLFree(panBandList); if (!bSubCall) { GDALDumpOpenDatasets(stderr); GDALDestroyDriverManager(); } CSLDestroy(argv); CSLDestroy(papszCreateOptions); return hOutDS == NULL; } /* -------------------------------------------------------------------- */ /* Establish some parameters. */ /* -------------------------------------------------------------------- */ if (pszOXSize == NULL) { nOXSize = anSrcWin[2]; nOYSize = anSrcWin[3]; } else { nOXSize = (int) ((pszOXSize[strlen(pszOXSize) - 1] == '%' ? CPLAtofM(pszOXSize) / 100 * anSrcWin[2] : atoi(pszOXSize))); nOYSize = (int) ((pszOYSize[strlen(pszOYSize) - 1] == '%' ? CPLAtofM(pszOYSize) / 100 * anSrcWin[3] : atoi(pszOYSize))); } /* ==================================================================== */ /* Create a virtual dataset. */ /* ==================================================================== */ VRTDataset *poVDS; /* -------------------------------------------------------------------- */ /* Make a virtual clone. */ /* -------------------------------------------------------------------- */ poVDS = (VRTDataset*) VRTCreate(nOXSize, nOYSize); if (nGCPCount == 0) { if (pszOutputSRS != NULL) { poVDS->SetProjection(pszOutputSRS); } else { pszProjection = GDALGetProjectionRef(hDataset); if (pszProjection != NULL && strlen(pszProjection) > 0) poVDS->SetProjection(pszProjection); } } if (bGotBounds) { adfGeoTransform[0] = adfULLR[0]; adfGeoTransform[1] = (adfULLR[2] - adfULLR[0]) / nOXSize; adfGeoTransform[2] = 0.0; adfGeoTransform[3] = adfULLR[1]; adfGeoTransform[4] = 0.0; adfGeoTransform[5] = (adfULLR[3] - adfULLR[1]) / nOYSize; poVDS->SetGeoTransform(adfGeoTransform); } else if (GDALGetGeoTransform(hDataset, adfGeoTransform) == CE_None && nGCPCount == 0) { adfGeoTransform[0] += anSrcWin[0] * adfGeoTransform[1] + anSrcWin[1] * adfGeoTransform[2]; adfGeoTransform[3] += anSrcWin[0] * adfGeoTransform[4] + anSrcWin[1] * adfGeoTransform[5]; adfGeoTransform[1] *= anSrcWin[2] / (double) nOXSize; adfGeoTransform[2] *= anSrcWin[3] / (double) nOYSize; adfGeoTransform[4] *= anSrcWin[2] / (double) nOXSize; adfGeoTransform[5] *= anSrcWin[3] / (double) nOYSize; poVDS->SetGeoTransform(adfGeoTransform); } if (nGCPCount != 0) { const char *pszGCPProjection = pszOutputSRS; if (pszGCPProjection == NULL) pszGCPProjection = GDALGetGCPProjection(hDataset); if (pszGCPProjection == NULL) pszGCPProjection = ""; poVDS->SetGCPs(nGCPCount, pasGCPs, pszGCPProjection); GDALDeinitGCPs(nGCPCount, pasGCPs); CPLFree(pasGCPs); } else if (GDALGetGCPCount(hDataset) > 0) { GDAL_GCP *pasGCPs; int nGCPs = GDALGetGCPCount(hDataset); pasGCPs = GDALDuplicateGCPs(nGCPs, GDALGetGCPs(hDataset)); for (i = 0; i < nGCPs; i++) { pasGCPs[i].dfGCPPixel -= anSrcWin[0]; pasGCPs[i].dfGCPLine -= anSrcWin[1]; pasGCPs[i].dfGCPPixel *= (nOXSize / (double) anSrcWin[2]); pasGCPs[i].dfGCPLine *= (nOYSize / (double) anSrcWin[3]); } poVDS->SetGCPs(nGCPs, pasGCPs, GDALGetGCPProjection(hDataset)); GDALDeinitGCPs(nGCPs, pasGCPs); CPLFree(pasGCPs); } /* -------------------------------------------------------------------- */ /* Transfer generally applicable metadata. */ /* -------------------------------------------------------------------- */ poVDS->SetMetadata(((GDALDataset*)hDataset)->GetMetadata()); AttachMetadata((GDALDatasetH) poVDS, papszMetadataOptions); const char *pszInterleave = GDALGetMetadataItem(hDataset, "INTERLEAVE", "IMAGE_STRUCTURE"); if (pszInterleave) poVDS->SetMetadataItem("INTERLEAVE", pszInterleave, "IMAGE_STRUCTURE"); /* -------------------------------------------------------------------- */ /* Transfer metadata that remains valid if the spatial */ /* arrangement of the data is unaltered. */ /* -------------------------------------------------------------------- */ if (bSpatialArrangementPreserved) { char **papszMD; papszMD = ((GDALDataset*)hDataset)->GetMetadata("RPC"); if (papszMD != NULL) poVDS->SetMetadata(papszMD, "RPC"); papszMD = ((GDALDataset*)hDataset)->GetMetadata("GEOLOCATION"); if (papszMD != NULL) poVDS->SetMetadata(papszMD, "GEOLOCATION"); } int nSrcBandCount = nBandCount; if (nRGBExpand != 0) { GDALRasterBand *poSrcBand; poSrcBand = ((GDALDataset*) hDataset)->GetRasterBand(ABS(panBandList[0])); if (panBandList[0] < 0) poSrcBand = poSrcBand->GetMaskBand(); GDALColorTable *poColorTable = poSrcBand->GetColorTable(); if (poColorTable == NULL) { fprintf(stderr, "Error : band %d has no color table\n", ABS(panBandList[0])); GDALClose(hDataset); CPLFree(panBandList); GDALDestroyDriverManager(); CSLDestroy(argv); CSLDestroy(papszCreateOptions); exit(1); } /* Check that the color table only contains gray levels */ /* when using -expand gray */ if (nRGBExpand == 1) { int nColorCount = poColorTable->GetColorEntryCount(); int nColor; for (nColor = 0; nColor < nColorCount; nColor++) { const GDALColorEntry *poEntry = poColorTable->GetColorEntry(nColor); if (poEntry->c1 != poEntry->c2 || poEntry->c1 != poEntry->c2) { fprintf(stderr, "Warning : color table contains non gray levels colors\n"); break; } } } if (nBandCount == 1) nBandCount = nRGBExpand; else if (nBandCount == 2 && (nRGBExpand == 3 || nRGBExpand == 4)) nBandCount = nRGBExpand; else { fprintf(stderr, "Error : invalid use of -expand option.\n"); exit(1); } } int bFilterOutStatsMetadata = (bScale || bUnscale || !bSpatialArrangementPreserved || nRGBExpand != 0); /* ==================================================================== */ /* Process all bands. */ /* ==================================================================== */ for (i = 0; i < nBandCount; i++) { VRTSourcedRasterBand *poVRTBand; GDALRasterBand *poSrcBand; GDALDataType eBandType; int nComponent = 0; int nSrcBand; if (nRGBExpand != 0) { if (nSrcBandCount == 2 && nRGBExpand == 4 && i == 3) nSrcBand = panBandList[1]; else { nSrcBand = panBandList[0]; nComponent = i + 1; } } else nSrcBand = panBandList[i]; poSrcBand = ((GDALDataset*) hDataset)->GetRasterBand(ABS(nSrcBand)); /* -------------------------------------------------------------------- */ /* Select output data type to match source. */ /* -------------------------------------------------------------------- */ if (eOutputType == GDT_Unknown) eBandType = poSrcBand->GetRasterDataType(); else eBandType = eOutputType; /* -------------------------------------------------------------------- */ /* Create this band. */ /* -------------------------------------------------------------------- */ poVDS->AddBand(eBandType, NULL); poVRTBand = (VRTSourcedRasterBand*) poVDS->GetRasterBand(i + 1); if (nSrcBand < 0) { poVRTBand->AddMaskBandSource(poSrcBand); continue; } /* -------------------------------------------------------------------- */ /* Do we need to collect scaling information? */ /* -------------------------------------------------------------------- */ double dfScale = 1.0, dfOffset = 0.0; if (bScale && !bHaveScaleSrc) { double adfCMinMax[2]; GDALComputeRasterMinMax(poSrcBand, TRUE, adfCMinMax); dfScaleSrcMin = adfCMinMax[0]; dfScaleSrcMax = adfCMinMax[1]; } if (bScale) { if (dfScaleSrcMax == dfScaleSrcMin) dfScaleSrcMax += 0.1; if (dfScaleDstMax == dfScaleDstMin) dfScaleDstMax += 0.1; dfScale = (dfScaleDstMax - dfScaleDstMin) / (dfScaleSrcMax - dfScaleSrcMin); dfOffset = -1 * dfScaleSrcMin * dfScale + dfScaleDstMin; } if (bUnscale) { dfScale = poSrcBand->GetScale(); dfOffset = poSrcBand->GetOffset(); } /* -------------------------------------------------------------------- */ /* Create a simple or complex data source depending on the */ /* translation type required. */ /* -------------------------------------------------------------------- */ if (bUnscale || bScale || (nRGBExpand != 0 && i < nRGBExpand)) { poVRTBand->AddComplexSource(poSrcBand, anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], 0, 0, nOXSize, nOYSize, dfOffset, dfScale, VRT_NODATA_UNSET, nComponent); } else poVRTBand->AddSimpleSource(poSrcBand, anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], 0, 0, nOXSize, nOYSize); /* -------------------------------------------------------------------- */ /* In case of color table translate, we only set the color */ /* interpretation other info copied by CopyBandInfo are */ /* not relevant in RGB expansion. */ /* -------------------------------------------------------------------- */ if (nRGBExpand == 1) { poVRTBand->SetColorInterpretation(GCI_GrayIndex); } else if (nRGBExpand != 0 && i < nRGBExpand) { poVRTBand->SetColorInterpretation((GDALColorInterp) (GCI_RedBand + i)); } /* -------------------------------------------------------------------- */ /* copy over some other information of interest. */ /* -------------------------------------------------------------------- */ else { CopyBandInfo(poSrcBand, poVRTBand, !bStats && !bFilterOutStatsMetadata, !bUnscale, !bSetNoData && !bUnsetNoData); } /* -------------------------------------------------------------------- */ /* Set a forcable nodata value? */ /* -------------------------------------------------------------------- */ if (bSetNoData) { double dfVal = dfNoDataReal; int bClamped = FALSE, bRounded = FALSE; #define CLAMP(val, type, minval, maxval) \ do { if (val < minval) { bClamped = TRUE; val = minval; \ } \ else if (val > maxval) { bClamped = TRUE; val = maxval; } \ else if (val != (type)val) { bRounded = TRUE; val = (type)(val + 0.5); } \ } \ while (0) switch (eBandType) { case GDT_Byte: CLAMP(dfVal, GByte, 0.0, 255.0); break; case GDT_Int16: CLAMP(dfVal, GInt16, -32768.0, 32767.0); break; case GDT_UInt16: CLAMP(dfVal, GUInt16, 0.0, 65535.0); break; case GDT_Int32: CLAMP(dfVal, GInt32, -2147483648.0, 2147483647.0); break; case GDT_UInt32: CLAMP(dfVal, GUInt32, 0.0, 4294967295.0); break; default: break; } if (bClamped) { printf("for band %d, nodata value has been clamped " "to %.0f, the original value being out of range.\n", i + 1, dfVal); } else if (bRounded) { printf("for band %d, nodata value has been rounded " "to %.0f, %s being an integer datatype.\n", i + 1, dfVal, GDALGetDataTypeName(eBandType)); } poVRTBand->SetNoDataValue(dfVal); } if (eMaskMode == MASK_AUTO && (GDALGetMaskFlags(GDALGetRasterBand(hDataset, 1)) & GMF_PER_DATASET) == 0 && (poSrcBand->GetMaskFlags() & (GMF_ALL_VALID | GMF_NODATA)) == 0) { if (poVRTBand->CreateMaskBand(poSrcBand->GetMaskFlags()) == CE_None) { VRTSourcedRasterBand *hMaskVRTBand = (VRTSourcedRasterBand*)poVRTBand->GetMaskBand(); hMaskVRTBand->AddMaskBandSource(poSrcBand, anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], 0, 0, nOXSize, nOYSize); } } } if (eMaskMode == MASK_USER) { GDALRasterBand *poSrcBand = (GDALRasterBand*)GDALGetRasterBand(hDataset, ABS(nMaskBand)); if (poSrcBand && poVDS->CreateMaskBand(GMF_PER_DATASET) == CE_None) { VRTSourcedRasterBand *hMaskVRTBand = (VRTSourcedRasterBand*) GDALGetMaskBand(GDALGetRasterBand((GDALDatasetH)poVDS, 1)); if (nMaskBand > 0) hMaskVRTBand->AddSimpleSource(poSrcBand, anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], 0, 0, nOXSize, nOYSize); else hMaskVRTBand->AddMaskBandSource(poSrcBand, anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], 0, 0, nOXSize, nOYSize); } } else if (eMaskMode == MASK_AUTO && nSrcBandCount > 0 && GDALGetMaskFlags(GDALGetRasterBand(hDataset, 1)) == GMF_PER_DATASET) { if (poVDS->CreateMaskBand(GMF_PER_DATASET) == CE_None) { VRTSourcedRasterBand *hMaskVRTBand = (VRTSourcedRasterBand*) GDALGetMaskBand(GDALGetRasterBand((GDALDatasetH)poVDS, 1)); hMaskVRTBand->AddMaskBandSource((GDALRasterBand*)GDALGetRasterBand(hDataset, 1), anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], 0, 0, nOXSize, nOYSize); } } /* -------------------------------------------------------------------- */ /* Compute stats if required. */ /* -------------------------------------------------------------------- */ if (bStats) { for (i = 0; i < poVDS->GetRasterCount(); i++) { double dfMin, dfMax, dfMean, dfStdDev; poVDS->GetRasterBand(i + 1)->ComputeStatistics(bApproxStats, &dfMin, &dfMax, &dfMean, &dfStdDev, GDALDummyProgress, NULL); } } /* -------------------------------------------------------------------- */ /* Write to the output file using CopyCreate(). */ /* -------------------------------------------------------------------- */ hOutDS = GDALCreateCopy(hDriver, pszDest, (GDALDatasetH) poVDS, bStrict, papszCreateOptions, pfnProgress, NULL); if (hOutDS != NULL) { int bHasGotErr = FALSE; CPLErrorReset(); GDALFlushCache(hOutDS); if (CPLGetLastErrorType() != CE_None) bHasGotErr = TRUE; GDALClose(hOutDS); if (bHasGotErr) hOutDS = NULL; } GDALClose((GDALDatasetH) poVDS); GDALClose(hDataset); CPLFree(panBandList); CPLFree(pszOutputSRS); if (!bSubCall) { GDALDumpOpenDatasets(stderr); GDALDestroyDriverManager(); } CSLDestroy(argv); CSLDestroy(papszCreateOptions); return hOutDS == NULL; }
void Terrain::applyDataset(const QString& file) { auto t = file.toLatin1(); GDALDataset *dataset_data = (GDALDataset*) GDALOpen(t.constData(), GA_ReadOnly); GDALDataset *dataset_mask = dataset;//(GDALDataset*) GDALOpen(map_file.toLatin1()constData(), GA_ReadOnly); if(dataset == nullptr) { qDebug() << "Unable to get GDAL Dataset for data file: " << file; exit(1); } if(dataset_mask == nullptr) { qDebug() << "Unable to get GDAL Dataset for mask file: " << map_file; exit(1); } GDALRasterBand *raster = dataset_data->GetRasterBand(1); GDALRasterBand *raster_mask = dataset_mask->GetRasterBand(1); int width = raster->GetXSize();//terrain_img.getWidth(); int height = raster->GetYSize();//terrain_img.getHeight(); int width_mask = raster_mask->GetXSize(); //int height_mask = raster_mask->GetYSize(); int gotMin, gotMax; float min = raster->GetMinimum(&gotMin); float max = raster->GetMaximum(&gotMax); double minMax[2] = {min, max}; if(!(gotMin && gotMax)) { GDALComputeRasterMinMax((GDALRasterBandH) raster, TRUE, minMax); min = minMax[0]; max = minMax[1]; } float min_mask = raster_mask->GetMinimum(&gotMin); float max_mask = raster_mask->GetMaximum(&gotMax); minMax[0] = min_mask; minMax[1] = max_mask; if(!(gotMin && gotMax)) { GDALComputeRasterMinMax((GDALRasterBandH) raster_mask, TRUE, minMax); min_mask = minMax[0]; max_mask = minMax[1]; } if(engine->getOptions().verbose) { qDebug() << "terrain mask: " << map_file << " min: " << min << " max: " << max; qDebug() << "terrain data: " << file << " min: " << min_mask << " max: " << max_mask; } int woffset = width / 2; int hoffset = height / 2; float maxOffset = max - min; float maxOffset_mask = max_mask - min_mask; float *lineData = (float*) CPLMalloc(sizeof(float) * width); float *lineData2 = (float*) CPLMalloc(sizeof(float) * width); float *lineData_mask = (float*) CPLMalloc(sizeof(float) * width_mask); float *lineData2_mask = (float*) CPLMalloc(sizeof(float) * width_mask); int i = 0; for(int z = -hoffset; z < height - hoffset-1; z++) { raster->RasterIO(GF_Read, 0, z + hoffset, width, 1, lineData, width, 1, GDT_Float32, 0, 0); raster->RasterIO(GF_Read, 0, z + hoffset + 1, width, 1, lineData2, width, 1, GDT_Float32, 0, 0); raster_mask->RasterIO(GF_Read, 0, z + hoffset, width_mask, 1, lineData_mask, width_mask, 1, GDT_Float32, 0, 0); raster_mask->RasterIO(GF_Read, 0, z + hoffset + 1, width_mask, 1, lineData2_mask, width_mask, 1, GDT_Float32, 0, 0); for(int x = -woffset; x < width - woffset-1; x++) { if((((lineData_mask[x+woffset]-min_mask) / maxOffset_mask) >= 0.1f) && (((lineData_mask[x+woffset+1]-min_mask) / maxOffset_mask) >= 0.1f) && (((lineData2_mask[x+woffset]-min_mask) / maxOffset_mask) >= 0.1f)) { geometry[i].dataPoint = (lineData[x+woffset]-min) / maxOffset; i++; geometry[i].dataPoint = (lineData[x+woffset+1]-min) / maxOffset; i++; geometry[i].dataPoint = (lineData2[x+woffset]-min) / maxOffset; i++; } if((((lineData2_mask[x+woffset]-min_mask) / maxOffset_mask) >= 0.1f) && (((lineData2_mask[x+woffset+1]-min_mask) / maxOffset_mask) >= 0.1f) && (((lineData_mask[x+woffset+1]-min_mask) / maxOffset_mask) >= 0.1f)) { geometry[i].dataPoint = (lineData2[x+woffset]-min) / maxOffset; i++; geometry[i].dataPoint = (lineData2[x+woffset+1]-min) / maxOffset; i++; geometry[i].dataPoint = (lineData[x+woffset+1]-min) / maxOffset; i++; } } } CPLFree(lineData); CPLFree(lineData2); CPLFree(lineData_mask); CPLFree(lineData2_mask); //GDALClose((GDALDatasetH) dataset); //GDALClose((GDALDatasetH) dataset_mask); program = engine->graphics->getShaderProgram("data"); initGL(false); }
// static functions QVector<Terrain*> Terrain::createTerrainFromDEMandMask(Engine *engine, const QString& dem, const QString& mask, Terrain *large_dem) { QVector<Terrain*> terrain_vec(2); Terrain *dem_t = new Terrain(engine, dem, engine->graphics->getShaderProgram("gray")); Terrain *mask_t = new Terrain(engine, mask, engine->graphics->getShaderProgram("color")); auto t = dem.toLatin1(); auto t2 = mask.toLatin1(); GDALDataset *dataset = (GDALDataset*) GDALOpen(t.constData(), GA_ReadOnly); GDALDataset *dataset_mask = (GDALDataset*) GDALOpen(t2.constData(), GA_ReadOnly); if(dataset == nullptr) { qDebug() << "Unable to get GDAL Dataset for file: " << dem; exit(1); } if(dataset_mask == nullptr) { qDebug() << "Unable to get GDAL Dataset for mask file: " << mask; exit(1); } GDALRasterBand *raster = dataset->GetRasterBand(1); GDALRasterBand *raster_mask = dataset_mask->GetRasterBand(1); int width = raster->GetXSize();//terrain_img.getWidth(); int height = raster->GetYSize();//terrain_img.getHeight(); int width_mask = raster_mask->GetXSize(); //int height_mask = raster_mask->GetYSize(); int gotMin, gotMax; float large_min, large_max; float large_max_offset; if(large_dem) { GDALRasterBand *large_raster = large_dem->dataset->GetRasterBand(1); large_min = large_raster->GetMinimum(&gotMin); large_max = large_raster->GetMaximum(&gotMax); if(!(gotMin && gotMax)) { double minMax[2] = {large_min, large_max}; GDALComputeRasterMinMax((GDALRasterBandH) large_raster, TRUE, minMax); large_min = minMax[0]; large_max = minMax[1]; } large_max_offset = large_max - large_min; } float min = raster->GetMinimum(&gotMin); float max = raster->GetMaximum(&gotMax); double minMax[2] = {min, max}; if(!(gotMin && gotMax)) { GDALComputeRasterMinMax((GDALRasterBandH) raster, TRUE, minMax); min = minMax[0]; max = minMax[1]; } float min_mask = raster_mask->GetMinimum(&gotMin); float max_mask = raster_mask->GetMaximum(&gotMax); minMax[0] = min_mask; minMax[1] = max_mask; if(!(gotMin && gotMax)) { GDALComputeRasterMinMax((GDALRasterBandH) raster_mask, TRUE, minMax); min_mask = minMax[0]; max_mask = minMax[1]; } if(engine->getOptions().verbose) { qDebug() << "terrain: " << dem << " min: " << min << " max: " << max; qDebug() << "terrain mask: " << mask << " min: " << min_mask << " max: " << max_mask; } int woffset = width / 2; int hoffset = height / 2; Vertex tempVert; float maxOffset = max - min; float maxOffset_mask = max_mask - min_mask; float scale = engine->getOptions().map_scalar * (2.5f / 10.0f); float *lineData = (float*) CPLMalloc(sizeof(float) * width); float *lineData2 = (float*) CPLMalloc(sizeof(float) * width); float *lineData_mask = (float*) CPLMalloc(sizeof(float) * width_mask); float *lineData2_mask = (float*) CPLMalloc(sizeof(float) * width_mask); if(!large_dem) { large_max_offset = maxOffset; large_min = min; } for(int z = -hoffset; z < height - hoffset-1; z++) { raster->RasterIO(GF_Read, 0, z + hoffset, width, 1, lineData, width, 1, GDT_Float32, 0, 0); raster->RasterIO(GF_Read, 0, z + hoffset + 1, width, 1, lineData2, width, 1, GDT_Float32, 0, 0); raster_mask->RasterIO(GF_Read, 0, z + hoffset, width_mask, 1, lineData_mask, width_mask, 1, GDT_Float32, 0, 0); raster_mask->RasterIO(GF_Read, 0, z + hoffset + 1, width_mask, 1, lineData2_mask, width_mask, 1, GDT_Float32, 0, 0); for(int x = -woffset; x < width - woffset-1; x++) { if((((lineData_mask[x+woffset]-min_mask) / maxOffset_mask) >= 0.1f) && (((lineData_mask[x+woffset+1]-min_mask) / maxOffset_mask) >= 0.1f) && (((lineData2_mask[x+woffset]-min_mask) / maxOffset_mask) >= 0.1f)) { tempVert.position[0] = x*scale; tempVert.position[1] = (lineData[x+woffset]-large_min) / large_max_offset; tempVert.position[2] = z*scale; mask_t->geometry.push_back(tempVert); tempVert.position[0] = (x+1) * scale; tempVert.position[1] = (lineData[x+woffset+1]-large_min) / large_max_offset; tempVert.position[2] = z*scale; mask_t->geometry.push_back(tempVert); tempVert.position[0] = x*scale; tempVert.position[1] = (lineData2[x+woffset]-large_min) / large_max_offset; tempVert.position[2] = (z+1) * scale; mask_t->geometry.push_back(tempVert); } else { tempVert.position[0] = x*scale; tempVert.position[1] = (lineData[x+woffset]-large_min) / large_max_offset; tempVert.position[2] = z*scale; dem_t->geometry.push_back(tempVert); tempVert.position[0] = (x+1) * scale; tempVert.position[1] = (lineData[x+woffset+1]-large_min) / large_max_offset; tempVert.position[2] = z*scale; dem_t->geometry.push_back(tempVert); tempVert.position[0] = x*scale; tempVert.position[1] = (lineData2[x+woffset]-large_min) / large_max_offset; tempVert.position[2] = (z+1) * scale; dem_t->geometry.push_back(tempVert); } if((((lineData2_mask[x+woffset]-min_mask) / maxOffset_mask) >= 0.1f) && (((lineData2_mask[x+woffset+1]-min_mask) / maxOffset_mask) >= 0.1f) && (((lineData_mask[x+woffset+1]-min_mask) / maxOffset_mask) >= 0.1f)) { tempVert.position[0] = x*scale; tempVert.position[1] = (lineData2[x+woffset]-large_min) / large_max_offset; tempVert.position[2] = (z+1) * scale; mask_t->geometry.push_back(tempVert); tempVert.position[0] = (x+1) * scale; tempVert.position[1] = (lineData2[x+woffset+1]-large_min) / large_max_offset; tempVert.position[2] = (z+1) * scale; mask_t->geometry.push_back(tempVert); tempVert.position[0] = (x+1) * scale; tempVert.position[1] = (lineData[x+woffset+1]-large_min) / large_max_offset; tempVert.position[2] = z*scale; mask_t->geometry.push_back(tempVert); } else { tempVert.position[0] = x*scale; tempVert.position[1] = (lineData2[x+woffset]-large_min) / large_max_offset; tempVert.position[2] = (z+1) * scale; dem_t->geometry.push_back(tempVert); tempVert.position[0] = (x+1) * scale; tempVert.position[1] = (lineData2[x+woffset+1]-large_min) / large_max_offset; tempVert.position[2] = (z+1) * scale; dem_t->geometry.push_back(tempVert); tempVert.position[0] = (x+1) * scale; tempVert.position[1] = (lineData[x+woffset+1]-large_min) / large_max_offset; tempVert.position[2] = z*scale; dem_t->geometry.push_back(tempVert); } } } CPLFree(lineData); CPLFree(lineData2); CPLFree(lineData_mask); CPLFree(lineData2_mask); //GDALClose((GDALDatasetH) dataset); //GDALClose((GDALDatasetH) dataset_mask); dem_t->dataset = dataset; mask_t->dataset = dataset_mask; dem_t->initGL(); mask_t->initGL(); mask_t->textures.push_back(engine->graphics->createTextureFromFile(QString::fromStdString(engine->getOptions().color_map), GL_TEXTURE_1D)); terrain_vec[0] = dem_t; terrain_vec[1] = mask_t; return terrain_vec; }
bool DEM::load(const std::string& filename) { GDALAllRegister(); GDALDataset* poDS; poDS = (GDALDataset*)GDALOpenEx(filename.c_str(), GDAL_OF_RASTER, NULL, NULL, NULL); if (poDS == NULL) return false; double adfGeoTransform[6]; if (poDS->GetGeoTransform(adfGeoTransform) == CE_None) { origin.x = adfGeoTransform[0]; origin.y = adfGeoTransform[3]; pixelSize.x = adfGeoTransform[1]; pixelSize.y = abs(adfGeoTransform[5]); } width = poDS->GetRasterXSize() * pixelSize.x; height = poDS->GetRasterYSize() * pixelSize.y; data.resize(width * height); min_val = std::numeric_limits<float>::max(); max_val = -std::numeric_limits<float>::max(); // bandが存在しない場合は、エラー if (poDS->GetRasterCount() == 0) return false; // 最初のbandのみを読み込む。複数bandは未対応 GDALRasterBand* poBand = poDS->GetRasterBand(1); int nBlockXSize, nBlockYSize; poBand->GetBlockSize(&nBlockXSize, &nBlockYSize); //printf("Block=%dx%d Type=%s, ColorInterp=%s\n", nBlockXSize, nBlockYSize, GDALGetDataTypeName(poBand->GetRasterDataType()), GDALGetColorInterpretationName(poBand->GetColorInterpretation())); // 最低、最高の値を取得 int bGotMin, bGotMax; double adfMinMax[2]; adfMinMax[0] = poBand->GetMinimum(&bGotMin); adfMinMax[1] = poBand->GetMaximum(&bGotMax); if (!(bGotMin && bGotMax)) GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax); //printf("Min=%.3fd, Max=%.3f\n", adfMinMax[0], adfMinMax[1]); min_val = adfMinMax[0]; max_val = adfMinMax[1]; //int nXSize = poBand->GetXSize(); //int nYSize = poBand->GetYSize(); int nXBlocks = (poBand->GetXSize() + nBlockXSize - 1) / nBlockXSize; int nYBlocks = (poBand->GetYSize() + nBlockYSize - 1) / nBlockYSize; float *pData = (float *)CPLMalloc(sizeof(float*) * nBlockXSize * nBlockYSize); for (int iYBlock = 0; iYBlock < nYBlocks; iYBlock++) { for (int iXBlock = 0; iXBlock < nXBlocks; iXBlock++) { int nXValid, nYValid; poBand->ReadBlock(iXBlock, iYBlock, pData); // Compute the portion of the block that is valid // for partial edge blocks. if ((iXBlock + 1) * nBlockXSize > poBand->GetXSize()) nXValid = poBand->GetXSize() - iXBlock * nBlockXSize; else nXValid = nBlockXSize; if ((iYBlock + 1) * nBlockYSize > poBand->GetYSize()) nYValid = poBand->GetYSize() - iYBlock * nBlockYSize; else nYValid = nBlockYSize; for (int iY = 0; iY < nYValid; iY++) { for (int iX = 0; iX < nXValid; iX++) { float val; if (pData[iY * nBlockXSize + iX] > max_val) { val = max_val; } else if (pData[iY * nBlockXSize + iX] < min_val) { val = min_val; } else { val = pData[iY * nBlockXSize + iX]; } for (int y = 0; y < pixelSize.y; ++y) { for (int x = 0; x < pixelSize.x; ++x) { data[((iYBlock * nBlockYSize + iY) * pixelSize.y + y) * width + (iXBlock * nBlockXSize + iX) * pixelSize.x + x] = val; } } } } } } GDALClose(poDS); return true; }
//this function is mainly there for debugging bool QgsRelief::exportFrequencyDistributionToCsv( const QString &file ) { int nCellsX, nCellsY; GDALDatasetH inputDataset = openInputFile( nCellsX, nCellsY ); if ( !inputDataset ) { return false; } //open first raster band for reading (elevation raster is always single band) GDALRasterBandH elevationBand = GDALGetRasterBand( inputDataset, 1 ); if ( !elevationBand ) { GDALClose( inputDataset ); return false; } //1. get minimum and maximum of elevation raster -> 252 elevation classes int minOk, maxOk; double minMax[2]; minMax[0] = GDALGetRasterMinimum( elevationBand, &minOk ); minMax[1] = GDALGetRasterMaximum( elevationBand, &maxOk ); if ( !minOk || !maxOk ) { GDALComputeRasterMinMax( elevationBand, true, minMax ); } //2. go through raster cells and get frequency of classes //store elevation frequency in 256 elevation classes double frequency[252]; double frequencyClassRange = ( minMax[1] - minMax[0] ) / 252.0; //initialize to zero for ( int i = 0; i < 252; ++i ) { frequency[i] = 0; } float *scanLine = ( float * ) CPLMalloc( sizeof( float ) * nCellsX ); int elevationClass = -1; for ( int i = 0; i < nCellsY; ++i ) { if ( GDALRasterIO( elevationBand, GF_Read, 0, i, nCellsX, 1, scanLine, nCellsX, 1, GDT_Float32, 0, 0 ) != CE_None ) { QgsDebugMsg( "Raster IO Error" ); } for ( int j = 0; j < nCellsX; ++j ) { elevationClass = frequencyClassForElevation( scanLine[j], minMax[0], frequencyClassRange ); if ( elevationClass >= 0 ) { frequency[elevationClass] += 1.0; } } } CPLFree( scanLine ); //log10 transformation for all frequency values for ( int i = 0; i < 252; ++i ) { frequency[i] = std::log10( frequency[i] ); } //write out frequency values to csv file for debugging QFile outFile( file ); if ( !outFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) ) { return false; } QTextStream outstream( &outFile ); for ( int i = 0; i < 252; ++i ) { outstream << QString::number( i ) + ',' + QString::number( frequency[i] ) << endl; } outFile.close(); return true; }
void readFrames( int argc, char* argv[] ) { pfs::DOMIO pfsio; bool verbose = false; // Parse command line parameters static struct option cmdLineOptions[] = { { "help", no_argument, NULL, 'h' }, { "verbose", no_argument, NULL, 'v' }, { NULL, 0, NULL, 0 } }; static const char optstring[] = "hv"; pfs::FrameFileIterator it( argc, argv, "rb", NULL, NULL, optstring, cmdLineOptions ); int optionIndex = 0; while( 1 ) { int c = getopt_long (argc, argv, optstring, cmdLineOptions, &optionIndex); if( c == -1 ) break; switch( c ) { case 'h': printHelp(); throw QuietException(); case 'v': verbose = true; break; case '?': throw QuietException(); case ':': throw QuietException(); } } GDALAllRegister(); GDALDataset *poDataset; GDALRasterBand *poBand; double adfGeoTransform[6]; size_t nBlockXSize, nBlockYSize, nBands; int bGotMin, bGotMax; double adfMinMax[2]; float *pafScanline; while( true ) { pfs::FrameFile ff = it.getNextFrameFile(); if( ff.fh == NULL ) break; // No more frames it.closeFrameFile( ff ); VERBOSE_STR << "reading file '" << ff.fileName << "'" << std::endl; if( !( poDataset = (GDALDataset *) GDALOpen( ff.fileName, GA_ReadOnly ) ) ) { std::cerr << "input does not seem to be in a format supported by GDAL" << std::endl; throw QuietException(); } VERBOSE_STR << "GDAL driver: " << poDataset->GetDriver()->GetDescription() << " / " << poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME ) << std::endl; nBlockXSize = poDataset->GetRasterXSize(); nBlockYSize = poDataset->GetRasterYSize(); nBands = poDataset->GetRasterCount(); VERBOSE_STR << "Data size " << nBlockXSize << "x" << nBlockYSize << "x" << nBands << std::endl; if( poDataset->GetProjectionRef() ) { VERBOSE_STR << "Projection " << poDataset->GetProjectionRef() << std::endl; } if( poDataset->GetGeoTransform( adfGeoTransform ) == CE_None ) { VERBOSE_STR << "Origin = (" << adfGeoTransform[0] << ", " << adfGeoTransform[3] << ")" << std::endl; VERBOSE_STR << "Pixel Size = (" << adfGeoTransform[1] << ", " << adfGeoTransform[5] << ")" << std::endl; } if( nBlockXSize==0 || nBlockYSize==0 || ( SIZE_MAX / nBlockYSize < nBlockXSize ) || ( SIZE_MAX / (nBlockXSize * nBlockYSize ) < 4 ) ) { std::cerr << "input data has invalid size" << std::endl; throw QuietException(); } if( !(pafScanline = (float *) CPLMalloc( sizeof(float) * nBlockXSize ) ) ) { std::cerr << "not enough memory" << std::endl; throw QuietException(); } pfs::Frame *frame = pfsio.createFrame( nBlockXSize, nBlockYSize ); pfs::Channel *C[nBands]; char channel_name[32]; frame->getTags()->setString( "X-GDAL_DRIVER_SHORTNAME", poDataset->GetDriver()->GetDescription() ); frame->getTags()->setString( "X-GDAL_DRIVER_LONGNAME", poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME ) ); frame->getTags()->setString( "X-PROJECTION", poDataset->GetProjectionRef() ); if( poDataset->GetGeoTransform( adfGeoTransform ) == CE_None ) { frame->getTags()->setString( "X-ORIGIN_X", stringify(adfGeoTransform[0]).c_str() ); frame->getTags()->setString( "X-ORIGIN_Y", stringify(adfGeoTransform[3]).c_str() ); frame->getTags()->setString( "X-PIXEL_WIDTH", stringify(adfGeoTransform[1]).c_str() ); frame->getTags()->setString( "X-PIXEL_HEIGHT", stringify(adfGeoTransform[5]).c_str() ); } for ( size_t band = 1; band <= nBands; band++) { size_t nBandXSize, nBandYSize; VERBOSE_STR << "Band " << band << ": " << std::endl; snprintf( channel_name, 32, "X-GDAL%zu", band ); C[band - 1] = frame->createChannel( channel_name ); poBand = poDataset->GetRasterBand( band ); nBandXSize = poBand->GetXSize(); nBandYSize = poBand->GetYSize(); VERBOSE_STR << " " << nBandXSize << "x" << nBandYSize << std::endl; if( nBandXSize != (int)nBlockXSize || nBandYSize != (int)nBlockYSize ) { std::cerr << "data in band " << band << " has different size" << std::endl; throw QuietException(); } VERBOSE_STR << " Type " << GDALGetDataTypeName( poBand->GetRasterDataType() ) << ", " << "Color Interpretation " << GDALGetColorInterpretationName( poBand->GetColorInterpretation() ) << std::endl; adfMinMax[0] = poBand->GetMinimum( &bGotMin ); adfMinMax[1] = poBand->GetMaximum( &bGotMax ); if( ! (bGotMin && bGotMax) ) { GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax); } VERBOSE_STR << " Min " << adfMinMax[0] << ", Max " << adfMinMax[1] << std::endl; C[band - 1]->getTags()->setString( "X-TYPE", GDALGetDataTypeName( poBand->GetRasterDataType() ) ); C[band - 1]->getTags()->setString( "X-COLOR_INTERPRETATION", GDALGetColorInterpretationName( poBand->GetColorInterpretation() ) ); C[band - 1]->getTags()->setString( "X-MIN", stringify(adfMinMax[0]).c_str() ); C[band - 1]->getTags()->setString( "X-MAX", stringify(adfMinMax[1]).c_str() ); for( size_t y = 0; y < nBlockYSize; y++ ) { if( poBand->RasterIO( GF_Read, 0, y, nBlockXSize, 1, pafScanline, nBlockXSize, 1, GDT_Float32, 0, 0) != CE_None ) { std::cerr << "input error" << std::endl; throw QuietException(); } memcpy( C[band - 1]->getRawData() + y * nBlockXSize, pafScanline, nBlockXSize * sizeof(float) ); } } CPLFree( pafScanline ); GDALClose( poDataset ); const char *fileNameTag = strcmp( "-", ff.fileName )==0 ? "stdin" : ff.fileName; frame->getTags()->setString( "FILE_NAME", fileNameTag ); pfsio.writeFrame( frame, stdout ); pfsio.freeFrame( frame ); } }
QList< QgsRelief::ReliefColor > QgsRelief::calculateOptimizedReliefClasses() { QList< QgsRelief::ReliefColor > resultList; int nCellsX, nCellsY; GDALDatasetH inputDataset = openInputFile( nCellsX, nCellsY ); if ( !inputDataset ) { return resultList; } //open first raster band for reading (elevation raster is always single band) GDALRasterBandH elevationBand = GDALGetRasterBand( inputDataset, 1 ); if ( !elevationBand ) { GDALClose( inputDataset ); return resultList; } //1. get minimum and maximum of elevation raster -> 252 elevation classes int minOk, maxOk; double minMax[2]; minMax[0] = GDALGetRasterMinimum( elevationBand, &minOk ); minMax[1] = GDALGetRasterMaximum( elevationBand, &maxOk ); if ( !minOk || !maxOk ) { GDALComputeRasterMinMax( elevationBand, true, minMax ); } //2. go through raster cells and get frequency of classes //store elevation frequency in 256 elevation classes double frequency[252]; double frequencyClassRange = ( minMax[1] - minMax[0] ) / 252.0; //initialize to zero for ( int i = 0; i < 252; ++i ) { frequency[i] = 0; } float *scanLine = ( float * ) CPLMalloc( sizeof( float ) * nCellsX ); int elevationClass = -1; for ( int i = 0; i < nCellsY; ++i ) { if ( GDALRasterIO( elevationBand, GF_Read, 0, i, nCellsX, 1, scanLine, nCellsX, 1, GDT_Float32, 0, 0 ) != CE_None ) { QgsDebugMsg( "Raster IO Error" ); } for ( int j = 0; j < nCellsX; ++j ) { elevationClass = frequencyClassForElevation( scanLine[j], minMax[0], frequencyClassRange ); if ( elevationClass < 0 ) { elevationClass = 0; } else if ( elevationClass >= 252 ) { elevationClass = 251; } frequency[elevationClass] += 1.0; } } CPLFree( scanLine ); //log10 transformation for all frequency values for ( int i = 0; i < 252; ++i ) { frequency[i] = std::log10( frequency[i] ); } //start with 9 uniformly distributed classes QList<int> classBreaks; classBreaks.append( 0 ); classBreaks.append( 28 ); classBreaks.append( 56 ); classBreaks.append( 84 ); classBreaks.append( 112 ); classBreaks.append( 140 ); classBreaks.append( 168 ); classBreaks.append( 196 ); classBreaks.append( 224 ); classBreaks.append( 252 ); for ( int i = 0; i < 10; ++i ) { optimiseClassBreaks( classBreaks, frequency ); } //debug, print out all the classbreaks for ( int i = 0; i < classBreaks.size(); ++i ) { qWarning( "%d", classBreaks[i] ); } //set colors according to optimised class breaks QVector<QColor> colorList; colorList.push_back( QColor( 7, 165, 144 ) ); colorList.push_back( QColor( 12, 221, 162 ) ); colorList.push_back( QColor( 33, 252, 183 ) ); colorList.push_back( QColor( 247, 252, 152 ) ); colorList.push_back( QColor( 252, 196, 8 ) ); colorList.push_back( QColor( 252, 166, 15 ) ); colorList.push_back( QColor( 175, 101, 15 ) ); colorList.push_back( QColor( 255, 133, 92 ) ); colorList.push_back( QColor( 204, 204, 204 ) ); resultList.reserve( classBreaks.size() ); for ( int i = 1; i < classBreaks.size(); ++i ) { double minElevation = minMax[0] + classBreaks[i - 1] * frequencyClassRange; double maxElevation = minMax[0] + classBreaks[i] * frequencyClassRange; resultList.push_back( QgsRelief::ReliefColor( colorList.at( i - 1 ), minElevation, maxElevation ) ); } return resultList; }
std::tuple<boost::shared_ptr<Map_Matrix<DataFormat> >, std::string, GeoTransform> read_in_map(fs::path file_path, GDALDataType data_type, const bool doCategorise) throw(std::runtime_error) { std::string projection; GeoTransform transformation; GDALDriver driver; //Check that the file name is valid if (!(fs::is_regular_file(file_path))) { throw std::runtime_error("Input file is not a regular file"); } // Get GDAL to open the file - code is based on the tutorial at http://www.gdal.org/gdal_tutorial.html GDALDataset *poDataset; GDALAllRegister(); //This registers all availble raster file formats for use with this utility. How neat is that. We can input any GDAL supported rater file format. //Open the Raster by calling GDALOpen. http://www.gdal.org/gdal_8h.html#a6836f0f810396c5e45622c8ef94624d4 //char pszfilename[] = file_path.c_str(); //Set this to the file name, as GDALOpen requires the standard C char pointer as function parameter. poDataset = (GDALDataset *) GDALOpen (file_path.string().c_str(), GA_ReadOnly); if (poDataset == NULL) { throw std::runtime_error("Unable to open file"); } // Print some general information about the raster double adfGeoTransform[6]; //An array of doubles that will be used to save information about the raster - where the origin is, what the raster pizel size is. printf( "Driver: %s/%s\n", poDataset->GetDriver()->GetDescription(), poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME ) ); printf( "Size is %dx%dx%d\n", poDataset->GetRasterXSize(), poDataset->GetRasterYSize(), poDataset->GetRasterCount() ); if( poDataset->GetProjectionRef() != NULL ) { printf( "Projection is `%s'\n", poDataset->GetProjectionRef() ); projection = poDataset->GetProjectionRef(); } if( poDataset->GetGeoTransform( adfGeoTransform ) == CE_None ) { printf( "Origin = (%.6f,%.6f)\n", adfGeoTransform[0], adfGeoTransform[3] ); printf( "Pixel Size = (%.6f,%.6f)\n", adfGeoTransform[1], adfGeoTransform[5] ); transformation.x_origin = adfGeoTransform[0]; transformation.pixel_width = adfGeoTransform[1]; transformation.x_line_space = adfGeoTransform[2]; transformation.y_origin = adfGeoTransform[3]; transformation.pixel_height = adfGeoTransform[4]; transformation.y_line_space = adfGeoTransform[5]; } /// Some raster file formats allow many layers of data (called a 'band', with each having the same pixel size and origin location and spatial extent). We will get the data for the first layer into a Boost Array. //Get the data from the first band, // TODO implement method with input to specify what band. GDALRasterBand *poBand; int nBlockXSize, nBlockYSize; int bGotMin, bGotMax; double adfMinMax[2]; poBand = poDataset->GetRasterBand( 1 ); poBand->GetBlockSize( &nBlockXSize, &nBlockYSize ); printf( "Block=%dx%d Type=%s, ColorInterp=%s\n", nBlockXSize, nBlockYSize, GDALGetDataTypeName(poBand->GetRasterDataType()), GDALGetColorInterpretationName( poBand->GetColorInterpretation()) ); adfMinMax[0] = poBand->GetMinimum( &bGotMin ); adfMinMax[1] = poBand->GetMaximum( &bGotMax ); if( ! (bGotMin && bGotMax) ) GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax); printf( "Min=%.3fd, Max=%.3f\n", adfMinMax[0], adfMinMax[1] ); if( poBand->GetOverviewCount() > 0 ) printf( "Band has %d overviews.\n", poBand->GetOverviewCount() ); if( poBand->GetColorTable() != NULL ) printf( "Band has a color table with %d entries.\n", poBand->GetColorTable()->GetColorEntryCount() ); DataFormat * pafScanline; int nXSize = poBand->GetXSize(); int nYSize = poBand->GetYSize(); boost::shared_ptr<Map_Matrix<DataFormat> > in_map(new Map_Matrix<DataFormat>(nYSize, nXSize)); //get a c array of this size and read into this. //pafScanline = new DataFormat[nXSize]; //for (int i = 0; i < nYSize; i++) //rows //{ // poBand->RasterIO(GF_Read, 0, i, nXSize, 1, // pafScanline, nXSize, 1, data_type, // 0, 0); // for (int j = 0; j < nXSize; j++) //cols // { // in_map->Get(i, j) = pafScanline[j]; // } //} //get a c array of this size and read into this. pafScanline = new DataFormat[nXSize * nYSize]; //pafScanline = (float *) CPLMalloc(sizeof(float)*nXSize); poBand->RasterIO( GF_Read, 0, 0, nXSize, nYSize, pafScanline, nXSize, nYSize, data_type, 0, 0 ); //Copy into Map_Matrix. int pafIterator = 0; // Note: Map Matrixes indexes are in opposite order to C arrays. e.g. map matrix is indexed by (row, Col) which is (y, x) and c matrices are done by (x, y) which is (Col, Row) //for (int i = 0; i < nXSize; i++) //{ // for(int j = 0; j < nYSize; j++) // { // in_map->Get(j, i) = pafScanline[pafIterator]; // pafIterator++; // } //} for (int i = 0; i < nYSize; i++) //rows { for (int j = 0; j < nXSize; j++) //cols { in_map->Get(i, j) = pafScanline[pafIterator]; pafIterator++; } } //free the c array storage delete pafScanline; int pbsuccess; // can be used with get no data value in_map->SetNoDataValue(poBand->GetNoDataValue(&pbsuccess)); //This creates a list (map?) listing all the unique values contained in the raster. if (doCategorise) in_map->updateCategories(); //Close GDAL, freeing the memory GDAL is using GDALClose( (GDALDatasetH)poDataset); return (std::make_tuple(in_map, projection, transformation)); }
T* GISToFloatArray(char* fname, int interpWidth, int interpHeight) { // Important note ------ Gdal considers images to be north up // the origin of datasets takes place in the upper-left or North-West corner. // Now to create a GDAL dataset // auto ds = ((GDALDataset*) GDALOpen(fname,GA_ReadOnly)); GDALDataset* ds = ((GDALDataset*) GDALOpen(fname,GA_ReadOnly)); if(ds == NULL) { return NULL; } // Creating a Raster band variable // A band represents one whole dataset within a dataset // in your case your files have one band. GDALRasterBand *poBand; int nBlockXSize, nBlockYSize; int bGotMin, bGotMax; double adfMinMax[2]; // Assign the band poBand = ds->GetRasterBand( 1 ); poBand->GetBlockSize( &nBlockXSize, &nBlockYSize ); // find the min and max adfMinMax[0] = poBand->GetMinimum( &bGotMin ); adfMinMax[1] = poBand->GetMaximum( &bGotMax ); if( ! (bGotMin && bGotMax) ) GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax); int min = adfMinMax[0]; int max = adfMinMax[1]; // get the width and height of the band or dataset int width = poBand->GetXSize(); int height = poBand->GetYSize(); // GDAL can handle files that have multiple datasets jammed witin it int bands = ds->GetRasterCount(); // the float variable to hold the DEM! T *pafScanline; // std::cout << "Min: " << adfMinMax[0] << " Max: " << adfMinMax[1] << endl; int dsize = 256; // pafScanline = (T *) CPLMalloc(sizeof(T)*width*height); pafScanline = (T *) CPLMalloc(sizeof(T)*interpWidth*interpHeight); // Lets acquire the data. ..... this funciton will interpolate for you // poBand->RasterIO(GF_Read,0,0,width,height,pafScanline,width,height,GDT_Float32,0,0); poBand->RasterIO(GF_Read,0,0,width,height,pafScanline,interpWidth,interpHeight,GDT_Float32,0,0); // chage these two to interpolate automatically ^ ^ // The Geotransform gives information on where a dataset is located in the world // and the resolution. // for more information look at http://www.gdal.org/gdal_datamodel.html double geot[6]; ds->GetGeoTransform(geot); // Get the x resolution per pixel(south and west) and y resolution per pixel (north and south) // float xres = geot[1]; // float yres = geot[5]; // string proj; // proj = string(ds->GetProjectionRef()); // You can get the projection string // The projection gives information about the coordinate system a dataset is in // This is important to allow other GIS softwares to place datasets into the same // coordinate space // char* test = &proj[0]; // The origin of the dataset // float startx = geot[0]; // east - west coord. // float starty = geot[3]; // north - south coord. // here is some code that I used to push that 1D array into a 2D array // I believe this puts everything in the correct order.... /*for(int i = 0; i < hsize; i++) { for(int j = 0; j < wsize; j++) { //cout << i << j << endl << pafS; vecs[i][j] = pafScanline[((int)i)*(int)wsize+((int)j)]; if(vecs[i][j]>0 && vecs[i][j] > max) { max = vecs[i][j]; } if(vecs[i][j]>0 && vecs[i][j] < min) { min = vecs[i][j]; } } }*/ //CPLFree(pafScanline); return pafScanline; }
int main(void) { GDALAllRegister(); /*Open a file*/ GDALDatasetH hDataset; hDataset = GDALOpen( "./dem.tif", GA_ReadOnly ); if( hDataset == NULL ) printf("The dataset is NULL!\n"); /*Getting Dasetset Information*/ GDALDriverH hDriver; double adfGeoTransform[6]; hDriver = GDALGetDatasetDriver( hDataset ); printf( "Driver: %s/%s\n", GDALGetDriverShortName( hDriver ), GDALGetDriverLongName( hDriver )); printf("Size is %dx%dx%d\n", GDALGetRasterXSize( hDataset ), GDALGetRasterYSize( hDataset ), GDALGetRasterCount( hDataset )); if( GDALGetProjectionRef( hDataset ) != NULL ) printf("Projection is '%s'\n", GDALGetProjectionRef( hDataset ) ); if (GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None ) { printf("Origin = (%.6f,%.6f)\n", adfGeoTransform[0], adfGeoTransform[3]); printf( "Pixel Size = (%.6f,%.6f)\n", adfGeoTransform[0], adfGeoTransform[5]); } /*Fetching a Raster Band*/ GDALRasterBandH hBand; int nBlockXSize, nBlockYSize; int bGotMin, bGotMax; double adfMinMax[2]; hBand = GDALGetRasterBand( hDataset, 1); GDALGetBlockSize( hBand, &nBlockXSize, &nBlockYSize); printf( "Block=%dx%d Type=%s, ColorInterp=%s\n", nBlockXSize, nBlockYSize, GDALGetDataTypeName(GDALGetRasterDataType(hBand)), GDALGetColorInterpretationName( GDALGetRasterColorInterpretation(hBand)) ); adfMinMax[0] = GDALGetRasterMinimum( hBand, &bGotMin ); adfMinMax[1] = GDALGetRasterMaximum( hBand, &bGotMax ); if( !(bGotMin && bGotMax) ) { GDALComputeRasterMinMax( hBand, TRUE, adfMinMax ); } printf( "Min=%.3fd, Max=%.3f\n", adfMinMax[0], adfMinMax[1]); if(GDALGetOverviewCount(hBand) > 0) printf( "Band has %d overviews.\n", GDALGetOverviewCount(hBand)); if( GDALGetRasterColorTable( hBand ) != NULL) printf( "Band has a color table with %d entries.\n", GDALGetColorEntryCount( GDALGetRasterColorTable( hBand))); /*Reading Raster Data*/ float *pafScanline; int nXSize = GDALGetRasterBandXSize( hBand ); pafScanline = (float *)CPLMalloc(sizeof(float)*nXSize); GDALRasterIO(hBand, GF_Read, 0, 0, nXSize, 1, pafScanline, nXSize, 1, GDT_Float32, 0, 0); CPLFree(pafScanline); return 0; }
void GDALTerrain::init() { dataset = (GDALDataset*) GDALOpen(gdalFile.c_str(), GA_ReadOnly); if(dataset == nullptr) { std::cerr << "Unable to open GDAL File: " << gdalFile << std::endl; exit(1); } auto raster = dataset->GetRasterBand(1); width = raster->GetXSize(); height = raster->GetYSize(); int gotMin, gotMax; float min = (float) raster->GetMinimum(&gotMin); float max = (float) raster->GetMaximum(&gotMax); double minMax[2] = {min, max}; if(!(gotMin && gotMax)) { GDALComputeRasterMinMax((GDALRasterBandH) raster, TRUE, minMax); min = (float) minMax[0]; max = (float) minMax[1]; } if(Engine::getEngine()->getOptions().verbose) { std::cout << "terrain: " << gdalFile << " x: " << width << " y: " << height << " min: " << min << " max: " << max << std::endl; } Vertex vert; vert.normal[0] = 0; vert.normal[1] = 1; vert.normal[2] = 0; float scale = Engine::getEngine()->getOptions().map_scalar; heightScale = 100.0f; gdal_data = std::vector<std::vector<float>>(height, std::vector<float>(width, 0.0f)); float *lineData1 = new float[width]; float *lineData2 = new float[width]; float range = max - min; for(int z = 0; z < height-1; z++) { raster->RasterIO(GF_Read, 0, z, width, 1, lineData1, width, 1, GDT_Float32, 0, 0); raster->RasterIO(GF_Read, 0, z+1, width, 1, lineData2, width, 1, GDT_Float32, 0, 0); gdal_data[z].assign(lineData1, lineData1+width); gdal_data[z+1].assign(lineData2, lineData2+width); for(int x = 0; x < width-1; x++) { vert.pos[0] = x * scale; vert.pos[1] = heightScale * (lineData1[x]-min)/range; vert.pos[2] = z * scale; vert.texture[0] = x;// / float(width); vert.texture[1] = z;// / float(height); calcNormal(x, z, vert, min, range); geometry.push_back(vert); vert.pos[0] = (x+1) * scale; vert.pos[1] = heightScale * (lineData1[x+1]-min)/range; vert.pos[2] = z * scale; vert.texture[0] = (x+1);// / float(width); vert.texture[1] = z;// / float(height); calcNormal(x, z, vert, min, range); geometry.push_back(vert); vert.pos[0] = x * scale; vert.pos[1] = heightScale * (lineData2[x]-min)/range; vert.pos[2] = (z+1) * scale; vert.texture[0] = x;// / float(width); vert.texture[1] = (z+1);// / float(height); calcNormal(x, z, vert, min, range); geometry.push_back(vert); vert.pos[0] = x * scale; vert.pos[1] = heightScale * (lineData2[x]-min)/range; vert.pos[2] = (z+1) * scale; vert.texture[0] = x;// / float(width); vert.texture[1] = (z+1);// / float(height); calcNormal(x, z, vert, min, range); geometry.push_back(vert); vert.pos[0] = (x+1) * scale; vert.pos[1] = heightScale * (lineData2[x+1]-min)/range; vert.pos[2] = (z+1) * scale; vert.texture[0] = (x+1);// / float(width); vert.texture[1] = (z+1);// / float(height); calcNormal(x, z, vert, min, range); geometry.push_back(vert); vert.pos[0] = (x+1) * scale; vert.pos[1] = heightScale * (lineData1[x+1]-min)/range; vert.pos[2] = z * scale; vert.texture[0] = (x+1);// / float(width); vert.texture[1] = z;// / float(height); calcNormal(x, z, vert, min, range); geometry.push_back(vert); } } // for(int i = 0; i < geometry.size(); i++) { // if(i % 6 == 0) // std::cout << i << ": " << geometry[i].pos[1] << std::endl; //} std::cout << "size: " << geometry.size() << std::endl; delete[] lineData1; delete[] lineData2; Vertex *geo = geometry.data(); glGenVertexArrays(1, &vao); glBindVertexArray(vao); glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * geometry.size(), geo, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(program->getLocation("vs_pos"), 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex,pos)); glEnableVertexAttribArray(1); glVertexAttribPointer(program->getLocation("vs_norm"), 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex,normal)); glEnableVertexAttribArray(2); glVertexAttribPointer(program->getLocation("vs_uv"), 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex,texture)); texture = new Texture("../assets/desert.jpg", GL_TEXTURE_2D); //model = glm::translate(model, glm::vec3(width/2, 0, height/2)); }