ArcGIS Engine中如何调用GP工具(二)

上一篇文章最后提到过GP工具的许可,这篇文章就详细讲解一下调用GP工具的许可问题,这也是Engine中调用GP工具出错最多的一类问题。除此之外,再介绍一下Engine中如何设置环境变量以及如何调用后台64位GP。首先看下最最重要的许可问题。
一、许可问题
ArcGIS按产品来说可以分为ArcGIS Desktop以及ArcGIS Engine(当然还包括ArcGIS Server、Portal for ArcGIS以及ArcGIS Runtime等,由于本文不涉及就不介绍了),这二者都是基于ArcObjects组件开发的产品。Desktop产品的许可分为三个级别,即Basic、Standard以及Advanced;Engine产品的许可分为两个级别,即Engine许可以及Engine + Geodatabase Update扩展许可(简称EngineGeoDB许可)。AO帮助中说明了Engine许可相当于Desktop的Basic许可级别,而EngineGeoDB许可则相当于Desktop的Standard许可级别。

Tips:至于Basic许可和Standard许可的区别(其实等同于Engine和EngineGeoDB许可的区别)可以参考Desktop help中ArcGIS for Desktop Basic and the geodatabase
为什么说上面一堆感觉无关主题的话呢,是因为每个GP工具都有其相应的许可级别,Basic级别能调用的工具用Engine许可就可以调用,Standard级别能调用的工具用EngineGeoDB许可就可以调用,而只有Advanced级别能调用的工具Engine产品是无法调用的。具体可以在ArcMap中打开该工具,点击GP对话框右下角的Tool Help,第一行就是该工具的License Level,如Buffer工具:

前面小方框中打钩就是说该许可级别可以调用,不打钩就是无法调用,而小方框中画黑色方框就是说使用过程中有限制,在工具帮助中会有相应说明,如:

也就是说如果要将line_side设为Left,Right等使用Engine许可或者EngineGDB许可是不行的。
再比如ExtractByMask工具,其License Level:

最下方一行有说明,该工具需要Spatial Analyst扩展许可。

也就是说Engine程序中需要检出Spatial Analyst扩展许可才能执行该工具。有两种方式检出扩展许可:
一是使用LicenseControl控件:
选中LicenseControl控件,右键选择属性,在弹出窗体右侧的Spatial Analyst方框处打钩;
二是使用AO代码检出扩展许可:
ao.CheckOutExtension(esriLicenseExtensionCode.esriLicenseExtensionCodeSpatialAnalyst);
再比如Erase工具:

只能Advanced许可才能调用,也就是Engine或EngineGeoDB许可无法调用该工具。但有的用户说了,我就想在程序中调用Erase工具怎么办?办法是有,但是有前提:首先机器上安装了Desktop产品,并且授权了Advanced许可;其次是程序界面不能使用MapControl、TOCControl、ToolBarControl等控件,原因在于任何接口都有其适用的产品,比如IMapControl控件,AO帮助中明确说明只能在ArcGIS Engine产品下使用:

所以如果想要调用Erase工具,而原有工程中使用了MapControl等控件的话,建议另外新建工程绑定Desktop产品(最好不要使用EngineOrDesktop,不然如果机子上安装了Engine会默认绑定Engine产品),代码中初始化Advanced许可,如下:
ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.Engine);
ESRI.ArcGIS.esriSystem.IAoInitialize ao = new ESRI.ArcGIS.esriSystem.AoInitialize(); ao.Initialize(ESRI.ArcGIS.esriSystem.esriLicenseProductCode.esriLicenseProductCodeAdvanced);


这里做一下提醒:如果程序中初始化了Advanced许可,给客户部署时也要求部署机上有该许可。
有一点很重要放在最后:一个程序中只能使用一种方式初始化一次许可。什么意思呢?包含两层意思:一是LicenseControl控件(左侧单选,右侧多选)和AO代码初始化许可两种方式只能选择一种,不然如果两种方法都用了但初始化的许可不一样,程序无法判断到底使用什么许可;二是不要初始化多次许可,比如初始化过一次Engine许可,后来又初始化了EngineGeoDB许可,同样,程序中也无法判断。举个例子,比如用户调用SimplifyLine_cartography工具(该工具Basic许可无法调用),一直报没有许可错误,但是用户一口咬定就是初始化的EngineGeoDB许可,那怎么还会报许可错误呢,查找原因就是因为其初始化了两次许可,而且还不一样导致。
二、如何设置环境变量?
GP工具有些通用的属性,当一个工具执行时,当前环境中的某些设置被当作全局输入参数,例如Extent、输出数据的坐标系、新生成栅格数据的像元大小等等,都可以在环境变量中设置。
1,设置环境变量
所有环境变量名称都用string表示,并且不区分大小写,即”workspace”和”Workspace”均可。下面是一些常用变量的写法:
设置workspace:
gp.SetEnvironmentValue("workspace", @"C:\data\saltlake.gdb");

