// ------------------------------------------------------------------- int main(int argc, char **argv) { char *ERROR_PRM = "Ungueltiger numerischer Wert fuer %s: %s\n!"; // Alle GDAL Treiber registrieren GDALAllRegister(); // Dateiname der Geotiff-Datei const char *format = "GTiff"; GDALDriverH h_drv = GDALGetDriverByName( format ); if( h_drv == NULL ) { error_exit(10,"Treiber %s nicht vorhanden!" ,format); } // Test ob Geotiffdateien erzeugt werden koennen char **test_meta; test_meta = GDALGetMetadata( h_drv, NULL ); if( ! CSLFetchBoolean( test_meta, GDAL_DCAP_CREATE, FALSE ) ) { error_exit(10,"Das Format %s kann nicht erzeugt werden" ,format); } // 3 Kommandozeilenparameter if (argc<6) { error_exit(10, "Fehlende Parameter\nUsage %s IN OUT EXT SZ ID X Y ID X Y ID X Y....!\n", argv[0]); } // Eingabemuster einlesen char *ifile = argv[1]; // Ausgabemuster einlesen char *ofile = argv[2]; // zusammengesetzte Ausgabedatei char cfile[512]; // Dateierweiterung setzen char *ext = argv[3]; // Fenstergroesse int size = 64; if (! sscanf(argv[4],"%d",&size) ) { error_exit(1000+3,ERROR_PRM,"SZ",argv[4]); } double trfm[] ={0,0,0,0,0,0}; // Vektoren fuer die Positionen und ID int_vector_t id; int_vector_init(&id, 10); dbl_vector_t pos_x; dbl_vector_init(&pos_x, 10); dbl_vector_t pos_y; dbl_vector_init(&pos_y, 10); // Positionen einlesen int a = 5; double dbl; int pk; while( a < argc-2 ) { // X Koordinate parsen if (! sscanf(argv[a],"%d",&pk) ) { error_exit(1000+a,ERROR_PRM,"ID", argv[a]); } int_vector_add(&id,pk); // X Koordinate parsen if (! sscanf(argv[a+1],"%lf",&dbl) ) { error_exit(1000+a+1,ERROR_PRM,"X", argv[a+1]); } dbl_vector_add(&pos_x,dbl); // Y Koordinate parsen if (! sscanf(argv[a+2],"%lf",&dbl) ) { error_exit(1000+a+2,ERROR_PRM,"Y", argv[a+2]); } dbl_vector_add(&pos_y,dbl); a+=3; } // Alle GDAL Treiber registrieren GDALAllRegister(); // Geotiff oeffnen printf("# IN FILE: %s\n", ifile); GDALDatasetH h_dset = GDALOpen( ifile, GA_ReadOnly); printf("# OUT FILE: %s\n", ofile); printf("# EXTENTION: %s\n", ext); // Transformation holen if( GDALGetGeoTransform( h_dset, trfm ) == CE_None ) { printf("# TRANSFORM: \n"); printf("# X = %.6f + %.6f * COL + %.6f * ROW\n", trfm[0], trfm[1], trfm[2] ); printf("# Y = %.6f + %.6f * COL + %.6f * ROW\n# EOF:\n", trfm[3], trfm[4], trfm[5] ); } else { error_exit(10, "Keine Transformation im TIFF vorhanden!\n"); } // Geotiff Fehler abfangen if( h_dset == NULL ) { error_exit(10, "Datensatz %s kann nicht geoeffnet werden!\n", ifile); } // Bilddimensionen ermitteln int img_width = GDALGetRasterXSize( h_dset ); int img_height = GDALGetRasterYSize( h_dset ); int num_bands = GDALGetRasterCount (h_dset ); // Bilddimensionen ermitteln GDALRasterBandH h_band[num_bands]; GDALDataType h_type[num_bands]; int h_tsize[num_bands]; for(int b=0 ; b<num_bands; b++) { h_band[b] = GDALGetRasterBand( h_dset, b+1 ); h_type[b] = GDALGetRasterDataType(h_band[b]); h_tsize[b] = GDALGetDataTypeSize(h_type[b]); } // Erzeuge Bildschnitte for (int c=0; c< pos_x.length; c++ ) { // Welt zu Pixeltransformation long icol = -1; long irow = -1; trfm_geo_pix(trfm, pos_x.data[c], pos_y.data[c], &icol , &irow); // Dateinamen erzeugen sprintf(cfile,"%s.%d%s",ofile, id.data[c],ext); // Test ob das Schnittfenstrer passt if (icol-size/2<=0 || irow-size/2<=0 || icol+size/2>=img_width || irow+size/2>=img_height){ printf ("IGN %d %s\n",id.data[c],ofile); continue; } // Schneiden printf ("ADD %d %s\n",id.data[c],ofile); int ioffs_col = icol-size/2; int ioffs_row = irow-size/2; // Tiff-Datei anlegen // char **options = NULL; GDALDatasetH h_dset_out = GDALCreate( h_drv, cfile, size, size, num_bands, h_type[0], NULL); // Iteration ueber alle Baender for (int b=0; b< num_bands; b++) { // IO Buffer allozieren @todo static void *io_buffer = CPLMalloc(h_tsize[0] * size * size); // Pixel lesen GDALRasterIO( h_band[b], GF_Read, ioffs_col, ioffs_row, size, size, io_buffer, size, size, h_type[b], 0, 0 ); // Pixel schreiben GDALRasterBandH h_band_out = GDALGetRasterBand(h_dset_out, b+1); GDALRasterIO( h_band_out, GF_Write, 0, 0, size, size, io_buffer, size, size, h_type[b], 0, 0 ); // IO Buffer freigeben CPLFree(io_buffer); } // resultierendes Tiff flushen und schliessen GDALClose( h_dset_out ); } // EOF Positions // Eingangsbild GDALClose( h_dset); return 0; }
bool toprsGadlReader::open() { if(isOpen()) { close(); } std::string driverNameTmp; if (theSubDatasets.size() == 0) { // Note: Cannot feed GDALOpen a NULL string! if (theImageFile.size()) { theDataset = GDALOpen(theImageFile.c_str(), GA_ReadOnly); if( theDataset == 0 ) { return false; } } else { return false; } // Check if it is nitf data for deciding whether or not open each sub-dataset //This will be removed eventually when toprs can handle 2GB nitf file. GDALDriverH driverTmp = GDALGetDatasetDriver(theDataset); bool isNtif = false; if (driverTmp != 0) { driverNameTmp = std::string(GDALGetDriverShortName(driverTmp)); std::transform(driverNameTmp.begin(), driverNameTmp.end(), driverNameTmp.begin(), [&](char ch){return toupper(ch);}); if (driverNameTmp == "NITF") { isNtif = true; } } // Check for sub data sets... char** papszMetadata = GDALGetMetadata( theDataset, "SUBDATASETS" ); if( CSLCount(papszMetadata) > 0 ) { theSubDatasets.clear(); for( int i = 0; papszMetadata[i] != 0; ++i ) { std::string os = papszMetadata[i]; if (os.find("_NAME=") != std::string::npos) { //Sub sets have already been set. Open each sub-dataset really slow down the process //specially for hdf data which sometimes has over 100 sub-datasets. Since following code //only for ntif cloud checking, so only open each sub-dataset here if the dataset is //nitf. This will be removed eventually when toprs can handle 2GB nitf file. //Otherwise open a sub-dataset when setCurrentEntry() gets called. if (isNtif) { GDALDatasetH subDataset = GDALOpen(filterSubDatasetsString(os).c_str(), GA_ReadOnly); if ( subDataset != 0 ) { // "Worldview ingest should ignore subimages when NITF_ICAT=CLOUD" // Hack: Ignore NITF subimages marked as cloud layers. std::string nitfIcatTag( GDALGetMetadataItem( subDataset, "NITF_ICAT", "" ) ); if ( nitfIcatTag.find("CLOUD") == std::string::npos ) { theSubDatasets.push_back(filterSubDatasetsString(os)); } } GDALClose(subDataset); } else { theSubDatasets.push_back(filterSubDatasetsString(os)); } } } //--- // Have multiple entries. We're going to default to open the first // entry like cidcadrg. //--- close(); theDataset = GDALOpen(theSubDatasets[theEntryNumberToRender].c_str(), GA_ReadOnly); if (theDataset == 0) { return false; } } // End of has subsets block. } // End of "if (theSubdatasets.size() == 0)" else { // Sub sets have already been set. theDataset = GDALOpen(theSubDatasets[theEntryNumberToRender].c_str(), GA_ReadOnly); if (theDataset == 0) { return false; } } // Set the driver. theDriver = GDALGetDatasetDriver( theDataset ); if(!theDriver) return false; theGdtType = GDT_Byte; theOutputGdtType = GDT_Byte; if(getNumberOfInputBands() < 1 ) { if(CSLCount(GDALGetMetadata(theDataset, "SUBDATASETS"))) { std::cout << "torsGdalReader::open WARNING:" << "\nHas multiple sub datasets and need to set the data before" << " we can get to the bands" << std::endl; } close(); std::cout << "torsGdalReader::open WARNING:" << "\nNo band data present in torsGdalReader::open" << std::endl; return false; } toprs_int32 i = 0; GDALRasterBandH bBand = GDALGetRasterBand( theDataset, 1 ); theGdtType = GDALGetRasterDataType(bBand); char** papszMetadata = GDALGetMetadata( bBand, NULL ); if (CSLCount(papszMetadata) > 0) { for(int i = 0; papszMetadata[i] != NULL; i++ ) { std::string metaStr = papszMetadata[i]; if (metaStr.find("AREA_OR_POINT") != std::string::npos) { //std::string pixel_is_point_or_area = metaStr.split("=")[1]; //pixel_is_point_or_area.downcase(); //if (pixel_is_point_or_area.contains("area")) // thePixelType = TOPRS_PIXEL_IS_AREA; break; } } } if(!isIndexed(1)) { for(i = 0; i < GDALGetRasterCount(theDataset); ++i) { if(theGdtType != GDALGetRasterDataType(GDALGetRasterBand( theDataset,i+1 ))) { std::cout << "torsGdalReader::open WARNING" << "\nWe currently do not support different scalar type bands." << std::endl; close(); return false; } } } theOutputGdtType = theGdtType; switch(theGdtType) { case GDT_CInt16: { // theOutputGdtType = GDT_Int16; theIsComplexFlag = true; break; } case GDT_CInt32: { // theOutputGdtType = GDT_Int32; theIsComplexFlag = true; break; } case GDT_CFloat32: { // theOutputGdtType = GDT_Float32; theIsComplexFlag = true; break; } case GDT_CFloat64: { // theOutputGdtType = GDT_Float64; theIsComplexFlag = true; break; } default: { theIsComplexFlag = false; break; } } if((std::string(GDALGetDriverShortName( theDriver )) == "PNG")&& (getNumberOfInputBands() == 4)) { theAlphaChannelFlag = true; } populateLut(); computeMinMax(); completeOpen(); theTile = toprsImgFactory::instance()->create(this); theSingleBandTile = toprsImgFactory::instance()->create(getInputScalarType(), 1); if ( m_preservePaletteIndexesFlag ) { theTile->setIndexedFlag(true); theSingleBandTile->setIndexedFlag(true); } theTile->initialize(); theSingleBandTile->initialize(); theGdalBuffer.resize(0); if(theIsComplexFlag) { theGdalBuffer.resize(theSingleBandTile->getSizePerBandInBytes()*2); } theImageBound = toprsIRect(0 ,0 ,GDALGetRasterXSize(theDataset)-1 ,GDALGetRasterYSize(theDataset)-1); int xSize=0, ySize=0; GDALGetBlockSize(GDALGetRasterBand( theDataset, 1 ), &xSize, &ySize); if (driverNameTmp.find("JPIP")!= std::string::npos || driverNameTmp.find("JP2")!= std::string::npos) { m_isBlocked = ((xSize > 1)&&(ySize > 1)); } else { m_isBlocked = false; } //if(m_isBlocked) //{ // setRlevelCache(); //} return true; }
int QgsZonalStatistics::calculateStatistics( QProgressDialog* p ) { if ( !mPolygonLayer || mPolygonLayer->geometryType() != QGis::Polygon ) { return 1; } QgsVectorDataProvider* vectorProvider = mPolygonLayer->dataProvider(); if ( !vectorProvider ) { return 2; } //open the raster layer and the raster band GDALAllRegister(); GDALDatasetH inputDataset = GDALOpen( TO8F( mRasterFilePath ), GA_ReadOnly ); if ( inputDataset == NULL ) { return 3; } if ( GDALGetRasterCount( inputDataset ) < ( mRasterBand - 1 ) ) { GDALClose( inputDataset ); return 4; } GDALRasterBandH rasterBand = GDALGetRasterBand( inputDataset, mRasterBand ); if ( rasterBand == NULL ) { GDALClose( inputDataset ); return 5; } mInputNodataValue = GDALGetRasterNoDataValue( rasterBand, NULL ); //get geometry info about raster layer int nCellsXGDAL = GDALGetRasterXSize( inputDataset ); int nCellsYGDAL = GDALGetRasterYSize( inputDataset ); double geoTransform[6]; if ( GDALGetGeoTransform( inputDataset, geoTransform ) != CE_None ) { GDALClose( inputDataset ); return 6; } double cellsizeX = geoTransform[1]; if ( cellsizeX < 0 ) { cellsizeX = -cellsizeX; } double cellsizeY = geoTransform[5]; if ( cellsizeY < 0 ) { cellsizeY = -cellsizeY; } QgsRectangle rasterBBox( geoTransform[0], geoTransform[3] - ( nCellsYGDAL * cellsizeY ), geoTransform[0] + ( nCellsXGDAL * cellsizeX ), geoTransform[3] ); //add the new count, sum, mean fields to the provider QList<QgsField> newFieldList; QString countFieldName = getUniqueFieldName( mAttributePrefix + "count" ); QString sumFieldName = getUniqueFieldName( mAttributePrefix + "sum" ); QString meanFieldName = getUniqueFieldName( mAttributePrefix + "mean" ); QgsField countField( countFieldName, QVariant::Double, "double precision" ); QgsField sumField( sumFieldName, QVariant::Double, "double precision" ); QgsField meanField( meanFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( countField ); newFieldList.push_back( sumField ); newFieldList.push_back( meanField ); vectorProvider->addAttributes( newFieldList ); //index of the new fields int countIndex = vectorProvider->fieldNameIndex( countFieldName ); int sumIndex = vectorProvider->fieldNameIndex( sumFieldName ); int meanIndex = vectorProvider->fieldNameIndex( meanFieldName ); if ( countIndex == -1 || sumIndex == -1 || meanIndex == -1 ) { return 8; } //progress dialog long featureCount = vectorProvider->featureCount(); if ( p ) { p->setMaximum( featureCount ); } //iterate over each polygon QgsFeatureRequest request; request.setSubsetOfAttributes( QgsAttributeList() ); QgsFeatureIterator fi = vectorProvider->getFeatures( request ); QgsFeature f; double count = 0; double sum = 0; double mean = 0; int featureCounter = 0; while ( fi.nextFeature( f ) ) { if ( p ) { p->setValue( featureCounter ); } if ( p && p->wasCanceled() ) { break; } QgsGeometry* featureGeometry = f.geometry(); if ( !featureGeometry ) { ++featureCounter; continue; } QgsRectangle featureRect = featureGeometry->boundingBox().intersect( &rasterBBox ); if ( featureRect.isEmpty() ) { ++featureCounter; continue; } int offsetX, offsetY, nCellsX, nCellsY; if ( cellInfoForBBox( rasterBBox, featureRect, cellsizeX, cellsizeY, offsetX, offsetY, nCellsX, nCellsY ) != 0 ) { ++featureCounter; continue; } //avoid access to cells outside of the raster (may occur because of rounding) if (( offsetX + nCellsX ) > nCellsXGDAL ) { nCellsX = nCellsXGDAL - offsetX; } if (( offsetY + nCellsY ) > nCellsYGDAL ) { nCellsY = nCellsYGDAL - offsetY; } statisticsFromMiddlePointTest( rasterBand, featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY, rasterBBox, sum, count ); if ( count <= 1 ) { //the cell resolution is probably larger than the polygon area. We switch to precise pixel - polygon intersection in this case statisticsFromPreciseIntersection( rasterBand, featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY, rasterBBox, sum, count ); } if ( count == 0 ) { mean = 0; } else { mean = sum / count; } //write the statistics value to the vector data provider QgsChangedAttributesMap changeMap; QgsAttributeMap changeAttributeMap; changeAttributeMap.insert( countIndex, QVariant( count ) ); changeAttributeMap.insert( sumIndex, QVariant( sum ) ); changeAttributeMap.insert( meanIndex, QVariant( mean ) ); changeMap.insert( f.id(), changeAttributeMap ); vectorProvider->changeAttributeValues( changeMap ); ++featureCounter; } if ( p ) { p->setValue( featureCount ); } GDALClose( inputDataset ); mPolygonLayer->updateFields(); if ( p && p->wasCanceled() ) { return 9; } return 0; }
int main( int argc, const char* argv[] ) { GDALDriverH hDriver; double adfGeoTransform[6]; GDALDatasetH in_Dataset; GDALDatasetH mask_Dataset; GDALDatasetH out_Dataset; GDALRasterBandH mask_band; char *mask_scan_line, *data_scan_line; int nBlockXSize, nBlockYSize; int bGotMin, bGotMax; int bands; int xsize; double adfMinMax[2]; GDALAllRegister(); if ( argc != 2) { printf("Usage: %s <file to add mask to> \n", argv[0]); printf("This utility adds a nodata mask to a file, were the datadata value is \"0\"\n"); printf("contact/blame [email protected] for questions/problems.\n"); return 0; } /* open datasets..*/ in_Dataset = GDAL_open( argv[1]); /* add mask.. */ GDALCreateDatasetMaskBand( in_Dataset, 0); /* Basic info on source dataset..*/ GDALGetBlockSize(GDALGetRasterBand( in_Dataset, 1 ) , &nBlockXSize, &nBlockYSize ); printf( "Block=%dx%d Type=%s, ColorInterp=%s\n", nBlockXSize, nBlockYSize, GDALGetDataTypeName(GDALGetRasterDataType( GDALGetRasterBand( in_Dataset, 1 ))), GDALGetColorInterpretationName( GDALGetRasterColorInterpretation(GDALGetRasterBand( in_Dataset, 1 )))); /* Loop though bands, wiping values with mask values of 0.. */ xsize = GDALGetRasterXSize( in_Dataset ); mask_scan_line = (char *) CPLMalloc(sizeof(char)*xsize); data_scan_line = (char *) CPLMalloc(sizeof(char)*xsize); for (bands=1; bands <= GDALGetRasterCount( in_Dataset ); bands ++ ) { int x; GDALRasterBandH data_band, out_band; int y_index = 0; printf("INFO: Doing band %d of %d\n", bands,GDALGetRasterCount( in_Dataset ) ); data_band = GDALGetRasterBand( in_Dataset, bands); mask_band = GDALGetMaskBand(data_band); for (y_index = 0; y_index <GDALGetRasterYSize( in_Dataset ); y_index ++ ) { /* Read data..*/ GDALRasterIO( data_band, GF_Read, 0, y_index, xsize , 1, data_scan_line, xsize , 1, GDT_Byte, 0, 0 ); for(x=0; x < xsize; x++) { /* if mask is set to 0, then mask off...*/ /* lame nodata handleing, but such is life.. */ if ( data_scan_line[x] == 0 ) mask_scan_line[x]=0; else mask_scan_line[x]=255; } /* now write out band..*/ GDALRasterIO( mask_band, GF_Write, 0, y_index, xsize , 1, mask_scan_line, xsize , 1, GDT_Byte, 0, 0 ); } } GDALClose(in_Dataset); }
int main(int argc, char *argv[]) { const char *index_filename = NULL; const char *tile_index = "location"; int i_arg, ti_field; OGRDataSourceH hTileIndexDS; OGRLayerH hLayer = NULL; OGRFeatureDefnH hFDefn; int write_absolute_path = FALSE; char* current_path = NULL; int i; int nExistingFiles; int skip_different_projection = FALSE; char** existingFilesTab = NULL; int alreadyExistingProjectionRefValid = FALSE; char* alreadyExistingProjectionRef = NULL; char* index_filename_mod; int bExists; VSIStatBuf sStatBuf; const char *pszTargetSRS = ""; int bSetTargetSRS = FALSE; OGRSpatialReferenceH hTargetSRS = NULL; /* Check that we are running against at least GDAL 1.4 */ /* Note to developers : if we use newer API, please change the requirement */ if (atoi(GDALVersionInfo("VERSION_NUM")) < 1400) { fprintf(stderr, "At least, GDAL >= 1.4.0 is required for this version of %s, " "which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME); exit(1); } GDALAllRegister(); OGRRegisterAll(); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); /* -------------------------------------------------------------------- */ /* Get commandline arguments other than the GDAL raster filenames. */ /* -------------------------------------------------------------------- */ for( i_arg = 1; i_arg < argc; i_arg++ ) { if( EQUAL(argv[i_arg], "--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( strcmp(argv[i_arg],"-tileindex") == 0 ) { tile_index = argv[++i_arg]; } else if( strcmp(argv[i_arg],"-t_srs") == 0 ) { pszTargetSRS = argv[++i_arg]; bSetTargetSRS = TRUE; } else if ( strcmp(argv[i_arg],"-write_absolute_path") == 0 ) { write_absolute_path = TRUE; } else if ( strcmp(argv[i_arg],"-skip_different_projection") == 0 ) { skip_different_projection = TRUE; } else if( argv[i_arg][0] == '-' ) Usage(); else if( index_filename == NULL ) { index_filename = argv[i_arg]; i_arg++; break; } } if( index_filename == NULL || i_arg == argc ) Usage(); /* -------------------------------------------------------------------- */ /* Create and validate target SRS if given. */ /* -------------------------------------------------------------------- */ if( bSetTargetSRS ) { if ( skip_different_projection ) { fprintf( stderr, "Warning : -skip_different_projection does not apply " "when -t_srs is requested.\n" ); } hTargetSRS = OSRNewSpatialReference(""); if( OSRSetFromUserInput( hTargetSRS, pszTargetSRS ) != CE_None ) { OSRDestroySpatialReference( hTargetSRS ); fprintf( stderr, "Invalid target SRS `%s'.\n", pszTargetSRS ); exit(1); } } /* -------------------------------------------------------------------- */ /* Open or create the target shapefile and DBF file. */ /* -------------------------------------------------------------------- */ index_filename_mod = CPLStrdup(CPLResetExtension(index_filename, "shp")); bExists = (VSIStat(index_filename_mod, &sStatBuf) == 0); if (!bExists) { CPLFree(index_filename_mod); index_filename_mod = CPLStrdup(CPLResetExtension(index_filename, "SHP")); bExists = (VSIStat(index_filename_mod, &sStatBuf) == 0); } CPLFree(index_filename_mod); if (bExists) { hTileIndexDS = OGROpen( index_filename, TRUE, NULL ); if (hTileIndexDS != NULL) { hLayer = OGR_DS_GetLayer(hTileIndexDS, 0); } } else { OGRSFDriverH hDriver; const char* pszDriverName = "ESRI Shapefile"; printf( "Creating new index file...\n" ); hDriver = OGRGetDriverByName( pszDriverName ); if( hDriver == NULL ) { printf( "%s driver not available.\n", pszDriverName ); exit( 1 ); } hTileIndexDS = OGR_Dr_CreateDataSource( hDriver, index_filename, NULL ); if (hTileIndexDS) { char* pszLayerName = CPLStrdup(CPLGetBasename(index_filename)); /* get spatial reference for output file from target SRS (if set) */ /* or from first input file */ OGRSpatialReferenceH hSpatialRef = NULL; if( bSetTargetSRS ) { hSpatialRef = OSRClone( hTargetSRS ); } else { GDALDatasetH hDS = GDALOpen( argv[i_arg], GA_ReadOnly ); if (hDS) { const char* pszWKT = GDALGetProjectionRef(hDS); if (pszWKT != NULL && pszWKT[0] != '\0') { hSpatialRef = OSRNewSpatialReference(pszWKT); } GDALClose(hDS); } } hLayer = OGR_DS_CreateLayer( hTileIndexDS, pszLayerName, hSpatialRef, wkbPolygon, NULL ); CPLFree(pszLayerName); if (hSpatialRef) OSRRelease(hSpatialRef); if (hLayer) { OGRFieldDefnH hFieldDefn = OGR_Fld_Create( tile_index, OFTString ); OGR_Fld_SetWidth( hFieldDefn, 255); OGR_L_CreateField( hLayer, hFieldDefn, TRUE ); OGR_Fld_Destroy(hFieldDefn); } } } if( hTileIndexDS == NULL || hLayer == NULL ) { fprintf( stderr, "Unable to open/create shapefile `%s'.\n", index_filename ); exit(2); } hFDefn = OGR_L_GetLayerDefn(hLayer); for( ti_field = 0; ti_field < OGR_FD_GetFieldCount(hFDefn); ti_field++ ) { OGRFieldDefnH hFieldDefn = OGR_FD_GetFieldDefn( hFDefn, ti_field ); if( strcmp(OGR_Fld_GetNameRef(hFieldDefn), tile_index) == 0 ) break; } if( ti_field == OGR_FD_GetFieldCount(hFDefn) ) { fprintf( stderr, "Unable to find field `%s' in DBF file `%s'.\n", tile_index, index_filename ); exit(2); } /* Load in memory existing file names in SHP */ nExistingFiles = OGR_L_GetFeatureCount(hLayer, FALSE); if (nExistingFiles) { OGRFeatureH hFeature; existingFilesTab = (char**)CPLMalloc(nExistingFiles * sizeof(char*)); for(i=0;i<nExistingFiles;i++) { hFeature = OGR_L_GetNextFeature(hLayer); existingFilesTab[i] = CPLStrdup(OGR_F_GetFieldAsString( hFeature, ti_field )); if (i == 0) { GDALDatasetH hDS = GDALOpen(existingFilesTab[i], GA_ReadOnly ); if (hDS) { alreadyExistingProjectionRefValid = TRUE; alreadyExistingProjectionRef = CPLStrdup(GDALGetProjectionRef(hDS)); GDALClose(hDS); } } OGR_F_Destroy( hFeature ); } } if (write_absolute_path) { current_path = CPLGetCurrentDir(); if (current_path == NULL) { fprintf( stderr, "This system does not support the CPLGetCurrentDir call. " "The option -write_absolute_path will have no effect\n"); write_absolute_path = FALSE; } } /* -------------------------------------------------------------------- */ /* loop over GDAL files, processing. */ /* -------------------------------------------------------------------- */ for( ; i_arg < argc; i_arg++ ) { GDALDatasetH hDS; double adfGeoTransform[6]; double adfX[5], adfY[5]; int nXSize, nYSize; char* fileNameToWrite; const char* projectionRef; VSIStatBuf sStatBuf; int k; OGRFeatureH hFeature; OGRGeometryH hPoly, hRing; /* Make sure it is a file before building absolute path name */ if (write_absolute_path && CPLIsFilenameRelative( argv[i_arg] ) && VSIStat( argv[i_arg], &sStatBuf ) == 0) { fileNameToWrite = CPLStrdup(CPLProjectRelativeFilename(current_path, argv[i_arg])); } else { fileNameToWrite = CPLStrdup(argv[i_arg]); } /* Checks that file is not already in tileindex */ for(i=0;i<nExistingFiles;i++) { if (EQUAL(fileNameToWrite, existingFilesTab[i])) { fprintf(stderr, "File %s is already in tileindex. Skipping it.\n", fileNameToWrite); break; } } if (i != nExistingFiles) { CPLFree(fileNameToWrite); continue; } hDS = GDALOpen( argv[i_arg], GA_ReadOnly ); if( hDS == NULL ) { fprintf( stderr, "Unable to open %s, skipping.\n", argv[i_arg] ); CPLFree(fileNameToWrite); continue; } GDALGetGeoTransform( hDS, adfGeoTransform ); if( adfGeoTransform[0] == 0.0 && adfGeoTransform[1] == 1.0 && adfGeoTransform[3] == 0.0 && ABS(adfGeoTransform[5]) == 1.0 ) { fprintf( stderr, "It appears no georeferencing is available for\n" "`%s', skipping.\n", argv[i_arg] ); GDALClose( hDS ); CPLFree(fileNameToWrite); continue; } projectionRef = GDALGetProjectionRef(hDS); /* if not set target srs, test that the current file uses same projection as others */ if( !bSetTargetSRS ) { if (alreadyExistingProjectionRefValid) { int projectionRefNotNull, alreadyExistingProjectionRefNotNull; projectionRefNotNull = projectionRef && projectionRef[0]; alreadyExistingProjectionRefNotNull = alreadyExistingProjectionRef && alreadyExistingProjectionRef[0]; if ((projectionRefNotNull && alreadyExistingProjectionRefNotNull && EQUAL(projectionRef, alreadyExistingProjectionRef) == 0) || (projectionRefNotNull != alreadyExistingProjectionRefNotNull)) { fprintf(stderr, "Warning : %s is not using the same projection system as " "other files in the tileindex.\n" "This may cause problems when using it in MapServer for example.\n" "Use -t_srs option to set target projection system (not supported by MapServer).\n" "%s\n", argv[i_arg], (skip_different_projection) ? "Skipping this file." : ""); if (skip_different_projection) { CPLFree(fileNameToWrite); GDALClose( hDS ); continue; } } } else { alreadyExistingProjectionRefValid = TRUE; alreadyExistingProjectionRef = CPLStrdup(projectionRef); } } nXSize = GDALGetRasterXSize( hDS ); nYSize = GDALGetRasterYSize( hDS ); adfX[0] = adfGeoTransform[0] + 0 * adfGeoTransform[1] + 0 * adfGeoTransform[2]; adfY[0] = adfGeoTransform[3] + 0 * adfGeoTransform[4] + 0 * adfGeoTransform[5]; adfX[1] = adfGeoTransform[0] + nXSize * adfGeoTransform[1] + 0 * adfGeoTransform[2]; adfY[1] = adfGeoTransform[3] + nXSize * adfGeoTransform[4] + 0 * adfGeoTransform[5]; adfX[2] = adfGeoTransform[0] + nXSize * adfGeoTransform[1] + nYSize * adfGeoTransform[2]; adfY[2] = adfGeoTransform[3] + nXSize * adfGeoTransform[4] + nYSize * adfGeoTransform[5]; adfX[3] = adfGeoTransform[0] + 0 * adfGeoTransform[1] + nYSize * adfGeoTransform[2]; adfY[3] = adfGeoTransform[3] + 0 * adfGeoTransform[4] + nYSize * adfGeoTransform[5]; adfX[4] = adfGeoTransform[0] + 0 * adfGeoTransform[1] + 0 * adfGeoTransform[2]; adfY[4] = adfGeoTransform[3] + 0 * adfGeoTransform[4] + 0 * adfGeoTransform[5]; /* if set target srs, do the forward transformation of all points */ if( bSetTargetSRS ) { OGRSpatialReferenceH hSourceSRS = NULL; OGRCoordinateTransformationH hCT = NULL; hSourceSRS = OSRNewSpatialReference( projectionRef ); if( hSourceSRS && !OSRIsSame( hSourceSRS, hTargetSRS ) ) { hCT = OCTNewCoordinateTransformation( hSourceSRS, hTargetSRS ); if( hCT == NULL || !OCTTransform( hCT, 5, adfX, adfY, NULL ) ) { fprintf( stderr, "Warning : unable to transform points from source SRS `%s' to target SRS `%s'\n" "for file `%s' - file skipped\n", projectionRef, pszTargetSRS, fileNameToWrite ); if ( hCT ) OCTDestroyCoordinateTransformation( hCT ); if ( hSourceSRS ) OSRDestroySpatialReference( hSourceSRS ); continue; } if ( hCT ) OCTDestroyCoordinateTransformation( hCT ); } if ( hSourceSRS ) OSRDestroySpatialReference( hSourceSRS ); } hFeature = OGR_F_Create( OGR_L_GetLayerDefn( hLayer ) ); OGR_F_SetFieldString( hFeature, ti_field, fileNameToWrite ); hPoly = OGR_G_CreateGeometry(wkbPolygon); hRing = OGR_G_CreateGeometry(wkbLinearRing); for(k=0;k<5;k++) OGR_G_SetPoint_2D(hRing, k, adfX[k], adfY[k]); OGR_G_AddGeometryDirectly( hPoly, hRing ); OGR_F_SetGeometryDirectly( hFeature, hPoly ); if( OGR_L_CreateFeature( hLayer, hFeature ) != OGRERR_NONE ) { printf( "Failed to create feature in shapefile.\n" ); break; } OGR_F_Destroy( hFeature ); CPLFree(fileNameToWrite); GDALClose( hDS ); } CPLFree(current_path); if (nExistingFiles) { for(i=0;i<nExistingFiles;i++) { CPLFree(existingFilesTab[i]); } CPLFree(existingFilesTab); } CPLFree(alreadyExistingProjectionRef); if ( hTargetSRS ) OSRDestroySpatialReference( hTargetSRS ); OGR_DS_Destroy( hTileIndexDS ); GDALDestroyDriverManager(); OGRCleanupAll(); CSLDestroy(argv); exit( 0 ); }
HRESULT CImage::Open(char* pszPathName,UINT uMode) { Close(); m_pszPathName=new char[strlen(pszPathName)+1]; strcpy(m_pszPathName,pszPathName); if(strcmp(m_pszPathName+strlen(m_pszPathName)-3,"txt")==0) { char szPath[512]; memset(szPath,0,512*sizeof(char)); int nPos=-1; int i=strlen(m_pszPathName)-1; for(;i>=0;i--) { if(m_pszPathName[i]=='\\'||m_pszPathName[i]=='/') { nPos=i; break; } } for(i=0;i<=nPos;i++) { szPath[i]=m_pszPathName[i]; } FILE* fp=fopen(m_pszPathName,"rt"); if(fp==NULL) { return S_FALSE; } BOOL bGeoCoded=FALSE; char szBuffer[1024]; char szTag[100],szEqualMark[10],szValue[512]; while(!feof(fp)) { memset(szBuffer, 0 ,sizeof(char)*1024); memset(szTag, 0 ,sizeof(char)*100); memset(szEqualMark, 0 ,sizeof(char)*10); memset(szValue, 0 ,sizeof(char)*512); fgets(szBuffer,1023,fp); sscanf(szBuffer,"%s%s%s",szTag,szEqualMark,szValue); int nLength=strlen(szValue); if(nLength>0) { if(szValue[nLength-1]==';') { szValue[nLength-1]='\0'; } } // Parse the satellite ID from the GC report file. [Wei.Zuo,4/15/2009] if(strcmp(szTag,"satelliteID")==0) { if(strcmp(szValue,"\"HJ1A\"")==0) m_nSatelliteID = 1; else if(strcmp(szValue,"\"HJ1B\"")==0) m_nSatelliteID = 2; else m_nSatelliteID = 0; } else if(strcmp(szTag,"sensorID")==0) { if(strcmp(szValue,"\"CCD\"")==0) { m_nSensorType=SENSOR_CCD; m_nBPB=1; m_datatype=ConvertDataType2GDALDataType(Pixel_Byte); } else if(strcmp(szValue,"\"HSI\"")==0) { m_nSensorType=SENSOR_HSI; m_nBPB=2; m_datatype=ConvertDataType2GDALDataType(Pixel_Int16); } else if(strcmp(szValue,"\"IRS\"")==0) { m_nSensorType=SENSOR_IRS; m_nBPB=2; m_datatype=ConvertDataType2GDALDataType(Pixel_Int16); } // Add sensor CCD1 and CCD2. [Wei.Zuo,4/15/2009] else if(strcmp(szValue,"\"CCD1\"")==0) { m_nSensorType=SENSOR_CCD1; m_nBPB=1; m_datatype=ConvertDataType2GDALDataType(Pixel_Byte); } else if(strcmp(szValue,"\"CCD2\"")==0) { m_nSensorType=SENSOR_CCD2; m_nBPB=1; m_datatype=ConvertDataType2GDALDataType(Pixel_Byte); } // Later will add sensor SAR. [Wei.Zuo,4/15/2009] } else if(strcmp(szTag,"ImgNum")==0) { m_nImgNum=atoi(szValue); m_nBandNum=m_nImgNum; } else if(strcmp(szTag,"Bands")==0) { m_nBandNum=atoi(szValue); } else if(strcmp(szTag,"processedImageWidth")==0) { m_nCols=atoi(szValue); } else if(strcmp(szTag,"processedImageHeight")==0) { m_nRows=atoi(szValue); } //������Ϣ else if(strcmp(szTag,"pixelSpacing")==0) { m_CellSize=atof(szValue); bGeoCoded=TRUE; } else if(strcmp(szTag,"productLowerLeftX")==0) { m_LBX=atof(szValue); } else if(strcmp(szTag,"productLowerLeftY")==0) { m_LBY=atof(szValue); } else if(strcmp(szTag,"productLowerRightX")==0) { } else if(strcmp(szTag,"productLowerRightY")==0) { } else if(strcmp(szTag,"productUpperRightX")==0) { m_RTX=atof(szValue); } else if(strcmp(szTag,"productUpperRightY")==0) { m_RTY=atof(szValue); } else if(strcmp(szTag,"productUpperLeftX")==0) { } else if(strcmp(szTag,"productUpperLeftY")==0) { } } if(m_nBandNum<=0||m_nImgNum<=0) { fclose(fp); return S_FALSE; } if(bGeoCoded==FALSE) { m_LBX=0; m_LBY=0; m_RTX=m_nCols; m_RTY=m_nRows; m_CellSize=1.0; } m_fpRaws=new FILE*[m_nImgNum]; memset(m_fpRaws,0,sizeof(FILE*)*m_nImgNum); for(i=0;i<m_nImgNum;i++) { char szStdTag[100]; sprintf(szStdTag,"outputdata%d",i); fseek(fp,0,SEEK_SET); while(!feof(fp)) { fgets(szBuffer,1023,fp); sscanf(szBuffer,"%s%s%s",szTag,szEqualMark,szValue); if(strcmp(szTag,szStdTag)==0) { char szName[512]; memset(szName,0,512*sizeof(char)); int nPos=-1; int k=strlen(szValue)-1; for(;k>=0;k--) { if(szValue[k]=='\\'||szValue[k]=='/') { nPos=k; break; } } for(k=nPos+1;k<((int)(strlen(szValue)));k++) { if(szValue[k]=='\"') { break; } szName[k-nPos-1]=szValue[k]; } char szRawPathName[512]; strcpy(szRawPathName,szPath); strcat(szRawPathName,szName); if(m_nSensorType==SENSOR_IRS&&i==3&&m_nRows==4500&&m_nCols==4500) { char szRawPathNameTemp[512]; sprintf(szRawPathNameTemp,"%s_resample.raw",szRawPathName); FILE* fpSrc=fopen(szRawPathName,"rb"); FILE* fpDst=fopen(szRawPathNameTemp,"wb"); if(fpSrc==NULL||fpDst==NULL) { Close(); fclose(fpSrc); fclose(fpDst); return S_FALSE; } BYTE* pSrcBuffer=new BYTE[m_nCols/2*m_nBPB]; BYTE* pDstBuffer=new BYTE[m_nCols*m_nBPB]; int m=0,n=0; for(m=0;m<m_nRows/2;m++) { fread(pSrcBuffer,m_nBPB,m_nCols/2,fpSrc); for(n=0;n<m_nCols/2;n++) { memcpy(pDstBuffer+(n*2+0)*m_nBPB,pSrcBuffer+n*m_nBPB,m_nBPB); memcpy(pDstBuffer+(n*2+1)*m_nBPB,pSrcBuffer+n*m_nBPB,m_nBPB); } fwrite(pDstBuffer,m_nBPB,m_nCols,fpDst); fwrite(pDstBuffer,m_nBPB,m_nCols,fpDst); } fclose(fpSrc); fclose(fpDst); delete [] pSrcBuffer; delete [] pDstBuffer; strcpy(szRawPathName,szRawPathNameTemp); } m_fpRaws[i]=fopen(szRawPathName,"rb"); if(m_fpRaws[i]==NULL) { Close(); fclose(fp); return S_FALSE; } } } } fclose(fp); } else { GDALAllRegister(); m_pGdalImage=(GDALDataset*)GDALOpen(m_pszPathName,GA_ReadOnly); if(m_pGdalImage==NULL) { return S_FALSE; } //��ȡӰ��ߴ���Ϣ m_nCols=GDALGetRasterXSize(m_pGdalImage); m_nRows=GDALGetRasterYSize(m_pGdalImage); m_nBandNum=GDALGetRasterCount(m_pGdalImage); if(m_nBandNum<=0) { return S_FALSE; } m_datatype=GDALGetRasterDataType(GDALGetRasterBand(m_pGdalImage,1)); m_nBPB=GDALGetDataTypeSize(m_datatype)/8; for(int i=2;i<=m_nBandNum;i++) { if(GDALGetRasterDataType(GDALGetRasterBand(m_pGdalImage,i))!=m_datatype) { GDALClose(m_pGdalImage); COutput::OutputFileOpenFailed(m_pszPathName); return S_FALSE; } } //��ȡ������Ϣ double grdTransform[6]; memset(grdTransform,0,sizeof(double)*6); CPLErr error=m_pGdalImage->GetGeoTransform(grdTransform); if(error==CE_None) { double X0,Y0,X2,Y2; X0=grdTransform[0]; Y0=grdTransform[3]; X2=grdTransform[0]+m_nCols*grdTransform[1]+m_nRows*grdTransform[2]; Y2=grdTransform[3]+m_nCols*grdTransform[4]+m_nRows*grdTransform[5]; m_LBX=__min(X0,X2); m_LBY=__min(Y0,Y2); m_RTX=__max(X0,X2); m_RTY=__max(Y0,Y2); m_CellSize=fabs(grdTransform[1]); } else { m_LBX=0; m_LBY=0; m_RTX=m_nCols; m_RTY=m_nRows; m_CellSize=1.0; } } //��ʼ�������� m_nCacheRow=m_CacheSize/(m_nCols*m_nBandNum*m_nBPB); if(m_nCacheRow<=0) { if(m_pCache) { delete [] m_pCache; } m_pCache=NULL; BOOL bMemEnough=FALSE; int nRow=24000; while(bMemEnough==FALSE&&nRow>1) { try { m_nCacheRow=nRow; m_CacheSize=m_nCols*m_nBandNum*m_nBPB*m_nCacheRow; m_pCache=new BYTE[m_CacheSize]; bMemEnough=TRUE; } catch(...) { nRow=nRow/2; if(nRow<=0) { nRow=1; } } } if(m_pCache==NULL) { try { m_pCache=new BYTE[m_nCols*m_nBandNum*m_nBPB*1]; m_CacheSize=m_nCols*m_nBandNum*m_nBPB*1; m_nCacheRow=1; } catch(...) { COutput::OutputMemoryError(); Close(); return S_FALSE; } } } if((uMode&modeAqlut)==modeAqlut) { //here pHistogram mast write as follows CHistogram* pHistogram=new CHistogram[m_nBandNum]; for(int i=0;i<m_nBandNum;i++) { pHistogram[i].StatHistogram(this,i); } m_pHistogram=pHistogram; pHistogram=NULL; } return S_OK; }
ral_grid_handle RAL_CALL ral_grid_create_using_GDAL(GDALDatasetH dataset, int band, ral_rectangle clip_region, double cell_size) { GDALRasterBandH hBand; GDALDataType datatype; int M, N, gd_datatype; int W, H; /* size of the full GDAL raster */ int north_up, east_up, i0, j0, i1, j1, w, h; /* the clip region (P) */ int ws, hs; /* the size of the buffer into which to rasterIO to */ CPLErr err; ral_grid *gd_s = NULL, *gd_t = NULL; double t[6] = {0,1,0,0,0,1}; /* the geotransformation P -> G */ double tx[6]; /* the inverse geotransformation G -> P */ ral_rectangle GDAL; /* boundaries of the GDAL raster */ ral_point p0, p1, p2, p3; /* locations of corners of clip region: top left, top right, bottom right, bottom left, i.e, 0,0 W',0 W',H' 0,H' */ CPLPushErrorHandler(ral_cpl_error); GDALGetGeoTransform(dataset, t); north_up = (t[2] == 0) AND (t[4] == 0); east_up = (t[1] == 0) AND (t[5] == 0); /*fprintf(stderr, "\nt is\n%f %f %f\n%f %f %f\n", t[0],t[1],t[2],t[3],t[4],t[5]);*/ W = GDALGetRasterXSize(dataset); H = GDALGetRasterYSize(dataset); /*fprintf(stderr, "cell size is %f, raster size is %i %i\n", cell_size, W, H);*/ /* test all corners to find the min & max xg and yg */ { double x, y; P2G(0, 0, t, GDAL.min.x, GDAL.min.y); GDAL.max.x = GDAL.min.x; GDAL.max.y = GDAL.min.y; P2G(0, H, t, x, y); GDAL.min.x = MIN(x, GDAL.min.x); GDAL.min.y = MIN(y, GDAL.min.y); GDAL.max.x = MAX(x, GDAL.max.x); GDAL.max.y = MAX(y, GDAL.max.y); P2G(W, H, t, x, y); GDAL.min.x = MIN(x, GDAL.min.x); GDAL.min.y = MIN(y, GDAL.min.y); GDAL.max.x = MAX(x, GDAL.max.x); GDAL.max.y = MAX(y, GDAL.max.y); P2G(W, 0, t, x, y); GDAL.min.x = MIN(x, GDAL.min.x); GDAL.min.y = MIN(y, GDAL.min.y); GDAL.max.x = MAX(x, GDAL.max.x); GDAL.max.y = MAX(y, GDAL.max.y); } /*fprintf(stderr, "clip region is %f %f %f %f\n", clip_region.min.x, clip_region.min.y, clip_region.max.x, clip_region.max.y); fprintf(stderr, "GDAL raster is %f %f %f %f\n", GDAL.min.x, GDAL.min.y, GDAL.max.x, GDAL.max.y);*/ clip_region.min.x = MAX(clip_region.min.x, GDAL.min.x); clip_region.min.y = MAX(clip_region.min.y, GDAL.min.y); clip_region.max.x = MIN(clip_region.max.x, GDAL.max.x); clip_region.max.y = MIN(clip_region.max.y, GDAL.max.y); /*fprintf(stderr, "visible region is %f %f %f %f\n", clip_region.min.x, clip_region.min.y, clip_region.max.x, clip_region.max.y);*/ RAL_CHECK((clip_region.min.x < clip_region.max.x) AND (clip_region.min.y < clip_region.max.y)); /* the inverse transformation, from georeferenced space to pixel space */ { double tmp = t[2]*t[4] - t[1]*t[5]; tx[0] = (t[0]*t[5] - t[2]*t[3])/tmp; tx[1] = -t[5]/tmp; tx[2] = t[2]/tmp; tx[3] = (t[1]*t[3] - t[0]*t[4])/tmp; tx[4] = t[4]/tmp; tx[5] = -t[1]/tmp; } /* the clip region in pixel space */ /* test all corners to find the min & max xp and yp (j0..j1, i0..i1) */ { int i, j; G2P(clip_region.min.x, clip_region.min.y, tx, j0, i0); j1 = j0; i1 = i0; G2P(clip_region.min.x, clip_region.max.y, tx, j, i); j0 = MIN(j, j0); i0 = MIN(i, i0); j1 = MAX(j, j1); i1 = MAX(i, i1); G2P(clip_region.max.x, clip_region.max.y, tx, j, i); j0 = MIN(j, j0); i0 = MIN(i, i0); j1 = MAX(j, j1); i1 = MAX(i, i1); G2P(clip_region.max.x, clip_region.min.y, tx, j, i); j0 = MIN(j, j0); i0 = MIN(i, i0); j1 = MAX(j, j1); i1 = MAX(i, i1); j0 = MAX(j0, 0); j0 = MIN(j0, W-1); j1 = MAX(j1, 0); j1 = MIN(j1, W-1); i0 = MAX(i0, 0); i0 = MIN(i0, H-1); i1 = MAX(i1, 0); i1 = MIN(i1, H-1); } w = j1 - j0 + 1; h = i1 - i0 + 1; /*fprintf(stderr, "visible region in raster is %i %i %i %i\n", j0, i0, j1, i1);*/ RAL_CHECK(w > 0 AND h > 0); /* the corners of the raster clip */ P2G(j0, i0, t, p0.x, p0.y); P2G(j1+1, i0, t, p1.x, p1.y); P2G(j1+1, i1+1, t, p2.x, p2.y); P2G(j0, i1+1, t, p3.x, p3.y); /*fprintf(stderr, "source corners: (%f,%f %f,%f %f,%f %f,%f)\n", p0.x, p0.y, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);*/ /* the width and height of the resized raster clip */ /* the resized clip has the same corner coordinates as the clip */ ws = round(sqrt((p1.x-p0.x)*(p1.x-p0.x)+(p1.y-p0.y)*(p1.y-p0.y))/cell_size); hs = round(sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y))/cell_size); /*fprintf(stderr, "clipped source size is %i, %i\n", ws, hs);*/ hBand = GDALGetRasterBand(dataset, band); RAL_CHECK(hBand); switch (GDALGetRasterDataType(hBand)) { case GDT_Byte: case GDT_UInt16: case GDT_Int16: case GDT_UInt32: case GDT_Int32: gd_datatype = RAL_INTEGER_GRID; switch (sizeof(RAL_INTEGER)) { /* hmm.. this breaks if INTEGER is unsigned */ case 1: datatype = GDT_Byte; break; case 2: datatype = GDT_Int16; break; case 4: datatype = GDT_Int32; break; default: RAL_CHECKM(0, ral_msg("Strange sizeof(INTEGER): %i",sizeof(RAL_INTEGER))); } break; case GDT_Float32: case GDT_Float64: gd_datatype = RAL_REAL_GRID; switch (sizeof(RAL_REAL)) { case 4: datatype = GDT_Float32; break; case 8: datatype = GDT_Float64; break; default: RAL_CHECKM(0, ral_msg("Strange sizeof(REAL): %i", sizeof(RAL_REAL))); } break; default: RAL_CHECKM(0, "complex data type not supported"); } /* size of the grid in display */ M = ceil(fabs(clip_region.max.y - clip_region.min.y)/cell_size); N = ceil(fabs(clip_region.max.x - clip_region.min.x)/cell_size); /*fprintf(stderr, "display size is %i, %i\n", N, M);*/ RAL_CHECK(gd_s = ral_grid_create(gd_datatype, hs, ws)); RAL_CHECK(gd_t = ral_grid_create(gd_datatype, M, N)); ral_grid_set_bounds_csnx(gd_t, cell_size, clip_region.min.x, clip_region.max.y); err = GDALRasterIO(hBand, GF_Read, j0, i0, w, h, gd_s->data, ws, hs, datatype, 0, 0); RAL_CHECK(err == CE_None); { int success; double nodata_value = GDALGetRasterNoDataValue(hBand, &success); if (success) { RAL_CHECK(ral_grid_set_real_nodata_value(gd_t, nodata_value)); RAL_CHECK(ral_grid_set_all_nodata(gd_t)); } else { RAL_CHECK(ral_grid_set_real_nodata_value(gd_t, -9999)); /* change this! */ RAL_CHECK(ral_grid_set_all_nodata(gd_t)); } } /* from source to target */ { /* b = from p0 to p1 */ double bx = p1.x - p0.x; double by = p1.y - p0.y; double b = east_up ? 0 : bx/by; double b2 = east_up ? 1 : sqrt(1+1/b/b); /*fprintf(stderr, "b = %f %f (%f)\n", bx, by, b);*/ /* c = from p0 to p3 */ double cx = p3.x - p0.x; double cy = p3.y - p0.y; double c = north_up ? 0 : cx/cy; double c2 = north_up ? 1 : sqrt(1+1/c/c); /*fprintf(stderr, "c = %f %f (%f)\n", cx, cy, c);*/ ral_cell cs, ct; switch (gd_t->datatype) { case RAL_REAL_GRID: RAL_FOR(ct, gd_t) { /* p = the location of the center of the target pixel in georeferenced coordinates */ double px = clip_region.min.x + cell_size*(ct.j+0.5); double py = clip_region.max.y - cell_size*(ct.i+0.5); /* vector a = from p0 to p */ double ax = px - p0.x; double ay = py - p0.y; /* x = the vector from p0 to the beginning of y */ double x = east_up ? ay : (north_up ? ax : (ax-c*ay)/(1-c/b)); if (!east_up AND !north_up AND (x/b > 0)) continue; /* the length */ x = fabs(x)*b2; /* y = length of the parallel to c vector from b to p */ double y = east_up ? ax : (north_up ? ay : (ax-b*ay)/(1-b/c)); if (!east_up AND !north_up AND (y/c < 0)) continue; /* the length */ y = fabs(y)*c2; ral_cell cs; /* the coordinates in the clipped raster */ cs.j = floor(x/cell_size); cs.i = floor(y/cell_size); if (RAL_GRID_CELL_IN(gd_s, cs)) RAL_REAL_GRID_CELL(gd_t, ct) = RAL_REAL_GRID_CELL(gd_s, cs); } break; case RAL_INTEGER_GRID: RAL_FOR(ct, gd_t) { /* p = the location of the center of the target pixel in georeferenced coordinates */ double px = clip_region.min.x + cell_size*(ct.j+0.5); double py = clip_region.max.y - cell_size*(ct.i+0.5); /* vector a = from p0 to p */ double ax = px - p0.x; double ay = py - p0.y; /* x = the vector from p0 to the beginning of y */ double x = east_up ? ay : (north_up ? ax : (ax-c*ay)/(1-c/b)); if (!east_up AND !north_up AND (x/b > 0)) continue; /* the length */ x = fabs(x)*b2; /* y = length of the parallel to c vector from b to p */ double y = east_up ? ax : (north_up ? ay : (ax-b*ay)/(1-b/c)); if (!east_up AND !north_up AND (y/c < 0)) continue; /* the length */ y = fabs(y)*c2; ral_cell cs; /* the coordinates in the clipped raster */ cs.j = floor(x/cell_size); cs.i = floor(y/cell_size); /* if ((cs.i == 0 AND cs.j == 0) OR (cs.i == hs-1 AND cs.j == 0) OR (cs.i == 0 AND cs.j == ws-1) OR (cs.i == hs-1 AND cs.j == ws-1) OR (ct.i == 0 AND ct.j == 0) OR (ct.i == M-1 AND ct.j == N-1)) { fprintf(stderr, "p = %f %f\n", px, py); fprintf(stderr, "a = %f %f\n", ax, ay); fprintf(stderr, "x = %f\n", x); fprintf(stderr, "y = %f\n", y); fprintf(stderr, "copy %i, %i -> %i, %i\n", cs.j, cs.i, ct.j, ct.i); } */ if (RAL_GRID_CELL_IN(gd_s, cs)) { RAL_INTEGER_GRID_CELL(gd_t, ct) = RAL_INTEGER_GRID_CELL(gd_s, cs); } } }
int main( int argc, char ** argv ) { const char *pszLocX = NULL, *pszLocY = NULL; const char *pszSrcFilename = NULL; char *pszSourceSRS = NULL; std::vector<int> anBandList; bool bAsXML = false, bLIFOnly = false; bool bQuiet = false, bValOnly = false; int nOverview = -1; char **papszOpenOptions = NULL; GDALAllRegister(); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); /* -------------------------------------------------------------------- */ /* Parse arguments. */ /* -------------------------------------------------------------------- */ int i; 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],"-b") && i < argc-1 ) { anBandList.push_back( atoi(argv[++i]) ); } else if( EQUAL(argv[i],"-overview") && i < argc-1 ) { nOverview = atoi(argv[++i]) - 1; } else if( EQUAL(argv[i],"-l_srs") && i < argc-1 ) { CPLFree(pszSourceSRS); pszSourceSRS = SanitizeSRS(argv[++i]); } else if( EQUAL(argv[i],"-geoloc") ) { CPLFree(pszSourceSRS); pszSourceSRS = CPLStrdup("-geoloc"); } else if( EQUAL(argv[i],"-wgs84") ) { CPLFree(pszSourceSRS); pszSourceSRS = SanitizeSRS("WGS84"); } else if( EQUAL(argv[i],"-xml") ) { bAsXML = true; } else if( EQUAL(argv[i],"-lifonly") ) { bLIFOnly = true; bQuiet = true; } else if( EQUAL(argv[i],"-valonly") ) { bValOnly = true; bQuiet = true; } else if( EQUAL(argv[i], "-oo") && i < argc-1 ) { papszOpenOptions = CSLAddString( papszOpenOptions, argv[++i] ); } else if( argv[i][0] == '-' && !isdigit(argv[i][1]) ) Usage(); else if( pszSrcFilename == NULL ) pszSrcFilename = argv[i]; else if( pszLocX == NULL ) pszLocX = argv[i]; else if( pszLocY == NULL ) pszLocY = argv[i]; else Usage(); } if( pszSrcFilename == NULL || (pszLocX != NULL && pszLocY == NULL) ) Usage(); /* -------------------------------------------------------------------- */ /* Open source file. */ /* -------------------------------------------------------------------- */ GDALDatasetH hSrcDS = NULL; hSrcDS = GDALOpenEx( pszSrcFilename, GDAL_OF_RASTER, NULL, (const char* const* )papszOpenOptions, NULL ); if( hSrcDS == NULL ) exit( 1 ); /* -------------------------------------------------------------------- */ /* Setup coordinate transformation, if required */ /* -------------------------------------------------------------------- */ OGRSpatialReferenceH hSrcSRS = NULL, hTrgSRS = NULL; OGRCoordinateTransformationH hCT = NULL; if( pszSourceSRS != NULL && !EQUAL(pszSourceSRS,"-geoloc") ) { hSrcSRS = OSRNewSpatialReference( pszSourceSRS ); hTrgSRS = OSRNewSpatialReference( GDALGetProjectionRef( hSrcDS ) ); hCT = OCTNewCoordinateTransformation( hSrcSRS, hTrgSRS ); if( hCT == NULL ) exit( 1 ); } /* -------------------------------------------------------------------- */ /* If no bands were requested, we will query them all. */ /* -------------------------------------------------------------------- */ if( anBandList.size() == 0 ) { for( i = 0; i < GDALGetRasterCount( hSrcDS ); i++ ) anBandList.push_back( i+1 ); } /* -------------------------------------------------------------------- */ /* Turn the location into a pixel and line location. */ /* -------------------------------------------------------------------- */ int inputAvailable = 1; double dfGeoX; double dfGeoY; CPLString osXML; if( pszLocX == NULL && pszLocY == NULL ) { if (fscanf(stdin, "%lf %lf", &dfGeoX, &dfGeoY) != 2) { inputAvailable = 0; } } else { dfGeoX = CPLAtof(pszLocX); dfGeoY = CPLAtof(pszLocY); } while (inputAvailable) { int iPixel, iLine; if (hCT) { if( !OCTTransform( hCT, 1, &dfGeoX, &dfGeoY, NULL ) ) exit( 1 ); } if( pszSourceSRS != NULL ) { double adfGeoTransform[6], adfInvGeoTransform[6]; if( GDALGetGeoTransform( hSrcDS, adfGeoTransform ) != CE_None ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot get geotransform"); exit( 1 ); } if( !GDALInvGeoTransform( adfGeoTransform, adfInvGeoTransform ) ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot invert geotransform"); exit( 1 ); } iPixel = (int) floor( adfInvGeoTransform[0] + adfInvGeoTransform[1] * dfGeoX + adfInvGeoTransform[2] * dfGeoY ); iLine = (int) floor( adfInvGeoTransform[3] + adfInvGeoTransform[4] * dfGeoX + adfInvGeoTransform[5] * dfGeoY ); } else { iPixel = (int) floor(dfGeoX); iLine = (int) floor(dfGeoY); } /* -------------------------------------------------------------------- */ /* Prepare report. */ /* -------------------------------------------------------------------- */ CPLString osLine; if( bAsXML ) { osLine.Printf( "<Report pixel=\"%d\" line=\"%d\">", iPixel, iLine ); osXML += osLine; } else if( !bQuiet ) { printf( "Report:\n" ); printf( " Location: (%dP,%dL)\n", iPixel, iLine ); } int bPixelReport = TRUE; if( iPixel < 0 || iLine < 0 || iPixel >= GDALGetRasterXSize( hSrcDS ) || iLine >= GDALGetRasterYSize( hSrcDS ) ) { if( bAsXML ) osXML += "<Alert>Location is off this file! No further details to report.</Alert>"; else if( bValOnly ) printf("\n"); else if( !bQuiet ) printf( "\nLocation is off this file! No further details to report.\n"); bPixelReport = FALSE; } /* -------------------------------------------------------------------- */ /* Process each band. */ /* -------------------------------------------------------------------- */ for( i = 0; bPixelReport && i < (int) anBandList.size(); i++ ) { GDALRasterBandH hBand = GDALGetRasterBand( hSrcDS, anBandList[i] ); int iPixelToQuery = iPixel; int iLineToQuery = iLine; if (nOverview >= 0 && hBand != NULL) { GDALRasterBandH hOvrBand = GDALGetOverview(hBand, nOverview); if (hOvrBand != NULL) { int nOvrXSize = GDALGetRasterBandXSize(hOvrBand); int nOvrYSize = GDALGetRasterBandYSize(hOvrBand); iPixelToQuery = (int)(0.5 + 1.0 * iPixel / GDALGetRasterXSize( hSrcDS ) * nOvrXSize); iLineToQuery = (int)(0.5 + 1.0 * iLine / GDALGetRasterYSize( hSrcDS ) * nOvrYSize); if (iPixelToQuery >= nOvrXSize) iPixelToQuery = nOvrXSize - 1; if (iLineToQuery >= nOvrYSize) iLineToQuery = nOvrYSize - 1; } else { CPLError(CE_Failure, CPLE_AppDefined, "Cannot get overview %d of band %d", nOverview + 1, anBandList[i] ); } hBand = hOvrBand; } if (hBand == NULL) continue; if( bAsXML ) { osLine.Printf( "<BandReport band=\"%d\">", anBandList[i] ); osXML += osLine; } else if( !bQuiet ) { printf( " Band %d:\n", anBandList[i] ); } /* -------------------------------------------------------------------- */ /* Request location info for this location. It is possible */ /* only the VRT driver actually supports this. */ /* -------------------------------------------------------------------- */ CPLString osItem; osItem.Printf( "Pixel_%d_%d", iPixelToQuery, iLineToQuery ); const char *pszLI = GDALGetMetadataItem( hBand, osItem, "LocationInfo"); if( pszLI != NULL ) { if( bAsXML ) osXML += pszLI; else if( !bQuiet ) printf( " %s\n", pszLI ); else if( bLIFOnly ) { /* Extract all files, if any. */ CPLXMLNode *psRoot = CPLParseXMLString( pszLI ); if( psRoot != NULL && psRoot->psChild != NULL && psRoot->eType == CXT_Element && EQUAL(psRoot->pszValue,"LocationInfo") ) { CPLXMLNode *psNode; for( psNode = psRoot->psChild; psNode != NULL; psNode = psNode->psNext ) { if( psNode->eType == CXT_Element && EQUAL(psNode->pszValue,"File") && psNode->psChild != NULL ) { char* pszUnescaped = CPLUnescapeString( psNode->psChild->pszValue, NULL, CPLES_XML); printf( "%s\n", pszUnescaped ); CPLFree(pszUnescaped); } } } CPLDestroyXMLNode( psRoot ); } } /* -------------------------------------------------------------------- */ /* Report the pixel value of this band. */ /* -------------------------------------------------------------------- */ double adfPixel[2]; if( GDALRasterIO( hBand, GF_Read, iPixelToQuery, iLineToQuery, 1, 1, adfPixel, 1, 1, GDT_CFloat64, 0, 0) == CE_None ) { CPLString osValue; if( GDALDataTypeIsComplex( GDALGetRasterDataType( hBand ) ) ) osValue.Printf( "%.15g+%.15gi", adfPixel[0], adfPixel[1] ); else osValue.Printf( "%.15g", adfPixel[0] ); if( bAsXML ) { osXML += "<Value>"; osXML += osValue; osXML += "</Value>"; } else if( !bQuiet ) printf( " Value: %s\n", osValue.c_str() ); else if( bValOnly ) printf( "%s\n", osValue.c_str() ); // Report unscaled if we have scale/offset values. int bSuccess; double dfOffset = GDALGetRasterOffset( hBand, &bSuccess ); double dfScale = GDALGetRasterScale( hBand, &bSuccess ); if( dfOffset != 0.0 || dfScale != 1.0 ) { adfPixel[0] = adfPixel[0] * dfScale + dfOffset; adfPixel[1] = adfPixel[1] * dfScale + dfOffset; if( GDALDataTypeIsComplex( GDALGetRasterDataType( hBand ) ) ) osValue.Printf( "%.15g+%.15gi", adfPixel[0], adfPixel[1] ); else osValue.Printf( "%.15g", adfPixel[0] ); if( bAsXML ) { osXML += "<DescaledValue>"; osXML += osValue; osXML += "</DescaledValue>"; } else if( !bQuiet ) printf( " Descaled Value: %s\n", osValue.c_str() ); } } if( bAsXML ) osXML += "</BandReport>"; } osXML += "</Report>"; if( (pszLocX != NULL && pszLocY != NULL) || (fscanf(stdin, "%lf %lf", &dfGeoX, &dfGeoY) != 2) ) { inputAvailable = 0; } } /* -------------------------------------------------------------------- */ /* Finalize xml report and print. */ /* -------------------------------------------------------------------- */ if( bAsXML ) { CPLXMLNode *psRoot; char *pszFormattedXML; psRoot = CPLParseXMLString( osXML ); pszFormattedXML = CPLSerializeXMLTree( psRoot ); CPLDestroyXMLNode( psRoot ); printf( "%s", pszFormattedXML ); CPLFree( pszFormattedXML ); } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ if (hCT) { OSRDestroySpatialReference( hSrcSRS ); OSRDestroySpatialReference( hTrgSRS ); OCTDestroyCoordinateTransformation( hCT ); } if (hSrcDS) GDALClose(hSrcDS); GDALDumpOpenDatasets( stderr ); GDALDestroyDriverManager(); CPLFree(pszSourceSRS); CSLDestroy(papszOpenOptions); CSLDestroy( argv ); return 0; }
static void test_gdal_to_raster() { rt_pixtype pixtype = PT_64BF; rt_band band = NULL; rt_raster raster; rt_raster rast; const uint32_t width = 100; const uint32_t height = 100; uint32_t x; uint32_t y; int v; double values[width][height]; int rtn = 0; double value; GDALDriverH gddrv = NULL; GDALDatasetH gdds = NULL; raster = rt_raster_new(width, height); CU_ASSERT(raster != NULL); /* or we're out of virtual memory */ band = cu_add_band(raster, pixtype, 1, 0); CU_ASSERT(band != NULL); for (x = 0; x < width; x++) { for (y = 0; y < height; y++) { values[x][y] = (((double) x * y) + (x + y) + (x + y * x)) / (x + y + 1); rt_band_set_pixel(band, x, y, values[x][y], NULL); } } gdds = rt_raster_to_gdal_mem(raster, NULL, NULL, NULL, 0, &gddrv); CU_ASSERT(gddrv != NULL); CU_ASSERT(gdds != NULL); CU_ASSERT_EQUAL(GDALGetRasterXSize(gdds), width); CU_ASSERT_EQUAL(GDALGetRasterYSize(gdds), height); rast = rt_raster_from_gdal_dataset(gdds); CU_ASSERT(rast != NULL); CU_ASSERT_EQUAL(rt_raster_get_num_bands(rast), 1); band = rt_raster_get_band(rast, 0); CU_ASSERT(band != NULL); for (x = 0; x < width; x++) { for (y = 0; y < height; y++) { rtn = rt_band_get_pixel(band, x, y, &value, NULL); CU_ASSERT_EQUAL(rtn, ES_NONE); CU_ASSERT_DOUBLE_EQUAL(value, values[x][y], DBL_EPSILON); } } GDALClose(gdds); gdds = NULL; gddrv = NULL; cu_free_raster(rast); cu_free_raster(raster); raster = rt_raster_new(width, height); CU_ASSERT(raster != NULL); /* or we're out of virtual memory */ pixtype = PT_8BSI; band = cu_add_band(raster, pixtype, 1, 0); CU_ASSERT(band != NULL); v = -127; for (x = 0; x < width; x++) { for (y = 0; y < height; y++) { values[x][y] = v++; rt_band_set_pixel(band, x, y, values[x][y], NULL); if (v == 128) v = -127; } } gdds = rt_raster_to_gdal_mem(raster, NULL, NULL, NULL, 0, &gddrv); CU_ASSERT(gddrv != NULL); CU_ASSERT(gdds != NULL); CU_ASSERT_EQUAL(GDALGetRasterXSize(gdds), width); CU_ASSERT_EQUAL(GDALGetRasterYSize(gdds), height); rast = rt_raster_from_gdal_dataset(gdds); CU_ASSERT(rast != NULL); CU_ASSERT_EQUAL(rt_raster_get_num_bands(rast), 1); band = rt_raster_get_band(rast, 0); CU_ASSERT(band != NULL); CU_ASSERT_EQUAL(rt_band_get_pixtype(band), PT_16BSI); for (x = 0; x < width; x++) { for (y = 0; y < height; y++) { rtn = rt_band_get_pixel(band, x, y, &value, NULL); CU_ASSERT_EQUAL(rtn, ES_NONE); CU_ASSERT_DOUBLE_EQUAL(value, values[x][y], 1.); } } GDALClose(gdds); cu_free_raster(rast); cu_free_raster(raster); }
int main( int argc, char ** argv ) { /* Check that we are running against at least GDAL 1.4 (probably older in fact !) */ /* Note to developers : if we use newer API, please change the requirement */ if (atoi(GDALVersionInfo("VERSION_NUM")) < 1400) { fprintf(stderr, "At least, GDAL >= 1.4.0 is required for this version of %s, " "which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME); exit(1); } /* -------------------------------------------------------------------- */ /* Generic arg processing. */ /* -------------------------------------------------------------------- */ GDALAllRegister(); GDALSetCacheMax( 100000000 ); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); /* -------------------------------------------------------------------- */ /* Parse arguments. */ /* -------------------------------------------------------------------- */ int i; const char *pszOutFile = NULL; const char *pszInFile = NULL; int nMaxNonBlack = 2; int nNearDist = 15; int bNearWhite = FALSE; 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], "-o") && i < argc-1 ) pszOutFile = argv[++i]; else if( EQUAL(argv[i], "-white") ) bNearWhite = TRUE; else if( EQUAL(argv[i], "-nb") && i < argc-1 ) nMaxNonBlack = atoi(argv[++i]); else if( EQUAL(argv[i], "-near") && i < argc-1 ) nNearDist = atoi(argv[++i]); else if( argv[i][0] == '-' ) Usage(); else if( pszInFile == NULL ) pszInFile = argv[i]; else Usage(); } if( pszInFile == NULL ) Usage(); if( pszOutFile == NULL ) pszOutFile = pszInFile; /* -------------------------------------------------------------------- */ /* Open input file. */ /* -------------------------------------------------------------------- */ GDALDatasetH hInDS, hOutDS = NULL; int nXSize, nYSize, nBands; if( pszOutFile == pszInFile ) hInDS = hOutDS = GDALOpen( pszInFile, GA_Update ); else hInDS = GDALOpen( pszInFile, GA_ReadOnly ); if( hInDS == NULL ) exit( 1 ); nXSize = GDALGetRasterXSize( hInDS ); nYSize = GDALGetRasterYSize( hInDS ); nBands = GDALGetRasterCount( hInDS ); /* -------------------------------------------------------------------- */ /* Do we need to create output file? */ /* -------------------------------------------------------------------- */ if( hOutDS == NULL ) { GDALDriverH hDriver = GDALGetDriverByName( "HFA" ); hOutDS = GDALCreate( hDriver, pszOutFile, nXSize, nYSize, nBands, GDT_Byte, NULL ); if( hOutDS == NULL ) exit( 1 ); double adfGeoTransform[6]; if( GDALGetGeoTransform( hInDS, adfGeoTransform ) == CE_None ) { GDALSetGeoTransform( hOutDS, adfGeoTransform ); GDALSetProjection( hOutDS, GDALGetProjectionRef( hInDS ) ); } } int iBand; for( iBand = 0; iBand < nBands; iBand++ ) { GDALRasterBandH hBand = GDALGetRasterBand(hInDS, iBand+1); if (GDALGetRasterDataType(hBand) != GDT_Byte) { CPLError(CE_Warning, CPLE_AppDefined, "Band %d is not of type GDT_Byte. It can lead to unexpected results.", iBand+1); } if (GDALGetRasterColorTable(hBand) != NULL) { CPLError(CE_Warning, CPLE_AppDefined, "Band %d has a color table, which is ignored by nearblack. " "It can lead to unexpected results.", iBand+1); } } /* -------------------------------------------------------------------- */ /* Allocate a line buffer. */ /* -------------------------------------------------------------------- */ GByte *pabyLine; int *panLastLineCounts; pabyLine = (GByte *) CPLMalloc(nXSize * nBands); panLastLineCounts = (int *) CPLCalloc(sizeof(int),nXSize); /* -------------------------------------------------------------------- */ /* Processing data one line at a time. */ /* -------------------------------------------------------------------- */ int iLine; for( iLine = 0; iLine < nYSize; iLine++ ) { CPLErr eErr; eErr = GDALDatasetRasterIO( hInDS, GF_Read, 0, iLine, nXSize, 1, pabyLine, nXSize, 1, GDT_Byte, nBands, NULL, nBands, nXSize * nBands, 1 ); if( eErr != CE_None ) break; ProcessLine( pabyLine, 0, nXSize-1, nBands, nNearDist, nMaxNonBlack, bNearWhite, panLastLineCounts, TRUE, TRUE ); ProcessLine( pabyLine, nXSize-1, 0, nBands, nNearDist, nMaxNonBlack, bNearWhite, NULL, TRUE, FALSE ); eErr = GDALDatasetRasterIO( hOutDS, GF_Write, 0, iLine, nXSize, 1, pabyLine, nXSize, 1, GDT_Byte, nBands, NULL, nBands, nXSize * nBands, 1 ); if( eErr != CE_None ) break; GDALTermProgress( 0.5 * ((iLine+1) / (double) nYSize), NULL, NULL ); } /* -------------------------------------------------------------------- */ /* Now process from the bottom back up, doing only the vertical pass.*/ /* -------------------------------------------------------------------- */ memset( panLastLineCounts, 0, sizeof(int) * nXSize); for( iLine = nYSize-1; iLine >= 0; iLine-- ) { CPLErr eErr; eErr = GDALDatasetRasterIO( hOutDS, GF_Read, 0, iLine, nXSize, 1, pabyLine, nXSize, 1, GDT_Byte, nBands, NULL, nBands, nXSize * nBands, 1 ); if( eErr != CE_None ) break; ProcessLine( pabyLine, 0, nXSize-1, nBands, nNearDist, nMaxNonBlack, bNearWhite, panLastLineCounts, FALSE, TRUE ); eErr = GDALDatasetRasterIO( hOutDS, GF_Write, 0, iLine, nXSize, 1, pabyLine, nXSize, 1, GDT_Byte, nBands, NULL, nBands, nXSize * nBands, 1 ); if( eErr != CE_None ) break; GDALTermProgress( 0.5 + 0.5 * (nYSize-iLine) / (double) nYSize, NULL, NULL ); } CPLFree(pabyLine); CPLFree( panLastLineCounts ); GDALClose( hOutDS ); if( hInDS != hOutDS ) GDALClose( hInDS ); GDALDumpOpenDatasets( stderr ); GDALDestroyDriverManager(); return 0; }
int main (int argc, const char *argv[]) { GDALDriverH hDriver; double adfGeoTransform[6]; GDALDatasetH in_Dataset; GDALDatasetH mask_Dataset; GDALDatasetH out_Dataset; GDALRasterBandH mask_band; char *mask_scan_line, *data_scan_line; int nBlockXSize, nBlockYSize; int bGotMin, bGotMax; int bands; int xsize; double adfMinMax[2]; GDALAllRegister (); /* Set cache to something reasonable.. - 1/2 gig */ CPLSetConfigOption ("GDAL_CACHEMAX", "512"); /* open datasets.. */ in_Dataset = GDAL_open_read (argv[1]); mask_Dataset = GDAL_open_read (argv[2]); out_Dataset = make_me_a_sandwitch (&in_Dataset, argv[3]); mask_band = GDALGetRasterBand (mask_Dataset, 1); /* Basic info on source dataset.. */ GDALGetBlockSize (GDALGetRasterBand (in_Dataset, 1), &nBlockXSize, &nBlockYSize); printf ("Block=%dx%d Type=%s, ColorInterp=%s\n", nBlockXSize, nBlockYSize, GDALGetDataTypeName (GDALGetRasterDataType (GDALGetRasterBand (in_Dataset, 1))), GDALGetColorInterpretationName (GDALGetRasterColorInterpretation (GDALGetRasterBand (in_Dataset, 1)))); /* Loop though bands, wiping values with mask values of 0.. */ xsize = GDALGetRasterXSize (in_Dataset); mask_scan_line = (char *) CPLMalloc (sizeof (char) * xsize); data_scan_line = (char *) CPLMalloc (sizeof (char) * xsize); for (bands = 1; bands <= GDALGetRasterCount (in_Dataset); bands++) { int x; GDALRasterBandH data_band, out_band; int y_index = 0; data_band = GDALGetRasterBand (in_Dataset, bands); out_band = GDALGetRasterBand (out_Dataset, bands); for (y_index = 0; y_index < GDALGetRasterYSize (in_Dataset); y_index++) { /* Read data.. */ GDALRasterIO (data_band, GF_Read, 0, y_index, xsize, 1, data_scan_line, xsize, 1, GDT_Byte, 0, 0); /* Read mask.. */ GDALRasterIO (mask_band, GF_Read, 0, y_index, xsize, 1, mask_scan_line, xsize, 1, GDT_Byte, 0, 0); GDALSetRasterNoDataValue (out_band, 0.0); for (x = 0; x < xsize; x++) { /* if mask is set to 0, then mask off... */ if (mask_scan_line[x] == 0) data_scan_line[x] = 0; /* if mask is not zero, and data is zero, then unmask.. */ if (mask_scan_line[x] != 0 && data_scan_line[x] == 0) data_scan_line[x] = 1; } /* now write out band.. */ GDALRasterIO (out_band, GF_Write, 0, y_index, xsize, 1, data_scan_line, xsize, 1, GDT_Byte, 0, 0); } } GDALClose (out_Dataset); }
static int msContourLayerReadRaster(layerObj *layer, rectObj rect) { mapObj *map = layer->map; char **bands; char pointer[64], memDSPointer[128]; int band = 1; double adfGeoTransform[6], adfInvGeoTransform[6]; double llx, lly, urx, ury; rectObj copyRect, mapRect; int dst_xsize, dst_ysize; int virtual_grid_step_x, virtual_grid_step_y; int src_xoff, src_yoff, src_xsize, src_ysize; double map_cellsize_x, map_cellsize_y, dst_cellsize_x, dst_cellsize_y; GDALRasterBandH hBand = NULL; CPLErr eErr; contourLayerInfo *clinfo = (contourLayerInfo *) layer->layerinfo; if (layer->debug) msDebug("Entering msContourLayerReadRaster().\n"); if (clinfo == NULL || clinfo->hOrigDS == NULL) { msSetError(MS_MISCERR, "Assertion failed: Contour layer not opened!!!", "msContourLayerReadRaster()"); return MS_FAILURE; } bands = CSLTokenizeStringComplex( CSLFetchNameValue(layer->processing,"BANDS"), " ,", FALSE, FALSE ); if (CSLCount(bands) > 0) { band = atoi(bands[0]); if (band < 1 || band > GDALGetRasterCount(clinfo->hOrigDS)) { msSetError( MS_IMGERR, "BANDS PROCESSING directive includes illegal band '%d', should be from 1 to %d.", "msContourLayerReadRaster()", band, GDALGetRasterCount(clinfo->hOrigDS)); CSLDestroy(bands); return MS_FAILURE; } } CSLDestroy(bands); hBand = GDALGetRasterBand(clinfo->hOrigDS, band); if (hBand == NULL) { msSetError(MS_IMGERR, "Band %d does not exist on dataset.", "msContourLayerReadRaster()", band); return MS_FAILURE; } if (layer->projection.numargs > 0 && EQUAL(layer->projection.args[0], "auto")) { const char *wkt; wkt = GDALGetProjectionRef(clinfo->hOrigDS); if (wkt != NULL && strlen(wkt) > 0) { if (msOGCWKT2ProjectionObj(wkt, &(layer->projection), layer->debug) != MS_SUCCESS) { char msg[MESSAGELENGTH*2]; errorObj *ms_error = msGetErrorObj(); snprintf( msg, sizeof(msg), "%s\n" "PROJECTION AUTO cannot be used for this " "GDAL raster (`%s').", ms_error->message, layer->data); msg[MESSAGELENGTH-1] = '\0'; msSetError(MS_OGRERR, "%s","msDrawRasterLayer()", msg); return MS_FAILURE; } } } /* * Compute the georeferenced window of overlap, and read the source data * downsampled to match output resolution, or at full resolution if * output resolution is lower than the source resolution. * * A large portion of this overlap calculation code was borrowed from * msDrawRasterLayerGDAL(). * Would be possible to move some of this to a reusable function? * * Note: This code works only if no reprojection is involved. It would * need rework to support cases where output projection differs from source * data file projection. */ src_xsize = GDALGetRasterXSize(clinfo->hOrigDS); src_ysize = GDALGetRasterYSize(clinfo->hOrigDS); /* set the Dataset extent */ msGetGDALGeoTransform(clinfo->hOrigDS, map, layer, adfGeoTransform); clinfo->extent.minx = adfGeoTransform[0]; clinfo->extent.maxy = adfGeoTransform[3]; clinfo->extent.maxx = adfGeoTransform[0] + src_xsize * adfGeoTransform[1]; clinfo->extent.miny = adfGeoTransform[3] + src_ysize * adfGeoTransform[5]; if (layer->transform) { if (layer->debug) msDebug("msContourLayerReadRaster(): Entering transform.\n"); InvGeoTransform(adfGeoTransform, adfInvGeoTransform); mapRect = rect; map_cellsize_x = map_cellsize_y = map->cellsize; #ifdef USE_PROJ /* if necessary, project the searchrect to source coords */ if (msProjectionsDiffer( &(map->projection), &(layer->projection))) { if ( msProjectRect(&map->projection, &layer->projection, &mapRect) != MS_SUCCESS ) { msDebug("msContourLayerReadRaster(%s): unable to reproject map request rectangle into layer projection, canceling.\n", layer->name); return MS_FAILURE; } map_cellsize_x = MS_CELLSIZE(mapRect.minx, mapRect.maxx, map->width); map_cellsize_y = MS_CELLSIZE(mapRect.miny, mapRect.maxy, map->height); /* if the projection failed to project the extent requested, we need to calculate the cellsize to preserve the initial map cellsize ratio */ if ( (mapRect.minx < GEO_TRANS(adfGeoTransform,0,src_ysize)) || (mapRect.maxx > GEO_TRANS(adfGeoTransform,src_xsize,0)) || (mapRect.miny < GEO_TRANS(adfGeoTransform+3,0,src_ysize)) || (mapRect.maxy > GEO_TRANS(adfGeoTransform+3,src_xsize,0)) ) { int src_unit, dst_unit; src_unit = GetMapserverUnitUsingProj(&map->projection); dst_unit = GetMapserverUnitUsingProj(&layer->projection); if (src_unit == -1 || dst_unit == -1) { msDebug("msContourLayerReadRaster(%s): unable to reproject map request rectangle into layer projection, canceling.\n", layer->name); return MS_FAILURE; } map_cellsize_x = MS_CONVERT_UNIT(src_unit, dst_unit, MS_CELLSIZE(rect.minx, rect.maxx, map->width)); map_cellsize_y = MS_CONVERT_UNIT(src_unit, dst_unit, MS_CELLSIZE(rect.miny, rect.maxy, map->height)); } } #endif if (map_cellsize_x == 0 || map_cellsize_y == 0) { if (layer->debug) msDebug("msContourLayerReadRaster(): Cellsize can't be 0.\n"); return MS_FAILURE; } /* Adjust MapServer pixel model to GDAL pixel model */ mapRect.minx -= map_cellsize_x*0.5; mapRect.maxx += map_cellsize_x*0.5; mapRect.miny -= map_cellsize_y*0.5; mapRect.maxy += map_cellsize_y*0.5; /* * If raw data cellsize (from geotransform) is larger than output map_cellsize * then we want to extract only enough data to match the output map resolution * which means that GDAL will automatically sample the data on read. * * To prevent bad contour effects on tile edges, we adjust the target cellsize * to align the extracted window with a virtual grid based on the origin of the * raw data and a virtual grid step size corresponding to an integer sampling step. * * If source data has a greater cellsize (i.e. lower res) that requested ouptut map * then we use the raw data cellsize as target cellsize since there is no point in * interpolating the data for contours in this case. */ virtual_grid_step_x = (int)floor(map_cellsize_x / ABS(adfGeoTransform[1])); if (virtual_grid_step_x < 1) virtual_grid_step_x = 1; /* Do not interpolate data if grid sampling step < 1 */ virtual_grid_step_y = (int)floor(map_cellsize_y / ABS(adfGeoTransform[5])); if (virtual_grid_step_y < 1) virtual_grid_step_y = 1; /* Do not interpolate data if grid sampling step < 1 */ /* target cellsize is a multiple of raw data cellsize based on grid step*/ dst_cellsize_x = ABS(adfGeoTransform[1]) * virtual_grid_step_x; dst_cellsize_y = ABS(adfGeoTransform[5]) * virtual_grid_step_y; /* Compute overlap between source and target views */ copyRect = mapRect; if (copyRect.minx < GEO_TRANS(adfGeoTransform,0,src_ysize)) copyRect.minx = GEO_TRANS(adfGeoTransform,0,src_ysize); if (copyRect.maxx > GEO_TRANS(adfGeoTransform,src_xsize,0)) copyRect.maxx = GEO_TRANS(adfGeoTransform,src_xsize,0); if (copyRect.miny < GEO_TRANS(adfGeoTransform+3,0,src_ysize)) copyRect.miny = GEO_TRANS(adfGeoTransform+3,0,src_ysize); if (copyRect.maxy > GEO_TRANS(adfGeoTransform+3,src_xsize,0)) copyRect.maxy = GEO_TRANS(adfGeoTransform+3,src_xsize,0); if (copyRect.minx >= copyRect.maxx || copyRect.miny >= copyRect.maxy) { if (layer->debug) msDebug("msContourLayerReadRaster(): No overlap.\n"); return MS_SUCCESS; } /* * Convert extraction window to raster coordinates */ llx = GEO_TRANS(adfInvGeoTransform+0,copyRect.minx,copyRect.miny); lly = GEO_TRANS(adfInvGeoTransform+3,copyRect.minx,copyRect.miny); urx = GEO_TRANS(adfInvGeoTransform+0,copyRect.maxx,copyRect.maxy); ury = GEO_TRANS(adfInvGeoTransform+3,copyRect.maxx,copyRect.maxy); /* * Align extraction window with virtual grid * (keep in mind raster coordinates origin is at upper-left) * We also add an extra buffer to fix tile boundarie issues when zoomed */ llx = floor(llx / virtual_grid_step_x) * virtual_grid_step_x - (virtual_grid_step_x*5); urx = ceil(urx / virtual_grid_step_x) * virtual_grid_step_x + (virtual_grid_step_x*5); ury = floor(ury / virtual_grid_step_y) * virtual_grid_step_y - (virtual_grid_step_x*5); lly = ceil(lly / virtual_grid_step_y) * virtual_grid_step_y + (virtual_grid_step_x*5); src_xoff = MAX(0,(int) floor(llx+0.5)); src_yoff = MAX(0,(int) floor(ury+0.5)); src_xsize = MIN(MAX(0,(int) (urx - llx + 0.5)), GDALGetRasterXSize(clinfo->hOrigDS) - src_xoff); src_ysize = MIN(MAX(0,(int) (lly - ury + 0.5)), GDALGetRasterYSize(clinfo->hOrigDS) - src_yoff); /* Update the geographic extent (buffer added) */ /* TODO: a better way to go the geo_trans */ copyRect.minx = GEO_TRANS(adfGeoTransform+0,src_xoff,0); copyRect.maxx = GEO_TRANS(adfGeoTransform+0,src_xoff+src_xsize,0); copyRect.miny = GEO_TRANS(adfGeoTransform+3,0,src_yoff+src_ysize); copyRect.maxy = GEO_TRANS(adfGeoTransform+3,0,src_yoff); /* * If input window is to small then stop here */ if (src_xsize < 2 || src_ysize < 2) { if (layer->debug) msDebug("msContourLayerReadRaster(): input window too small, or no apparent overlap between map view and this window(1).\n"); return MS_SUCCESS; } /* Target buffer size */ dst_xsize = (int)ceil((copyRect.maxx - copyRect.minx) / dst_cellsize_x); dst_ysize = (int)ceil((copyRect.maxy - copyRect.miny) / dst_cellsize_y); if (dst_xsize == 0 || dst_ysize == 0) { if (layer->debug) msDebug("msContourLayerReadRaster(): no apparent overlap between map view and this window(2).\n"); return MS_SUCCESS; } if (layer->debug) msDebug( "msContourLayerReadRaster(): src=%d,%d,%d,%d, dst=%d,%d,%d,%d\n", src_xoff, src_yoff, src_xsize, src_ysize, 0, 0, dst_xsize, dst_ysize ); } else { src_xoff = 0; src_yoff = 0; dst_xsize = src_xsize = MIN(map->width,src_xsize); dst_ysize = src_ysize = MIN(map->height,src_ysize); copyRect.minx = copyRect.miny = 0; copyRect.maxx = map->width; copyRect.maxy = map->height; dst_cellsize_y = dst_cellsize_x = 1; } /* -------------------------------------------------------------------- */ /* Allocate buffer, and read data into it. */ /* -------------------------------------------------------------------- */ clinfo->buffer = (double *) malloc(sizeof(double) * dst_xsize * dst_ysize); if (clinfo->buffer == NULL) { msSetError(MS_MEMERR, "Malloc(): Out of memory.", "msContourLayerReadRaster()"); return MS_FAILURE; } eErr = GDALRasterIO(hBand, GF_Read, src_xoff, src_yoff, src_xsize, src_ysize, clinfo->buffer, dst_xsize, dst_ysize, GDT_Float64, 0, 0); if (eErr != CE_None) { msSetError( MS_IOERR, "GDALRasterIO() failed: %s", "msContourLayerReadRaster()", CPLGetLastErrorMsg() ); free(clinfo->buffer); return MS_FAILURE; } memset(pointer, 0, sizeof(pointer)); CPLPrintPointer(pointer, clinfo->buffer, sizeof(pointer)); sprintf(memDSPointer,"MEM:::DATAPOINTER=%s,PIXELS=%d,LINES=%d,BANDS=1,DATATYPE=Float64", pointer, dst_xsize, dst_ysize); clinfo->hDS = GDALOpen(memDSPointer, GA_ReadOnly); if (clinfo->hDS == NULL) { msSetError(MS_IMGERR, "Unable to open GDAL Memory dataset.", "msContourLayerReadRaster()"); free(clinfo->buffer); return MS_FAILURE; } adfGeoTransform[0] = copyRect.minx; adfGeoTransform[1] = dst_cellsize_x; adfGeoTransform[2] = 0; adfGeoTransform[3] = copyRect.maxy; adfGeoTransform[4] = 0; adfGeoTransform[5] = -dst_cellsize_y; clinfo->cellsize = MAX(dst_cellsize_x, dst_cellsize_y); { char buf[64]; sprintf(buf, "%lf", clinfo->cellsize); msInsertHashTable(&layer->metadata, "__data_cellsize__", buf); } GDALSetGeoTransform(clinfo->hDS, adfGeoTransform); return MS_SUCCESS; }
static void msTransformToGeospatialPDF(imageObj *img, mapObj *map, cairo_renderer *r) { /* We need a GDAL 1.10 PDF driver at runtime, but as far as the C API is concerned, GDAL 1.9 is */ /* largely sufficient. */ #if defined(USE_GDAL) && defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1900 GDALDatasetH hDS = NULL; const char* pszGEO_ENCODING = NULL; GDALDriverH hPDFDriver = NULL; const char* pszVirtualIO = NULL; int bVirtualIO = FALSE; char* pszTmpFilename = NULL; VSILFILE* fp = NULL; if (map == NULL) return; pszGEO_ENCODING = msGetOutputFormatOption(img->format, "GEO_ENCODING", NULL); if (pszGEO_ENCODING == NULL) return; msGDALInitialize(); hPDFDriver = GDALGetDriverByName("PDF"); if (hPDFDriver == NULL) return; /* When compiled against libpoppler, the PDF driver is VirtualIO capable */ /* but not, when it is compiled against libpodofo. */ pszVirtualIO = GDALGetMetadataItem( hPDFDriver, GDAL_DCAP_VIRTUALIO, NULL ); if (pszVirtualIO) bVirtualIO = CSLTestBoolean(pszVirtualIO); if (bVirtualIO) pszTmpFilename = msTmpFile(map, NULL, "/vsimem/mscairopdf/", "pdf"); else pszTmpFilename = msTmpFile(map, map->mappath, NULL, "pdf"); /* Copy content of outputStream buffer into file */ fp = VSIFOpenL(pszTmpFilename, "wb"); if (fp == NULL) { msFree(pszTmpFilename); return; } VSIFWriteL(r->outputStream->data, 1, r->outputStream->size, fp); VSIFCloseL(fp); fp = NULL; hDS = GDALOpen(pszTmpFilename, GA_Update); if ( hDS != NULL ) { char* pszWKT = msProjectionObj2OGCWKT( &(map->projection) ); if( pszWKT != NULL ) { double adfGeoTransform[6]; int i; /* Add user-specified options */ for( i = 0; i < img->format->numformatoptions; i++ ) { const char* pszOption = img->format->formatoptions[i]; if( strncasecmp(pszOption,"METADATA_ITEM:",14) == 0 ) { char* pszKey = NULL; const char* pszValue = CPLParseNameValue(pszOption + 14, &pszKey); if( pszKey != NULL ) { GDALSetMetadataItem(hDS, pszKey, pszValue, NULL); CPLFree(pszKey); } } } /* We need to rescale the geotransform because GDAL will not necessary */ /* open the PDF with the DPI that was used to generate it */ memcpy(adfGeoTransform, map->gt.geotransform, 6 * sizeof(double)); adfGeoTransform[1] = adfGeoTransform[1] * map->width / GDALGetRasterXSize(hDS); adfGeoTransform[5] = adfGeoTransform[5] * map->height / GDALGetRasterYSize(hDS); GDALSetGeoTransform(hDS, adfGeoTransform); GDALSetProjection(hDS, pszWKT); msFree( pszWKT ); pszWKT = NULL; CPLSetThreadLocalConfigOption("GDAL_PDF_GEO_ENCODING", pszGEO_ENCODING); GDALClose(hDS); hDS = NULL; CPLSetThreadLocalConfigOption("GDAL_PDF_GEO_ENCODING", NULL); /* We need to replace the buffer with the content of the GDAL file */ fp = VSIFOpenL(pszTmpFilename, "rb"); if( fp != NULL ) { int nFileSize; VSIFSeekL(fp, 0, SEEK_END); nFileSize = (int)VSIFTellL(fp); msBufferResize(r->outputStream, nFileSize); VSIFSeekL(fp, 0, SEEK_SET); r->outputStream->size = VSIFReadL(r->outputStream->data, 1, nFileSize, fp); VSIFCloseL(fp); fp = NULL; } } } if ( hDS != NULL ) GDALClose(hDS); VSIUnlink(pszTmpFilename); msFree(pszTmpFilename); #endif }
int main( int argc, char ** argv ) { GDALDatasetH hDataset = NULL; GDALRasterBandH hBand = NULL; 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; int bReportProj4 = FALSE; int nSubdataset = -1; const char *pszFilename = NULL; char **papszExtraMDDomains = NULL, **papszFileList; const char *pszProjection = NULL; OGRCoordinateTransformationH hTransform = NULL; int bShowFileList = TRUE; /* 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); } EarlySetConfigOptions(argc, argv); 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],"--help") ) Usage(NULL); else if( EQUAL(argv[i], "-mm") ) bComputeMinMax = TRUE; else if( EQUAL(argv[i], "-hist") ) bReportHistograms = TRUE; else if( EQUAL(argv[i], "-proj4") ) bReportProj4 = 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") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); papszExtraMDDomains = CSLAddString( papszExtraMDDomains, argv[++i] ); } else if( EQUAL(argv[i], "-nofl") ) bShowFileList = FALSE; else if( EQUAL(argv[i], "-sd") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); nSubdataset = atoi(argv[++i]); } else if( argv[i][0] == '-' ) Usage(CPLSPrintf("Unkown option name '%s'", argv[i])); else if( pszFilename == NULL ) pszFilename = argv[i]; else Usage("Too many command options."); } if( pszFilename == NULL ) Usage("No datasource specified."); /* -------------------------------------------------------------------- */ /* Open dataset. */ /* -------------------------------------------------------------------- */ hDataset = GDALOpen( pszFilename, GA_ReadOnly ); if( hDataset == NULL ) { fprintf( stderr, "gdalinfo failed - unable to open '%s'.\n", pszFilename ); /* -------------------------------------------------------------------- */ /* If argument is a VSIFILE, then print its contents */ /* -------------------------------------------------------------------- */ if ( strncmp( pszFilename, "/vsizip/", 8 ) == 0 || strncmp( pszFilename, "/vsitar/", 8 ) == 0 ) { papszFileList = VSIReadDirRecursive( pszFilename ); if ( papszFileList ) { int nCount = CSLCount( papszFileList ); fprintf( stdout, "Unable to open source `%s' directly.\n" "The archive contains %d files:\n", pszFilename, nCount ); for ( i = 0; i < nCount; i++ ) { fprintf( stdout, " %s/%s\n", pszFilename, papszFileList[i] ); } CSLDestroy( papszFileList ); papszFileList = NULL; } } CSLDestroy( argv ); CSLDestroy( papszExtraMDDomains ); GDALDumpOpenDatasets( stderr ); GDALDestroyDriverManager(); CPLDumpSharedList( NULL ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Read specified subdataset if requested. */ /* -------------------------------------------------------------------- */ if ( nSubdataset > 0 ) { char **papszSubdatasets = GDALGetMetadata( hDataset, "SUBDATASETS" ); int nSubdatasets = CSLCount( papszSubdatasets ); if ( nSubdatasets > 0 && nSubdataset <= nSubdatasets ) { char szKeyName[1024]; char *pszSubdatasetName; snprintf( szKeyName, sizeof(szKeyName), "SUBDATASET_%d_NAME", nSubdataset ); szKeyName[sizeof(szKeyName) - 1] = '\0'; pszSubdatasetName = CPLStrdup( CSLFetchNameValue( papszSubdatasets, szKeyName ) ); GDALClose( hDataset ); hDataset = GDALOpen( pszSubdatasetName, GA_ReadOnly ); CPLFree( pszSubdatasetName ); } else { fprintf( stderr, "gdalinfo warning: subdataset %d of %d requested. " "Reading the main dataset.\n", nSubdataset, nSubdatasets ); } } /* -------------------------------------------------------------------- */ /* 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] ); if( bShowFileList ) { 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 ) ); if ( bReportProj4 ) { char *pszProj4 = NULL; OSRExportToProj4( hSRS, &pszProj4 ); printf("PROJ.4 string is:\n\'%s\'\n",pszProj4); CPLFree( pszProj4 ); } 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++ ) { if (EQUALN(papszExtraMDDomains[iMDD], "xml:", 4)) printf( "%s\n", papszMetadata[i] ); else 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 ) { if (CPLIsNan(dfNoData)) printf( " NoData Value=nan\n" ); else 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 ); if (hOverview != NULL) { printf( "%dx%d", GDALGetRasterBandXSize( hOverview ), GDALGetRasterBandYSize( hOverview ) ); pszResampling = GDALGetMetadataItem( hOverview, "RESAMPLING", "" ); if( pszResampling != NULL && EQUALN(pszResampling,"AVERAGE_BIT2",12) ) printf( "*" ); } else printf( "(null)" ); } printf( "\n" ); if ( bComputeChecksum) { printf( " Overviews checksum: " ); for( iOverview = 0; iOverview < GDALGetOverviewCount(hBand); iOverview++ ) { GDALRasterBandH hOverview; if( iOverview != 0 ) printf( ", " ); hOverview = GDALGetOverview( hBand, iOverview ); if (hOverview) printf( "%d", GDALChecksumImage(hOverview, 0, 0, GDALGetRasterBandXSize(hOverview), GDALGetRasterBandYSize(hOverview))); else printf( "(null)" ); } 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 ); }
int main (int argc, const char *argv[]) { GDALDriverH hDriver; double adfGeoTransform[6]; GDALDatasetH in_Dataset; GDALDatasetH out_Dataset; double *data_scan_line; char *out_scan_line; int nBlockXSize, nBlockYSize; int bGotMin, bGotMax; int bands; int xsize; double lower_fiddle, upper_fiddle; double adfMinMax[2]; /* These are hard coded for now - need to figure out a better way to handle this.. */ double palette_in[256] = { 0.0, 1.00011, 1.9999649999999998, 3.000075, 3.9999299999999995, 5.00004, 5.999895, 7.000005, 8.000115, 8.99997, 10.00008, 10.999935, 12.000044999999998, 12.9999, 14.00001, 15.00012, 15.999975, 17.000085000000002, 17.99994, 19.00005, 19.999905000000002, 21.000014999999998, 22.000125, 22.99998, 24.000089999999997, 24.999945, 26.000055, 26.99991, 28.00002, 28.999875000000003, 29.999985, 31.000094999999998, 31.99995, 33.00006, 33.999915, 35.000024999999994, 35.99988, 36.999990000000004, 38.0001, 38.999955, 40.000065, 40.99992, 42.000029999999995, 42.999885, 43.999995000000006, 45.000105, 45.99996, 47.00007, 47.999925000000005, 49.000035, 49.99989, 51.0, 52.00011, 52.999965, 54.000075, 54.99993, 56.00004, 56.999895, 58.000004999999994, 59.000115, 59.99997, 61.000080000000004, 61.999935, 63.000045, 63.9999, 65.00001, 66.00012, 66.999975, 68.000085, 68.99994, 70.00004999999999, 70.999905, 72.000015, 73.000125, 73.99998000000001, 75.00009, 75.999945, 77.00005499999999, 77.99991, 79.00002, 79.99987499999999, 80.99998500000001, 82.000095, 82.99995, 84.00005999999999, 84.999915, 86.00002500000001, 86.99987999999999, 87.99999000000001, 89.0001, 89.999955, 91.00006499999999, 91.99992, 93.00003, 93.99988499999999, 94.999995, 96.000105, 96.99996, 98.00007, 98.999925, 100.000035, 100.99989, 102.0, 103.00011, 103.999965, 105.000075, 105.99993, 107.00004, 107.999895, 109.000005, 110.00011500000001, 110.99997, 112.00008, 112.99993500000001, 114.000045, 114.9999, 116.00000999999999, 117.00012, 117.999975, 119.000085, 119.99994, 121.00005, 121.999905, 123.00001499999999, 124.000125, 124.99998000000001, 126.00009, 126.999945, 128.000055, 128.99991, 130.00002, 130.999875, 131.99998499999998, 133.000095, 133.99995, 135.00006, 135.999915, 137.00002500000002, 137.99988, 138.99999, 140.00009999999997, 140.999955, 142.000065, 142.99991999999997, 144.00003, 144.999885, 145.99999499999998, 147.000105, 147.99996000000002, 149.00007, 149.999925, 151.00003500000003, 151.99989, 153.0, 154.00010999999998, 154.999965, 156.000075, 156.99992999999998, 158.00004, 158.999895, 160.000005, 161.000115, 161.99997000000002, 163.00008, 163.999935, 165.000045, 165.9999, 167.00001, 168.00011999999998, 168.999975, 170.000085, 170.99993999999998, 172.00005000000002, 172.999905, 174.000015, 175.000125, 175.99998000000002, 177.00009, 177.999945, 179.00005499999997, 179.99991, 181.00002, 181.999875, 182.999985, 184.00009500000002, 184.99994999999998, 186.00006, 186.99991500000002, 188.000025, 188.99988, 189.99999, 191.0001, 191.999955, 193.00006499999998, 193.99992, 195.00003, 195.99988499999998, 196.999995, 198.00010500000002, 198.99996, 200.00007, 200.99992500000002, 202.000035, 202.99989, 204.0, 205.00011, 205.999965, 207.00007499999998, 207.99993, 209.00004, 209.99989499999998, 211.00000500000002, 212.000115, 212.99997, 214.00008, 214.999935, 216.000045, 216.9999, 218.00001, 219.00012, 219.999975, 221.00008499999998, 221.99994, 223.00005000000002, 223.99990499999998, 225.00001500000002, 226.000125, 226.99998, 228.00009, 228.999945, 230.000055, 230.99991, 232.00001999999998, 232.999875, 233.999985, 235.000095, 235.99995, 237.00006, 237.999915, 239.000025, 239.99988, 240.99999, 242.0001, 242.999955, 244.000065, 244.99992, 246.00002999999998, 246.999885, 247.999995, 249.000105, 249.99996000000002, 251.00007, 251.999925, 253.000035, 253.99989, 255.0 }; double palette_out[256] = { 0.0, 0.042075, 0.08415, 0.126225, 0.169065, 0.21216, 0.255765, 0.29988, 0.345015, 0.390915, 0.437835, 0.48602999999999996, 0.5352450000000001, 0.58599, 0.63801, 0.69156, 0.7468950000000001, 0.804015, 0.8629199999999999, 0.9238649999999999, 0.98685, 1.05213, 1.119705, 1.18983, 1.26225, 1.337475, 1.415505, 1.49634, 1.580235, 1.6674449999999998, 1.75746, 1.851045, 1.9482, 2.04867, 2.152965, 2.2608300000000003, 2.3727750000000003, 2.4885450000000002, 2.6083950000000002, 2.73258, 2.8611000000000004, 2.993955, 3.1313999999999997, 3.27369, 3.42057, 3.572295, 3.72912, 3.891045, 4.05807, 4.23045, 4.408440000000001, 4.591785, 4.780995, 4.975815, 5.1765, 5.38305, 5.595975, 5.8150200000000005, 6.040185, 6.27198, 6.510405, 6.755205, 7.007145, 7.265715, 7.53117, 7.8040199999999995, 8.084010000000001, 8.37114, 8.66592, 8.968095, 9.27792, 9.59565, 9.92103, 10.25457, 10.596015, 10.945875, 11.30415, 11.670585, 12.04569, 12.429465, 12.82191, 13.223279999999999, 13.63383, 14.053305, 14.48196, 14.919794999999999, 15.36732, 15.82428, 16.29093, 16.767270000000003, 17.253555, 17.749785, 18.256215, 18.925845, 19.456245000000003, 19.99863, 20.552745, 21.11859, 21.696165, 22.285725, 22.887014999999998, 23.500035, 24.125295, 24.762285, 25.411260000000002, 26.071965, 26.74491, 27.42984, 28.12701, 28.835910000000002, 29.55705, 30.29043, 31.035795, 31.7934, 32.56299, 33.345075, 34.139145, 34.94571, 35.764514999999996, 36.595305, 37.438845, 38.294625, 39.162645, 40.04316, 40.935915, 41.84142, 42.759165, 43.68966, 44.632394999999995, 45.58788, 46.55586, 47.536335, 48.529560000000004, 49.535535, 50.554005000000004, 51.58497, 52.62894, 53.68566, 54.75513, 55.837095, 56.932064999999994, 58.040040000000005, 59.160765, 60.294239999999995, 61.44072, 62.59995000000001, 63.772439999999996, 64.95768000000001, 66.15592500000001, 67.36743, 68.591685, 69.82919999999999, 71.07972, 72.343245, 73.620285, 74.910075, 76.21337999999999, 77.52968999999999, 78.85926, 80.20209, 81.55843499999999, 82.927785, 84.31065, 85.66419, 87.10264500000001, 88.611225, 90.18712500000001, 91.82779500000001, 93.52992, 95.291205, 97.108845, 98.979525, 100.90095, 102.87006, 104.884305, 106.94037, 109.03596, 111.16827, 113.33424000000001, 115.531065, 117.756195, 120.00657, 122.27964, 124.572345, 126.88213499999999, 129.20595, 131.54124, 133.8852, 136.23477, 138.58714500000002, 140.939775, 143.289855, 145.63458, 147.97089, 150.296235, 152.60781, 154.902555, 157.17817499999998, 159.431355, 161.65929, 163.859685, 166.02948, 168.165615, 170.26554, 172.32645, 174.34554, 176.320005, 178.24704, 180.292905, 182.130945, 183.953685, 185.76138, 187.554285, 189.33291, 191.09751, 192.84834, 194.58591, 196.310475, 198.02229, 199.72161, 201.4092, 203.084805, 204.74944499999998, 206.402865, 208.04557499999999, 209.67808499999998, 211.30065, 212.913525, 214.516965, 216.11148, 217.69758000000002, 219.27501, 220.84479, 222.406665, 223.9614, 225.50924999999998, 227.05047000000002, 228.585315, 230.114295, 231.63766500000003, 233.15568000000002, 234.66885000000002, 236.17743, 237.681675, 239.18184, 240.67869, 242.172225, 243.66295499999998, 245.15088, 246.636765, 248.12061000000003, 249.602925, 251.083965, 252.56424, 254.04375, 255.0 }; GDALAllRegister (); /* ussage.. */ if (argc != 3) ussage (); /* Set cache to something reasonable.. - 1/2 gig */ CPLSetConfigOption ("GDAL_CACHEMAX", "512"); /* open datasets.. */ in_Dataset = GDAL_open_read (argv[1]); out_Dataset = make_me_a_sandwitch (&in_Dataset, argv[2]); /* Basic info on source dataset.. */ GDALGetBlockSize (GDALGetRasterBand (in_Dataset, 1), &nBlockXSize, &nBlockYSize); printf ("Block=%dx%d Type=%s, ColorInterp=%s\n", nBlockXSize, nBlockYSize, GDALGetDataTypeName (GDALGetRasterDataType (GDALGetRasterBand (in_Dataset, 1))), GDALGetColorInterpretationName (GDALGetRasterColorInterpretation (GDALGetRasterBand (in_Dataset, 1)))); /* Loop though bands, scaling the data.. */ xsize = GDALGetRasterXSize (in_Dataset); data_scan_line = (double *) CPLMalloc (sizeof (double) * xsize); out_scan_line = (char *) CPLMalloc (sizeof (char) * xsize); for (bands = 1; bands <= GDALGetRasterCount (in_Dataset); bands++) { int x; double min = 9999999.0, max = 0.0; /* probibly a better way to set these.. */ double dmin, dmax, middle; GDALRasterBandH data_band, out_band; int y_index = 0; data_band = GDALGetRasterBand (in_Dataset, bands); out_band = GDALGetRasterBand (out_Dataset, bands); /* Set nodata for that band */ GDALSetRasterNoDataValue (out_band, 0.0); /*Find Min,Max, required for scaling */ for (y_index = 0; y_index < GDALGetRasterYSize (in_Dataset); y_index++) { /* Read data.. */ GDALRasterIO (data_band, GF_Read, 0, y_index, xsize, 1, data_scan_line, xsize, 1, GDT_Float64, 0, 0); for (x = 0; x < xsize; x++) { if (data_scan_line[x] < MAX_MODIS && data_scan_line[x] > MIN_VALUE) { if (data_scan_line[x] > max) max = data_scan_line[x]; else if (data_scan_line[x] < min) min = data_scan_line[x]; } } } dmax = (double) max; dmin = (double) min; printf ("Info: For Band %d -> Min=%g,Max=%g\n", bands, dmin, dmax); for (y_index = 0; y_index < GDALGetRasterYSize (in_Dataset); y_index++) { double scaled; /* Read data.. */ GDALRasterIO (data_band, GF_Read, 0, y_index, xsize, 1, data_scan_line, xsize, 1, GDT_Float64, 0, 0); /* scale each .. */ for (x = 0; x < xsize; x++) { out_scan_line[x] = scale (palette_in, palette_out, data_scan_line[x], dmin, dmax); } /* now write out band.. */ GDALRasterIO (out_band, GF_Write, 0, y_index, xsize, 1, out_scan_line, xsize, 1, GDT_Byte, 0, 0); } } /* close file, and we are done. */ GDALClose (out_Dataset); }
int main (int argc, const char *argv[]) { GDALDriverH hDriver; double adfGeoTransform[6]; GDALDatasetH in_Dataset; GDALDatasetH mask_Dataset; GDALDatasetH out_Dataset; GDALRasterBandH mask_band; unsigned char *out_scan_line, *data_scan_line; int nBlockXSize, nBlockYSize; int bGotMin, bGotMax; int bands; int xsize; double adfMinMax[2]; int valid_data_pixels[10]; int saturated_data_pixels[10]; int y_index, x; GDALRasterBandH out_band; if (argc != 3) { ussage (argv[0]); } GDALAllRegister (); /* Set cache to something reasonable.. - 1/2 gig */ CPLSetConfigOption ("GDAL_CACHEMAX", "512"); /* open datasets.. */ in_Dataset = GDAL_open_read (argv[1]); out_Dataset = make_me_a_sandwitch (&in_Dataset, argv[2]); /* Basic info on source dataset.. */ GDALGetBlockSize (GDALGetRasterBand (in_Dataset, 1), &nBlockXSize, &nBlockYSize); /* Loop though bands, checking for saturated pixels .... */ xsize = GDALGetRasterXSize (in_Dataset); data_scan_line = (char *) CPLMalloc (sizeof (char) * xsize); out_scan_line = (char *) CPLMalloc (sizeof (char) * xsize); /* The output band... */ out_band = GDALGetRasterBand (out_Dataset, 1); /* wipe counters.. */ for (bands = 1; bands <= GDALGetRasterCount (in_Dataset); bands++) { valid_data_pixels[bands] = 0; saturated_data_pixels[bands] = 0; } /* loop though the lines of the data, looking for no data and saturated pixels.. */ for (y_index = 0; y_index < GDALGetRasterYSize (in_Dataset); y_index++) { for (bands = 1; bands <= GDALGetRasterCount (in_Dataset); bands++) { GDALRasterBandH data_band; /* Read data.. */ data_band = GDALGetRasterBand (in_Dataset, bands); GDALRasterIO (data_band, GF_Read, 0, y_index, xsize, 1, data_scan_line, xsize, 1, GDT_Byte, 0, 0); /* If first band, then copy into output slice.. */ if (bands == 1) { unsigned char data_value; for (x = 0; x < xsize; x++) { /*shift to make darker... */ out_scan_line[x] = data_scan_line[x] >> 1; if (out_scan_line[x] == 0 && data_scan_line[x] != 0) { out_scan_line[x] = 1; } } } /* Loop though, looking for saturated pixels and no-data values.. */ for (x = 0; x < xsize; x++) { if (data_scan_line[x] == 0) { out_scan_line[x] = 255; } } } GDALRasterIO (out_band, GF_Write, 0, y_index, xsize, 1, out_scan_line, xsize, 1, GDT_Byte, 0, 0); }
s_sat * sat_load(const char * dname) { try; bool is_first = true; unsigned v, height, width, height_width, raster_num = 0; char str[BUF_SIZE], * sstr; DIR * dir = NULL; struct dirent * entry; GDALDatasetH ds = NULL; s_sat * sat = NULL; throw_null((sat = sat_init(DIM))); throw_null((dir = opendir(dname))); while((entry = readdir(dir)) != NULL) for(v = 0; v < DIM; v++) { sprintf(str, "B%u0.tif", v + 1); sstr = strstr(entry->d_name, str); if((sstr != NULL) && (sstr[7] == '\0')) { sprintf(str, "%s/%s", dname, entry->d_name); throw_null(ds = GDALOpen(str, GA_ReadOnly)); if(is_first) { height = sat->height = GDALGetRasterYSize(ds); width = sat->width = GDALGetRasterXSize(ds); throw((GDALGetGeoTransform(ds, sat->gt_coef) == CE_Failure)); throw_null((sat->proj_ref = strdup(GDALGetProjectionRef(ds)))); height_width = height * width; is_first = false; } throw_null((sat->pixel[v] = sfire_alloc(sizeof(uint8_t), 1, height_width))); throw((GDALDatasetRasterIO(ds, GF_Read, 0, 0, width, height, sat->pixel[v], width, height, GDT_Byte, 1, NULL, 0, 0, 0) == CE_Failure)); GDALClose(ds); ds = NULL; raster_num++; break; } } throw((raster_num != DIM)); catch; sat_destroy(sat); sat = NULL; finally; if(ds != NULL) GDALClose(ds); if(dir != NULL) closedir(dir); return sat; }
static ERL_NIF_TERM gdal_nif_get_meta(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { gdal_img_handle* handle; if (enif_get_resource(env, argv[0], gdal_img_RESOURCE, (void**)&handle)) { GDALDatasetH in_ds = handle->in_ds; if (in_ds != NULL) { ERL_NIF_TERM terms[8]; int idx = 0; terms[idx++] = enif_make_tuple2(env, enif_make_atom(env, "description"), enif_make_string(env, GDALGetDescription(in_ds), ERL_NIF_LATIN1)); GDALDriverH hDriver = GDALGetDatasetDriver(in_ds); char buf[256]; sprintf(buf, "%s/%s", GDALGetDriverShortName(hDriver), GDALGetDriverLongName(hDriver)); terms[idx++] = enif_make_tuple2(env, enif_make_atom(env, "driver"), enif_make_string(env, buf, ERL_NIF_LATIN1)); terms[idx++] = enif_make_tuple2(env, enif_make_atom(env, "rasterSize"), enif_make_tuple2(env, enif_make_int(env, GDALGetRasterXSize(in_ds)), enif_make_int(env, GDALGetRasterYSize(in_ds)))); terms[idx++] = enif_make_tuple2(env, enif_make_atom(env, "rasterCount"), enif_make_int(env, GDALGetRasterCount(in_ds))); double adfGeoTransform[6]; if( GDALGetGeoTransform( in_ds, adfGeoTransform ) == CE_None ) { terms[idx++] = enif_make_tuple2(env, enif_make_atom(env, "origin"), enif_make_tuple2(env, enif_make_double(env, adfGeoTransform[0]), enif_make_double(env, adfGeoTransform[3]))); terms[idx++] = enif_make_tuple2(env, enif_make_atom(env, "pixelSize"), enif_make_tuple2(env, enif_make_double(env, adfGeoTransform[1]), enif_make_double(env, adfGeoTransform[5]))); } if (GDALGetProjectionRef(in_ds) != NULL) { terms[idx++] = enif_make_tuple2(env, enif_make_atom(env, "projection"), enif_make_string(env, GDALGetProjectionRef(in_ds), ERL_NIF_LATIN1)); } char** fileList = GDALGetFileList(in_ds); if (fileList != NULL) { ERL_NIF_TERM fileTerms[16]; int fileIdx = 0; char** files = fileList; do { fileTerms[ fileIdx++ ] = enif_make_string(env, *files, ERL_NIF_LATIN1); } while(*(++files)) ; CSLDestroy(fileList); terms[idx++] = enif_make_tuple2(env, enif_make_atom(env, "fileList"), enif_make_list_from_array(env, fileTerms, fileIdx)); } return enif_make_list_from_array(env, terms, idx); } else { return ATOM_NOT_OPEN; } } else { return enif_make_badarg(env); } }
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; }
MAIN_START(argc, argv) { // Check that we are running against at least GDAL 1.4. // Note to developers: if we use newer API, please change the requirement. if( atoi(GDALVersionInfo("VERSION_NUM")) < 1400 ) { fprintf(stderr, "At least, GDAL >= 1.4.0 is required for this version of %s, " "which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME); exit(1); } GDALAllRegister(); OGRRegisterAll(); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); /* -------------------------------------------------------------------- */ /* Get commandline arguments other than the GDAL raster filenames. */ /* -------------------------------------------------------------------- */ const char* pszIndexLayerName = nullptr; const char *index_filename = nullptr; const char *tile_index = "location"; const char* pszDriverName = nullptr; size_t nMaxFieldSize = 254; bool write_absolute_path = false; char* current_path = nullptr; bool skip_different_projection = false; const char *pszTargetSRS = ""; bool bSetTargetSRS = false; const char* pszSrcSRSName = nullptr; int i_SrcSRSName = -1; bool bSrcSRSFormatSpecified = false; SrcSRSFormat eSrcSRSFormat = FORMAT_AUTO; int iArg = 1; // Used after for. for( ; iArg < argc; iArg++ ) { if( EQUAL(argv[iArg], "--utility_version") ) { printf("%s was compiled against GDAL %s and is running against " "GDAL %s\n", argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); CSLDestroy( argv ); return 0; } else if( EQUAL(argv[iArg],"--help") ) Usage(nullptr); else if( (strcmp(argv[iArg],"-f") == 0 || strcmp(argv[iArg],"-of") == 0) ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszDriverName = argv[++iArg]; } else if( strcmp(argv[iArg],"-lyr_name") == 0 ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszIndexLayerName = argv[++iArg]; } else if( strcmp(argv[iArg],"-tileindex") == 0 ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); tile_index = argv[++iArg]; } else if( strcmp(argv[iArg],"-t_srs") == 0 ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszTargetSRS = argv[++iArg]; bSetTargetSRS = true; } else if ( strcmp(argv[iArg],"-write_absolute_path") == 0 ) { write_absolute_path = true; } else if ( strcmp(argv[iArg],"-skip_different_projection") == 0 ) { skip_different_projection = true; } else if( strcmp(argv[iArg], "-src_srs_name") == 0 ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszSrcSRSName = argv[++iArg]; } else if( strcmp(argv[iArg], "-src_srs_format") == 0 ) { const char* pszFormat; bSrcSRSFormatSpecified = true; CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszFormat = argv[++iArg]; if( EQUAL(pszFormat, "AUTO") ) eSrcSRSFormat = FORMAT_AUTO; else if( EQUAL(pszFormat, "WKT") ) eSrcSRSFormat = FORMAT_WKT; else if( EQUAL(pszFormat, "EPSG") ) eSrcSRSFormat = FORMAT_EPSG; else if( EQUAL(pszFormat, "PROJ") ) eSrcSRSFormat = FORMAT_PROJ; } else if( argv[iArg][0] == '-' ) Usage(CPLSPrintf("Unknown option name '%s'", argv[iArg])); else if( index_filename == nullptr ) { index_filename = argv[iArg]; iArg++; break; } } if( index_filename == nullptr ) Usage("No index filename specified."); if( iArg == argc ) Usage("No file to index specified."); if( bSrcSRSFormatSpecified && pszSrcSRSName == nullptr ) Usage("-src_srs_name must be specified when -src_srs_format is " "specified."); /* -------------------------------------------------------------------- */ /* Create and validate target SRS if given. */ /* -------------------------------------------------------------------- */ OGRSpatialReferenceH hTargetSRS = nullptr; if( bSetTargetSRS ) { if( skip_different_projection ) { fprintf( stderr, "Warning : -skip_different_projection does not apply " "when -t_srs is requested.\n" ); } hTargetSRS = OSRNewSpatialReference(""); // coverity[tainted_data] if( OSRSetFromUserInput( hTargetSRS, pszTargetSRS ) != CE_None ) { OSRDestroySpatialReference( hTargetSRS ); fprintf( stderr, "Invalid target SRS `%s'.\n", pszTargetSRS ); exit(1); } } /* -------------------------------------------------------------------- */ /* Open or create the target datasource */ /* -------------------------------------------------------------------- */ GDALDatasetH hTileIndexDS = GDALOpenEx( index_filename, GDAL_OF_VECTOR | GDAL_OF_UPDATE, nullptr, nullptr, nullptr ); OGRLayerH hLayer = nullptr; CPLString osFormat; if( hTileIndexDS != nullptr ) { GDALDriverH hDriver = GDALGetDatasetDriver(hTileIndexDS); if( hDriver ) osFormat = GDALGetDriverShortName(hDriver); if( GDALDatasetGetLayerCount(hTileIndexDS) == 1 ) { hLayer = GDALDatasetGetLayer(hTileIndexDS, 0); } else { if( pszIndexLayerName == nullptr ) { printf( "-lyr_name must be specified.\n" ); exit( 1 ); } CPLPushErrorHandler(CPLQuietErrorHandler); hLayer = GDALDatasetGetLayerByName(hTileIndexDS, pszIndexLayerName); CPLPopErrorHandler(); } } else { printf( "Creating new index file...\n" ); if( pszDriverName == nullptr ) { std::vector<CPLString> aoDrivers = GetOutputDriversFor(index_filename, GDAL_OF_VECTOR); if( aoDrivers.empty() ) { CPLError( CE_Failure, CPLE_AppDefined, "Cannot guess driver for %s", index_filename); exit( 10 ); } else { if( aoDrivers.size() > 1 ) { CPLError( CE_Warning, CPLE_AppDefined, "Several drivers matching %s extension. Using %s", CPLGetExtension(index_filename), aoDrivers[0].c_str() ); } osFormat = aoDrivers[0]; } } else { osFormat = pszDriverName; } if( !EQUAL(osFormat, "ESRI Shapefile") ) nMaxFieldSize = 0; GDALDriverH hDriver = GDALGetDriverByName( osFormat.c_str() ); if( hDriver == nullptr ) { printf( "%s driver not available.\n", osFormat.c_str() ); exit( 1 ); } hTileIndexDS = GDALCreate( hDriver, index_filename, 0, 0, 0, GDT_Unknown, nullptr ); } if( hTileIndexDS != nullptr && hLayer == nullptr ) { OGRSpatialReferenceH hSpatialRef = nullptr; char* pszLayerName = nullptr; if( pszIndexLayerName == nullptr ) { VSIStatBuf sStat; if( EQUAL(osFormat, "ESRI Shapefile") || VSIStat(index_filename, &sStat) == 0 ) { pszLayerName = CPLStrdup(CPLGetBasename(index_filename)); } else { printf( "-lyr_name must be specified.\n" ); exit( 1 ); } } else { pszLayerName = CPLStrdup(pszIndexLayerName); } /* get spatial reference for output file from target SRS (if set) */ /* or from first input file */ if( bSetTargetSRS ) { hSpatialRef = OSRClone( hTargetSRS ); } else { GDALDatasetH hDS = GDALOpen( argv[iArg], GA_ReadOnly ); if( hDS ) { const char* pszWKT = GDALGetProjectionRef(hDS); if (pszWKT != nullptr && pszWKT[0] != '\0') { hSpatialRef = OSRNewSpatialReference(pszWKT); } GDALClose(hDS); } } hLayer = GDALDatasetCreateLayer( hTileIndexDS, pszLayerName, hSpatialRef, wkbPolygon, nullptr ); CPLFree(pszLayerName); if( hSpatialRef ) OSRRelease(hSpatialRef); if( hLayer ) { OGRFieldDefnH hFieldDefn = OGR_Fld_Create( tile_index, OFTString ); if( nMaxFieldSize ) OGR_Fld_SetWidth( hFieldDefn, static_cast<int>(nMaxFieldSize)); OGR_L_CreateField( hLayer, hFieldDefn, TRUE ); OGR_Fld_Destroy(hFieldDefn); if( pszSrcSRSName != nullptr ) { hFieldDefn = OGR_Fld_Create( pszSrcSRSName, OFTString ); if( nMaxFieldSize ) OGR_Fld_SetWidth(hFieldDefn, static_cast<int>(nMaxFieldSize)); OGR_L_CreateField( hLayer, hFieldDefn, TRUE ); OGR_Fld_Destroy(hFieldDefn); } } } if( hTileIndexDS == nullptr || hLayer == nullptr ) { fprintf( stderr, "Unable to open/create shapefile `%s'.\n", index_filename ); exit(2); } OGRFeatureDefnH hFDefn = OGR_L_GetLayerDefn(hLayer); const int ti_field = OGR_FD_GetFieldIndex( hFDefn, tile_index ); if( ti_field < 0 ) { fprintf( stderr, "Unable to find field `%s' in file `%s'.\n", tile_index, index_filename ); exit(2); } if( pszSrcSRSName != nullptr ) i_SrcSRSName = OGR_FD_GetFieldIndex( hFDefn, pszSrcSRSName ); // Load in memory existing file names in SHP. int nExistingFiles = static_cast<int>(OGR_L_GetFeatureCount(hLayer, FALSE)); if( nExistingFiles < 0) nExistingFiles = 0; char** existingFilesTab = nullptr; bool alreadyExistingProjectionRefValid = false; char* alreadyExistingProjectionRef = nullptr; if( nExistingFiles > 0 ) { OGRFeatureH hFeature = nullptr; existingFilesTab = static_cast<char **>( CPLMalloc(nExistingFiles * sizeof(char*))); for( int i = 0; i < nExistingFiles; i++ ) { hFeature = OGR_L_GetNextFeature(hLayer); existingFilesTab[i] = CPLStrdup(OGR_F_GetFieldAsString( hFeature, ti_field )); if( i == 0 ) { GDALDatasetH hDS = GDALOpen(existingFilesTab[i], GA_ReadOnly ); if( hDS ) { alreadyExistingProjectionRefValid = true; alreadyExistingProjectionRef = CPLStrdup(GDALGetProjectionRef(hDS)); GDALClose(hDS); } } OGR_F_Destroy( hFeature ); } } if( write_absolute_path ) { current_path = CPLGetCurrentDir(); if (current_path == nullptr) { fprintf( stderr, "This system does not support the CPLGetCurrentDir call. " "The option -write_absolute_path will have no effect\n" ); write_absolute_path = FALSE; } } /* -------------------------------------------------------------------- */ /* loop over GDAL files, processing. */ /* -------------------------------------------------------------------- */ for( ; iArg < argc; iArg++ ) { char *fileNameToWrite = nullptr; VSIStatBuf sStatBuf; // Make sure it is a file before building absolute path name. if( write_absolute_path && CPLIsFilenameRelative( argv[iArg] ) && VSIStat( argv[iArg], &sStatBuf ) == 0 ) { fileNameToWrite = CPLStrdup(CPLProjectRelativeFilename(current_path, argv[iArg])); } else { fileNameToWrite = CPLStrdup(argv[iArg]); } // Checks that file is not already in tileindex. { int i = 0; // Used after for. for( ; i < nExistingFiles; i++ ) { if (EQUAL(fileNameToWrite, existingFilesTab[i])) { fprintf(stderr, "File %s is already in tileindex. Skipping it.\n", fileNameToWrite); break; } } if (i != nExistingFiles) { CPLFree(fileNameToWrite); continue; } } GDALDatasetH hDS = GDALOpen( argv[iArg], GA_ReadOnly ); if( hDS == nullptr ) { fprintf( stderr, "Unable to open %s, skipping.\n", argv[iArg] ); CPLFree(fileNameToWrite); continue; } double adfGeoTransform[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; GDALGetGeoTransform( hDS, adfGeoTransform ); if( adfGeoTransform[0] == 0.0 && adfGeoTransform[1] == 1.0 && adfGeoTransform[3] == 0.0 && std::abs(adfGeoTransform[5]) == 1.0 ) { fprintf( stderr, "It appears no georeferencing is available for\n" "`%s', skipping.\n", argv[iArg] ); GDALClose( hDS ); CPLFree(fileNameToWrite); continue; } const char *projectionRef = GDALGetProjectionRef(hDS); // If not set target srs, test that the current file uses same // projection as others. if( !bSetTargetSRS ) { if( alreadyExistingProjectionRefValid ) { int projectionRefNotNull, alreadyExistingProjectionRefNotNull; projectionRefNotNull = projectionRef && projectionRef[0]; alreadyExistingProjectionRefNotNull = alreadyExistingProjectionRef && alreadyExistingProjectionRef[0]; if ((projectionRefNotNull && alreadyExistingProjectionRefNotNull && EQUAL(projectionRef, alreadyExistingProjectionRef) == 0) || (projectionRefNotNull != alreadyExistingProjectionRefNotNull)) { fprintf( stderr, "Warning : %s is not using the same projection system " "as other files in the tileindex.\n" "This may cause problems when using it in MapServer " "for example.\n" "Use -t_srs option to set target projection system " "(not supported by MapServer).\n" "%s\n", argv[iArg], skip_different_projection ? "Skipping this file." : ""); if( skip_different_projection ) { CPLFree(fileNameToWrite); GDALClose( hDS ); continue; } } } else { alreadyExistingProjectionRefValid = true; alreadyExistingProjectionRef = CPLStrdup(projectionRef); } } const int nXSize = GDALGetRasterXSize( hDS ); const int nYSize = GDALGetRasterYSize( hDS ); double adfX[5] = { 0.0, 0.0, 0.0, 0.0, 0.0 }; double adfY[5] = { 0.0, 0.0, 0.0, 0.0, 0.0 }; adfX[0] = adfGeoTransform[0] + 0 * adfGeoTransform[1] + 0 * adfGeoTransform[2]; adfY[0] = adfGeoTransform[3] + 0 * adfGeoTransform[4] + 0 * adfGeoTransform[5]; adfX[1] = adfGeoTransform[0] + nXSize * adfGeoTransform[1] + 0 * adfGeoTransform[2]; adfY[1] = adfGeoTransform[3] + nXSize * adfGeoTransform[4] + 0 * adfGeoTransform[5]; adfX[2] = adfGeoTransform[0] + nXSize * adfGeoTransform[1] + nYSize * adfGeoTransform[2]; adfY[2] = adfGeoTransform[3] + nXSize * adfGeoTransform[4] + nYSize * adfGeoTransform[5]; adfX[3] = adfGeoTransform[0] + 0 * adfGeoTransform[1] + nYSize * adfGeoTransform[2]; adfY[3] = adfGeoTransform[3] + 0 * adfGeoTransform[4] + nYSize * adfGeoTransform[5]; adfX[4] = adfGeoTransform[0] + 0 * adfGeoTransform[1] + 0 * adfGeoTransform[2]; adfY[4] = adfGeoTransform[3] + 0 * adfGeoTransform[4] + 0 * adfGeoTransform[5]; OGRSpatialReferenceH hSourceSRS = nullptr; if( (bSetTargetSRS || i_SrcSRSName >= 0) && projectionRef != nullptr && projectionRef[0] != '\0' ) { hSourceSRS = OSRNewSpatialReference( projectionRef ); } // If set target srs, do the forward transformation of all points. if( bSetTargetSRS && projectionRef != nullptr && projectionRef[0] != '\0' ) { OGRCoordinateTransformationH hCT = nullptr; if( hSourceSRS && !OSRIsSame( hSourceSRS, hTargetSRS ) ) { hCT = OCTNewCoordinateTransformation( hSourceSRS, hTargetSRS ); if( hCT == nullptr || !OCTTransform( hCT, 5, adfX, adfY, nullptr ) ) { fprintf( stderr, "Warning : unable to transform points from source " "SRS `%s' to target SRS `%s'\n" "for file `%s' - file skipped\n", projectionRef, pszTargetSRS, fileNameToWrite ); if( hCT ) OCTDestroyCoordinateTransformation( hCT ); if( hSourceSRS ) OSRDestroySpatialReference( hSourceSRS ); continue; } if( hCT ) OCTDestroyCoordinateTransformation( hCT ); } } OGRFeatureH hFeature = OGR_F_Create( OGR_L_GetLayerDefn( hLayer ) ); OGR_F_SetFieldString( hFeature, ti_field, fileNameToWrite ); if( i_SrcSRSName >= 0 && hSourceSRS != nullptr ) { const char* pszAuthorityCode = OSRGetAuthorityCode(hSourceSRS, nullptr); const char* pszAuthorityName = OSRGetAuthorityName(hSourceSRS, nullptr); if( eSrcSRSFormat == FORMAT_AUTO ) { if( pszAuthorityName != nullptr && pszAuthorityCode != nullptr ) { OGR_F_SetFieldString( hFeature, i_SrcSRSName, CPLSPrintf("%s:%s", pszAuthorityName, pszAuthorityCode) ); } else if( nMaxFieldSize == 0 || strlen(projectionRef) <= nMaxFieldSize ) { OGR_F_SetFieldString(hFeature, i_SrcSRSName, projectionRef); } else { char* pszProj4 = nullptr; if( OSRExportToProj4(hSourceSRS, &pszProj4) == OGRERR_NONE ) { OGR_F_SetFieldString( hFeature, i_SrcSRSName, pszProj4 ); CPLFree(pszProj4); } else { OGR_F_SetFieldString( hFeature, i_SrcSRSName, projectionRef ); } } } else if( eSrcSRSFormat == FORMAT_WKT ) { if( nMaxFieldSize == 0 || strlen(projectionRef) <= nMaxFieldSize ) { OGR_F_SetFieldString( hFeature, i_SrcSRSName, projectionRef ); } else { fprintf(stderr, "Cannot write WKT for file %s as it is too long!\n", fileNameToWrite); } } else if( eSrcSRSFormat == FORMAT_PROJ ) { char* pszProj4 = nullptr; if( OSRExportToProj4(hSourceSRS, &pszProj4) == OGRERR_NONE ) { OGR_F_SetFieldString( hFeature, i_SrcSRSName, pszProj4 ); CPLFree(pszProj4); } } else if( eSrcSRSFormat == FORMAT_EPSG ) { if( pszAuthorityName != nullptr && pszAuthorityCode != nullptr ) OGR_F_SetFieldString( hFeature, i_SrcSRSName, CPLSPrintf("%s:%s", pszAuthorityName, pszAuthorityCode) ); } } if( hSourceSRS ) OSRDestroySpatialReference( hSourceSRS ); OGRGeometryH hPoly = OGR_G_CreateGeometry(wkbPolygon); OGRGeometryH hRing = OGR_G_CreateGeometry(wkbLinearRing); for( int k = 0; k < 5; k++ ) OGR_G_SetPoint_2D(hRing, k, adfX[k], adfY[k]); OGR_G_AddGeometryDirectly( hPoly, hRing ); OGR_F_SetGeometryDirectly( hFeature, hPoly ); if( OGR_L_CreateFeature( hLayer, hFeature ) != OGRERR_NONE ) { printf( "Failed to create feature in shapefile.\n" ); break; } OGR_F_Destroy( hFeature ); CPLFree(fileNameToWrite); GDALClose( hDS ); } CPLFree(current_path); if (nExistingFiles) { for( int i = 0; i < nExistingFiles; i++ ) { CPLFree(existingFilesTab[i]); } CPLFree(existingFilesTab); } CPLFree(alreadyExistingProjectionRef); if ( hTargetSRS ) OSRDestroySpatialReference( hTargetSRS ); GDALClose( hTileIndexDS ); GDALDestroyDriverManager(); OGRCleanupAll(); CSLDestroy(argv); exit( 0 ); }
int main( int argc, char ** argv ) { /* Check that we are running against at least GDAL 1.4 (probably older in fact !) */ /* Note to developers : if we use newer API, please change the requirement */ if (atoi(GDALVersionInfo("VERSION_NUM")) < 1400) { fprintf(stderr, "At least, GDAL >= 1.4.0 is required for this version of %s, " "which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME); exit(1); } /* -------------------------------------------------------------------- */ /* Generic arg processing. */ /* -------------------------------------------------------------------- */ GDALAllRegister(); GDALSetCacheMax( 100000000 ); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); /* -------------------------------------------------------------------- */ /* Parse arguments. */ /* -------------------------------------------------------------------- */ int i; const char *pszOutFile = NULL; const char *pszInFile = NULL; int nMaxNonBlack = 2; int nNearDist = 15; int bNearWhite = FALSE; int bSetAlpha = FALSE; int bSetMask = FALSE; const char* pszDriverName = "HFA"; int bFormatExplicitelySet = FALSE; char** papszCreationOptions = NULL; int bQuiet = FALSE; Colors oColors; 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], "-o") && i < argc-1 ) pszOutFile = argv[++i]; else if( EQUAL(argv[i], "-of") && i < argc-1 ) { pszDriverName = argv[++i]; bFormatExplicitelySet = TRUE; } else if( EQUAL(argv[i], "-white") ) { bNearWhite = TRUE; } /***** -color c1,c2,c3...cn *****/ else if( EQUAL(argv[i], "-color") && i < argc-1 ) { Color oColor; /***** tokenize the arg on , *****/ char **papszTokens; papszTokens = CSLTokenizeString2( argv[++i], ",", 0 ); /***** loop over the tokens *****/ int iToken; for( iToken = 0; papszTokens && papszTokens[iToken]; iToken++ ) { /***** ensure the token is an int and add it to the color *****/ if ( IsInt( papszTokens[iToken] ) ) oColor.push_back( atoi( papszTokens[iToken] ) ); else { CPLError(CE_Failure, CPLE_AppDefined, "Colors must be valid integers." ); CSLDestroy( papszTokens ); exit(1); } } CSLDestroy( papszTokens ); /***** check if the number of bands is consistant *****/ if ( oColors.size() > 0 && oColors.front().size() != oColor.size() ) { CPLError(CE_Failure, CPLE_AppDefined, "ERROR: all -color args must have the same number of values.\n" ); exit(1); } /***** add the color to the colors *****/ oColors.push_back( oColor ); } else if( EQUAL(argv[i], "-nb") && i < argc-1 ) nMaxNonBlack = atoi(argv[++i]); else if( EQUAL(argv[i], "-near") && i < argc-1 ) nNearDist = atoi(argv[++i]); else if( EQUAL(argv[i], "-setalpha") ) bSetAlpha = TRUE; else if( EQUAL(argv[i], "-setmask") ) bSetMask = TRUE; else if( EQUAL(argv[i], "-q") || EQUAL(argv[i], "-quiet") ) bQuiet = TRUE; else if( EQUAL(argv[i], "-co") && i < argc-1 ) papszCreationOptions = CSLAddString(papszCreationOptions, argv[++i]); else if( argv[i][0] == '-' ) Usage(); else if( pszInFile == NULL ) pszInFile = argv[i]; else Usage(); } if( pszInFile == NULL ) Usage(); if( pszOutFile == NULL ) pszOutFile = pszInFile; /* -------------------------------------------------------------------- */ /* Open input file. */ /* -------------------------------------------------------------------- */ GDALDatasetH hInDS, hOutDS = NULL; int nXSize, nYSize, nBands; if( pszOutFile == pszInFile ) hInDS = hOutDS = GDALOpen( pszInFile, GA_Update ); else hInDS = GDALOpen( pszInFile, GA_ReadOnly ); if( hInDS == NULL ) exit( 1 ); nXSize = GDALGetRasterXSize( hInDS ); nYSize = GDALGetRasterYSize( hInDS ); nBands = GDALGetRasterCount( hInDS ); int nDstBands = nBands; if( hOutDS != NULL && papszCreationOptions != NULL) { CPLError(CE_Warning, CPLE_AppDefined, "Warning: creation options are ignored when writing to an existing file."); } /* -------------------------------------------------------------------- */ /* Do we need to create output file? */ /* -------------------------------------------------------------------- */ if( hOutDS == NULL ) { GDALDriverH hDriver = GDALGetDriverByName( pszDriverName ); if (hDriver == NULL) exit(1); if (!bQuiet && !bFormatExplicitelySet) CheckExtensionConsistency(pszOutFile, pszDriverName); if (bSetAlpha) { /***** fixme there should be a way to preserve alpha band data not in the collar *****/ if (nBands == 4) nBands --; else nDstBands ++; } if (bSetMask) { if (nBands == 4) nDstBands = nBands = 3; } hOutDS = GDALCreate( hDriver, pszOutFile, nXSize, nYSize, nDstBands, GDT_Byte, papszCreationOptions ); if( hOutDS == NULL ) exit( 1 ); double adfGeoTransform[6]; if( GDALGetGeoTransform( hInDS, adfGeoTransform ) == CE_None ) { GDALSetGeoTransform( hOutDS, adfGeoTransform ); GDALSetProjection( hOutDS, GDALGetProjectionRef( hInDS ) ); } } else { if (bSetAlpha) { if (nBands != 4 && (nBands < 2 || GDALGetRasterColorInterpretation(GDALGetRasterBand(hOutDS, nBands)) != GCI_AlphaBand)) { CPLError(CE_Failure, CPLE_AppDefined, "Last band is not an alpha band."); exit(1); } nBands --; } if (bSetMask) { if (nBands == 4) nDstBands = nBands = 3; } } /***** set a color if there are no colors set? *****/ if ( oColors.size() == 0) { Color oColor; /***** loop over the bands to get the right number of values *****/ int iBand; for (iBand = 0; iBand < nBands ; iBand++) { /***** black or white? *****/ if (bNearWhite) oColor.push_back(255); else oColor.push_back(0); } /***** add the color to the colors *****/ oColors.push_back(oColor); } /***** does the number of bands match the number of color values? *****/ if ( (int)oColors.front().size() != nBands ) { CPLError( CE_Failure, CPLE_AppDefined, "-color args must have the same number of values as the non alpha input band count.\n" ); exit(1); } /***** check the input and output datasets are the same size *****/ if (GDALGetRasterXSize(hOutDS) != nXSize || GDALGetRasterYSize(hOutDS) != nYSize) { CPLError(CE_Failure, CPLE_AppDefined, "The dimensions of the output dataset don't match " "the dimensions of the input dataset."); exit(1); } int iBand; for( iBand = 0; iBand < nBands; iBand++ ) { GDALRasterBandH hBand = GDALGetRasterBand(hInDS, iBand+1); if (GDALGetRasterDataType(hBand) != GDT_Byte) { CPLError(CE_Warning, CPLE_AppDefined, "Band %d is not of type GDT_Byte. It can lead to unexpected results.", iBand+1); } if (GDALGetRasterColorTable(hBand) != NULL) { CPLError(CE_Warning, CPLE_AppDefined, "Band %d has a color table, which is ignored by nearblack. " "It can lead to unexpected results.", iBand+1); } } GDALRasterBandH hMaskBand = NULL; if (bSetMask) { /***** if there isn't already a mask band on the output file create one *****/ if ( GMF_PER_DATASET != GDALGetMaskFlags( GDALGetRasterBand(hOutDS, 1) ) ) { if ( CE_None != GDALCreateDatasetMaskBand(hOutDS, GMF_PER_DATASET) ) { CPLError(CE_Failure, CPLE_AppDefined, "Failed to create mask band on output DS"); bSetMask = FALSE; } } if (bSetMask) { hMaskBand = GDALGetMaskBand(GDALGetRasterBand(hOutDS, 1)); } } /* -------------------------------------------------------------------- */ /* Allocate a line buffer. */ /* -------------------------------------------------------------------- */ GByte *pabyLine; GByte *pabyMask=NULL; int *panLastLineCounts; pabyLine = (GByte *) CPLMalloc(nXSize * nDstBands); if (bSetMask) pabyMask = (GByte *) CPLMalloc(nXSize); panLastLineCounts = (int *) CPLCalloc(sizeof(int),nXSize); /* -------------------------------------------------------------------- */ /* Processing data one line at a time. */ /* -------------------------------------------------------------------- */ int iLine; for( iLine = 0; iLine < nYSize; iLine++ ) { CPLErr eErr; eErr = GDALDatasetRasterIO( hInDS, GF_Read, 0, iLine, nXSize, 1, pabyLine, nXSize, 1, GDT_Byte, nBands, NULL, nDstBands, nXSize * nDstBands, 1 ); if( eErr != CE_None ) break; if (bSetAlpha) { int iCol; for(iCol = 0; iCol < nXSize; iCol ++) { pabyLine[iCol * nDstBands + nDstBands - 1] = 255; } } if (bSetMask) { int iCol; for(iCol = 0; iCol < nXSize; iCol ++) { pabyMask[iCol] = 255; } } ProcessLine( pabyLine, pabyMask, 0, nXSize-1, nBands, nDstBands, nNearDist, nMaxNonBlack, bNearWhite, &oColors, panLastLineCounts, TRUE, // bDoHorizontalCheck TRUE, // bDoVerticalCheck FALSE // bBottomUp ); ProcessLine( pabyLine, pabyMask, nXSize-1, 0, nBands, nDstBands, nNearDist, nMaxNonBlack, bNearWhite, &oColors, panLastLineCounts, TRUE, // bDoHorizontalCheck FALSE, // bDoVerticalCheck FALSE // bBottomUp ); eErr = GDALDatasetRasterIO( hOutDS, GF_Write, 0, iLine, nXSize, 1, pabyLine, nXSize, 1, GDT_Byte, nDstBands, NULL, nDstBands, nXSize * nDstBands, 1 ); if( eErr != CE_None ) break; /***** write out the mask band line *****/ if (bSetMask) { eErr = GDALRasterIO ( hMaskBand, GF_Write, 0, iLine, nXSize, 1, pabyMask, nXSize, 1, GDT_Byte, 0, 0 ); if( eErr != CE_None ) { CPLError(CE_Warning, CPLE_AppDefined, "ERROR writeing out line to mask band."); break; } } if (!bQuiet) GDALTermProgress( 0.5 * ((iLine+1) / (double) nYSize), NULL, NULL ); } /* -------------------------------------------------------------------- */ /* Now process from the bottom back up .*/ /* -------------------------------------------------------------------- */ memset( panLastLineCounts, 0, sizeof(int) * nXSize); for( iLine = nYSize-1; iLine >= 0; iLine-- ) { CPLErr eErr; eErr = GDALDatasetRasterIO( hOutDS, GF_Read, 0, iLine, nXSize, 1, pabyLine, nXSize, 1, GDT_Byte, nDstBands, NULL, nDstBands, nXSize * nDstBands, 1 ); if( eErr != CE_None ) break; /***** read the mask band line back in *****/ if (bSetMask) { eErr = GDALRasterIO ( hMaskBand, GF_Read, 0, iLine, nXSize, 1, pabyMask, nXSize, 1, GDT_Byte, 0, 0 ); if( eErr != CE_None ) break; } ProcessLine( pabyLine, pabyMask, 0, nXSize-1, nBands, nDstBands, nNearDist, nMaxNonBlack, bNearWhite, &oColors, panLastLineCounts, TRUE, // bDoHorizontalCheck TRUE, // bDoVerticalCheck TRUE // bBottomUp ); ProcessLine( pabyLine, pabyMask, nXSize-1, 0, nBands, nDstBands, nNearDist, nMaxNonBlack, bNearWhite, &oColors, panLastLineCounts, TRUE, // bDoHorizontalCheck FALSE, // bDoVerticalCheck TRUE // bBottomUp ); eErr = GDALDatasetRasterIO( hOutDS, GF_Write, 0, iLine, nXSize, 1, pabyLine, nXSize, 1, GDT_Byte, nDstBands, NULL, nDstBands, nXSize * nDstBands, 1 ); if( eErr != CE_None ) break; /***** write out the mask band line *****/ if (bSetMask) { eErr = GDALRasterIO ( hMaskBand, GF_Write, 0, iLine, nXSize, 1, pabyMask, nXSize, 1, GDT_Byte, 0, 0 ); if( eErr != CE_None ) break; } if (!bQuiet) GDALTermProgress( 0.5 + 0.5 * (nYSize-iLine) / (double) nYSize, NULL, NULL ); } CPLFree(pabyLine); if (bSetMask) CPLFree(pabyMask); CPLFree( panLastLineCounts ); GDALClose( hOutDS ); if( hInDS != hOutDS ) GDALClose( hInDS ); GDALDumpOpenDatasets( stderr ); CSLDestroy( argv ); CSLDestroy( papszCreationOptions ); GDALDestroyDriverManager(); return 0; }
SVImage init(int xLow, int xHigh, int yLow, int yHigh, const char *filepath){ GDALDatasetH hDataset; // Register drivers GDALAllRegister(); // open the given file as Read Only hDataset = GDALOpen(filepath, GA_ReadOnly ); // if opening failed if( hDataset == NULL ) { fprintf(stderr, "Unable to open file."); exit(EXIT_FAILURE); } /* Declare some variables to be used later */ int *xBlockSize = malloc(sizeof(int)); int *yBlockSize = malloc(sizeof(int)); int xOutputSize; int yOutputSize; int numXBlocks; int numYBlocks; int origWidth; int origHeight; int origBandCount; /*Get some information on the image*/ origWidth = GDALGetRasterXSize( hDataset ); // Get raster pixel width origHeight = GDALGetRasterYSize( hDataset ); // Get raster pixel height origBandCount = GDALGetRasterCount( hDataset ); // Get number of raster bands in the image GDALRasterBandH hBand = GDALGetRasterBand( hDataset, 1 ); // Get raster band with id 1 GDALGetBlockSize( hBand, xBlockSize, yBlockSize); // Fetch the block size for this band /*TODO make sure scale is set somewhere*/ /*Store some information on what the output should have*/ xOutputSize = ((*xBlockSize) / scale); // get the new x block size yOutputSize = ((*yBlockSize) / scale); // get the new y block size numXBlocks = origWidth/(*xBlockSize); // Get x block count numYBlocks = origHeight/(*yBlockSize); // Get y block count int bandCount; if (origBandCount >= 3) // Just a guess, limit bands to RGB? { bandCount = 3; } else // Otherwise image is probably grayscale, one band? { bandCount = 1; } /*TODO edit this or remove it since we aren't using focusing on openGL*/ /* *int format; *if (bandCount == 3) *{ * format = GL_RGBA; *} *else *{ * format = GL_LUMINANCE_ALPHA; *} */ int usedBlocks; int usedXBlocks; int usedYBlocks; /* *This is odd, xHigh and yHigh are *passed as parameters but changed here *TODO see if we can remove parameters or just use this */ if ((xHigh < 0) || (xHigh < xLow)) { xHigh = numXBlocks; } if ((yHigh < 0)|| (yHigh < yLow)) { yHigh = numYBlocks; } usedXBlocks = (xHigh - xLow); // This is probably the part of the image that should be displayed on screen usedYBlocks = (yHigh - yLow); // Y part on screen? usedBlocks = (usedXBlocks * usedYBlocks); // Total blocks on screen? SVImage svip = { .Width = xOutputSize*usedXBlocks, .Height = yOutputSize*usedYBlocks, .BytesPerPixel = 1, .Data = (CPLMalloc((sizeof(char) * xOutputSize * yOutputSize * usedBlocks * (bandCount+1)))) // Data = xOutputSize * yOutputSize = pixels/block * usedBlocks = totalpixels }; free(xBlockSize); free(yBlockSize); return svip; } /* Uses stochastic sampling to fill the data section of an SVImage struct. */ void sample(params *in) //TODO handle 32 bit representations { /*Set variables from the params struct*/ SVImage* out = in->target; int xLow = in->xLow; int xHigh = in->xHigh; int yLow = in->yLow; int yHigh = in->yHigh; const char *file = in->file; GDALDatasetH hDataset; GDALRasterBandH hBand; /*Register drivers*/ GDALAllRegister(); //TODO Dynamically calculate sample count? int avgSampleCount = 25; //Open GDAL File //------------------------------------------------ hDataset = GDALOpen(file, GA_ReadOnly ); if( hDataset == NULL ) { fprintf(stderr, "Unable to open file.\n"); exit(EXIT_FAILURE); } //GDAL FILE INFO //--------------------------------------------- GDALDriverH hDriver; hDriver = GDALGetDatasetDriver( hDataset ); // Get driver for this file double adfGeoTransform[6]; //Print GDAL Driver printf( "Driver: %s/%s\n", GDALGetDriverShortName( hDriver ), GDALGetDriverLongName( hDriver ) ); //Get original raster size int origWidth = GDALGetRasterXSize( hDataset ); int origHeight = GDALGetRasterYSize( hDataset ); printf("width = %i\n", origWidth); printf("height = %i\n", origHeight); //Get Raster band count int origBandCount = GDALGetRasterCount( hDataset ); printf("origBandCount = %i\n", origBandCount); int bandCount; if (origBandCount >= 3) { bandCount = 3; } else { bandCount = 1; } //Target output Width and Height float stride = (scale * scale); stride /= (avgSampleCount); //the greatest number of pixels that can be skipped in a single iteration int maxStride = ((int)stride) + 1; //Load band 1 hBand = GDALGetRasterBand( hDataset, 1 ); if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None ) { printf( "Pixel Size = (%.6f,%.6f)\n", adfGeoTransform[1], adfGeoTransform[5] ); } else { fprintf(stderr, "Failed to get pixel size\n"); } int* xBlockSize = malloc(sizeof(int)); int* yBlockSize = malloc(sizeof(int)); //get block size GDALGetBlockSize( hBand, xBlockSize, yBlockSize); printf("xBlockSize = %i\n", *xBlockSize); printf("yBlockSize = %i\n", *yBlockSize); int xOutputSize = ((*xBlockSize) / scale); int yOutputSize = ((*yBlockSize) / scale); printf("X Output Size%i\n", xOutputSize); int numXBlocks = origWidth/(*xBlockSize); int numYBlocks = origHeight/(*yBlockSize); printf("numXBlocks = %i\n", numXBlocks); printf("numYBlocks = %i\n", numYBlocks); if ((xHigh < 0) || (xHigh < xLow)) { xHigh = numXBlocks; } if ((yHigh < 0)|| (yHigh < yLow)) { yHigh = numYBlocks; } int usedXBlocks = (xHigh - xLow); int usedYBlocks = (yHigh - yLow); int usedBlocks = (usedXBlocks * usedYBlocks); unsigned char* output = CPLMalloc((sizeof(char) * xOutputSize* yOutputSize *usedBlocks * (bandCount+1))); // Allocate space for the output float* vals = calloc( xOutputSize* yOutputSize *usedBlocks * (bandCount+1), sizeof(float)); //stores pixel values unsigned long* valsPerIndex = calloc( xOutputSize* yOutputSize * usedBlocks * (bandCount+1), sizeof(unsigned long)); //stores number of pixel values per output index unsigned long rseed = 0; unsigned long rowIndex = 0; //the index of the row to which we will output our value unsigned long colIndex = 0; //the index of the column to which we will output our value unsigned long outIndex = 0; unsigned long sampledIndex = 0; //One dimensional representation of column/row index //iterate through each pixel, jump to the last pixel we sampled. long long i = 0; int outputXOffset = 0; int outputYOffset = 0; int outputIndexOffset = 0; if (GDALGetRasterDataType(hBand) == GDT_Int16) { short* data = (short *) CPLMalloc(sizeof(unsigned short) * (*xBlockSize)*(*yBlockSize)); //TODO: GDAL Raster can be 16 bit pixel representation int band; for (band = 1; band <= bandCount; band++){ hBand = GDALGetRasterBand( hDataset, band ); int yBlock, xBlock; for(yBlock = yLow; yBlock < yHigh; yBlock++){ for(xBlock = xLow; xBlock < xHigh; xBlock++){ if(GDALReadBlock(hBand,xBlock,yBlock, data) != CE_None) { fprintf(stderr, "Read block failed\n"); exit(EXIT_FAILURE); } for(i = 0 ; i < ((*xBlockSize)*(*yBlockSize)-1) ; i += rseed){ rseed = (214013 * rseed + 2531011); // Magic numbers. rseed %= maxStride; sampledIndex = i; i = (maxStride ==1) ? (i+1) : i; rowIndex = (sampledIndex/(xOutputSize*scale* scale)) + ((yBlock - yLow)* yOutputSize); colIndex = ((sampledIndex % (xOutputSize * scale))/scale) + ((xBlock - xLow) * xOutputSize); outIndex = ((rowIndex * (xOutputSize * usedXBlocks ) + colIndex) * (bandCount+1) ) + (band -1); vals[outIndex] += (*(data + sampledIndex)); vals[outIndex] += 118.450588 + ((*(data + sampledIndex))/128); if (vals[outIndex]/valsPerIndex[outIndex] < 0) { vals[outIndex] =0; }else if (vals[outIndex]/valsPerIndex[outIndex] > 255){ vals[outIndex] = 255; } } } } } } else { unsigned char* data = (unsigned char *) CPLMalloc(sizeof(char) * (*xBlockSize)*(*yBlockSize)); int band; for (band = 1; band <= bandCount; band++) { hBand = GDALGetRasterBand( hDataset, band ); int yBlock, xBlock; outputYOffset = 0; for(yBlock = yLow; yBlock < yHigh; yBlock++){ outputYOffset = ((yBlock - yLow) * yOutputSize * xOutputSize * usedXBlocks * (bandCount + 1)); outputXOffset = 0; for(xBlock = xLow; xBlock < xHigh; xBlock++){ outputXOffset = ((xBlock - xLow) * xOutputSize * (bandCount + 1)); if(GDALReadBlock(hBand,xBlock,yBlock, data) != CE_None) { fprintf(stderr, "Read block failed\n"); exit(EXIT_FAILURE); } for(i = 0 ; i < ((*xBlockSize)*(*yBlockSize)) ; i += rseed){ rseed = (214013 * rseed + 2531011); rseed %= maxStride; sampledIndex = i; i = (maxStride ==1) ? (i+1) : i; rowIndex = (sampledIndex/(xOutputSize*scale* scale)) + ((yBlock - yLow)* yOutputSize); colIndex = ((sampledIndex % (xOutputSize * scale))/scale) + ((xBlock - xLow) * xOutputSize); outIndex = ((rowIndex * (xOutputSize * usedXBlocks ) + colIndex) * (bandCount+1) ) + (band -1); vals[outIndex] += (*(data + sampledIndex)); valsPerIndex[outIndex] +=1; } outputIndexOffset = (outputYOffset + outputXOffset); int j; for (j = 0; j<yOutputSize; j++){ i = outputIndexOffset; int k = (i + (xOutputSize * (bandCount+1))); for (i = 0; i<k;i++){ int x = (i+(j*(xOutputSize * (bandCount + 1) * (usedXBlocks)))); if(((x+1)%4==0&&bandCount==3)||((x+1)%2==0&&bandCount==1)){ output[x] = (unsigned char) 1; //Sets the alpha to opaque }else{ output[x] = (unsigned char) (vals[x]/valsPerIndex[x]); //calculate final output by averaging each color value } } } out->Data = output; } } } } printf("sampling complete\n"); GDALClose(hDataset); }
int main( int argc, char ** argv ) { GDALDatasetH hSrcDS; int iY, iX, nOutLevel=0, nXSize, nYSize, iArg, nFillDist=0; void *pStream; GInt16 *panData; const char *pszFilename = NULL; GDALRasterBandH hSrcBand; double adfGeoTransform[6]; int bEnableTrim = FALSE; GInt16 noDataValue = 0; int bHasNoData; /* -------------------------------------------------------------------- */ /* Identify arguments. */ /* -------------------------------------------------------------------- */ for( iArg = 1; iArg < argc; iArg++ ) { if( EQUAL(argv[iArg],"-trim") ) bEnableTrim = TRUE; else if( EQUAL(argv[iArg],"-fill") ) nFillDist = atoi(argv[++iArg]); else if( EQUAL(argv[iArg],"-level") ) nOutLevel = atoi(argv[++iArg]); else { if( pszFilename != NULL ) Usage(); pszFilename = argv[iArg]; } } if( pszFilename == NULL ) Usage(); /* -------------------------------------------------------------------- */ /* Open input file. */ /* -------------------------------------------------------------------- */ GDALAllRegister(); hSrcDS = GDALOpen( pszFilename, GA_ReadOnly ); if( hSrcDS == NULL ) exit(1); hSrcBand = GDALGetRasterBand( hSrcDS, 1 ); noDataValue = (GInt16)GDALGetRasterNoDataValue(hSrcBand, &bHasNoData); nXSize = GDALGetRasterXSize( hSrcDS ); nYSize = GDALGetRasterYSize( hSrcDS ); GDALGetGeoTransform( hSrcDS, adfGeoTransform ); /* -------------------------------------------------------------------- */ /* Create output stream. */ /* -------------------------------------------------------------------- */ pStream = DTEDCreatePtStream( ".", nOutLevel ); if( pStream == NULL ) exit( 1 ); /* -------------------------------------------------------------------- */ /* Process all the profiles. */ /* -------------------------------------------------------------------- */ panData = (GInt16 *) malloc(sizeof(GInt16) * nXSize); for( iY = 0; iY < nYSize; iY++ ) { GDALRasterIO( hSrcBand, GF_Read, 0, iY, nXSize, 1, panData, nXSize, 1, GDT_Int16, 0, 0 ); if (bHasNoData) { for( iX = 0; iX < nXSize; iX++ ) { if (panData[iX] == noDataValue) panData[iX] = DTED_NODATA_VALUE; } } for( iX = 0; iX < nXSize; iX++ ) { DTEDWritePt( pStream, adfGeoTransform[0] + adfGeoTransform[1] * (iX + 0.5) + adfGeoTransform[2] * (iY + 0.5), adfGeoTransform[3] + adfGeoTransform[4] * (iX + 0.5) + adfGeoTransform[5] * (iY + 0.5), panData[iX] ); } } free( panData ); /* -------------------------------------------------------------------- */ /* Cleanup. */ /* -------------------------------------------------------------------- */ if( bEnableTrim ) DTEDPtStreamTrimEdgeOnlyTiles( pStream ); if( nFillDist > 0 ) DTEDFillPtStream( pStream, nFillDist ); DTEDClosePtStream( pStream ); GDALClose( hSrcDS ); exit( 0 ); }
void *GDALCreateGeoLocTransformer( GDALDatasetH hBaseDS, char **papszGeolocationInfo, int bReversed ) { GDALGeoLocTransformInfo *psTransform; if( CSLFetchNameValue(papszGeolocationInfo,"PIXEL_OFFSET") == NULL || CSLFetchNameValue(papszGeolocationInfo,"LINE_OFFSET") == NULL || CSLFetchNameValue(papszGeolocationInfo,"PIXEL_STEP") == NULL || CSLFetchNameValue(papszGeolocationInfo,"LINE_STEP") == NULL || CSLFetchNameValue(papszGeolocationInfo,"X_BAND") == NULL || CSLFetchNameValue(papszGeolocationInfo,"Y_BAND") == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Missing some geolocation fields in GDALCreateGeoLocTransformer()" ); return NULL; } /* -------------------------------------------------------------------- */ /* Initialize core info. */ /* -------------------------------------------------------------------- */ psTransform = (GDALGeoLocTransformInfo *) CPLCalloc(sizeof(GDALGeoLocTransformInfo),1); psTransform->bReversed = bReversed; memcpy( psTransform->sTI.abySignature, GDAL_GTI2_SIGNATURE, strlen(GDAL_GTI2_SIGNATURE) ); psTransform->sTI.pszClassName = "GDALGeoLocTransformer"; psTransform->sTI.pfnTransform = GDALGeoLocTransform; psTransform->sTI.pfnCleanup = GDALDestroyGeoLocTransformer; psTransform->sTI.pfnSerialize = GDALSerializeGeoLocTransformer; psTransform->sTI.pfnCreateSimilar = GDALCreateSimilarGeoLocTransformer; psTransform->papszGeolocationInfo = CSLDuplicate( papszGeolocationInfo ); /* -------------------------------------------------------------------- */ /* Pull geolocation info from the options/metadata. */ /* -------------------------------------------------------------------- */ psTransform->dfPIXEL_OFFSET = CPLAtof(CSLFetchNameValue( papszGeolocationInfo, "PIXEL_OFFSET" )); psTransform->dfLINE_OFFSET = CPLAtof(CSLFetchNameValue( papszGeolocationInfo, "LINE_OFFSET" )); psTransform->dfPIXEL_STEP = CPLAtof(CSLFetchNameValue( papszGeolocationInfo, "PIXEL_STEP" )); psTransform->dfLINE_STEP = CPLAtof(CSLFetchNameValue( papszGeolocationInfo, "LINE_STEP" )); /* -------------------------------------------------------------------- */ /* Establish access to geolocation dataset(s). */ /* -------------------------------------------------------------------- */ const char *pszDSName = CSLFetchNameValue( papszGeolocationInfo, "X_DATASET" ); if( pszDSName != NULL ) { psTransform->hDS_X = GDALOpenShared( pszDSName, GA_ReadOnly ); } else { psTransform->hDS_X = hBaseDS; GDALReferenceDataset( psTransform->hDS_X ); psTransform->papszGeolocationInfo = CSLSetNameValue( psTransform->papszGeolocationInfo, "X_DATASET", GDALGetDescription( hBaseDS ) ); } pszDSName = CSLFetchNameValue( papszGeolocationInfo, "Y_DATASET" ); if( pszDSName != NULL ) { psTransform->hDS_Y = GDALOpenShared( pszDSName, GA_ReadOnly ); } else { psTransform->hDS_Y = hBaseDS; GDALReferenceDataset( psTransform->hDS_Y ); psTransform->papszGeolocationInfo = CSLSetNameValue( psTransform->papszGeolocationInfo, "Y_DATASET", GDALGetDescription( hBaseDS ) ); } if (psTransform->hDS_X == NULL || psTransform->hDS_Y == NULL) { GDALDestroyGeoLocTransformer( psTransform ); return NULL; } /* -------------------------------------------------------------------- */ /* Get the band handles. */ /* -------------------------------------------------------------------- */ int nBand; nBand = MAX(1,atoi(CSLFetchNameValue( papszGeolocationInfo, "X_BAND" ))); psTransform->hBand_X = GDALGetRasterBand( psTransform->hDS_X, nBand ); nBand = MAX(1,atoi(CSLFetchNameValue( papszGeolocationInfo, "Y_BAND" ))); psTransform->hBand_Y = GDALGetRasterBand( psTransform->hDS_Y, nBand ); if (psTransform->hBand_X == NULL || psTransform->hBand_Y == NULL) { GDALDestroyGeoLocTransformer( psTransform ); return NULL; } /* -------------------------------------------------------------------- */ /* Check that X and Y bands have the same dimensions */ /* -------------------------------------------------------------------- */ int nXSize_XBand = GDALGetRasterXSize( psTransform->hDS_X ); int nYSize_XBand = GDALGetRasterYSize( psTransform->hDS_X ); int nXSize_YBand = GDALGetRasterXSize( psTransform->hDS_Y ); int nYSize_YBand = GDALGetRasterYSize( psTransform->hDS_Y ); if (nYSize_XBand == 1 || nYSize_YBand == 1) { if (nYSize_XBand != 1 || nYSize_YBand != 1) { CPLError(CE_Failure, CPLE_AppDefined, "X_BAND and Y_BAND should have both nYSize == 1"); GDALDestroyGeoLocTransformer( psTransform ); return NULL; } } else if (nXSize_XBand != nXSize_YBand || nYSize_XBand != nYSize_YBand ) { CPLError(CE_Failure, CPLE_AppDefined, "X_BAND and Y_BAND do not have the same dimensions"); GDALDestroyGeoLocTransformer( psTransform ); return NULL; } if (nXSize_XBand > INT_MAX / nYSize_XBand) { CPLError(CE_Failure, CPLE_AppDefined, "Int overflow : %d x %d", nXSize_XBand, nYSize_XBand); GDALDestroyGeoLocTransformer( psTransform ); return NULL; } /* -------------------------------------------------------------------- */ /* Load the geolocation array. */ /* -------------------------------------------------------------------- */ if( !GeoLocLoadFullData( psTransform ) || !GeoLocGenerateBackMap( psTransform ) ) { GDALDestroyGeoLocTransformer( psTransform ); return NULL; } return psTransform; }
static int GeoLocLoadFullData( GDALGeoLocTransformInfo *psTransform ) { int nXSize, nYSize; int nXSize_XBand = GDALGetRasterXSize( psTransform->hDS_X ); int nYSize_XBand = GDALGetRasterYSize( psTransform->hDS_X ); int nXSize_YBand = GDALGetRasterXSize( psTransform->hDS_Y ); int nYSize_YBand = GDALGetRasterYSize( psTransform->hDS_Y ); if (nYSize_XBand == 1 && nYSize_YBand == 1) { nXSize = nXSize_XBand; nYSize = nXSize_YBand; } else { nXSize = nXSize_XBand; nYSize = nYSize_XBand; } psTransform->nGeoLocXSize = nXSize; psTransform->nGeoLocYSize = nYSize; psTransform->padfGeoLocY = (double *) VSIMalloc3(sizeof(double), nXSize, nYSize); psTransform->padfGeoLocX = (double *) VSIMalloc3(sizeof(double), nXSize, nYSize); if( psTransform->padfGeoLocX == NULL || psTransform->padfGeoLocY == NULL ) { CPLError(CE_Failure, CPLE_OutOfMemory, "GeoLocLoadFullData : Out of memory"); return FALSE; } if (nYSize_XBand == 1 && nYSize_YBand == 1) { /* Case of regular grid */ /* The XBAND contains the x coordinates for all lines */ /* The YBAND contains the y coordinates for all columns */ double* padfTempX = (double*)VSIMalloc2(nXSize, sizeof(double)); double* padfTempY = (double*)VSIMalloc2(nYSize, sizeof(double)); if (padfTempX == NULL || padfTempY == NULL) { CPLFree(padfTempX); CPLFree(padfTempY); CPLError(CE_Failure, CPLE_OutOfMemory, "GeoLocLoadFullData : Out of memory"); return FALSE; } CPLErr eErr = CE_None; eErr = GDALRasterIO( psTransform->hBand_X, GF_Read, 0, 0, nXSize, 1, padfTempX, nXSize, 1, GDT_Float64, 0, 0 ); int i,j; for(j=0;j<nYSize;j++) { memcpy( psTransform->padfGeoLocX + j * nXSize, padfTempX, nXSize * sizeof(double) ); } if (eErr == CE_None) { eErr = GDALRasterIO( psTransform->hBand_Y, GF_Read, 0, 0, nYSize, 1, padfTempY, nYSize, 1, GDT_Float64, 0, 0 ); for(j=0;j<nYSize;j++) { for(i=0;i<nXSize;i++) { psTransform->padfGeoLocY[j * nXSize + i] = padfTempY[j]; } } } CPLFree(padfTempX); CPLFree(padfTempY); if (eErr != CE_None) return FALSE; } else { if( GDALRasterIO( psTransform->hBand_X, GF_Read, 0, 0, nXSize, nYSize, psTransform->padfGeoLocX, nXSize, nYSize, GDT_Float64, 0, 0 ) != CE_None || GDALRasterIO( psTransform->hBand_Y, GF_Read, 0, 0, nXSize, nYSize, psTransform->padfGeoLocY, nXSize, nYSize, GDT_Float64, 0, 0 ) != CE_None ) return FALSE; } psTransform->dfNoDataX = GDALGetRasterNoDataValue( psTransform->hBand_X, &(psTransform->bHasNoData) ); return TRUE; }
int main(int argc, char *argv[]) { GDALDatasetH hDataset = NULL; OGRDataSourceH hDS = NULL; OGRSFDriverH *pahDriver = NULL; OGRLayerH hLR = NULL; OGREnvelope hEnv; double adfGeoTransform[6]; int columns, lines; double minx, miny, maxx, maxy, x, y, z; register int i; FILE *fin=NULL; if(argc != 2) { printf("Usage: geo_extents <input file>\n"); return 1; } GDALAllRegister(); OGRRegisterAll(); char *egsa = "PROJCS[\"GGRS87 / Greek Grid\",GEOGCS[\"GGRS87\",DATUM[\"Greek_Geodetic_Reference_System_1987\",SPHEROID[\"GRS 1980\",6378137,298.257222101,AUTHORITY[\"EPSG\",\"7019\"]],TOWGS84[-199.87,74.79,246.62,0,0,0,0],AUTHORITY[\"EPSG\",\"6121\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.01745329251994328,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY[\"EPSG\",\"4121\"]],UNIT[\"metre\",1,AUTHORITY[\"EPSG\",\"9001\"]],PROJECTION[\"Transverse_Mercator\"],PARAMETER[\"latitude_of_origin\",0],PARAMETER[\"central_meridian\",24],PARAMETER[\"scale_factor\",0.9996],PARAMETER[\"false_easting\",500000],PARAMETER[\"false_northing\",0],AUTHORITY[\"EPSG\",\"2100\"],AXIS[\"Easting\",EAST],AXIS[\"Northing\",NORTH]]"; char *wgs = "GEOGCS[\"WGS 84\",DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,298.257223563,AUTHORITY[\"EPSG\",\"7030\"]],AUTHORITY[\"EPSG\",\"6326\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.01745329251994328,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY[\"EPSG\",\"4326\"]]"; OGRSpatialReferenceH oSourceSRS; OGRSpatialReferenceH oTargetSRS; oSourceSRS = OSRNewSpatialReference(NULL); oTargetSRS = OSRNewSpatialReference(NULL); OSRImportFromWkt(oSourceSRS, &egsa); OSRImportFromWkt(oTargetSRS, &wgs); OGRCoordinateTransformationH poCT; poCT = OCTNewCoordinateTransformation(oSourceSRS, oTargetSRS); hDataset = GDALOpen(argv[1], GA_ReadOnly); if(hDataset != NULL)//It is raster { columns = GDALGetRasterXSize(hDataset); lines = GDALGetRasterYSize(hDataset); if(GDALGetGeoTransform(hDataset, adfGeoTransform) == CE_None) { minx = (adfGeoTransform[0] - (adfGeoTransform[1] / 2)); maxy = (adfGeoTransform[3] - (adfGeoTransform[5] / 2)); miny = (maxy + ((lines + 1) * adfGeoTransform[5])); maxx = (minx + (adfGeoTransform[1] * (columns + 1))); OCTTransform(poCT, 1, &minx, &miny, 0); OCTTransform(poCT, 1, &maxx, &maxy, 0); printf("BoundingBox: %f %f %f %f\n",minx ,miny, maxx, maxy); GDALClose (hDataset); } else { printf("Failure: No Georeference info found for this raster file\n"); return 0; } } else//Try if it is vector { hDS = OGROpen( argv[1], FALSE , pahDriver ); if( hDS == NULL )//Not vector { //Parse for DTM file fin=fopen(argv[1],"r"); fseek(fin,0L,SEEK_SET); minx=50000000.0; miny=50000000.0; maxx=0.0; maxy=0.0; while(!feof(fin)) { fscanf(fin,"%lf,%lf,%lf\n",&x,&y,&z); if(ferror(fin))//input error { printf("Failure: Unsupported file type\n"); return 0; } if(x>maxx) maxx=x; if(y>maxy) maxy=y; if(x<minx) minx=x; if(y<miny) miny=y; } if(minx==50000000.0 || miny==50000000.0) { printf("Failure: Unsupported file type\n"); return 0; } if(maxx==0 || maxy==0) { printf("Failure: Unsupported file type\n"); return 0; } if(minx==maxx) { minx-=1; maxx+=1; } if(miny==maxy) { miny-=1; maxy+=1; } //DTM file OCTTransform(poCT, 1, &minx, &miny, 0); OCTTransform(poCT, 1, &maxx, &maxy, 0); printf("BoundingBox: %f %f %f %f\n",minx ,miny, maxx, maxy); return 0; } //It is vector for(i=0; i< OGR_DS_GetLayerCount (hDS); i++) { hLR = OGR_DS_GetLayer(hDS, i); if(OGR_L_GetExtent (hLR, &hEnv, FALSE) == OGRERR_NONE) { minx = hEnv.MinX; miny = hEnv.MinY; maxx = hEnv.MaxX; maxy = hEnv.MaxY; OCTTransform(poCT, 1, &minx, &miny, 0); OCTTransform(poCT, 1, &maxx, &maxy, 0); printf("BoundingBox: %f %f %f %f\n",minx ,miny, maxx, maxy); } } OGRReleaseDataSource( hDS ); } return 0; }
GDALDataset * RasterliteCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, CPL_UNUSED int bStrict, CPL_UNUSED char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { int nBands = poSrcDS->GetRasterCount(); if (nBands == 0) { CPLError(CE_Failure, CPLE_NotSupported, "nBands == 0"); return NULL; } const char* pszDriverName = CSLFetchNameValueDef(papszOptions, "DRIVER", "GTiff"); if (EQUAL(pszDriverName, "MEM") || EQUAL(pszDriverName, "VRT")) { CPLError(CE_Failure, CPLE_AppDefined, "GDAL %s driver cannot be used as underlying driver", pszDriverName); return NULL; } GDALDriverH hTileDriver = GDALGetDriverByName(pszDriverName); if ( hTileDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL %s driver", pszDriverName); return NULL; } GDALDriverH hMemDriver = GDALGetDriverByName("MEM"); if (hMemDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL MEM driver"); return NULL; } int nXSize = GDALGetRasterXSize(poSrcDS); int nYSize = GDALGetRasterYSize(poSrcDS); double adfGeoTransform[6]; if (poSrcDS->GetGeoTransform(adfGeoTransform) != CE_None) { adfGeoTransform[0] = 0; adfGeoTransform[1] = 1; adfGeoTransform[2] = 0; adfGeoTransform[3] = 0; adfGeoTransform[4] = 0; adfGeoTransform[5] = -1; } else if (adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot use geotransform with rotational terms"); return NULL; } int bTiled = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "TILED", "YES")); int nBlockXSize, nBlockYSize; if (bTiled) { nBlockXSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKXSIZE", "256")); nBlockYSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKYSIZE", "256")); if (nBlockXSize < 64) nBlockXSize = 64; else if (nBlockXSize > 4096) nBlockXSize = 4096; if (nBlockYSize < 64) nBlockYSize = 64; else if (nBlockYSize > 4096) nBlockYSize = 4096; } else { nBlockXSize = nXSize; nBlockYSize = nYSize; } /* -------------------------------------------------------------------- */ /* Analyze arguments */ /* -------------------------------------------------------------------- */ CPLString osDBName; CPLString osTableName; VSIStatBuf sBuf; int bExists; /* Skip optionnal RASTERLITE: prefix */ const char* pszFilenameWithoutPrefix = pszFilename; if (EQUALN(pszFilename, "RASTERLITE:", 11)) pszFilenameWithoutPrefix += 11; char** papszTokens = CSLTokenizeStringComplex( pszFilenameWithoutPrefix, ", ", FALSE, FALSE ); int nTokens = CSLCount(papszTokens); if (nTokens == 0) { osDBName = pszFilenameWithoutPrefix; osTableName = CPLGetBasename(pszFilenameWithoutPrefix); } else { osDBName = papszTokens[0]; int i; for(i=1;i<nTokens;i++) { if (EQUALN(papszTokens[i], "table=", 6)) osTableName = papszTokens[i] + 6; else { CPLError(CE_Warning, CPLE_AppDefined, "Invalid option : %s", papszTokens[i]); } } } CSLDestroy(papszTokens); papszTokens = NULL; bExists = (VSIStat(osDBName.c_str(), &sBuf) == 0); if (osTableName.size() == 0) { if (bExists) { CPLError(CE_Failure, CPLE_AppDefined, "Database already exists. Explicit table name must be specified"); return NULL; } osTableName = CPLGetBasename(osDBName.c_str()); } CPLString osRasterLayer; osRasterLayer.Printf("%s_rasters", osTableName.c_str()); CPLString osMetatadataLayer; osMetatadataLayer.Printf("%s_metadata", osTableName.c_str()); /* -------------------------------------------------------------------- */ /* Create or open the SQLite DB */ /* -------------------------------------------------------------------- */ if (OGRGetDriverCount() == 0) OGRRegisterAll(); OGRSFDriverH hSQLiteDriver = OGRGetDriverByName("SQLite"); if (hSQLiteDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load OGR SQLite driver"); return NULL; } OGRDataSourceH hDS; if (!bExists) { char** papszOGROptions = CSLAddString(NULL, "SPATIALITE=YES"); hDS = OGR_Dr_CreateDataSource(hSQLiteDriver, osDBName.c_str(), papszOGROptions); CSLDestroy(papszOGROptions); } else { hDS = OGROpen(osDBName.c_str(), TRUE, NULL); } if (hDS == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load or create SQLite database"); return NULL; } CPLString osSQL; /* -------------------------------------------------------------------- */ /* Get the SRID for the SRS */ /* -------------------------------------------------------------------- */ int nSRSId = RasterliteInsertSRID(hDS, poSrcDS->GetProjectionRef()); /* -------------------------------------------------------------------- */ /* Create or wipe existing tables */ /* -------------------------------------------------------------------- */ int bWipeExistingData = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "WIPE", "NO")); hDS = RasterliteCreateTables(hDS, osTableName.c_str(), nSRSId, bWipeExistingData); if (hDS == NULL) return NULL; OGRLayerH hRasterLayer = OGR_DS_GetLayerByName(hDS, osRasterLayer.c_str()); OGRLayerH hMetadataLayer = OGR_DS_GetLayerByName(hDS, osMetatadataLayer.c_str()); if (hRasterLayer == NULL || hMetadataLayer == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot find metadata and/or raster tables"); OGRReleaseDataSource(hDS); return NULL; } /* -------------------------------------------------------------------- */ /* Check if there is overlapping data and warn the user */ /* -------------------------------------------------------------------- */ double minx = adfGeoTransform[0]; double maxx = adfGeoTransform[0] + nXSize * adfGeoTransform[1]; double maxy = adfGeoTransform[3]; double miny = adfGeoTransform[3] + nYSize * adfGeoTransform[5]; osSQL.Printf("SELECT COUNT(geometry) FROM \"%s\" " "WHERE rowid IN " "(SELECT pkid FROM \"idx_%s_metadata_geometry\" " "WHERE xmin < %.15f AND xmax > %.15f " "AND ymin < %.15f AND ymax > %.15f) " "AND pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND " "pixel_y_size >= %.15f AND pixel_y_size <= %.15f", osMetatadataLayer.c_str(), osTableName.c_str(), maxx, minx, maxy, miny, adfGeoTransform[1] - 1e-15, adfGeoTransform[1] + 1e-15, - adfGeoTransform[5] - 1e-15, - adfGeoTransform[5] + 1e-15); int nOverlappingGeoms = 0; OGRLayerH hCountLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); if (hCountLyr) { OGRFeatureH hFeat = OGR_L_GetNextFeature(hCountLyr); if (hFeat) { nOverlappingGeoms = OGR_F_GetFieldAsInteger(hFeat, 0); OGR_F_Destroy(hFeat); } OGR_DS_ReleaseResultSet(hDS, hCountLyr); } if (nOverlappingGeoms != 0) { CPLError(CE_Warning, CPLE_AppDefined, "Raster tiles already exist in the %s table within " "the extent of the data to be inserted in", osTableName.c_str()); } /* -------------------------------------------------------------------- */ /* Iterate over blocks to add data into raster and metadata tables */ /* -------------------------------------------------------------------- */ int nXBlocks = (nXSize + nBlockXSize - 1) / nBlockXSize; int nYBlocks = (nYSize + nBlockYSize - 1) / nBlockYSize; GDALDataType eDataType = poSrcDS->GetRasterBand(1)->GetRasterDataType(); int nDataTypeSize = GDALGetDataTypeSize(eDataType) / 8; GByte* pabyMEMDSBuffer = (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands * nDataTypeSize); if (pabyMEMDSBuffer == NULL) { OGRReleaseDataSource(hDS); return NULL; } CPLString osTempFileName; osTempFileName.Printf("/vsimem/%p", hDS); int nTileId = 0; int nBlocks = 0; int nTotalBlocks = nXBlocks * nYBlocks; char** papszTileDriverOptions = RasterliteGetTileDriverOptions(papszOptions); OGR_DS_ExecuteSQL(hDS, "BEGIN", NULL, NULL); CPLErr eErr = CE_None; int nBlockXOff, nBlockYOff; for(nBlockYOff=0;eErr == CE_None && nBlockYOff<nYBlocks;nBlockYOff++) { for(nBlockXOff=0;eErr == CE_None && nBlockXOff<nXBlocks;nBlockXOff++) { /* -------------------------------------------------------------------- */ /* Create in-memory tile */ /* -------------------------------------------------------------------- */ int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize; if ((nBlockXOff+1) * nBlockXSize > nXSize) nReqXSize = nXSize - nBlockXOff * nBlockXSize; if ((nBlockYOff+1) * nBlockYSize > nYSize) nReqYSize = nYSize - nBlockYOff * nBlockYSize; eErr = poSrcDS->RasterIO(GF_Read, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize, nReqXSize, nReqYSize, pabyMEMDSBuffer, nReqXSize, nReqYSize, eDataType, nBands, NULL, 0, 0, 0); if (eErr != CE_None) { break; } GDALDatasetH hMemDS = GDALCreate(hMemDriver, "MEM:::", nReqXSize, nReqYSize, 0, eDataType, NULL); if (hMemDS == NULL) { eErr = CE_Failure; break; } int iBand; for(iBand = 0; iBand < nBands; iBand ++) { char** papszMEMDSOptions = NULL; char szTmp[64]; memset(szTmp, 0, sizeof(szTmp)); CPLPrintPointer(szTmp, pabyMEMDSBuffer + iBand * nDataTypeSize * nReqXSize * nReqYSize, sizeof(szTmp)); papszMEMDSOptions = CSLSetNameValue(papszMEMDSOptions, "DATAPOINTER", szTmp); GDALAddBand(hMemDS, eDataType, papszMEMDSOptions); CSLDestroy(papszMEMDSOptions); } GDALDatasetH hOutDS = GDALCreateCopy(hTileDriver, osTempFileName.c_str(), hMemDS, FALSE, papszTileDriverOptions, NULL, NULL); GDALClose(hMemDS); if (hOutDS) GDALClose(hOutDS); else { eErr = CE_Failure; break; } /* -------------------------------------------------------------------- */ /* Insert new entry into raster table */ /* -------------------------------------------------------------------- */ vsi_l_offset nDataLength = 0; GByte *pabyData = VSIGetMemFileBuffer( osTempFileName.c_str(), &nDataLength, FALSE); OGRFeatureH hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hRasterLayer) ); OGR_F_SetFieldBinary(hFeat, 0, (int)nDataLength, pabyData); OGR_L_CreateFeature(hRasterLayer, hFeat); /* Query raster ID to set it as the ID of the associated metadata */ int nRasterID = (int)OGR_F_GetFID(hFeat); OGR_F_Destroy(hFeat); VSIUnlink(osTempFileName.c_str()); /* -------------------------------------------------------------------- */ /* Insert new entry into metadata table */ /* -------------------------------------------------------------------- */ hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hMetadataLayer) ); OGR_F_SetFID(hFeat, nRasterID); OGR_F_SetFieldString(hFeat, 0, GDALGetDescription(poSrcDS)); OGR_F_SetFieldInteger(hFeat, 1, nTileId ++); OGR_F_SetFieldInteger(hFeat, 2, nReqXSize); OGR_F_SetFieldInteger(hFeat, 3, nReqYSize); OGR_F_SetFieldDouble(hFeat, 4, adfGeoTransform[1]); OGR_F_SetFieldDouble(hFeat, 5, -adfGeoTransform[5]); minx = adfGeoTransform[0] + (nBlockXSize * nBlockXOff) * adfGeoTransform[1]; maxx = adfGeoTransform[0] + (nBlockXSize * nBlockXOff + nReqXSize) * adfGeoTransform[1]; maxy = adfGeoTransform[3] + (nBlockYSize * nBlockYOff) * adfGeoTransform[5]; miny = adfGeoTransform[3] + (nBlockYSize * nBlockYOff + nReqYSize) * adfGeoTransform[5]; OGRGeometryH hRectangle = OGR_G_CreateGeometry(wkbPolygon); OGRGeometryH hLinearRing = OGR_G_CreateGeometry(wkbLinearRing); OGR_G_AddPoint_2D(hLinearRing, minx, miny); OGR_G_AddPoint_2D(hLinearRing, minx, maxy); OGR_G_AddPoint_2D(hLinearRing, maxx, maxy); OGR_G_AddPoint_2D(hLinearRing, maxx, miny); OGR_G_AddPoint_2D(hLinearRing, minx, miny); OGR_G_AddGeometryDirectly(hRectangle, hLinearRing); OGR_F_SetGeometryDirectly(hFeat, hRectangle); OGR_L_CreateFeature(hMetadataLayer, hFeat); OGR_F_Destroy(hFeat); nBlocks++; if (pfnProgress && !pfnProgress(1.0 * nBlocks / nTotalBlocks, NULL, pProgressData)) eErr = CE_Failure; } } if (eErr == CE_None) OGR_DS_ExecuteSQL(hDS, "COMMIT", NULL, NULL); else OGR_DS_ExecuteSQL(hDS, "ROLLBACK", NULL, NULL); CSLDestroy(papszTileDriverOptions); VSIFree(pabyMEMDSBuffer); OGRReleaseDataSource(hDS); return (GDALDataset*) GDALOpen(pszFilename, GA_Update); }
int CPL_STDCALL GDALSimpleImageWarp( GDALDatasetH hSrcDS, GDALDatasetH hDstDS, int nBandCount, int *panBandList, GDALTransformerFunc pfnTransform, void *pTransformArg, GDALProgressFunc pfnProgress, void *pProgressArg, char **papszWarpOptions ) { VALIDATE_POINTER1( hSrcDS, "GDALSimpleImageWarp", 0 ); VALIDATE_POINTER1( hDstDS, "GDALSimpleImageWarp", 0 ); bool bError = false; /* -------------------------------------------------------------------- */ /* If no bands provided assume we should process all bands. */ /* -------------------------------------------------------------------- */ if( nBandCount == 0 ) { nBandCount = GDALGetRasterCount( hSrcDS ); if (nBandCount == 0) { CPLError(CE_Failure, CPLE_AppDefined, "No raster band in source dataset"); return FALSE; } panBandList = (int *) CPLCalloc(sizeof(int),nBandCount); for( int iBand = 0; iBand < nBandCount; iBand++ ) panBandList[iBand] = iBand+1; const int nResult = GDALSimpleImageWarp( hSrcDS, hDstDS, nBandCount, panBandList, pfnTransform, pTransformArg, pfnProgress, pProgressArg, papszWarpOptions ); CPLFree( panBandList ); return nResult; } /* -------------------------------------------------------------------- */ /* Post initial progress. */ /* -------------------------------------------------------------------- */ if( pfnProgress ) { if( !pfnProgress( 0.0, "", pProgressArg ) ) return FALSE; } /* -------------------------------------------------------------------- */ /* Load the source image band(s). */ /* -------------------------------------------------------------------- */ const int nSrcXSize = GDALGetRasterXSize(hSrcDS); const int nSrcYSize = GDALGetRasterYSize(hSrcDS); GByte **papabySrcData = static_cast<GByte **>( CPLCalloc(nBandCount, sizeof(GByte*)) ); bool ok = true; for( int iBand = 0; iBand < nBandCount; iBand++ ) { papabySrcData[iBand] = static_cast<GByte *>( VSI_MALLOC2_VERBOSE(nSrcXSize, nSrcYSize) ); if( papabySrcData[iBand] == NULL ) { CPLError( CE_Failure, CPLE_OutOfMemory, "GDALSimpleImageWarp out of memory.\n" ); ok = false; break; } if( GDALRasterIO( GDALGetRasterBand(hSrcDS,panBandList[iBand]), GF_Read, 0, 0, nSrcXSize, nSrcYSize, papabySrcData[iBand], nSrcXSize, nSrcYSize, GDT_Byte, 0, 0 ) != CE_None ) { CPLError( CE_Failure, CPLE_FileIO, "GDALSimpleImageWarp " "GDALRasterIO failure %s ", CPLGetLastErrorMsg() ); ok = false; break; } } if( !ok ) { for( int i=0; i <= nBandCount; i++ ) { VSIFree(papabySrcData[i]); } CPLFree(papabySrcData); return FALSE; } /* -------------------------------------------------------------------- */ /* Check for remap request(s). */ /* -------------------------------------------------------------------- */ GDALSimpleWarpRemapping( nBandCount, papabySrcData, nSrcXSize, nSrcYSize, papszWarpOptions ); /* -------------------------------------------------------------------- */ /* Allocate scanline buffers for output image. */ /* -------------------------------------------------------------------- */ const int nDstXSize = GDALGetRasterXSize( hDstDS ); const int nDstYSize = GDALGetRasterYSize( hDstDS ); GByte **papabyDstLine = static_cast<GByte **>( CPLCalloc(nBandCount, sizeof(GByte*)) ); for( int iBand = 0; iBand < nBandCount; iBand++ ) papabyDstLine[iBand] = static_cast<GByte *>(CPLMalloc( nDstXSize )); /* -------------------------------------------------------------------- */ /* Allocate x,y,z coordinate arrays for transformation ... one */ /* scanlines worth of positions. */ /* -------------------------------------------------------------------- */ double *padfX = static_cast<double *>( CPLMalloc(sizeof(double) * nDstXSize) ); double *padfY = static_cast<double *>( CPLMalloc(sizeof(double) * nDstXSize) ); double *padfZ = static_cast<double *>( CPLMalloc(sizeof(double) * nDstXSize) ); int *pabSuccess = static_cast<int *>( CPLMalloc(sizeof(int) * nDstXSize) ); /* -------------------------------------------------------------------- */ /* Establish the value we will use to initialize the bands. We */ /* default to -1 indicating the initial value should be read */ /* and preserved from the source file, but allow this to be */ /* overridden by passed */ /* option(s). */ /* -------------------------------------------------------------------- */ int * const panBandInit = static_cast<int *>( CPLCalloc(sizeof(int), nBandCount) ); if( CSLFetchNameValue( papszWarpOptions, "INIT" ) ) { char **papszTokens = CSLTokenizeStringComplex( CSLFetchNameValue( papszWarpOptions, "INIT" ), " ,", FALSE, FALSE ); const int nTokenCount = CSLCount(papszTokens); for( int iBand = 0; iBand < nBandCount; iBand++ ) { if( nTokenCount == 0 ) panBandInit[iBand] = 0; else panBandInit[iBand] = atoi(papszTokens[MIN(iBand,nTokenCount-1)]); } CSLDestroy(papszTokens); } /* -------------------------------------------------------------------- */ /* Loop over all the scanlines in the output image. */ /* -------------------------------------------------------------------- */ for( int iDstY = 0; iDstY < nDstYSize; iDstY++ ) { // Clear output buffer to "transparent" value. Should not we // really be reading from the destination file to support overlay? for( int iBand = 0; iBand < nBandCount; iBand++ ) { if( panBandInit[iBand] == -1 ) { if( GDALRasterIO( GDALGetRasterBand(hDstDS,iBand+1), GF_Read, 0, iDstY, nDstXSize, 1, papabyDstLine[iBand], nDstXSize, 1, GDT_Byte, 0, 0 ) != CE_None ) { bError = TRUE; break; } } else memset( papabyDstLine[iBand], panBandInit[iBand], nDstXSize ); } // Set point to transform. for( int iDstX = 0; iDstX < nDstXSize; iDstX++ ) { padfX[iDstX] = iDstX + 0.5; padfY[iDstX] = iDstY + 0.5; padfZ[iDstX] = 0.0; } // Transform the points from destination pixel/line coordinates // to source pixel/line coordinates. pfnTransform( pTransformArg, TRUE, nDstXSize, padfX, padfY, padfZ, pabSuccess ); // Loop over the output scanline. for( int iDstX = 0; iDstX < nDstXSize; iDstX++ ) { if( !pabSuccess[iDstX] ) continue; // We test against the value before casting to avoid the // problem of asymmetric truncation effects around zero. That is // -0.5 will be 0 when cast to an int. if( padfX[iDstX] < 0.0 || padfY[iDstX] < 0.0 ) continue; const int iSrcX = static_cast<int>( padfX[iDstX] ); const int iSrcY = static_cast<int>( padfY[iDstX] ); if( iSrcX >= nSrcXSize || iSrcY >= nSrcYSize ) continue; const int iSrcOffset = iSrcX + iSrcY * nSrcXSize; for( int iBand = 0; iBand < nBandCount; iBand++ ) papabyDstLine[iBand][iDstX] = papabySrcData[iBand][iSrcOffset]; } // Write scanline to disk. for( int iBand = 0; iBand < nBandCount; iBand++ ) { if( GDALRasterIO( GDALGetRasterBand(hDstDS,iBand+1), GF_Write, 0, iDstY, nDstXSize, 1, papabyDstLine[iBand], nDstXSize, 1, GDT_Byte, 0, 0 ) != CE_None ) { bError = TRUE; break; } } if( pfnProgress != NULL ) { if( !pfnProgress( (iDstY+1) / (double) nDstYSize, "", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); bError = TRUE; break; } } } /* -------------------------------------------------------------------- */ /* Cleanup working buffers. */ /* -------------------------------------------------------------------- */ for( int iBand = 0; iBand < nBandCount; iBand++ ) { CPLFree( papabyDstLine[iBand] ); CPLFree( papabySrcData[iBand] ); } CPLFree( panBandInit ); CPLFree( papabyDstLine ); CPLFree( papabySrcData ); CPLFree( padfX ); CPLFree( padfY ); CPLFree( padfZ ); CPLFree( pabSuccess ); return !bError; }
int QgsZonalStatistics::calculateStatistics( QProgressDialog* p ) { if ( !mPolygonLayer || mPolygonLayer->geometryType() != QgsWkbTypes::PolygonGeometry ) { return 1; } QgsVectorDataProvider* vectorProvider = mPolygonLayer->dataProvider(); if ( !vectorProvider ) { return 2; } //open the raster layer and the raster band GDALAllRegister(); GDALDatasetH inputDataset = GDALOpen( TO8F( mRasterFilePath ), GA_ReadOnly ); if ( !inputDataset ) { return 3; } if ( GDALGetRasterCount( inputDataset ) < ( mRasterBand - 1 ) ) { GDALClose( inputDataset ); return 4; } GDALRasterBandH rasterBand = GDALGetRasterBand( inputDataset, mRasterBand ); if ( !rasterBand ) { GDALClose( inputDataset ); return 5; } mInputNodataValue = GDALGetRasterNoDataValue( rasterBand, nullptr ); //get geometry info about raster layer int nCellsXGDAL = GDALGetRasterXSize( inputDataset ); int nCellsYGDAL = GDALGetRasterYSize( inputDataset ); double geoTransform[6]; if ( GDALGetGeoTransform( inputDataset, geoTransform ) != CE_None ) { GDALClose( inputDataset ); return 6; } double cellsizeX = geoTransform[1]; if ( cellsizeX < 0 ) { cellsizeX = -cellsizeX; } double cellsizeY = geoTransform[5]; if ( cellsizeY < 0 ) { cellsizeY = -cellsizeY; } QgsRectangle rasterBBox( geoTransform[0], geoTransform[3] - ( nCellsYGDAL * cellsizeY ), geoTransform[0] + ( nCellsXGDAL * cellsizeX ), geoTransform[3] ); //add the new fields to the provider QList<QgsField> newFieldList; QString countFieldName; if ( mStatistics & QgsZonalStatistics::Count ) { countFieldName = getUniqueFieldName( mAttributePrefix + "count" ); QgsField countField( countFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( countField ); } QString sumFieldName; if ( mStatistics & QgsZonalStatistics::Sum ) { sumFieldName = getUniqueFieldName( mAttributePrefix + "sum" ); QgsField sumField( sumFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( sumField ); } QString meanFieldName; if ( mStatistics & QgsZonalStatistics::Mean ) { meanFieldName = getUniqueFieldName( mAttributePrefix + "mean" ); QgsField meanField( meanFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( meanField ); } QString medianFieldName; if ( mStatistics & QgsZonalStatistics::Median ) { medianFieldName = getUniqueFieldName( mAttributePrefix + "median" ); QgsField medianField( medianFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( medianField ); } QString stdevFieldName; if ( mStatistics & QgsZonalStatistics::StDev ) { stdevFieldName = getUniqueFieldName( mAttributePrefix + "stdev" ); QgsField stdField( stdevFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( stdField ); } QString minFieldName; if ( mStatistics & QgsZonalStatistics::Min ) { minFieldName = getUniqueFieldName( mAttributePrefix + "min" ); QgsField minField( minFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( minField ); } QString maxFieldName; if ( mStatistics & QgsZonalStatistics::Max ) { maxFieldName = getUniqueFieldName( mAttributePrefix + "max" ); QgsField maxField( maxFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( maxField ); } QString rangeFieldName; if ( mStatistics & QgsZonalStatistics::Range ) { rangeFieldName = getUniqueFieldName( mAttributePrefix + "range" ); QgsField rangeField( rangeFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( rangeField ); } QString minorityFieldName; if ( mStatistics & QgsZonalStatistics::Minority ) { minorityFieldName = getUniqueFieldName( mAttributePrefix + "minority" ); QgsField minorityField( minorityFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( minorityField ); } QString majorityFieldName; if ( mStatistics & QgsZonalStatistics::Majority ) { majorityFieldName = getUniqueFieldName( mAttributePrefix + "majority" ); QgsField majField( majorityFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( majField ); } QString varietyFieldName; if ( mStatistics & QgsZonalStatistics::Variety ) { varietyFieldName = getUniqueFieldName( mAttributePrefix + "variety" ); QgsField varietyField( varietyFieldName, QVariant::Int, QStringLiteral( "int" ) ); newFieldList.push_back( varietyField ); } vectorProvider->addAttributes( newFieldList ); //index of the new fields int countIndex = mStatistics & QgsZonalStatistics::Count ? vectorProvider->fieldNameIndex( countFieldName ) : -1; int sumIndex = mStatistics & QgsZonalStatistics::Sum ? vectorProvider->fieldNameIndex( sumFieldName ) : -1; int meanIndex = mStatistics & QgsZonalStatistics::Mean ? vectorProvider->fieldNameIndex( meanFieldName ) : -1; int medianIndex = mStatistics & QgsZonalStatistics::Median ? vectorProvider->fieldNameIndex( medianFieldName ) : -1; int stdevIndex = mStatistics & QgsZonalStatistics::StDev ? vectorProvider->fieldNameIndex( stdevFieldName ) : -1; int minIndex = mStatistics & QgsZonalStatistics::Min ? vectorProvider->fieldNameIndex( minFieldName ) : -1; int maxIndex = mStatistics & QgsZonalStatistics::Max ? vectorProvider->fieldNameIndex( maxFieldName ) : -1; int rangeIndex = mStatistics & QgsZonalStatistics::Range ? vectorProvider->fieldNameIndex( rangeFieldName ) : -1; int minorityIndex = mStatistics & QgsZonalStatistics::Minority ? vectorProvider->fieldNameIndex( minorityFieldName ) : -1; int majorityIndex = mStatistics & QgsZonalStatistics::Majority ? vectorProvider->fieldNameIndex( majorityFieldName ) : -1; int varietyIndex = mStatistics & QgsZonalStatistics::Variety ? vectorProvider->fieldNameIndex( varietyFieldName ) : -1; if (( mStatistics & QgsZonalStatistics::Count && countIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Sum && sumIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Mean && meanIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Median && medianIndex == -1 ) || ( mStatistics & QgsZonalStatistics::StDev && stdevIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Min && minIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Max && maxIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Range && rangeIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Minority && minorityIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Majority && majorityIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Variety && varietyIndex == -1 ) ) { //failed to create a required field return 8; } //progress dialog long featureCount = vectorProvider->featureCount(); if ( p ) { p->setMaximum( featureCount ); } //iterate over each polygon QgsFeatureRequest request; request.setSubsetOfAttributes( QgsAttributeList() ); QgsFeatureIterator fi = vectorProvider->getFeatures( request ); QgsFeature f; bool statsStoreValues = ( mStatistics & QgsZonalStatistics::Median ) || ( mStatistics & QgsZonalStatistics::StDev ); bool statsStoreValueCount = ( mStatistics & QgsZonalStatistics::Minority ) || ( mStatistics & QgsZonalStatistics::Majority ); FeatureStats featureStats( statsStoreValues, statsStoreValueCount ); int featureCounter = 0; QgsChangedAttributesMap changeMap; while ( fi.nextFeature( f ) ) { if ( p ) { p->setValue( featureCounter ); } if ( p && p->wasCanceled() ) { break; } if ( !f.hasGeometry() ) { ++featureCounter; continue; } QgsGeometry featureGeometry = f.geometry(); QgsRectangle featureRect = featureGeometry.boundingBox().intersect( &rasterBBox ); if ( featureRect.isEmpty() ) { ++featureCounter; continue; } int offsetX, offsetY, nCellsX, nCellsY; if ( cellInfoForBBox( rasterBBox, featureRect, cellsizeX, cellsizeY, offsetX, offsetY, nCellsX, nCellsY ) != 0 ) { ++featureCounter; continue; } //avoid access to cells outside of the raster (may occur because of rounding) if (( offsetX + nCellsX ) > nCellsXGDAL ) { nCellsX = nCellsXGDAL - offsetX; } if (( offsetY + nCellsY ) > nCellsYGDAL ) { nCellsY = nCellsYGDAL - offsetY; } statisticsFromMiddlePointTest( rasterBand, featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY, rasterBBox, featureStats ); if ( featureStats.count <= 1 ) { //the cell resolution is probably larger than the polygon area. We switch to precise pixel - polygon intersection in this case statisticsFromPreciseIntersection( rasterBand, featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY, rasterBBox, featureStats ); } //write the statistics value to the vector data provider QgsAttributeMap changeAttributeMap; if ( mStatistics & QgsZonalStatistics::Count ) changeAttributeMap.insert( countIndex, QVariant( featureStats.count ) ); if ( mStatistics & QgsZonalStatistics::Sum ) changeAttributeMap.insert( sumIndex, QVariant( featureStats.sum ) ); if ( featureStats.count > 0 ) { double mean = featureStats.sum / featureStats.count; if ( mStatistics & QgsZonalStatistics::Mean ) changeAttributeMap.insert( meanIndex, QVariant( mean ) ); if ( mStatistics & QgsZonalStatistics::Median ) { qSort( featureStats.values.begin(), featureStats.values.end() ); int size = featureStats.values.count(); bool even = ( size % 2 ) < 1; double medianValue; if ( even ) { medianValue = ( featureStats.values.at( size / 2 - 1 ) + featureStats.values.at( size / 2 ) ) / 2; } else //odd { medianValue = featureStats.values.at(( size + 1 ) / 2 - 1 ); } changeAttributeMap.insert( medianIndex, QVariant( medianValue ) ); } if ( mStatistics & QgsZonalStatistics::StDev ) { double sumSquared = 0; for ( int i = 0; i < featureStats.values.count(); ++i ) { double diff = featureStats.values.at( i ) - mean; sumSquared += diff * diff; } double stdev = qPow( sumSquared / featureStats.values.count(), 0.5 ); changeAttributeMap.insert( stdevIndex, QVariant( stdev ) ); } if ( mStatistics & QgsZonalStatistics::Min ) changeAttributeMap.insert( minIndex, QVariant( featureStats.min ) ); if ( mStatistics & QgsZonalStatistics::Max ) changeAttributeMap.insert( maxIndex, QVariant( featureStats.max ) ); if ( mStatistics & QgsZonalStatistics::Range ) changeAttributeMap.insert( rangeIndex, QVariant( featureStats.max - featureStats.min ) ); if ( mStatistics & QgsZonalStatistics::Minority || mStatistics & QgsZonalStatistics::Majority ) { QList<int> vals = featureStats.valueCount.values(); qSort( vals.begin(), vals.end() ); if ( mStatistics & QgsZonalStatistics::Minority ) { float minorityKey = featureStats.valueCount.key( vals.first() ); changeAttributeMap.insert( minorityIndex, QVariant( minorityKey ) ); } if ( mStatistics & QgsZonalStatistics::Majority ) { float majKey = featureStats.valueCount.key( vals.last() ); changeAttributeMap.insert( majorityIndex, QVariant( majKey ) ); } } if ( mStatistics & QgsZonalStatistics::Variety ) changeAttributeMap.insert( varietyIndex, QVariant( featureStats.valueCount.count() ) ); } changeMap.insert( f.id(), changeAttributeMap ); ++featureCounter; } vectorProvider->changeAttributeValues( changeMap ); if ( p ) { p->setValue( featureCount ); } GDALClose( inputDataset ); mPolygonLayer->updateFields(); if ( p && p->wasCanceled() ) { return 9; } return 0; }
int main( int argc, char ** argv ) { GDALDatasetH hSrcDS, hDstDS; GDALDataset * poSrcDS, *poDstDS = NULL; int i; int nRasterXSize, nRasterYSize; const char *pszSource=NULL, *pszDest=NULL, *pszFormat = "GTiff"; GDALDriverH hDriver; int *panBandList = NULL, nBandCount = 0, bDefBands = TRUE; GDALDataType eOutputType = GDT_Unknown; int nOXSize = 0, nOYSize = 0; char **papszCreateOptions = NULL; char **papszAsyncOptions = NULL; int anSrcWin[4]; int bQuiet = FALSE; GDALProgressFunc pfnProgress = GDALTermProgress; int iSrcFileArg = -1, iDstFileArg = -1; int bMulti = FALSE; double dfTimeout = -1.0; const char *pszOXSize = NULL, *pszOYSize = NULL; anSrcWin[0] = 0; anSrcWin[1] = 0; anSrcWin[2] = 0; anSrcWin[3] = 0; /* Check strict compilation and runtime library version as we use C++ API */ if (! GDAL_CHECK_VERSION(argv[0])) exit(1); /* -------------------------------------------------------------------- */ /* 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],"-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 ) { if( atoi(argv[i+1]) < 1 ) { printf( "Unrecognizable band number (%s).\n", argv[i+1] ); Usage(); GDALDestroyDriverManager(); exit( 2 ); } nBandCount++; panBandList = (int *) CPLRealloc(panBandList, sizeof(int) * nBandCount); panBandList[nBandCount-1] = atoi(argv[++i]); if( panBandList[nBandCount-1] != nBandCount ) bDefBands = FALSE; } else if( EQUAL(argv[i],"-co") && i < argc-1 ) { papszCreateOptions = CSLAddString( papszCreateOptions, argv[++i] ); } else if( EQUAL(argv[i],"-ao") && i < argc-1 ) { papszAsyncOptions = CSLAddString( papszAsyncOptions, argv[++i] ); } else if( EQUAL(argv[i],"-to") && i < argc-1 ) { dfTimeout = atof(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],"-multi") ) { bMulti = 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 ); } /* -------------------------------------------------------------------- */ /* Attempt to open source file. */ /* -------------------------------------------------------------------- */ hSrcDS = GDALOpenShared( pszSource, GA_ReadOnly ); poSrcDS = (GDALDataset *) hSrcDS; if( hSrcDS == NULL ) { fprintf( stderr, "GDALOpen failed - %d\n%s\n", CPLGetLastErrorNo(), CPLGetLastErrorMsg() ); GDALDestroyDriverManager(); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Collect some information from the source file. */ /* -------------------------------------------------------------------- */ nRasterXSize = GDALGetRasterXSize( hSrcDS ); nRasterYSize = GDALGetRasterYSize( hSrcDS ); 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; } /* -------------------------------------------------------------------- */ /* Establish output size. */ /* -------------------------------------------------------------------- */ if( pszOXSize == NULL ) { nOXSize = anSrcWin[2]; nOYSize = anSrcWin[3]; } else { nOXSize = (int) ((pszOXSize[strlen(pszOXSize)-1]=='%' ? atof(pszOXSize)/100*anSrcWin[2] : atoi(pszOXSize))); nOYSize = (int) ((pszOYSize[strlen(pszOYSize)-1]=='%' ? atof(pszOYSize)/100*anSrcWin[3] : atoi(pszOYSize))); } /* -------------------------------------------------------------------- */ /* Build band list to translate */ /* -------------------------------------------------------------------- */ if( nBandCount == 0 ) { nBandCount = GDALGetRasterCount( hSrcDS ); 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( panBandList[i] < 1 || panBandList[i] > GDALGetRasterCount(hSrcDS) ) { fprintf( stderr, "Band %d requested, but only bands 1 to %d available.\n", panBandList[i], GDALGetRasterCount(hSrcDS) ); GDALDestroyDriverManager(); exit( 2 ); } } if( nBandCount != GDALGetRasterCount( hSrcDS ) ) bDefBands = FALSE; } /* -------------------------------------------------------------------- */ /* Verify source window. */ /* -------------------------------------------------------------------- */ if( anSrcWin[0] < 0 || anSrcWin[1] < 0 || anSrcWin[2] <= 0 || anSrcWin[3] <= 0 || anSrcWin[0] + anSrcWin[2] > GDALGetRasterXSize(hSrcDS) || anSrcWin[1] + anSrcWin[3] > GDALGetRasterYSize(hSrcDS) ) { 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(hSrcDS), GDALGetRasterYSize(hSrcDS) ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Find the output driver. */ /* -------------------------------------------------------------------- */ hDriver = GDALGetDriverByName( pszFormat ); if( hDriver == NULL ) { printf( "Output driver `%s' not recognised.\n", pszFormat ); } else if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) == NULL ) { printf( "Output driver '%s' does not support direct creation.\n", pszFormat ); hDriver = NULL; } if( hDriver == NULL ) { int iDr; 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 ) { printf( " %s: %s\n", GDALGetDriverShortName( hDriver ), GDALGetDriverLongName( hDriver ) ); } } printf( "\n" ); Usage(); GDALClose( hSrcDS ); CPLFree( panBandList ); GDALDestroyDriverManager(); CSLDestroy( argv ); CSLDestroy( papszCreateOptions ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Establish the pixel data type to use. */ /* -------------------------------------------------------------------- */ if( eOutputType == GDT_Unknown ) eOutputType = poSrcDS->GetRasterBand(1)->GetRasterDataType(); /* -------------------------------------------------------------------- */ /* Allocate one big buffer for the whole imagery area to */ /* transfer. */ /* -------------------------------------------------------------------- */ int nBytesPerPixel = nBandCount * (GDALGetDataTypeSize(eOutputType) / 8); void *pImage = VSIMalloc3( nOXSize, nOYSize, nBytesPerPixel ); if( pImage == NULL ) { printf( "Unable to allocate %dx%dx%d byte window buffer.\n", nOXSize, nOYSize, nBytesPerPixel ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Establish view window */ /* -------------------------------------------------------------------- */ GDALAsyncReader *poAsyncReq; int nPixelSpace = nBytesPerPixel; int nLineSpace = nBytesPerPixel * nOXSize; int nBandSpace = nBytesPerPixel / nBandCount; poAsyncReq = poSrcDS->BeginAsyncReader( anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], pImage, nOXSize, nOYSize, eOutputType, nBandCount, panBandList, nPixelSpace, nLineSpace, nBandSpace, papszAsyncOptions ); if( poAsyncReq == NULL ) exit( 1 ); /* -------------------------------------------------------------------- */ /* Process until done or an error. */ /* -------------------------------------------------------------------- */ GDALAsyncStatusType eAStatus; CPLErr eErr = CE_None; int iMultiCounter = 0; hDstDS = NULL; do { /* ==================================================================== */ /* Create the output file, and initialize if needed. */ /* ==================================================================== */ if( hDstDS == NULL ) { CPLString osOutFilename = pszDest; if( bMulti ) osOutFilename.Printf( "%s_%d", pszDest, iMultiCounter++ ); hDstDS = GDALCreate( hDriver, osOutFilename, nOXSize, nOYSize, nBandCount, eOutputType, papszCreateOptions ); if (hDstDS == NULL) { exit(1); } poDstDS = (GDALDataset *) hDstDS; /* -------------------------------------------------------------------- */ /* Copy georeferencing. */ /* -------------------------------------------------------------------- */ double adfGeoTransform[6]; if( poSrcDS->GetGeoTransform( adfGeoTransform ) == CE_None ) { 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; poDstDS->SetGeoTransform( adfGeoTransform ); } poDstDS->SetProjection( poSrcDS->GetProjectionRef() ); /* -------------------------------------------------------------------- */ /* Transfer generally applicable metadata. */ /* -------------------------------------------------------------------- */ poDstDS->SetMetadata( poSrcDS->GetMetadata() ); } /* ==================================================================== */ /* Fetch an update and write it to the output file. */ /* ==================================================================== */ int nUpXOff, nUpYOff, nUpXSize, nUpYSize; eAStatus = poAsyncReq->GetNextUpdatedRegion( dfTimeout, &nUpXOff, &nUpYOff, &nUpXSize, &nUpYSize ); if( eAStatus != GARIO_UPDATE && eAStatus != GARIO_COMPLETE ) continue; if( !bQuiet ) { printf( "Got %dx%d @ (%d,%d)\n", nUpXSize, nUpYSize, nUpXOff, nUpYOff ); } poAsyncReq->LockBuffer(); eErr = poDstDS->RasterIO( GF_Write, nUpXOff, nUpYOff, nUpXSize, nUpYSize, ((GByte *) pImage) + nUpXOff * nPixelSpace + nUpYOff * nLineSpace, nUpXSize, nUpYSize, eOutputType, nBandCount, NULL, nPixelSpace, nLineSpace, nBandSpace ); poAsyncReq->UnlockBuffer(); /* -------------------------------------------------------------------- */ /* In multi mode we will close this file and reopen another for */ /* the next request. */ /* -------------------------------------------------------------------- */ if( bMulti ) { GDALClose( hDstDS ); hDstDS = NULL; } else GDALFlushCache( hDstDS ); } while( eAStatus != GARIO_ERROR && eAStatus != GARIO_COMPLETE && eErr == CE_None ); poSrcDS->EndAsyncReader( poAsyncReq ); /* -------------------------------------------------------------------- */ /* Cleanup. */ /* -------------------------------------------------------------------- */ VSIFree( pImage ); if( hDstDS ) GDALClose( hDstDS ); GDALClose( hSrcDS ); CPLFree( panBandList ); CSLDestroy( argv ); CSLDestroy( papszCreateOptions ); CSLDestroy( papszAsyncOptions ); GDALDumpOpenDatasets( stderr ); GDALDestroyDriverManager(); }