SEXP RGDAL_GetMetadata(SEXP sDataset, SEXP tag) { char **papszMetadata; SEXP ans; int i, n, pc=0; GDALDataset *pDataset = getGDALDatasetPtr(sDataset); installErrorHandler(); if (tag == R_NilValue) { papszMetadata = pDataset->GetMetadata( NULL ); } else { papszMetadata = pDataset->GetMetadata(CHAR(STRING_ELT(tag, 0))); } uninstallErrorHandlerAndTriggerError(); if (CSLCount(papszMetadata) == 0) return(R_NilValue); for (n=0; papszMetadata[n] != NULL; n++); PROTECT(ans = NEW_CHARACTER(n)); pc++; for (i=0; i<n; i++) SET_STRING_ELT(ans, i, COPY_TO_USER_STRING(papszMetadata[i])); UNPROTECT(pc); return(ans); }
CPLErr GDALPamDataset::TryLoadAux() { /* -------------------------------------------------------------------- */ /* Initialize PAM. */ /* -------------------------------------------------------------------- */ PamInitialize(); if( psPam == NULL ) return CE_None; /* -------------------------------------------------------------------- */ /* What is the name of the physical file we are referencing? */ /* We allow an override via the psPam->pszPhysicalFile item. */ /* -------------------------------------------------------------------- */ const char *pszPhysicalFile = psPam->osPhysicalFilename; if( strlen(pszPhysicalFile) == 0 && GetDescription() != NULL ) pszPhysicalFile = GetDescription(); if( strlen(pszPhysicalFile) == 0 ) return CE_None; /* -------------------------------------------------------------------- */ /* Try to open .aux file. */ /* -------------------------------------------------------------------- */ GDALDataset *poAuxDS = GDALFindAssociatedAuxFile( pszPhysicalFile, GA_ReadOnly, this ); if( poAuxDS == NULL ) return CE_None; /* -------------------------------------------------------------------- */ /* Do we have an SRS on the aux file? */ /* -------------------------------------------------------------------- */ if( strlen(poAuxDS->GetProjectionRef()) > 0 ) GDALPamDataset::SetProjection( poAuxDS->GetProjectionRef() ); /* -------------------------------------------------------------------- */ /* Geotransform. */ /* -------------------------------------------------------------------- */ if( poAuxDS->GetGeoTransform( psPam->adfGeoTransform ) == CE_None ) psPam->bHaveGeoTransform = TRUE; /* -------------------------------------------------------------------- */ /* GCPs */ /* -------------------------------------------------------------------- */ if( poAuxDS->GetGCPCount() > 0 ) { psPam->nGCPCount = poAuxDS->GetGCPCount(); psPam->pasGCPList = GDALDuplicateGCPs( psPam->nGCPCount, poAuxDS->GetGCPs() ); } /* -------------------------------------------------------------------- */ /* Apply metadata. We likely ought to be merging this in rather */ /* than overwriting everything that was there. */ /* -------------------------------------------------------------------- */ char **papszMD = poAuxDS->GetMetadata(); if( CSLCount(papszMD) > 0 ) { char **papszMerged = CSLMerge( CSLDuplicate(GetMetadata()), papszMD ); GDALPamDataset::SetMetadata( papszMerged ); CSLDestroy( papszMerged ); } papszMD = poAuxDS->GetMetadata("XFORMS"); if( CSLCount(papszMD) > 0 ) { char **papszMerged = CSLMerge( CSLDuplicate(GetMetadata("XFORMS")), papszMD ); GDALPamDataset::SetMetadata( papszMerged, "XFORMS" ); CSLDestroy( papszMerged ); } /* ==================================================================== */ /* Process bands. */ /* ==================================================================== */ int iBand; for( iBand = 0; iBand < poAuxDS->GetRasterCount(); iBand++ ) { if( iBand >= GetRasterCount() ) break; GDALRasterBand *poAuxBand = poAuxDS->GetRasterBand( iBand+1 ); GDALRasterBand *poBand = GetRasterBand( iBand+1 ); papszMD = poAuxBand->GetMetadata(); if( CSLCount(papszMD) > 0 ) { char **papszMerged = CSLMerge( CSLDuplicate(poBand->GetMetadata()), papszMD ); poBand->SetMetadata( papszMerged ); CSLDestroy( papszMerged ); } if( poAuxBand->GetCategoryNames() != NULL ) poBand->SetCategoryNames( poAuxBand->GetCategoryNames() ); if( poAuxBand->GetColorTable() != NULL && poBand->GetColorTable() == NULL ) poBand->SetColorTable( poAuxBand->GetColorTable() ); // histograms? double dfMin, dfMax; int nBuckets, *panHistogram=NULL; if( poAuxBand->GetDefaultHistogram( &dfMin, &dfMax, &nBuckets, &panHistogram, FALSE, NULL, NULL ) == CE_None ) { poBand->SetDefaultHistogram( dfMin, dfMax, nBuckets, panHistogram ); CPLFree( panHistogram ); } // RAT if( poAuxBand->GetDefaultRAT() != NULL ) poBand->SetDefaultRAT( poAuxBand->GetDefaultRAT() ); // NoData int bSuccess = FALSE; double dfNoDataValue = poAuxBand->GetNoDataValue( &bSuccess ); if( bSuccess ) poBand->SetNoDataValue( dfNoDataValue ); } GDALClose( poAuxDS ); /* -------------------------------------------------------------------- */ /* Mark PAM info as clean. */ /* -------------------------------------------------------------------- */ nPamFlags &= ~GPF_DIRTY; return CE_Failure; }
bool CreateSubRaster( wxGISRasterDatasetSPtr pSrcRasterDataSet, OGREnvelope &Env, const OGRGeometry *pGeom, GDALDriver* pDriver, CPLString &szDstPath, GDALDataType eOutputType, int nBandCount, int *panBandList, double dfOutResX, double dfOutResY, bool bCopyNodata, bool bSkipSourceMetadata, char** papszOptions, ITrackCancel* pTrackCancel ) { GDALDataset* pDset = pSrcRasterDataSet->GetRaster(); if(!pDset) { if(pTrackCancel) pTrackCancel->PutMessage(_("Get raster failed"), -1, enumGISMessageErr); return false; } double adfGeoTransform[6] = { 0, 0, 0, 0, 0, 0 }; CPLErr err = pDset->GetGeoTransform(adfGeoTransform); if(err == CE_Fatal) { if(pTrackCancel) pTrackCancel->PutMessage(_("Get raster failed"), -1, enumGISMessageErr); return false; } if( adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0 ) { if(pTrackCancel) pTrackCancel->PutMessage(_("The geotransform is rotated. This configuration is not supported."), -1, enumGISMessageErr); return false; } int anSrcWin[4] = {0, 0, 0, 0}; anSrcWin[0] = floor ((Env.MinX - adfGeoTransform[0]) / adfGeoTransform[1] + 0.001); anSrcWin[1] = floor ((Env.MaxY - adfGeoTransform[3]) / adfGeoTransform[5] + 0.001); anSrcWin[2] = ceil ((Env.MaxX - Env.MinX) / adfGeoTransform[1]); anSrcWin[3] = ceil ((Env.MinY - Env.MaxY) / adfGeoTransform[5]); if(pTrackCancel) pTrackCancel->PutMessage(wxString::Format(_("Computed source pixel window %d %d %d %d from geographic window."), anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3] ), -1, enumGISMessageInfo); if( anSrcWin[0] < 0 || anSrcWin[1] < 0 || anSrcWin[0] + anSrcWin[2] > pSrcRasterDataSet->GetWidth() || anSrcWin[1] + anSrcWin[3] > pSrcRasterDataSet->GetHeight() ) { if(pTrackCancel) pTrackCancel->PutMessage(wxString::Format(_("Computed source pixel window falls outside raster size of %dx%d."), pSrcRasterDataSet->GetWidth(), pSrcRasterDataSet->GetHeight()), -1, enumGISMessageErr); return false; } int nOXSize = 0, nOYSize = 0; if(IsDoubleEquil(dfOutResX, -1) && IsDoubleEquil(dfOutResY, -1)) { nOXSize = anSrcWin[2]; nOYSize = anSrcWin[3]; } else { nOXSize = ceil ((Env.MaxX - Env.MinX) / dfOutResX); nOYSize = ceil ((Env.MinY - Env.MaxY) / (adfGeoTransform[5] < 0 ? dfOutResY * -1 : dfOutResY)); } /* ==================================================================== */ /* Create a virtual dataset. */ /* ==================================================================== */ VRTDataset *poVDS; /* -------------------------------------------------------------------- */ /* Make a virtual clone. */ /* -------------------------------------------------------------------- */ poVDS = (VRTDataset *) VRTCreate( nOXSize, nOYSize ); if( pSrcRasterDataSet->GetSpatialReference() != NULL ) { poVDS->SetProjection( pDset->GetProjectionRef() ); } adfGeoTransform[0] += anSrcWin[0] * adfGeoTransform[1] + anSrcWin[1] * adfGeoTransform[2]; adfGeoTransform[3] += anSrcWin[0] * adfGeoTransform[4] + anSrcWin[1] * adfGeoTransform[5]; adfGeoTransform[1] *= anSrcWin[2] / (double) nOXSize; adfGeoTransform[2] *= anSrcWin[3] / (double) nOYSize; adfGeoTransform[4] *= anSrcWin[2] / (double) nOXSize; adfGeoTransform[5] *= anSrcWin[3] / (double) nOYSize; poVDS->SetGeoTransform( adfGeoTransform ); int nGCPs = pDset->GetGCPCount(); if( nGCPs > 0 ) { GDAL_GCP *pasGCPs = GDALDuplicateGCPs( nGCPs, pDset->GetGCPs() ); for(size_t i = 0; i < nGCPs; ++i ) { pasGCPs[i].dfGCPPixel -= anSrcWin[0]; pasGCPs[i].dfGCPLine -= anSrcWin[1]; pasGCPs[i].dfGCPPixel *= (nOXSize / (double) anSrcWin[2] ); pasGCPs[i].dfGCPLine *= (nOYSize / (double) anSrcWin[3] ); } poVDS->SetGCPs( nGCPs, pasGCPs, pDset->GetGCPProjection() ); GDALDeinitGCPs( nGCPs, pasGCPs ); CPLFree( pasGCPs ); } /* -------------------------------------------------------------------- */ /* Transfer generally applicable metadata. */ /* -------------------------------------------------------------------- */ if(!bSkipSourceMetadata) poVDS->SetMetadata( pDset->GetMetadata() ); /* ==================================================================== */ /* Process all bands. */ /* ==================================================================== */ for(size_t i = 0; i < nBandCount; ++i ) { VRTSourcedRasterBand *poVRTBand; GDALRasterBand *poSrcBand; GDALDataType eBandType; int nComponent = 0; poSrcBand = pDset->GetRasterBand(panBandList[i]); /* -------------------------------------------------------------------- */ /* Select output data type to match source. */ /* -------------------------------------------------------------------- */ if( eOutputType == GDT_Unknown ) eBandType = poSrcBand->GetRasterDataType(); else eBandType = eOutputType; /* -------------------------------------------------------------------- */ /* Create this band. */ /* -------------------------------------------------------------------- */ poVDS->AddBand( eBandType, NULL ); poVRTBand = (VRTSourcedRasterBand *) poVDS->GetRasterBand( i + 1 ); /* -------------------------------------------------------------------- */ /* Create a simple data source depending on the */ /* translation type required. */ /* -------------------------------------------------------------------- */ //if( bUnscale || bScale || (nRGBExpand != 0 && i < nRGBExpand) ) //{ // poVRTBand->AddComplexSource( poSrcBand, // anSrcWin[0], anSrcWin[1], // anSrcWin[2], anSrcWin[3], // 0, 0, nOXSize, nOYSize, // dfOffset, dfScale, // VRT_NODATA_UNSET, // nComponent ); //} //else CPLString pszResampling = CSLFetchNameValueDef(papszOptions, "DEST_RESAMPLING", "near"); poVRTBand->AddSimpleSource( poSrcBand, anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], 0, 0, nOXSize, nOYSize, pszResampling ); /* -------------------------------------------------------------------- */ /* copy some other information of interest. */ /* -------------------------------------------------------------------- */ CopyBandInfo( poSrcBand, poVRTBand, bCopyNodata ); /* -------------------------------------------------------------------- */ /* Set a forcable nodata value? */ /* -------------------------------------------------------------------- */ // if( bSetNoData ) // { // double dfVal = dfNoDataReal; // int bClamped = FALSE, bRounded = FALSE; // //#define CLAMP(val,type,minval,maxval) \ // do { if (val < minval) { bClamped = TRUE; val = minval; } \ // else if (val > maxval) { bClamped = TRUE; val = maxval; } \ // else if (val != (type)val) { bRounded = TRUE; val = (type)(val + 0.5); } } \ // while(0) // // switch(eBandType) // { // case GDT_Byte: // CLAMP(dfVal, GByte, 0.0, 255.0); // break; // case GDT_Int16: // CLAMP(dfVal, GInt16, -32768.0, 32767.0); // break; // case GDT_UInt16: // CLAMP(dfVal, GUInt16, 0.0, 65535.0); // break; // case GDT_Int32: // CLAMP(dfVal, GInt32, -2147483648.0, 2147483647.0); // break; // case GDT_UInt32: // CLAMP(dfVal, GUInt32, 0.0, 4294967295.0); // break; // default: // break; // } // // if (bClamped) // { // printf( "for band %d, nodata value has been clamped " // "to %.0f, the original value being out of range.\n", // i + 1, dfVal); // } // else if(bRounded) // { // printf("for band %d, nodata value has been rounded " // "to %.0f, %s being an integer datatype.\n", // i + 1, dfVal, // GDALGetDataTypeName(eBandType)); // } // // poVRTBand->SetNoDataValue( dfVal ); // } //if (eMaskMode == MASK_AUTO && // (GDALGetMaskFlags(GDALGetRasterBand(hDataset, 1)) & GMF_PER_DATASET) == 0 && // (poSrcBand->GetMaskFlags() & (GMF_ALL_VALID | GMF_NODATA)) == 0) //{ // if (poVRTBand->CreateMaskBand(poSrcBand->GetMaskFlags()) == CE_None) // { // VRTSourcedRasterBand* hMaskVRTBand = // (VRTSourcedRasterBand*)poVRTBand->GetMaskBand(); // hMaskVRTBand->AddMaskBandSource(poSrcBand, // anSrcWin[0], anSrcWin[1], // anSrcWin[2], anSrcWin[3], // 0, 0, nOXSize, nOYSize ); // } //} } //if (eMaskMode == MASK_USER) //{ // GDALRasterBand *poSrcBand = // (GDALRasterBand*)GDALGetRasterBand(hDataset, ABS(nMaskBand)); // if (poSrcBand && poVDS->CreateMaskBand(GMF_PER_DATASET) == CE_None) // { // VRTSourcedRasterBand* hMaskVRTBand = (VRTSourcedRasterBand*) // GDALGetMaskBand(GDALGetRasterBand((GDALDatasetH)poVDS, 1)); // if (nMaskBand > 0) // hMaskVRTBand->AddSimpleSource(poSrcBand, // anSrcWin[0], anSrcWin[1], // anSrcWin[2], anSrcWin[3], // 0, 0, nOXSize, nOYSize ); // else // hMaskVRTBand->AddMaskBandSource(poSrcBand, // anSrcWin[0], anSrcWin[1], // anSrcWin[2], anSrcWin[3], // 0, 0, nOXSize, nOYSize ); // } //} //else //if (eMaskMode == MASK_AUTO && nSrcBandCount > 0 && // GDALGetMaskFlags(GDALGetRasterBand(hDataset, 1)) == GMF_PER_DATASET) //{ // if (poVDS->CreateMaskBand(GMF_PER_DATASET) == CE_None) // { // VRTSourcedRasterBand* hMaskVRTBand = (VRTSourcedRasterBand*) // GDALGetMaskBand(GDALGetRasterBand((GDALDatasetH)poVDS, 1)); // hMaskVRTBand->AddMaskBandSource((GDALRasterBand*)GDALGetRasterBand(hDataset, 1), // anSrcWin[0], anSrcWin[1], // anSrcWin[2], anSrcWin[3], // 0, 0, nOXSize, nOYSize ); // } //} /* -------------------------------------------------------------------- */ /* Write to the output file using CopyCreate(). */ /* -------------------------------------------------------------------- */ GDALDataset* pOutDS = pDriver->CreateCopy(szDstPath, poVDS, false, papszOptions, GDALDummyProgress, NULL); //hOutDS = GDALCreateCopy( hDriver, pszDest, (GDALDatasetH) poVDS, bStrict, papszCreateOptions, pfnProgress, NULL ); if( pOutDS ) { CPLErrorReset(); GDALFlushCache( pOutDS ); if (CPLGetLastErrorType() != CE_None) { if(pTrackCancel) pTrackCancel->PutMessage(_("GDALFlushCache failed!"), -1, enumGISMessageErr); } GDALClose( pOutDS ); GDALClose( poVDS ); return true; } else { GDALClose( poVDS ); return false; } //CPLFree( panBandList ); // //CPLFree( pszOutputSRS ); //if( !bSubCall ) //{ // GDALDumpOpenDatasets( stderr ); // GDALDestroyDriverManager(); //} //CSLDestroy( papszCreateOptions ); return true; }