在使用Erdas或者ArcGIS開啟柵格映像的時候,會建立一個尾碼名為rrd的金字塔檔案,用於快速顯示映像。那麼在使用GDAL編寫自己的映像演算法後,像快速的在Erdas或者ArcGIS中顯示,就需要自己建立rrd格式的金字塔檔案,這樣在開啟該影像檔時,開啟速度會非常快,在我的電腦上一個2G的img不到一秒鐘可以全部載入進來。
查看GDAL中,有個gdaladdo的工具,就是一個專門用於建立金字塔檔案的,但是預設的建立的是一個尾碼名為ovr的金字塔檔案,該種格式的金字塔不能被Erdas或者ArcGIS使用,但是可以在QGIS等使用。為了能夠在Erdas中使用,在建立的時候需要指定一個選項,那就是 USE_RRD=YES,使用該選項後,建立的金字塔格式是一個aux檔案,雖然尾碼名不是rrd,但是該檔案是可以被Erdas或者ArcGIS中使用的。
關於gdaladdo的使用協助,可以參考網址:http://www.gdal.org/gdaladdo.html
Erdas的金字塔是按照2的次方來採樣,金字塔頂層的大小應該是小於等於64*64,建立金字塔的,於是按照gdaladdo中的說明,其命令列參數應該是:
gdaladdo --config USE_RRD YES airphoto.img 2 4 8 16 ...
最後的...表示採樣層級,一直到最頂層的像元個數小於等於64*64結束。有了上面的知識,下面就給出我寫的一個函數,用於建立金字塔。
/*** @brief 建立金字塔* @param pszFileName 輸入的柵格檔案* @param pProgress 進度條指標* @return 成功返回0*/int CreatePyramids(const char* pszFileName, LT_Progress *pProgress){ if (pProgress != NULL) { pProgress->SetProgressCaption("建立金字塔"); pProgress->SetProgressTip("正在建立金字塔..."); } GDALAllRegister(); CPLSetConfigOption("USE_RRD","YES"); //建立Erdas格式的字塔檔案 /* -------------------------------------------------------------------- */ /* Open data file. */ /* -------------------------------------------------------------------- */ GDALDatasetH hDataset; hDataset = GDALOpen( pszFileName, GA_ReadOnly ); GDALDriverH hDriver = GDALGetDatasetDriver(hDataset); const char* pszDriver = GDALGetDriverShortName(hDriver); if (EQUAL(pszDriver, "HFA") || EQUAL(pszDriver, "PCIDSK")) { GDALClose(hDataset); //如果檔案是Erdas的img或者PCI的pix格式,建立內金字塔,其他的建立外金字塔 hDataset = GDALOpen( pszFileName, GA_Update ); } if( hDataset == NULL ) { if (pProgress != NULL) pProgress->SetProgressTip("開啟映像失敗,請檢查映像是否存在或檔案是否是影像檔!"); return RE_NOFILE; } /* -------------------------------------------------------------------- */ /* Get File basic infomation */ /* -------------------------------------------------------------------- */ int iWidth = GDALGetRasterXSize(hDataset); int iHeigh = GDALGetRasterYSize(hDataset); int iPixelNum = iWidth * iHeigh; //映像中的總像元個數 int iTopNum = 4096; //頂層金字塔大小,64*64 int iCurNum = iPixelNum / 4; int anLevels[1024] = { 0 }; int nLevelCount = 0; //金字塔級數 do //計算金字塔級數,從第二級到頂層 { anLevels[nLevelCount] = static_cast<int>(pow(2.0, nLevelCount+2)); nLevelCount ++; iCurNum /= 4; } while (iCurNum > iTopNum); const char *pszResampling = "nearest"; //採樣方式 GDALProgressFunc pfnProgress = GDALProgress;//進度條 /* -------------------------------------------------------------------- */ /* Generate overviews. */ /* -------------------------------------------------------------------- */ if (nLevelCount > 0 && GDALBuildOverviews( hDataset,pszResampling, nLevelCount, anLevels, 0, NULL, pfnProgress, pProgress ) != CE_None ) { if (pProgress != NULL) pProgress->SetProgressTip("建立金字塔失敗!"); return RE_FAILD; } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ GDALClose(hDataset); GDALDestroyDriverManager(); if (pProgress != NULL) pProgress->SetProgressTip("建立金字塔完成!"); return RE_SUCCESS;}
需要說明的是,這段代碼建立img格式和pix格式的金字塔會建立內金字塔,Erdas的img格式和PCI的pix格式可以把金字塔存放在檔案內部。
PS:在給img檔案建立內金字塔後,使用除ArcGIS9.2以外的軟體開啟後,都正常,但是使用ArcGIS9.2開啟後會出現圖層位移的問題,不知道是否ArcGIS9.2的bug。ArcGIS10正常!ArcGIS9.3沒有測試。
測試代碼:
void main(){ LT_ConsoleProgress *pProgress = new LT_ConsoleProgress(); int f = CreatePyramids("C://Work//Data//ttttt.img", pProgress); if (f == RE_SUCCESS) printf("計算成功/n"); else printf("計算失敗/n"); delete pProgress;}
測試:在使用ArcGIS10開啟沒有金字塔的檔案時,提示:
運行測試代碼:
再次開啟剛才的檔案,沒有上面的提示對話方塊了,而且很快載入進來,說明已經有金字塔了,如果使用Erdas開啟的話,可以看到詳細的金字塔資訊。不過可以試用QGIS查看金字塔資訊。右側的列表顯示的是金字塔的層級,Erdas的金字塔是從第二級開始建立的,所以看到第一級的表徵圖上有個紅色的小叉叉。見: