GDAL库中提供了很多的算法,同时也提供了进度条的参数。对于C++调用来说,应该没什么问题,但是对C#调用来说,在进度条这块需要写一个代理来进行传递。首先写一个简单的测试代码。

首先定义一个委托函数原型,需要与GDAL库中的C#进度条接口保持一致,一个简单的原型如下。

    /// <summary>/// 进度信息回调函数/// </summary>/// <param name="dfComplete">完成比例,0~1之间的数</param>/// <param name="pszMessage">进度条信息</param>/// <param name="pProgressArg">进度条用户数据</param>/// <returns></returns>public delegate int ProgressFunc(double dfComplete, char[] pszMessage, IntPtr pProgressArg);

接下来在自己的测试代码中编写一个进度条函数,为了方便,先编写一个控制台的,直接从GDAL库中提供的控制台进度条修改而成,进度条函数代码如下。具体可以参考GDAL库中的控制台进度条实现代码,几乎完全一样,除了将printf函数改成了Console.Write,别的没有啥区别。

    class GDALAlgCsTest{//进度信息回调函数static int nLastTick = -1;public int TermProgress(double dfComplete, char[] strMessage, IntPtr Data){int nThisTick = (int) (dfComplete * 40.0);nThisTick = Math.Min(40, Math.Max(0, nThisTick));// Have we started a new progress run?if( nThisTick < nLastTick && nLastTick >= 39 )nLastTick = -1;if( nThisTick <= nLastTick )return 1;while( nThisTick > nLastTick ){nLastTick++;if( nLastTick % 4 == 0 )Console.Write("{0}", (nLastTick / 4) * 10);elseConsole.Write(".");}if( nThisTick == 40 )Console.Write( " - done.\n");elseConsole.Write("");return 1;}
}

接下来就是在测试代码中进行调用了。下面是我将GDAL库的算法进行了封装,不过进度条的接口与GDAL库中的算法进度条接口一模一样,我封装了一个波段合并的算法,就是将好几个单波段文件合并为一个多波段文件,主要是用来将Landsat卫星下载的分波段存储的数据进行合并形成一个多波段的数据。函数的接口声明如下:

        /// <summary>/// 图像波段合并/// </summary>/// <param name="astrSrcFileList">输入文件列表,所有的输入路径中间使用*号进行分割</param>/// <param name="strDstFile">输出文件路径</param>/// <param name="iDataType">栅格数据的数据类型(参考GDALDataType)</param>/// <param name="bUnion">范围不一致的图像处理方式,true为求并,false为求交</param>/// <param name="strFormat">输出文件格式,详细参考GDAL支持数据类型</param>/// <param name="pFun">进度条回调函数</param>/// <param name="pUserData">进度条指针</param>/// <returns>返回值,表示计算过程中出现的各种错误信息</returns>[DllImport("GDALAlg", EntryPoint = "ImageLayerStack")]public static extern int ImageLayerStack(char[] astrSrcFileList, char[] strDstFile, int iDataType,bool bUnion, string strFormat, ProgressFunc pFun, IntPtr pUserData);