设置extent:
gp.SetEnvironmentValue("extent", "-3532000, -911000, -3515000, -890000");

设置输出坐标系:
gp.SetEnvironmentValue("outputCoordinateSystem", @"…\NAD 1983 UTM Zone 11N.prj");
 
或者
gp.SetEnvironmentValue("outputCoordinateSystem", "PROJCS['NAD_1983_UTM_Zone_11N',GEOGCS['GCS_North_American_1983',DATUM['D_North_American_1983',SPHEROID['GRS_1980',6378137.0,298.257222101]],PRIMEM['Greenwich',0.0],UNIT['Degree',0.0174532925199433]],PROJECTION['Transverse_Mercator'],PARAMETER['False_Easting',500000.0],PARAMETER['False_Northing',0.0],PARAMETER['Central_Meridian',-117.0],PARAMETER['Scale_Factor',0.9996],PARAMETER['Latitude_Of_Origin',0.0],UNIT['Meter',1.0]]");

设置Mask:
gp.SetEnvironmentValue("mask", @"E:\ZhuXinying\testData\Data.gdb\polygonMask");

2,获取当前环境变量的值并重置到原始状态
// Get the cell size environment value.
object env = gp.GetEnvironmentValue("cellsize");
// Reset the environment values to their defaults.
gp.ResetEnvironments();


3,将设置的环境变量保存为.xml,后续使用的话可以直接加载:
gp.SetEnvironmentValue("workspace", @"C:/data/mydata.gdb");
gp.SetEnvironmentValue("extent", "-3532000, -911000, -3515000, -890000");
// Save environment settings to an XML file.
string settingsFile = @"C:\sdk\MyCustomSettings.xml";
gp.SaveSettings(settingsFile);
// Load previously saved environment settings.
gp.LoadSettings(settingsFile);
object sExtent = gp.GetEnvironmentValue("workspace");

详细信息可以参考<a href="http://resources.arcgis.com/en ... Using environment settings
三、如何调用后台GP?
不知您是否注意到ArcGIS Engine安装光盘里有这样一个安装包:

这个安装包就是Engine的后台64位GP工具包,该包是在ArcGIS Engine 10.1 SP1中开始出现的,只能安装在64位机子上,安装后会在Engine的安装目录下多一个bin64的目录(后台执行应该使用的是这里的dll),在使用Geoprocessor.ExecuteAsync异步执行GP工具时调用。
相关事件:
1,ExecuteAsync方法是提交工具到当前进程已存在的geoprocessing队列中,当后台执行到这个工具时会触发ToolExecuting事件,这时该工具的IGeoProcessorResults.Status属性变为esriJobStatus.esriJobWaiting。该事件所有工具都会触发。
2,在工具执行过程中能触发MessagesCreated和ProgressChanged事件,这些事件依赖于所使用的工具以及工具处理的数据量。
3,当工具执行完成时触发ToolExecuted事件,该事件所有工具执行结束时都会触发。
4,模型工具可以看作单一工具,触发ToolExecuting以及ToolExecuted事件,MessagesCreated事件描述模型中每一个工具的进度。
5,工具可以在任何时刻取消,调用IGeoProcessorResult2.Canael()即可,取消后其状态变为esriJobStatus.esriJobCancelled。当工具执行失败时,返回esriJobStatus.esriJobFail。
下面看下具体实现:
Geoprocessor gp = new Geoprocessor();
gp.OverwriteOutput = true;
gp.ToolExecuting += new EventHandler<ESRI.ArcGIS.Geoprocessor.ToolExecutingEventArgs>(gpToolExecuting);
gp.ProgressChanged += new EventHandler<ESRI.ArcGIS.Geoprocessor.ProgressChangedEventArgs>(gpProgressChanged);
//Register to receive the geoprocessor event when the tools have completed execution.
gp.ToolExecuted += new EventHandler<ESRI.ArcGIS.Geoprocessor.ToolExecutedEventArgs>(gpToolExecuted);

