From a83556f247c985dac8034895aa70fef81d289cfe Mon Sep 17 00:00:00 2001 From: Toby Collett Date: Mon, 6 May 2013 18:25:14 +1200 Subject: [PATCH] Better support for writing RATs #4903 * track thematic/athematic RAT type * Write RATs for Imagine/HFA output by default * Copy RATs during gdalwarp file-creation as well (if using nearest). * Copy RATs during gdal_translate VRT-path as well. * but, discard RATs if the operation makes them invalid --- autotest/utilities/data/onepixelcontinuous.img | Bin 0 -> 8700 bytes autotest/utilities/data/onepixelthematic.img | Bin 0 -> 8700 bytes autotest/utilities/test_gdal_translate.py | 110 ++++++++++++++- gdal/apps/gdal_translate.cpp | 11 ++ gdal/apps/gdalwarp.cpp | 47 ++++++- gdal/frmts/hfa/hfadataset.cpp | 22 +++ gdal/frmts/vrt/vrtdataset.h | 7 + gdal/frmts/vrt/vrtrasterband.cpp | 34 +++++ gdal/gcore/gdal.h | 15 +- gdal/gcore/gdal_rat.cpp | 186 ++++++++++++++++++++++++- gdal/gcore/gdal_rat.h | 7 + gdal/swig/include/RasterAttributeTable.i | 18 +++ 12 files changed, 451 insertions(+), 6 deletions(-) create mode 100644 autotest/utilities/data/onepixelcontinuous.img create mode 100644 autotest/utilities/data/onepixelthematic.img diff --git a/autotest/utilities/data/onepixelcontinuous.img b/autotest/utilities/data/onepixelcontinuous.img new file mode 100644 index 0000000000000000000000000000000000000000..2bc983aad30598f19a20b7ecb81b49ce0848bddf GIT binary patch literal 8700 zcmeHM&5zqe6n7~gzJvgQ5SOx2FI8o#&2F?^e)F66#^d*UV{NtS zgDtDxw7P?SebcyQobS1W?%zFU7+s{F8qQng(bh|OIn+ANOXtr$#`v#4Y5!U$$uut^ z`sZ1sfcPfz9dRVXLB&|BR4Xett5xcEp2t$&c)&u=9L4jKMv~vSUQM@!89U@#Ql)4j=ht4C%!pR#B|%$ha7eC>Dc)kP|2j zV`dw}`0M?o{l8Mf_!D|+UC!}dLH=3^?;Q~ePsTEgPMPz}Dz;^gHy5(LO6s6zhWCrj z*SO-VH2nr?W@Bpj7G=^Y?KQIR&%pR2ekdAE8QGx>f5o>{#D~*I3ObvVPs05*B2?K{QRbGQN{k+>s(LT z$Q@OJ_?vo$vsEN30UP=(^`;vDu0F~rV zeHBN5KqvLK2xw`chm#Gum>1&6K>CjK?c_BL-GcUbN#6o z>VpW_C~Nb!q>`+x)~wBDebE2tjy2e=n1#Yhu~01*)(eGRv9McND>ju%yQ@Wky;7-F zF0B=3Ym`fsm37k*FfnZ&ETEd;?=|Y3dUtSp;{&VFPchUtI##J>yWa1%@0F^$^%)EFPUS{3RrQYc+pw(?u6iJyyVQ2VMk5%Gt+P_= zxb&^Z=Ct?FS2- z^eU~dR?Hh%PJ{M@d7Sp!?wL2TBea{Ikw3uMpf6E-dov$yoZsb|pFR~|OlB_E&9@C> zgrkyNoD9!4^5o~upc)r+Z|KnEv#vOGDL=!Joz|E5+_r(hFvjUeCu=+6+Qh{mw~*YN z4D%)Q9bpX4uK{Tt*^9YkL3lqq1PQ|_4`Y4-4KHHOU4PHl2R@^I2j%&PuvgBgZ_ny; zmyX<9fqETJWXMuKpCbpkBRD_TqP)<+LIVp8EHtptz(NE6Ck=f6u3`L*1=Swk<%GxS z9Kt_#jz9*;scC2(I?89}iR#Rgc2Z9|>C^*JNQf!uBGUq}3Ozr58U!-z$Whz?6NE2( zS|3**$goRJ`g|vzgS~9d5ev>3XuNBU!?2pvZ;+Z9Q#V-6Z-G_~W)LuM*q{re<65FxQzPpQ{*k!bLBDO6?ky6vUSZo65koey9oL8lYZE7~@mqIb*n z1UNc}rV8;ZYDXw$KZ$xVvChIXNfaW&DZtevf?lYk8e>icyNI(b;%rF}uM|sL#Mu^c zwmdrcWN|heSx>jqLkqx}tUNwL9h}RvtQ2%qJDzk@noB+)P82&1oS0)PD%~dX_Z4R` z?w>f0UadJQ#7D|>l`lm|9~Qy43h)o)Vc;rT#pW=-tV*2$g40nR+GuidnB}hz(U%K! zbwC$xg^MnBAxn1*Y*%t93Cs1Nb!fX&Cyhx{RjG6RcANbyd{%mUDrgD%wBAFnLh&P# ngL|2|iHjf-XM+Ne$t7)mGlly%^9B)wb=*KMo`nX^qk(?`%lm*y literal 0 HcmV?d00001 diff --git a/autotest/utilities/data/onepixelthematic.img b/autotest/utilities/data/onepixelthematic.img new file mode 100644 index 0000000000000000000000000000000000000000..c86f1f8ac20ed90ac7dad6ccec653321154a9c53 GIT binary patch literal 8700 zcmeHMOOG2x5bh8_yu?c&goMIMxu9r>;@xGl@&&y1IBVohBHIh$WZE-rZznU;qnYtO zh*p9h!IfXYZ$LQ!;sQd5AHazdf?SXg2gFx3GoBf5mSi`lAdh5sRX?h~uIlNjs3Nsc>Jdj<%mE_{f-~;7(56fBc;Wlc4RLvCL$i4pT8clRRJKI=RG_`0QCBzId#_5rDpgA^k)qI!?3`i__tV6FDpi znMZ*=GP8{kci&Ch?^g=(JM`2(Ti`th`mGAy>oStQN>mgdo%8q_wq=305VF2P>cCUr zz5B-tT=Q2}in}jV?D`^j(kbmVvhNST_$_{5MN7p_q{GBS!+{)mN}Lp@8#~!ZGS2Zh zp{JYJP##T+hjd2IRq*Ffp5M^Hussc&M4RBeI2{hi$VG@;>GS%^H#^VHf4`XbsQl`k zmzX8(W$rMpI~;kw56) zN%q#AH(qA3-(}^GC`pC+?-!~+R;T}<)!=9gp+_v+>UEn-j`71t#WC?EdTry>5 zw(G~k4|J4FrMKZ3=T;{e8*4-Ab!Q4@33yp%99Hx=(> z0IJBJ20DoWfllfz8Pd`sA151hF)zebp$c3TBw6=X&bPIP70n6m_;RB7>?c_BLy88B z^Ma`#nY|d;h;(>c5~pe_b^A)IF&un!-5ze&tP-(A0dWq?mneEzIxv9c!uapJ$ zD_pzEt(9kMR=L{py5&lkm^Kd4*kezxZX;yjfW_n@YMV{%#yfM{UQ-ZJQ`v7F&YG zp$4xIy-MpVHR~dl)1*CN9cKNu`qst#2<>HO5`mCwIB#r_aQfio)f( z{F)GB9F^qaar za&vObXV7lFzVOA&p(8{c1(R| zR$sVu=jU4R3k@tZu+YFl0}Bl-H1L1Yz}IgI@h28ke{h!* z9;dqx|JXf1FhEXC)0oKB0Y{#w&OK>2^Q6;GeFO?=V2W^&!vaJVW`6uM3{})s}4}WQE(oCmYgs4nY~?Pekcw_OhMr^2ezOosc8pEbZ|YP z*<-+n4pPUwtAYuK2whimv@6qIhnzIb!_;n|_Bm2P)W1v8Lm5$23(DEio=XJ#>j*HY zWTb1Wbtj-ec4fKlWYJwIvZtgXgF^7KR(Cu(QXa|K;edgVrWjJ31394}r@SnWmdG<@ zV6zopH7>_(UQE`(m~bYG;|+?Ha&s1eky@$4hom^(vE+;zkCP=cUW%0T-sWJ@UE+0e zti@4J8gidLYWmNREKM?SFvTI>qX&D~pN{&{57TsqTCPWFJiCjq+(cHkE$+GbX3LH# z=x&l#VN8<-*ic($UdS9vFIH9(Azt^)1a{K2Bhe6;N~+54_c}{gdYx9Kc0PfXCY_FC zuV~x&n%*tXmx$3hHC4)AQ9DvGyJ^;o1M56JlV%}eoB~`;BIt!mt1;%DU>A9|MV>89 z;#G2Ki#*#R&sJmyA1=>^BkR$2dT0SSleN!hsEc!XMk+~1wd*TaXH@zDapS~w;lv!; zapg9VzpprpasR}5^wqknBYdPRPX|gy^kI>Fs{sE%?T4OrbYhK)%c{&7AUIv^qm3q) z`#F7Kgucws)d5|&l`gv2g{<5$uwBWaBrF$3_P*my-7F_fRh7<-YaRBp@LB2K(qUWD vr}YMUmDrC+4(?^SetMetadata( poSrcBand->GetMetadata() ); + poDstBand->SetDefaultRAT( poSrcBand->GetDefaultRAT() ); } else { @@ -1518,6 +1519,16 @@ static void CopyBandInfo( GDALRasterBand * poSrcBand, GDALRasterBand * poDstBand } poDstBand->SetMetadata( papszMetadataNew ); CSLDestroy(papszMetadataNew); + + // we need to strip histogram data from the source RAT + if (poSrcBand->GetDefaultRAT()) + { + GDALRasterAttributeTable *poNewRAT = poSrcBand->GetDefaultRAT()->Clone(); + poNewRAT->RemoveStatistics(); + poDstBand->SetDefaultRAT( poNewRAT ); + // since SetDefaultRAT copies the RAT data we need to delete our original + delete poNewRAT; + } } poDstBand->SetColorTable( poSrcBand->GetColorTable() ); diff --git a/gdal/apps/gdalwarp.cpp b/gdal/apps/gdalwarp.cpp index 8a2a932..b7c2e4b 100644 --- a/gdal/apps/gdalwarp.cpp +++ b/gdal/apps/gdalwarp.cpp @@ -51,7 +51,8 @@ GDALWarpCreateOutput( char **papszSrcFiles, const char *pszFilename, char ***ppapszCreateOptions, GDALDataType eDT, void ** phTransformArg, GDALDatasetH* phSrcDS, - int bSetColorInterpretation ); + int bSetColorInterpretation, + GDALResampleAlg eResampleAlg ); static void RemoveConflictingMetadata( GDALMajorObjectH hObj, char **papszMetadata, @@ -899,7 +900,8 @@ int main( int argc, char ** argv ) hDstDS = GDALWarpCreateOutput( papszSrcFiles, pszDstFilename,pszFormat, papszTO, &papszCreateOptions, eOutputType, &hUniqueTransformArg, - &hUniqueSrcDS, bSetColorInterpretation); + &hUniqueSrcDS, bSetColorInterpretation, + eResampleAlg); bCreateOutput = TRUE; if( CSLFetchNameValue( papszWarpOptions, "INIT_DEST" ) == NULL @@ -1464,7 +1466,8 @@ GDALWarpCreateOutput( char **papszSrcFiles, const char *pszFilename, char ***ppapszCreateOptions, GDALDataType eDT, void ** phTransformArg, GDALDatasetH* phSrcDS, - int bSetColorInterpretation) + int bSetColorInterpretation, + GDALResampleAlg eResampleAlg) { @@ -1472,6 +1475,7 @@ GDALWarpCreateOutput( char **papszSrcFiles, const char *pszFilename, GDALDatasetH hDstDS; void *hTransformArg; GDALColorTableH hCT = NULL; + GDALRasterAttributeTableH hRAT = NULL; double dfWrkMinX=0, dfWrkMaxX=0, dfWrkMinY=0, dfWrkMaxY=0; double dfWrkResX=0, dfWrkResY=0; int nDstBandCount = 0; @@ -1553,6 +1557,35 @@ GDALWarpCreateOutput( char **papszSrcFiles, const char *pszFilename, eDT = GDALGetRasterDataType(GDALGetRasterBand(hSrcDS,1)); /* -------------------------------------------------------------------- */ +/* If we are processing the first file, and it has a raster */ +/* attribute table, then we will copy it to the destination file. */ +/* -------------------------------------------------------------------- */ + if( iSrc == 0 ) + { + hRAT = GDALGetDefaultRAT( GDALGetRasterBand(hSrcDS,1) ); + if( hRAT != NULL ) + { + if ( eResampleAlg != GRA_NearestNeighbour && eResampleAlg != GRA_Mode && + GDALRATGetTableType(hRAT) == GRTT_THEMATIC ) + { + if( !bQuiet ) + { + fprintf( stderr, "Warning: Input file %s has a thematic RAT, which will likely lead " + "to bad results when using a resampling method other than nearest neighbour " + "or mode so we are discarding it.\n", papszSrcFiles[iSrc] ); + } + hRAT = NULL; + } + else + { + if( !bQuiet ) + printf( "Copying raster attribute table from %s to new file.\n", + papszSrcFiles[iSrc] ); + } + } + } + +/* -------------------------------------------------------------------- */ /* If we are processing the first file, and it has a color */ /* table, then we will copy it to the destination file. */ /* -------------------------------------------------------------------- */ @@ -1936,6 +1969,14 @@ GDALWarpCreateOutput( char **papszSrcFiles, const char *pszFilename, } /* -------------------------------------------------------------------- */ +/* Copy the raster attribute table, if required. */ +/* -------------------------------------------------------------------- */ + if( hRAT != NULL ) + { + GDALSetDefaultRAT( GDALGetRasterBand(hDstDS,1), hRAT ); + } + +/* -------------------------------------------------------------------- */ /* Copy the color table, if required. */ /* -------------------------------------------------------------------- */ if( hCT != NULL ) diff --git a/gdal/frmts/hfa/hfadataset.cpp b/gdal/frmts/hfa/hfadataset.cpp index cef5e56..08e21e5 100644 --- a/gdal/frmts/hfa/hfadataset.cpp +++ b/gdal/frmts/hfa/hfadataset.cpp @@ -681,6 +681,16 @@ void HFARasterBand::ReadAuxMetadata() CPLAssert( FALSE ); } } + /* if we have a default RAT we can now set its thematic/athematic state + from the metadata we just read in */ + if ( poDefaultRAT ) + { + const char * psLayerType = GetMetadataItem( "LAYER_TYPE","" ); + if (psLayerType) + { + poDefaultRAT->SetTableType(EQUALN(psLayerType,"athematic",9)?GRTT_ATHEMATIC:GRTT_THEMATIC); + } + } } /************************************************************************/ @@ -4509,6 +4519,18 @@ HFADataset::CreateCopy( const char * pszFilename, GDALDataset *poSrcDS, return NULL; /* -------------------------------------------------------------------- */ +/* Does the source have a RAT for any of the bands? If so, */ +/* copy it over. */ +/* -------------------------------------------------------------------- */ + for( iBand = 0; iBand < nBandCount; iBand++ ) + { + GDALRasterBand *poBand = poSrcDS->GetRasterBand( iBand+1 ); + + if( poBand->GetDefaultRAT() != NULL ) + poDS->GetRasterBand(iBand+1)->SetDefaultRAT( poBand->GetDefaultRAT() ); + } + +/* -------------------------------------------------------------------- */ /* Does the source have a PCT for any of the bands? If so, */ /* copy it over. */ /* -------------------------------------------------------------------- */ diff --git a/gdal/frmts/vrt/vrtdataset.h b/gdal/frmts/vrt/vrtdataset.h index c8d7876..de17709 100644 --- a/gdal/frmts/vrt/vrtdataset.h +++ b/gdal/frmts/vrt/vrtdataset.h @@ -33,6 +33,7 @@ #include "gdal_priv.h" #include "gdal_pam.h" #include "gdal_vrt.h" +#include "gdal_rat.h" #include "cpl_hash_set.h" int VRTApplyMetadata( CPLXMLNode *, GDALMajorObject * ); @@ -259,6 +260,8 @@ class CPL_DLL VRTRasterBand : public GDALRasterBand GDALColorInterp eColorInterp; + GDALRasterAttributeTable *poDefaultRAT; + char *pszUnitType; char **papszCategoryNames; @@ -342,6 +345,10 @@ class CPL_DLL VRTRasterBand : public GDALRasterBand virtual int CloseDependentDatasets(); virtual int IsSourcedRasterBand() { return FALSE; } + + virtual const GDALRasterAttributeTable *GetDefaultRAT(); + virtual CPLErr SetDefaultRAT( const GDALRasterAttributeTable * ); + }; /************************************************************************/ diff --git a/gdal/frmts/vrt/vrtrasterband.cpp b/gdal/frmts/vrt/vrtrasterband.cpp index f532ad4..1b8b729 100644 --- a/gdal/frmts/vrt/vrtrasterband.cpp +++ b/gdal/frmts/vrt/vrtrasterband.cpp @@ -73,6 +73,7 @@ void VRTRasterBand::Initialize( int nXSize, int nYSize ) dfNoDataValue = -10000.0; poColorTable = NULL; eColorInterp = GCI_Undefined; + poDefaultRAT = NULL; pszUnitType = NULL; papszCategoryNames = NULL; @@ -96,6 +97,9 @@ VRTRasterBand::~VRTRasterBand() if( poColorTable != NULL ) delete poColorTable; + if( poDefaultRAT != NULL ) + delete poDefaultRAT; + CSLDestroy( papszCategoryNames ); if( psSavedHistograms != NULL ) CPLDestroyXMLNode( psSavedHistograms ); @@ -116,6 +120,7 @@ CPLErr VRTRasterBand::CopyCommonInfoFrom( GDALRasterBand * poSrcBand ) int bSuccess; double dfNoData; + SetDefaultRAT(poSrcBand->GetDefaultRAT()); SetMetadata( poSrcBand->GetMetadata() ); SetColorTable( poSrcBand->GetColorTable() ); SetColorInterpretation(poSrcBand->GetColorInterpretation()); @@ -1138,3 +1143,32 @@ int VRTRasterBand::CloseDependentDatasets() { return FALSE; } + +/************************************************************************/ +/* GetDefaultRAT() */ +/************************************************************************/ + +const GDALRasterAttributeTable *VRTRasterBand::GetDefaultRAT() +{ + return poDefaultRAT; +} + +/************************************************************************/ +/* SetDefaultRAT() */ +/************************************************************************/ + +CPLErr VRTRasterBand::SetDefaultRAT(const GDALRasterAttributeTable *poRAT) +{ + if( poDefaultRAT != NULL ) + { + delete poDefaultRAT; + poDefaultRAT = NULL; + } + + if( poRAT == NULL ) + poDefaultRAT = NULL; + else + poDefaultRAT = poRAT->Clone(); + + return CE_None; +} diff --git a/gdal/gcore/gdal.h b/gdal/gcore/gdal.h index 0176f12..0056c21 100644 --- a/gdal/gcore/gdal.h +++ b/gdal/gcore/gdal.h @@ -692,6 +692,14 @@ typedef enum { /*! Maximum GFU value */ GFU_MaxCount } GDALRATFieldUsage; +/** RAT table type (thematic or athematic) + * @since GDAL 2.0 + */ +typedef enum { + /*! Thematic table type */ GRTT_THEMATIC, + /*! Athematic table type */ GRTT_ATHEMATIC +} GDALRATTableType; + GDALRasterAttributeTableH CPL_DLL CPL_STDCALL GDALCreateRasterAttributeTable(void); void CPL_DLL CPL_STDCALL GDALDestroyRasterAttributeTable( @@ -733,6 +741,9 @@ CPLErr CPL_DLL CPL_STDCALL GDALRATSetLinearBinning( GDALRasterAttributeTableH, double, double ); int CPL_DLL CPL_STDCALL GDALRATGetLinearBinning( GDALRasterAttributeTableH, double *, double * ); +CPLErr CPL_STDCALL GDALRATSetTableType( GDALRasterAttributeTableH hRAT, + const GDALRATTableType eInTableType ); +GDALRATTableType CPL_STDCALL GDALRATGetTableType( GDALRasterAttributeTableH hRAT); CPLErr CPL_DLL CPL_STDCALL GDALRATInitializeFromColorTable( GDALRasterAttributeTableH, GDALColorTableH ); GDALColorTableH CPL_DLL CPL_STDCALL GDALRATTranslateToColorTable( @@ -740,10 +751,12 @@ GDALColorTableH CPL_DLL CPL_STDCALL GDALRATTranslateToColorTable( void CPL_DLL CPL_STDCALL GDALRATDumpReadable( GDALRasterAttributeTableH, FILE * ); GDALRasterAttributeTableH CPL_DLL CPL_STDCALL - GDALRATClone( GDALRasterAttributeTableH ); + GDALRATClone( const GDALRasterAttributeTableH ); int CPL_DLL CPL_STDCALL GDALRATGetRowOfValue( GDALRasterAttributeTableH , double ); +void CPL_DLL CPL_STDCALL GDALRATRemoveStatistics( GDALRasterAttributeTableH ); + /* ==================================================================== */ /* GDAL Cache Management */ diff --git a/gdal/gcore/gdal_rat.cpp b/gdal/gcore/gdal_rat.cpp index 48a9aec..7930bcf 100644 --- a/gdal/gcore/gdal_rat.cpp +++ b/gdal/gcore/gdal_rat.cpp @@ -84,6 +84,7 @@ GDALRasterAttributeTable::GDALRasterAttributeTable() bLinearBinning = FALSE; dfRow0Min = -0.5; dfBinSize = 1.0; + eTableType = GRTT_THEMATIC; nRowCount = 0; } @@ -1175,6 +1176,98 @@ GDALRATGetLinearBinning( GDALRasterAttributeTableH hRAT, } /************************************************************************/ +/* GetTableType() */ +/************************************************************************/ + +/** + * \brief Get RAT Table Type + * + * Returns whether table type is thematic or athematic + * + * This method is the same as the C function GDALRATGetTableType(). + * + * @since GDAL 2.0 + * + * @return GRTT_THEMATIC or GRTT_ATHEMATIC + */ + +GDALRATTableType GDALRasterAttributeTable::GetTableType() const +{ + return eTableType; +} + + +/************************************************************************/ +/* GDALRATGetTableType() */ +/************************************************************************/ + +/** + * \brief Get Rat Table Type + * + * @since GDAL 2.0 + * + * This function is the same as the C++ method GDALRasterAttributeTable::GetTableType() + */ +GDALRATTableType CPL_STDCALL +GDALRATGetTableType( GDALRasterAttributeTableH hRAT) +{ + VALIDATE_POINTER1( hRAT, "GDALRATGetLinearBinning", GRTT_THEMATIC ); + + return ((GDALRasterAttributeTable *) hRAT)->GetTableType(); +} + + +/************************************************************************/ +/* SetTableType() */ +/************************************************************************/ + +/** + * \brief Set RAT Table Type + * + * Set whether table type is thematic or athematic + * + * This method is the same as the C function GDALRATSetTableType(). + * @param dfRow0MinIn the lower bound (pixel value) of the first category. + * + * @param eTableType the new RAT table type (GRTT_THEMATIC or GRTT_ATHEMATIC) + * + * @since GDAL 2.0 + * + * @return CE_None on success or CE_Failure on failure. + */ + +CPLErr GDALRasterAttributeTable::SetTableType(const GDALRATTableType eInTableType) +{ + if (eInTableType < GRTT_THEMATIC || eInTableType > GRTT_ATHEMATIC) + return CE_Failure; + eTableType = eInTableType; + return CE_None; +} + +/************************************************************************/ +/* GDALRATSetTableType() */ +/************************************************************************/ + +/** + * \brief Set RAT Table Type + * + * @since GDAL 2.0 + * + * This function is the same as the C++ method GDALRasterAttributeTable::SetTableType() + */ +CPLErr CPL_STDCALL +GDALRATSetTableType( GDALRasterAttributeTableH hRAT, + const GDALRATTableType eInTableType ) + +{ + VALIDATE_POINTER1( hRAT, "GDALRATSetTableType", CE_Failure ); + + return ((GDALRasterAttributeTable *) hRAT)->SetTableType( + eInTableType ); +} + + +/************************************************************************/ /* CreateColumn() */ /************************************************************************/ @@ -1458,6 +1551,17 @@ CPLErr GDALRasterAttributeTable::XMLInit( CPLXMLNode *psTree, } /* -------------------------------------------------------------------- */ +/* Table Type */ +/* -------------------------------------------------------------------- */ + if( CPLGetXMLValue( psTree, "TableType", NULL ) ) + { + int iTableType = atoi(CPLGetXMLValue( psTree, "TableType","" )); + if (iTableType >= GRTT_THEMATIC && iTableType <= GRTT_ATHEMATIC) + SetTableType( (GDALRATTableType) iTableType ); + } + + +/* -------------------------------------------------------------------- */ /* Column definitions */ /* -------------------------------------------------------------------- */ CPLXMLNode *psChild; @@ -1533,6 +1637,15 @@ CPLXMLNode *GDALRasterAttributeTable::Serialize() const } /* -------------------------------------------------------------------- */ +/* Store table type */ +/* -------------------------------------------------------------------- */ + sprintf( szValue, "%d", eTableType ); + CPLCreateXMLNode( + CPLCreateXMLNode( psTree, CXT_Attribute, "TableType" ), + CXT_Text, szValue ); + + +/* -------------------------------------------------------------------- */ /* Define each column. */ /* -------------------------------------------------------------------- */ int iCol; @@ -1676,10 +1789,81 @@ GDALRasterAttributeTable *GDALRasterAttributeTable::Clone() const * This function is the same as the C++ method GDALRasterAttributeTable::Clone() */ GDALRasterAttributeTableH CPL_STDCALL -GDALRATClone( GDALRasterAttributeTableH hRAT ) +GDALRATClone( const GDALRasterAttributeTableH hRAT ) { VALIDATE_POINTER1( hRAT, "GDALRATClone", NULL ); return ((GDALRasterAttributeTable *) hRAT)->Clone(); } + + +/************************************************************************/ +/* RemoveStatistics() */ +/************************************************************************/ + +/** + * \brief Remove Statistics from RAT + * + * Remove statistics (such as histogram) from the RAT. This is important + * if these have been invalidated, for example by cropping the image. + * + * This method is the same as the C function GDALRATRemoveStatistics(). + * + * @since GDAL 2.0 + */ + +void GDALRasterAttributeTable::RemoveStatistics() + +{ + // since we are storing the fields in a vector it will generally + // be faster to create a new vector and replace the old one + // rather than actually erasing columns. + std::vector aoNewFields; + for (std::vector::const_iterator itr = aoFields.begin(); + itr != aoFields.end(); ++itr) + { + switch (itr->eUsage) + { + case GFU_PixelCount: + case GFU_Min: + case GFU_Max: + case GFU_RedMin: + case GFU_GreenMin: + case GFU_BlueMin: + case GFU_AlphaMin: + case GFU_RedMax: + case GFU_GreenMax: + case GFU_BlueMax: + case GFU_AlphaMax: + { + break; + } + + default: + if (itr->sName != "Histogram") + aoNewFields.push_back(*itr); + } + } + aoFields = aoNewFields; +} + +/************************************************************************/ +/* GDALRATDumpReadable() */ +/************************************************************************/ + +/** + * \brief Remove Statistics from RAT + * + * This function is the same as the C++ method GDALRasterAttributeTable::RemoveStatistics() + * + * @since GDAL 2.0 + */ +void CPL_STDCALL +GDALRATRemoveStatistics( GDALRasterAttributeTableH hRAT ) + +{ + VALIDATE_POINTER0( hRAT, "GDALRATRemoveStatistics" ); + + ((GDALRasterAttributeTable *) hRAT)->RemoveStatistics(); +} diff --git a/gdal/gcore/gdal_rat.h b/gdal/gcore/gdal_rat.h index 4c4db91..ff407c5 100644 --- a/gdal/gcore/gdal_rat.h +++ b/gdal/gcore/gdal_rat.h @@ -70,6 +70,8 @@ private: double dfRow0Min; double dfBinSize; + GDALRATTableType eTableType; + void AnalyseColumns(); int bColumnsAnalysed; int nMinCol; @@ -118,6 +120,9 @@ public: CPLErr SetLinearBinning( double dfRow0Min, double dfBinSize ); int GetLinearBinning( double *pdfRow0Min, double *pdfBinSize ) const; + CPLErr SetTableType(const GDALRATTableType eInTableType); + GDALRATTableType GetTableType() const; + CPLXMLNode *Serialize() const; CPLErr XMLInit( CPLXMLNode *, const char * ); @@ -125,6 +130,8 @@ public: GDALColorTable *TranslateToColorTable( int nEntryCount = -1 ); void DumpReadable( FILE * = NULL ); + + void RemoveStatistics(); }; #endif /* ndef GDAL_RAT_H_INCLUDED */ diff --git a/gdal/swig/include/RasterAttributeTable.i b/gdal/swig/include/RasterAttributeTable.i index 11328d3..8da844c 100644 --- a/gdal/swig/include/RasterAttributeTable.i +++ b/gdal/swig/include/RasterAttributeTable.i @@ -36,6 +36,7 @@ #ifndef SWIGCSHARP typedef int GDALRATFieldType; typedef int GDALRATFieldUsage; +typedef int GDALRATTableType; #else %rename (RATFieldType) GDALRATFieldType; typedef enum { @@ -66,6 +67,14 @@ typedef enum { /*! Color Range Alpha Maximum */ GFU_AlphaMax = 17, /*! Maximum GFU value */ GFU_MaxCount } GDALRATFieldUsage; + +/** RAT table type (thematic or athematic) */ +%rename (RATTabelType) GDALRATTableType; +typedef enum { + /*! Thematic table type */ GRTT_THEMATIC, + /*! Athematic table type */ GRTT_ATHEMATIC +} GDALRATTableType; + #endif /* CSHARP */ %rename (RasterAttributeTable) GDALRasterAttributeTableShadow; @@ -169,6 +178,15 @@ public: int GetRowOfValue( double dfValue ) { return GDALRATGetRowOfValue( self, dfValue ); } + + GDALRATTableType GetTableType( ) { + return GDALRATGetTableType( self ); + } + + void SetTableType( GDALRATTableType value) { + GDALRATSetTableType( self, value ); + } + } }; -- 1.8.1.2