最后两个参数就是进度条参数,倒数第二个为进度条回调函数(C#里面的委托函数),倒数第一个参数为进度条所需的参数信息。具体请参考我之前的进度条相关的博客。上面的函数实现此处不再进行说明,也不是本文的重点。下面就看看怎么调用这个函数并将进度条传入。

using System;
using GdalAlg;
using System.Collections;
using System.IO;
using System.Text;namespace GDALAlgCS
{class GDALAlgCsTest{//进度信息回调函数static int nLastTick = -1;public int TermProgress1(double dfComplete, char[] strMessage, IntPtr Data){int nThisTick = (int) (dfComplete * 40.0);nThisTick = Math.Min(40, Math.Max(0, nThisTick));// Have we started a new progress run?if( nThisTick < nLastTick && nLastTick >= 39 )nLastTick = -1;if( nThisTick <= nLastTick )return 1;while( nThisTick > nLastTick ){nLastTick++;if( nLastTick % 4 == 0 )Console.Write("{0}", (nLastTick / 4) * 10);elseConsole.Write(".");}if( nThisTick == 40 )Console.Write( " - done.\n");elseConsole.Write("");return 1;}static void Main(string[] args){//声明进度信息回调函数ProgressFunc pd = new ProgressFunc(new GDALAlgCsTest().TermProgress1);IntPtr p = new IntPtr(0);int ire = 0;string strLandsat1 = @"F:\Data\LandSat\LT51230322011159IKR00\LT51230322011159IKR00_B1.TIF";string strLandsat2 = @"F:\Data\LandSat\LT51230322011159IKR00\LT51230322011159IKR00_B2.TIF";string strLandsat3 = @"F:\Data\LandSat\LT51230322011159IKR00\LT51230322011159IKR00_B3.TIF";string strLandsat4 = @"F:\Data\LandSat\LT51230322011159IKR00\LT51230322011159IKR00_B4.TIF";string strLandsat5 = @"F:\Data\LandSat\LT51230322011159IKR00\LT51230322011159IKR00_B5.TIF";string strLandsat6 = @"F:\Data\LandSat\LT51230322011159IKR00\LT51230322011159IKR00_B6.TIF";string strLandsat7 = @"F:\Data\LandSat\LT51230322011159IKR00\LT51230322011159IKR00_B7.TIF";string strInfiles = strLandsat1 + "*" + strLandsat2 + "*" + strLandsat3 + "*" + strLandsat4 + "*" + strLandsat5 + "*" + strLandsat6 + "*" + strLandsat7;string strChineseOut = @"F:\Data\LandSat\LT51230322011159IKR00.tif";ire = GdalAlgInterface.ImageLayerStack(strInfiles.ToCharArray(), strChineseOut.ToCharArray(), 0, false, "GTiff", pd, p);Console.Write(ire.ToString());}}
}

上面程序运行中进度效果如下图所示。

上面的是控制台的,那么在图形界面中如何编写呢。接下来就写一个图形界面的进度条。声明代理函数都一样,只不过就是自己需要根据各自界面的进度条控件编写对应的进度函数。也就是上面类似的TermProgress1函数。首先做一个简单的界面,如下图所示。

首先看这个界面的进度条实现函数。在该Form类中定义一个进度条类,具体代码如下:

        public class Progress{public int ProgressBarInfo(double dfComplete, char[] strMessage, IntPtr pData){GDALForm form = (GDALForm)Control.FromHandle(pData);int iValue = (int)(100 * dfComplete + 0.5);form.progressBar.Value = iValue;string strMsg = new string(strMessage);form.labelMessage.Text = strMsg;return 1;}}

首先对函数ProgressBarInfo的参数进行说明,dfComplete是进度信息,0~1之间的小数,strMessage是进度信息,主要是一些说明文字,最后一个pData是用户自定义的结构信息,这里的pData就是整个Form的handle。这样就可以从这个Form的handle中转换为界面类的一个对象,并从中获取进度条控件,然后将进度信息设置给进度条控件,将Message设置给界面的一个Label。

下面再看看函数调用。

        private void buttonOK_Click(object sender, EventArgs e){try{int iRev = 0;string strInput = textBoxInput.Text;string strOutput = textBoxOutput.Text;string strField = "OBJECTID";ProgressFunc pd = new ProgressFunc(new Progress().ProgressBarInfo);IntPtr pre = this.Handle;iRev = GdalAlgInterface.ShpRasterize(strInput.ToCharArray(), strOutput.ToCharArray(), 10, 1, 0, strField.ToCharArray(), "GTiff", pd, pre);MessageBox.Show("处理返回代码:" + iRev.ToString(), "提示");}catch (System.Exception ex){MessageBox.Show(ex.ToString(), "提示");}}

在点击【计算】按钮之后,先获取输入和输出的文件路径,然后声明一个委托,用户定义的结构信息给当前form的handle。然后将委托函数和handle传入算法函数即可。程序运行的截图如下所示。该算法为矢量栅格化的一个封装函数。

上面的两个截图和界面设计截图有点不一致,主要是将矢量栅格化的几个参数可以由界面进行设置。上面的代码中这几个参数都是在代码中设置死的。其他的都一样,对于进度条这块没有任何变动。

C#调用GDAL算法进度信息传递相关推荐

  1. GDAL算法进度条使用说明

    在调用GDAL算法的时候,希望能够显示其处理进度信息,其实在GDAL的算法API中,一般最后两个参数就是进度信息的指针.下面分别实现两种进度条信息,一种是在控制台中的进度条,一种是基于QT界面的进度条 ...

  2. GDAL库进度信息编写示例

    GDAL进度信息编写 GDAL库中的算法以及读写数据的时候一般都会提供两个与进度信息相关的参数,下面分别进行描述: GDALProgressFunc pfnProgress void * pProgr ...

  3. 从信息传递的角度来看Android中的广播和Binder

    缘起 在<关于Android学习的三个终极问题>一文的最后,我曾提到过在看完<信息简史>一书后,顿悟到"开发软件的时候仿佛能看到信息在流动".<信息简 ...

  4. 面向对象之信息传递为何是调用方法

    为啥对象之间的信息传递是调用对象的方法呢?为啥通知对象或向对象发送消息就是调用被通知对象的方法呢?为啥我通知你就是调用你的方法? 面向对象的终极目标是高度拟人化. 可以观察下,人的五官就是人类的方法, ...

  5. 图网络算法——信息传递和节点分类

    图网络算法--信息传递和节点分类 在开始介绍下面的算法问题之前,我们首先从提出一个问题,给定一个某些节点具有分类标签的网络结构,我们应该如何去预测网络中其他节点的标签呢? 这种节点分类的方式称为半监督 ...

  6. 信息传递(tarjan算法)

    信息传递 来源: NOIP 2015 Day1 T2 题目描述: 有个同学(编号为 1 到)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为的同学的信息传递对象是编号为的 ...

  7. Notification使用详解之四:由后台服务向Activity发送进度信息

    上次讲到了如何在Activity中监听后台服务的进度信息,实现的方式是让Activity与后台服务绑定,通过中间对象Binder的实例操作后台服务.从效果上来讲,这种方式是可行的,不过这种实现有个缺点 ...

  8. Qt多线程调用gdal库接口

    作者:朱金灿 来源:clever101的专栏 为什么大多数人学不会人工智能编程?>>> 效果图和程序说明   效果图如下:   这个程序是Qt的GUI程序,用于给指定的图像文件创建金 ...

  9. java调用python算法

    做项目的时候,尤其是java开发时,经常会遇到调用python算法的情况,本人最近在项目中遇到这样一个问题:网页前端设计了一个与用户聊天的对话窗口(类似qq聊天),主要目的是为用户解答一些常见的问题. ...

最新文章

  1. Delphi - 数组 详解
  2. 开源企业级数字化服务平台——Choerodon猪齿鱼发布0.8版本
  3. 安装JDK、Tomcat
  4. 用python处理excel数据的优势-python数据分析相对于bi和excel的优势是什么?
  5. 计算机视觉与模式识别方面的代码code
  6. python无法使用pip_解决无法使用pip命令加载Python的扩展库问题
  7. webservice用soapUI测试日期格式输入
  8. 深入理解HTML表格
  9. 信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言——1083:计算星期几
  10. Spring cloud集成Rabbitmq
  11. 计算机网络实验中S1是啥意思,某计算机A需要访问域名www.yy.com,它首先向本域DNS服务器S1查询,.._简答题试题答案...
  12. node.js中对 redis 的安装和基本操作
  13. 苹果抛弃 OpenGL!
  14. 简单实用的带引脚保护的RS232驱动电路
  15. 数学建模——怎样学习数学建模
  16. CAD绘图设计效率慢?这些外挂神器帮你1小时完成3小时的工作!
  17. 我的NAS安装之旅(1)——硬件和软件选型篇
  18. MATLAB绘图函数ezplot入门详解
  19. Java实现百度贴吧自动签到器
  20. FastQC原始安装

热门文章

  1. enter对应的keycode_vue 添加enter回车事件
  2. 计算机考试属于相对性评价还是绝对性评价,【易错检测】查漏补缺第46天 — 相对性评价与绝对性评价...
  3. ifpc币_劳力士手表价格表一览表
  4. js+运行+php+文件,php中运行JS
  5. SLS机器学习介绍(05):时间序列预测
  6. [译] 使用 iPhone X 与 Maya 实现快速面部捕捉
  7. Spring3.0核心组件的源码简单分析
  8. 【Computer Organization笔记29】大作业展示
  9. zabbix------监控小技巧
  10. java gui 布局 旋转_JAVA GUI编程之布局管理器