// Create a variant array to hold the parameter values.
IVariantArray parameters = new VarArrayClass();
// Populate the variant array with parameter values.
parameters.Add(FileGDBPath + "\\testPoint_10w");
parameters.Add(FileGDBPath + "\\testPoint_10w_Copy");
IGeoProcessorResult2 gpResult = gp.ExecuteAsync("CopyFeatures_management", parameters) as
IGeoProcessorResult2;

 
public void gpToolExecuting(object sender, ToolExecutingEventArgs e)
{
IGeoProcessorResult2 result = e.GPResult as IGeoProcessorResult2;
//Determine if this is the tool to handle this event.
if (result.Process.Tool.Name.Equals("CopyFeatures_management") && result.GetInput(0)
.GetAsText().Equals(FileGDBPath + "\\testPoint_10w") && result.GetOutput(0)
.GetAsText().Equals(FileGDBPath + "\\testPoint_10w_Copy"))
{
//Application specific code.
}
}

 
 public void gpProgressChanged(object sender, ESRI.ArcGIS.Geoprocessor.ProgressChangedEventArgs e)
{
System.Windows.Forms.ProgressBar progressBar = progressBar1;
IGeoProcessorResult2 gpResult = (IGeoProcessorResult2)e.GPResult;
switch (e.ProgressChangedType)
{
case (ProgressChangedType.Show):
//The tool that is running reports progress or has stopped reporting progress; make the
// progress bar visible if appropriate.
//progressBar.Visible = e.Show;
break;
case (ProgressChangedType.Message):
//The application does not use these, since a tool being used reports percentage progress.
break;
case (ProgressChangedType.Percentage): progressBar.Value = (int)
e.ProgressPercentage;
break;
default:
throw new ApplicationException(
"unexpected ProgressChangedEventsArgs.ProgressChangedType");
break;
}
}
 
public void gpToolExecuted(object sender, ToolExecutedEventArgs e)
{
IGeoProcessorResult2 result = e.GPResult as IGeoProcessorResult2;
if (result.Status.Equals(esriJobStatus.esriJobSucceeded))
{
//Check that there are no information or warning messages.
if (result.MaxSeverity == 0)
{
//Get the return value.
object returnValue = result.ReturnValue;
//Application specific code,
//for example, find the layer to which this return value corresponds.
}
else
{
//Application specific code.
}
myWatch.Stop();
string time = myWatch.Elapsed.TotalSeconds.ToString();
MessageBox.Show(time + " Seconds");
}
else
{
//Get all messages.
IGPMessages msgs = result.GetResultMessages();
for (int i = 0; i < result.MessageCount; i++)
{
IGPMessage2 msg = msgs.GetMessage(i) as IGPMessage2;
//Application specific code.
}
}
}


再来测试下对相同数据前台执行Copy Features工具和后台执行Copy Features工具的用时对比:
10万个点:前台用时13.26秒,后台用时13.42秒
100万个点:前台用时1分55秒,后台用时1分50秒
最后总结一下调用后台GP的优势:
1,后台GP执行时,用户界面是可响应的,可以执行工具的同时与MapControl进行交互。如果一个GP工具花费很长时间,而用户界面不可能一直无响应,这时使用后台GP就比较好。
2,由于ArcGIS Engine 是32位应用程序,因此,最大只能利用4G内存,如果数据量大或者计算复杂会导致内存超过4G或接近这个数,那么在32位下可能会出错,但是如果安装了64位的后台GP工具包,则不会有这个限制。
3,如果处理小数据量数据用不用后台GP差别不大,但是处理数据量大的话,调用后台GP处理速度更快。
4,不过也有一些限制,如不支持mdb数据、不能调用Geodatabase administration toolset里的工具、操作SDE数据时需要安装64位客户端等,具体可以参考Desktop帮助:Background Geoprocessing (64-bit)
Demo
使用ArcGIS Engine 10.5,Visual Studio 2013编写,界面为:

工程下载地址:
GP_ArcGISEngine
文章来源:http://blog.csdn.net/xinying180/article/details/70159142

1 个评论

史上最好、最经典的ArcGIS Engine和ArcGIS Python开发学习教程重磅出炉了,观看地址: http://i.youku.com/gisxiaotian

下载地址:https://gisxiaotian.taobao.com/

要回复文章请先登录注册