日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

GDAL算法进度条使用说明

發布時間:2025/3/21 编程问答 63 豆豆
生活随笔 收集整理的這篇文章主要介紹了 GDAL算法进度条使用说明 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? 在調用GDAL算法的時候,希望能夠顯示其處理進度信息,其實在GDAL的算法API中,一般最后兩個參數就是進度信息的指針。下面分別實現兩種進度條信息,一種是在控制臺中的進度條,一種是基于QT界面的進度條(你可以參考寫一個MFC的)。

? ? 對于GDAL來說,本身就實現了一個基于控制臺的進度條函數,名字叫GDALTermProgress,其函數說明參考這里?,調用這個進度函數后,會在控制臺中顯示一個進度信息,形狀大概就是下面的樣子:

0...10...20...30...40...50...60...70...80...90...100 - done. ? ? 每個2.5%就會輸出一個點,然后每到10%就會輸出數字,在完成結束后會輸出done。

? ? GDAL的算法中,一般最后兩個參數是用來返回進度信息的,下面以柵格矢量化的接口舉例說明,GDAL柵格矢量化的函數接口定義為:

CPLErr GDALPolygonize ( GDALRasterBandH? hSrcBand,
? ? GDALRasterBandH? hMaskBand,
? ? OGRLayerH? hOutLayer,
? ? int? iPixValField,
? ? char **? papszOptions,
? ? GDALProgressFunc? pfnProgress,
? ? void *? pProgressArg ?
? )

? ? 算法說明文檔參考地址:http://www.gdal.org/gdal__alg_8h.html#a3f522a9035d3512b5d414fb4752671b1。從文檔中可以看到,最后兩個參數說明是:

pfnProgress? callback for reporting algorithm progress matching the?GDALProgressFunc()?semantics. May be NULL.
pProgressArg? callback argument passed to pfnProgress. ?
? ? 上面的意思大概就是說,參數pfnProgress?是一個回調函數指針,回調函數定義參考?GDALProgressFunc(),參數pProgressArg?是回調函數pfnProgress?的第三個參數。關于GDALProgressFunc()的定義如下: int (*GDALProgressFunc)(double dfComplete, const char *pszMessage, void *pProgressArg);

? ??該回調函數參數說明分別是:

