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);
else
Console.Write(".");
} if( nThisTick == 40 )
Console.Write( " - done.\n");
else
Console.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);
else
Console.Write(".");
} if( nThisTick == 40 )
Console.Write( " - done.\n");
else
Console.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库中的算法以及读写数据的时候一般都会提供两个与进度信息相关的参数,下面分别进行描述: GDALProgressFunc pfnProgress void * pProgr ...

  2. tg2015 信息传递 (洛谷p2661)

    题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...

  3. 如何使用 WinInet 时提供下载上载进度信息

    概要许多开发人员都使用 WinInet 函数来下载或上载文件在 Internet 上的想要提供一个进度条以指示多少文件传输已完成,但多少就越长.您可以使用以下机制来完成此.Collapse image ...

  4. NOIP 2015 信息传递

    kawayi 题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的 ...

  5. 【原创】用JAVA实现大文件上传及显示进度信息

    用JAVA实现大文件上传及显示进度信息 ---解析HTTP MultiPart协议 (本文提供全部源码下载,请访问 https://github.com/grayprince/UploadBigFil ...

  6. 如何在Azure环境里做好信息传递可扩展性经验分享

    作者 王枫 发布于2014年5月15日 综述 本文介绍建立一个在Azure上使用Azure服务总线, 高吞吐量短信平台的必要步骤.在这篇文章中提出的解决方案是在响应由客户的具体要求,建立一个基于Win ...

  7. 实现winfrom进度条及进度信息提示,winfrom程序假死处理

    1.方法一:使用线程 功能描述:在用c#做WinFrom开发的过程中.我们经常需要用到进度条(ProgressBar)用于显示进度信息.这时候我们可能就需要用到多线程,如果不采用多线程控制进度条,窗口 ...

  8. 使用VB6写一个自定义的进度信息框窗口

    一.起因说明 之前有些项目是用Access完成的,当时为了给用户显示一些进度信息,自制了一个进度信息窗体,类似下图所示: 随着项目不断变迁,需要将进度信息按阶段及子进度进行显示,并且出于代码封装的需求 ...

  9. 【原创】大叔经验分享(18)hive2.0以后通过beeline执行sql没有进度信息

    一 问题 在hive1.2中使用hive或者beeline执行sql都有进度信息,但是升级到hive2.0以后,只有hive执行sql还有进度信息,beeline执行sql完全silence,在等待结 ...

随机推荐

  1. Unrecognized token 'XXXX': was expecting ('true', 'false' or 'null')

    原因是,返回或发送数据格式不规范. 当dataType指定为json后,1.4+以上的jquery版本对json格式要求更加严格.如果不是严格的json格式,就不能正常执行success回调函数. J ...

  2. 数据挖掘_requests模块的post方法

    前面已经跟大家讲了requests模块的get方法,这一篇文章我们要介绍的是requests模块中的另一个比较常用的方法,post方法 post方法的形式相比于get要复杂一些,这时因为post在提交 ...

  3. 常用java开发文档链接

    使用java开源工具httpClient及jsoup抓取解析网页数据 : https://blog.csdn.net/lovoo/article/details/52674712 jsoup Cook ...

  4. 阻止Enter键回发到服务端Asp.net

    //阻止enter键回发到服务端$(function () {    $("input[type=text]").each(function () {        $(this) ...

  5. Oracle中的列转行例子详解

    数据如下:name id张三 1,2,3 要求实现:name id张三 1张三 2张三 3 --创建临时表 create table tmp as(select '张三' name, '1,2,3' ...

  6. nginx时间设置解析函数

    https://trac.nginx.org/nginx/browser/nginx/src/core/ngx_parse.c /* * Copyright (C) Igor Sysoev * Cop ...

  7. J2EE进阶(十九)FileNotFoundException: http://hibernate.org/dtd/hibernate-mapping-3.0.dtd

    J2EE进阶(十九)Nested exception: java.io.FileNotFoundException: http://hibernate.org/dtd/hibernate-mappin ...

  8. iOS下JS与OC互相调用(八)--Cordova详解+实战

    扯两句,可以跳过 由于项目中Cordova相关功能一直是同事在负责,所以也没有仔细的去探究Cordova到底是怎么使用的,又是如何实现JS 与 OC 的交互.所以我基本上是从零开始研究和学习Cordo ...

  9. XMPP(二)-基于asmack+openfire的安卓客户端(仿QQ)的介绍以及个人心得

    关于XMPP第一篇-openfire的搭建写完后,就一直在赶本篇所要介绍的这个基于asmack+openfire的安卓客户端,费了不少精力,因为有不少同学在还在焦急的等待着(自恋了呵呵),所以紧赶慢赶 ...

  10. 大页内存(HugePages)在通用程序优化中的应用

    今天给大家介绍一种比较新奇的程序性能优化方法-大页内存(HugePages),简单来说就是通过增大操作系统页的大小来减小页表,从而避免快表缺失.这方面的资料比较贫乏,而且网上绝大多数资料都是介绍它在O ...