? dfComplete? 進度值,取值范圍是0.0~1.0,0.0表示開始,1.0表示完成。
? pszMessage? 可選項,用來顯示的字符串信息。通常用NULL即可。
? pProgressArg? 應用程序回調函數參數,是一個自定義的類(或結構體)指針。
? ? 下面以GDAL自帶的進度函數GDALTermProgress為例,進行說明。GDALTermProgress的源代碼在GDALSrc\gcore\gdal_misc.cpp,762行左右(GDAL1.8.1版本),代碼如下: int CPL_STDCALL GDALTermProgress( double dfComplete, const char *pszMessage, void * pProgressArg ){static int nLastTick = -1;int nThisTick = (int) (dfComplete * 40.0);(void) pProgressArg;nThisTick = MIN(40,MAX(0,nThisTick));// Have we started a new progress run? if( nThisTick < nLastTick && nLastTick >= 39 )nLastTick = -1;if( nThisTick <= nLastTick )return TRUE;while( nThisTick > nLastTick ){nLastTick++;if( nLastTick % 4 == 0 )fprintf( stdout, "%d", (nLastTick / 4) * 10 );elsefprintf( stdout, "." );}if( nThisTick == 40 )fprintf( stdout, " - done.\n" );elsefflush( stdout );return TRUE; }? ? 可以看出,上面的函數中,只用了第一個參數,后面兩個參數沒用,就是將第一個參數使用printf函數輸出在屏幕上。基于上面的分析,可以自己實現一個自己的GDAL進度條類,首先看類聲明:
/** * @brief 進度條基類 * * 提供進度條基類接口,來反映當前算法的進度值 */ class IMGALG_API CProcessBase { public:/*** @brief 構造函數*/CProcessBase() {m_dPosition = 0.0;m_iStepCount = 100;m_iCurStep = 0;m_bIsContinue = true;}/*** @brief 析構函數*/virtual ~CProcessBase() {}/*** @brief 設置進度信息* @param pszMsg 進度信息*/virtual void SetMessage(const char* pszMsg) = 0;/*** @brief 設置進度值* @param dPosition 進度值* @return 返回是否取消的狀態,true為不取消,false為取消*/virtual bool SetPosition(double dPosition) = 0;/*** @brief 進度條前進一步,返回true表示繼續,false表示取消* @return 返回是否取消的狀態,true為不取消,false為取消*/virtual bool StepIt() = 0;/*** @brief 設置進度個數* @param iStepCount 進度個數*/virtual void SetStepCount(int iStepCount){ReSetProcess(); m_iStepCount = iStepCount;}/*** @brief 獲取進度信息* @return 返回當前進度信息*/string GetMessage(){return m_strMessage;}/*** @brief 獲取進度值* @return 返回當前進度值*/double GetPosition(){return m_dPosition;}/*** @brief 重置進度條*/void ReSetProcess(){m_dPosition = 0.0;m_iStepCount = 100;m_iCurStep = 0;m_bIsContinue = true;}/*! 進度信息 */string m_strMessage;/*! 進度值 */double m_dPosition; /*! 進度個數 */int m_iStepCount; /*! 進度當前個數 */int m_iCurStep; /*! 是否取消,值為false時表示計算取消 */bool m_bIsContinue; }; ? ? 該類是一個進度條基類,將一些通用的函數進行實現,比如獲取進度值,獲取進度信息等之類的,然后將一些需要根據使用方式不同的設置為虛函數,比如設置進度值等。下面給出一個控制臺進度條類,用于顯示基于控制臺程序的進度值顯示,參考GDALTermProgress函數寫的:/** * @brief 控制臺進度條類 * * 提供控制臺程序的進度條類接口,來反映當前算法的進度值 */ class CConsoleProcess : public CProcessBase { public:/*** @brief 構造函數*/CConsoleProcess() {m_dPosition = 0.0;m_iStepCount = 100;m_iCurStep = 0;};/*** @brief 析構函數*/~CConsoleProcess() {//remove(m_pszFile);};/*** @brief 設置進度信息* @param pszMsg 進度信息*/void SetMessage(const char* pszMsg){m_strMessage = pszMsg;printf("%s\n", pszMsg);}/*** @brief 設置進度值* @param dPosition 進度值* @return 返回是否取消的狀態,true為不取消,false為取消*/bool SetPosition(double dPosition){m_dPosition = dPosition;TermProgress(m_dPosition);m_bIsContinue = true;return true;}/*** @brief 進度條前進一步* @return 返回是否取消的狀態,true為不取消,false為取消*/bool StepIt(){m_iCurStep ++;m_dPosition = m_iCurStep*1.0 / m_iStepCount;TermProgress(m_dPosition);m_bIsContinue = true;return true;}private:void TermProgress(double dfComplete){static int nLastTick = -1;int nThisTick = (int) (dfComplete * 40.0);nThisTick = MIN(40,MAX(0,nThisTick));// Have we started a new progress run? if( nThisTick < nLastTick && nLastTick >= 39 )nLastTick = -1;if( nThisTick <= nLastTick )return ;while( nThisTick > nLastTick ){nLastTick++;if( nLastTick % 4 == 0 )fprintf( stdout, "%d", (nLastTick / 4) * 10 );elsefprintf( stdout, "." );}if( nThisTick == 40 )fprintf( stdout, " - done.\n" );elsefflush( stdout );} };? ? 至此,一個控制臺的進度條就完成了,使用方式如下(注意:之前的博客中出現的LT_ConsoleProgress就是上面這個類):
void main() {CConsoleProcess *pProgress = new CConsoleProcess();//參考建立Erdas金字塔的那篇博客:http://blog.csdn.net/liminlu0314/article/details/6127755int f = CreatePyramids("C://Work//Data//ttttt.img", pProgress);if (f == RE_SUCCESS)printf("計算成功/n");elseprintf("計算失敗/n");delete pProgress; }

? ? 效果圖如下:


? ? 下面開始編寫一個基于QT界面的進度條類,首先是類定義,基于QT界面的,對于MFC界面的可以參考這個寫一個:

/** * @brief 進度條對話框類 * * 提供GUI程序的進度條類接口,來反映當前算法的進度值 */ class CProcessDlg : public QProgressDialog, public CProcessBase {Q_OBJECTpublic:/*** @brief 構造函數*/CProcessDlg(QWidget *parent = 0); /*** @brief 析構函數*/~CProcessDlg();/*** @brief 設置進度信息* @param pszMsg 進度信息*/void SetMessage(const char* pszMsg);/*** @brief 設置進度值* @param dPosition 進度值*/bool SetPosition(double dPosition);/*** @brief 進度條前進一步*/bool StepIt();public slots:void updateProgress(int); }; ? ? 接下來是實現部分代碼,具體和上面的控制臺類一樣,只不過是設置進度值都是設置在界面上的相應的控件中:/** * @brief 構造函數 */ CProcessDlg::CProcessDlg(QWidget *parent) :QProgressDialog(parent) {m_dPosition = 0.0;m_iStepCount = 100;m_iCurStep = 0;setModal(true);setLabelText(tr("處理中..."));setAutoClose(false);setAutoReset(false);setCancelButtonText(tr("取消"));setWindowTitle(tr("進度"));//禁用關閉按鈕setWindowFlags(Qt::WindowTitleHint | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); };/** * @brief 析構函數 */ CProcessDlg::~CProcessDlg() { };/** * @brief 設置進度信息 * @param pszMsg 進度信息 */ void CProcessDlg::SetMessage(const char* pszMsg) {if (pszMsg != NULL){m_strMessage = pszMsg;setLabelText(QString(pszMsg));} }/** * @brief 設置進度值 * @param dPosition 進度值 */ bool CProcessDlg::SetPosition(double dPosition) {m_dPosition = dPosition;setValue( std::min( 100u, ( uint )( m_dPosition*100.0 ) ) );QCoreApplication::instance()->processEvents(); if(this->wasCanceled())return false;return true; }/** * @brief 進度條前進一步,返回false表示終止操作 */ bool CProcessDlg::StepIt() {m_iCurStep ++;m_dPosition = m_iCurStep*1.0 / m_iStepCount;setValue( std::min( 100u, ( uint )( m_dPosition*100.0 ) ) );QCoreApplication::instance()->processEvents(); if(this->wasCanceled())return false;return true; }void CProcessDlg::updateProgress(int step) {this->setValue(step);QCoreApplication::instance()->processEvents(); } ? ? 至此,QT界面的進度條類已經完成,調用方式和上面控制臺的基本類似,示例代碼: //省略部分代碼CProcessDlg *pPro = new CProcessDlg();pPro->setWindowTitle(tr("正在執行柵格矢量化"));pPro->show();int iRev = ImagePolygonize(m_strInputName.c_str(), m_strOutputName.c_str(), pszFormat, pPro);delete pPro;

? ? 這樣,我們基本上就實現了兩個進度條,一個控制臺,一個QT界面的。執行的效果圖如下:


? ? 那么在自己的算法中如何使用這個進度條類呢,下面給出一個簡單的算法,圖像反色算法:

/** * @brief 圖像反色 * @param pszSrcFile 輸入文件路徑 * @param pszDstFile 輸出文件路徑 * @param pszFormat 輸出文件格式,詳細參考GDAL支持數據類型 * @param pProcess 進度條指針 * @return 返回值,表示計算過程中出現的各種錯誤信息 */ int ImageAnticolor(const char* pszSrcFile, const char* pszDstFile, const char* pszFormat, CProcessBase* pProcess = NULL) {if(pProcess != NULL){pProcess->ReSetProcess();pProcess->SetMessage("執行圖像反色...");}if(pszSrcFile == NULL || pszDstFile == NULL)return RE_PARAMERROR;GDALAllRegister();GDALDataset *poSrcDS = (GDALDataset *) GDALOpen( pszSrcFile, GA_ReadOnly );if( poSrcDS == NULL ){if(pProcess != NULL)pProcess->SetMessage("輸入文件不能打開,請檢查文件是否存在!");return RE_FILENOTEXIST;}GDALDriver *poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat);if( poDriver == NULL ){if(pProcess != NULL)pProcess->SetMessage("不能創建制定類型的文件,請檢查該文件類型GDAL是否支持創建!");GDALClose( (GDALDatasetH) poSrcDS );return RE_FILENOTSUPPORT;}//獲取圖像寬高和波段數int iXSize = poSrcDS->GetRasterXSize();int iYSize = poSrcDS->GetRasterYSize();int iBandCount = poSrcDS->GetRasterCount();//假設輸入圖像也是8U的數據GDALDataset *poDstDS = poDriver->Create(pszDstFile, iXSize, iYSize, iBandCount, GDT_Byte, NULL);double dGeoTrans[6] = {0};//設置仿射變換參數poSrcDS->GetGeoTransform(dGeoTrans);poDstDS->SetGeoTransform(dGeoTrans);//設置圖像投影信息poDstDS->SetProjection(poSrcDS->GetProjectionRef());DT_8U *pSrcData = new DT_8U[iXSize];DT_8U *pDstData = new DT_8U[iXSize];if(m_pProcess != NULL){m_pProcess->SetMessage("計算圖像反色...");m_pProcess->SetStepCount(iYSize*iBandCount); //設置進度條的總步長}//循環波段for(int iBand=1; iBand<=iBandCount; iBand++){GDALRasterBand *pSrcBand = poSrcDS->GetRasterBand(iBand);GDALRasterBand *pDstBand = poDstDS->GetRasterBand(iBand);for(int i=0; i<iYSize; i++) //循環圖像高{pSrcBand->RasterIO(GF_Read, 0, i, iXSize, 1, pSrcData, iXSize, 1, GDT_Byte, 0, 0);for(int j=0; j<iXSize; j++) //循環圖像寬pDstData[j] = 255 - pSrcData[j];pDstBand->RasterIO(GF_Write, 0, i, iXSize, 1, pDstData, iXSize, 1, GDT_Byte, 0, 0);if(m_pProcess != NULL){bool bIsCancel = m_pProcess->StepIt();if(!bIsCancel){RELEASE(pSrcData);RELEASE(pDstData);//關閉原始圖像和結果圖像GDALClose( (GDALDatasetH) poDstDS );GDALClose( (GDALDatasetH) poSrcDS );remove(pszDstFile); //刪除結果圖像if(pProcess != NULL)pProcess->SetMessage("圖像反色取消!");return RE_CANCEL;}}}}RELEASE(pSrcData);RELEASE(pDstData);//關閉原始圖像和結果圖像GDALClose( (GDALDatasetH) poDstDS );GDALClose( (GDALDatasetH) poSrcDS );if(pProcess != NULL)pProcess->SetMessage("圖像反色完成!");return RE_SUCCESS; }? ? 如果我要使用GDAL提供的算法,該怎么使用上面的進度條呢,很簡單,具體是要實現一個GDALProgressFunc()函數相同的一個使用__stdcall導出的函數即可,函數定義如下:
/** * @brief 導出符號定義 */ #ifndef STD_API #define STD_API __stdcall #endif /** * \brief 調用GDAL進度條接口 * * 該函數用于將GDAL算法中的進度信息導出到CProcessBase基類中,供給界面顯示 * * @param dfComplete 完成進度值,其取值為 0.0 到 1.0 之間 * @param pszMessage 進度信息 * @param pProgressArg CProcessBase的指針 * * @return 返回TRUE表示繼續計算,否則為取消 */ int STD_API ALGTermProgress( double dfComplete, const char *pszMessage, void * pProgressArg ); ? ? 下面為該函數的實現代碼,請重點看第三個參數的使用方式:/** * \brief 調用GDAL進度條接口 * * 該函數用于將GDAL算法中的進度信息導出到CProcessBase基類中,供給界面顯示 * * @param dfComplete 完成進度值,其取值為 0.0 到 1.0 之間 * @param pszMessage 進度信息 * @param pProgressArg CProcessBase的指針 * * @return 返回TRUE表示繼續計算,否則為取消 */ int STD_API ALGTermProgress( double dfComplete, const char *pszMessage, void * pProgressArg ) {if(pProgressArg != NULL){CProcessBase * pProcess = (CProcessBase*) pProgressArg;pProcess->m_bIsContinue = pProcess->SetPosition(dfComplete);if(pProcess->m_bIsContinue)return TRUE;elsereturn FALSE;}elsereturn TRUE; }? ? 稍微對上面的函數體進行說明一下,關鍵是第三個參數,第三個參數其實就是我們上面定義的控制臺類獲取QT界面類的對象指針,只不過是專為一個void指針,在函數體中,我們需要將其轉為基類CProcessBase的指針,然后調用該基類的設置進度值函數即可。對于該函數的使用,下面還是以柵格矢量化為例來進行說明,廢話不多說,看代碼://前面省略很多代碼GDALRasterBandH hSrcBand = (GDALRasterBandH)poSrcDS->GetRasterBand(1);if(GDALPolygonize(hSrcBand, NULL, (OGRLayerH)poLayer, 0, NULL, ALGTermProgress, pProcess)!= CE_None){GDALClose( (GDALDatasetH) poSrcDS );if(pProcess != NULL){if(!pProcess->m_bIsContinue){pProcess->SetMessage("計算取消!");return RE_USERCANCEL;}else{pProcess->SetMessage("計算失敗!");return RE_PARAMERROR;}}return RE_PARAMERROR;}//后面省略部分代碼? ? 終于寫完了。好長啊~~~

轉載于:https://www.cnblogs.com/xiaowangba/archive/2012/02/20/6314032.html

總結

以上是生活随笔為你收集整理的GDAL算法进度条使用说明的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 伊人福利视频 | av网站大全在线 | 亚洲乱人伦 | 日韩精品一区二区免费视频 | 蜜桃精品视频在线 | 国产传媒第一页 | 三级黄网 | 亚洲一区综合 | 国产一区二区三区在线看 | 欧美老熟妇xb水多毛多 | 三级理论电影 | 国产欧美精品一区二区 | 蜜臀av免费在线观看 | 精品人妻一区二区三区日产乱码 | 雨宫琴音一区二区三区 | 亚洲爱爱网站 | 久久一二三区 | 国产精品国产三级国产专播品爱网 | 久久久亚洲综合 | 日韩免费观看一区二区 | 少妇av一区二区三区无码 | 美女网站在线看 | 极品女神无套呻吟啪啪 | 黄色网址在线视频 | 亚洲AV蜜桃永久无码精品性色 | 国产91在线免费观看 | 自拍偷拍 亚洲 | 熟妇高潮精品一区二区三区 | 女人十八毛片嫩草av | 人人亚洲 | 亚洲视频导航 | 自拍偷拍欧美日韩 | 欧美视频一区 | 激情欧美一区二区三区精品 | 九九九国产视频 | 国产欧美日韩综合精品一区二区 | 深爱激情av| 日韩av一区二区三区在线 | 性活交片大全免费看 | 国产精品999久久久 在线青草 | 无码人妻精品丰满熟人区 | 国产午夜啪啪 | www黄色网址 | 一级片aaa| 亚洲第一页av | 一区二区三区国产av | 欧美aaaaaaaaaa | 欧美日韩专区 | 在线免费观看日韩av | 亚洲成色在线 | 欧美性爱视频久久 | 麻豆videos| 国产精品777 | 婷婷丁香视频 | 国产精品久久久久久久久久久久久久 | 日本亚洲国产 | 成人福利一区二区 | 国产高清av在线 | 天天综合网天天综合色 | 人人色网 | 国产xxxxxxxxx | 小蝌蚪视频色 | 日本顶级大片 | 欧美交换国产一区内射 | 欧美亚洲免费 | 免费成人av | 欧美精品福利 | 日韩av影片在线观看 | 一区二区三区视频免费在线观看 | 噜噜噜av| 天天操狠狠操 | 高清av免费观看 | 精品国产不卡 | 免费观看视频一区 | 九九视屏 | 天天干天天操 | 天天鲁一鲁摸一摸爽一爽 | 久人人| 国产一区二区精品丝袜 | 2021天天操 | 超碰95在线 | 99国产精品白浆在线观看免费 | 香蕉视频网站入口 | 国产免费一级视频 | 欧美寡妇性猛交ⅹxxx | 美女久久久久久久久久 | 成年人在线视频 | 日韩丰满少妇无码内射 | 欧美丰满一区二区免费视频 | 91精品国产成人www | 午夜毛片在线 | 成人午夜免费网站 | 国产综合内射日韩久 | 超碰精品在线 | 国产综合久久久久久鬼色 | 黑人与亚洲人色ⅹvideos | 草草影院最新网址 | 特一级黄色| 国产精品suv一区二区三区 |