ArcGIS Engine使用GP工具
在ArcGIS Engine的开发过程中也必不可少的会遇到调用GP工具的问题,调用GP工具的方式有两种:一种是使用Geoprocessing类;另一种是使用Geoprocessor托管类。两者也可能混合使用。
一、GP工具的调用方式
以调用系统工具Dissolve为例:
准备数据:
1、使用Geoprocessing类
工具参数使用IVariantArray方式输入;且参数是有顺序的,其顺序以工具帮助中的参数顺序为准。 如果想要略过某个参数,则传入空字符串(即采用该参数的默认值),以保证参数的顺序是正确的。工具的名称也要按照语法中的写。例如Dissove工具的名称为"Dissolve_management"。顺序写错导致执行失败。
private void Dissolve(IFeatureClass sourceFClass)
{
ESRI.ArcGIS.Geoprocessing.IGeoProcessor gp = new ESRI.ArcGIS.Geoprocessing.GeoProcessorClass();
gp.OverwriteOutput = true;
//除了使用IGeoProcessorResult接口获取GP处理结果外,还可以直接将GP的输出结果写入FeatureClass中,方便进行使用
ESRI.ArcGIS.Geoprocessing.IGeoProcessorResult result = new ESRI.ArcGIS.Geoprocessing.GeoProcessorResultClass();
// Create a variant array to hold the parameter values.
IVariantArray parameters = new VarArrayClass();
object sev = null;
try
{
// Populate the variant array with parameter values.用参数值填充变量数组
parameters.Add("F:\\GIS测试数据\\新建文件地理数据库.gdb\\ABCD");//parameters.Add(sourceFClass);
parameters.Add("F:\\GIS测试数据\\新建文件地理数据库.gdb\\diss");
ESRI.ArcGIS.Geoprocessing.IGpValueTableObject pObject = new ESRI.ArcGIS.Geoprocessing.GpValueTableObjectClass(); //对多个字段进行融合添加
pObject.SetColumns(1);
pObject.AddRow("MC");
pObject.AddRow("DM");
parameters.Add(pObject); //等同于parameters.Add("MC;DM");
parameters.Add(""); //传入空值,保证顺序正确
parameters.Add("SINGLE_PART"); // 等同于parameters.Add("false");
// Execute the tool.
result = gp.Execute("Dissolve_management", parameters, null);
IFeatureClass dealFclss = gp.Open(result.ReturnValue) as IFeatureClass;
}
catch (Exception ex)
{
// geoprocessing execution error messages.
gp.GetMessages(ref sev); //不知为什么返回一直为null
ReturnMessages(gp);
}
}
2、使用Geoprocessor托管类
需要创建工具对象,参数作为该工具对象的属性输入。需要添加该工具的工具箱的引用,例如Dissolve工具需要添加ESRI.ArcGIS.DataManagementTools引用。
private void Dissolve(IFeatureClass sourceFClass)
{
ESRI.ArcGIS.Geoprocessor.Geoprocessor gp = new ESRI.ArcGIS.Geoprocessor.Geoprocessor();
gp.OverwriteOutput = true; //是否覆盖原文件
try
{
ESRI.ArcGIS.DataManagementTools.Dissolve diss = new ESRI.ArcGIS.DataManagementTools.Dissolve();
diss.in_features = "F:\\GIS测试数据\\新建文件地理数据库.gdb\\ABCD";//sourceFClass; 可以填写文件路径或则要素类
diss.out_feature_class = "F:\\GIS测试数据\\diss2.SHP";//"F:\\GIS测试数据\\新建文件地理数据库.gdb\\AC";
diss.multi_part = "false"; //Boolean只能填写"false"或"true"
diss.dissolve_field = "MC;DM";
gp.Execute(diss, null);
//IGeoProcessorResult result = (IGeoProcessorResult)gp.Execute(diss,null);
////除了使用IGeoProcessorResult接口获取GP处理结果外,还可以直接将GP的输出结果写入FeatureClass中,方便进行使用
//IFeatureClass dealFclss = gp.Open(result.ReturnValue) as IFeatureClass;
}
catch
{
ReturnMessages(gp);
}
}
工具执行后效果为:
二、设置GP环境变量
GP工具有些通用的属性,当一个工具执行时,当前环境中的某些设置被当作全局输入参数,例如工作空间、输出数据的坐标系、容差等等,都可以在环境变量中设置。详细信息参考:Using environment settings
/// <summary>
/// 设置GP工具环境变量
/// </summary>
public void SetGPEnvironment()
{
ESRI.ArcGIS.Geoprocessing.IGeoProcessor gp = new ESRI.ArcGIS.Geoprocessing.GeoProcessorClass();
//或则ESRI.ArcGIS.Geoprocessor.Geoprocessor gp = new ESRI.ArcGIS.Geoprocessor.Geoprocessor();
// Set overwrite option to true.
gp.OverwriteOutput = true;
// Set workspace environment.
gp.SetEnvironmentValue("workspace", "F:\\GIS测试数据\\测试.gdb");
gp.SetEnvironmentValue("XYTolerance", "0.02 meters");
// Get the workspace environment value.//获取当前环境变量的值
object env = gp.GetEnvironmentValue("workspace");
// Reset the environment values to their defaults. 重置到原始状态
gp.ResetEnvironments();
}
三、GP工具参数写法的注意事项
1,如果GP工具的参数类型是要素类,要素图层,栅格数据,栅格图层的话,最好使用要素类或者栅格数据的绝对路径,这样最稳定。如果传入AO对象,比如IFeatureLayer、IFeatureClass、IRasterDataset、IRasterLayer等,不太稳定,有时可以成功,有时则失败,所以强烈推荐使用数据的绝对路径方式。还有一点需要注意就是要素类的路径中最好不要含有中文、空格等特殊字符、路径不要过长,并且需要对该数据具有读写权限。
2,如果要素类存储在SDE中,怎么写呢?可以使用该.sde连接文件的绝对路径+要素类名称的写法,比如: @”C:\Users\Feng\AppData\Roaming\ESRI\Desktop10.2\ArcCatalog\连接到 127.0.0.1.sde\SDE.diss”;当然这是使用的ArcCatalog中自动生成的.sde文件,如果没有或者不想使用该连接文件的话也可以使用IWorkspaceFactory.Create()方法或者GP工具Create ArcSDE Connection File根据参数来创建.sde连接文件。
3,GP工具的参数不会写或者写法有误的处理技巧:可以先在ArcMap中使用相同参数执行该GP工具成功后,然后在菜单栏–>Geoprocessing–>Results中打开Results窗口,查看刚才执行成功的GP历史,在Inputs项中查看或直接复制各参数的填写方式到代码中即可。
4,如果工具中需要输入多个要素类,参数怎么写?比如Intersect_analysis工具,如果对两个要素类求交可以这么写:intersect.in_features = @”C:\Users\a\Desktop\test\1.shp;C:\Users\a\Desktop\test\2.shp”;
其实在Result界面有其分隔符的写法即分号。其它工具也类似,比如:Reclassify工具,其映射参数可以这样写reclassify.remap = “589 1070 1;1070 1555 2;1555 2169 3;2169 3311 4”; 不同类别用分号隔开,同一类别的最大最小值用空格隔开。再比如Clip_management工具,其范围可以这样写clip.rectangle = “-117.35334730268 33.8297125828826 -116.792366370644 34.4768962586111”;中间用空格隔开。再强调一下:最保险并且准确的就是ArcMap执行成功后,在Results界面复制其写法。
四、获取GP详细报错信息
方法就是把执行GP的语句放进try-catch-finally的结构体中;尝试获取具体的报错信息,如许可级别不够、参数错误等。
/// <summary>
/// 获取GP工具执行后信息
/// </summary>
/// <param name="gp">gp对象(工具调用者)</param>
/// <returns></returns>
private string ReturnMessages(object gpr)
{
string ms = "";
if (gpr is ESRI.ArcGIS.Geoprocessor.Geoprocessor gp)
{
if (gp.MessageCount > 0)
{
for (int Count = 0; Count <= gp.MessageCount - 1; Count++)
{
ms += "$" + gp.GetMessage(Count) + "\n\n";
}
}
}
else if(gpr is ESRI.ArcGIS.Geoprocessing.IGeoProcessor gp2)
{
if (gp2.MessageCount > 0)
{
for (int Count = 0; Count <= gp2.MessageCount - 1; Count++)
{
ms += "$" + gp2.GetMessage(Count) + "\n\n";
}
}
}
return ms;
}
五、给GP工具注册事件
1、ExecuteAsync方法是提交工具到当前进程已存在的geoprocessing队列中,当后台执行到这个工具时会触发ToolExecuting事件,这时该工具的IGeoProcessorResults.Status属性变为esriJobStatus.esriJobWaiting。该事件所有工具都会触发。
2、在工具执行过程中能触发MessagesCreated和ProgressChanged事件,这些事件依赖于所使用的工具以及工具处理的数据量。
3、当工具执行完成时触发ToolExecuted事件,该事件所有工具执行结束时都会触发。
4、工具可以在任何时刻取消,调用IGeoProcessorResult2.Canael() 即可,取消后其状态变为esriJobStatus.esriJobCancelled。当工具执行失败时,返回esriJobStatus.esriJobFail。
原文来自:https://blog.csdn.net/xinying180/article/details/70159142
/// <summary>
/// 注册GP工具事件
/// </summary>
public void RegisterGPEvent()
{
ESRI.ArcGIS.Geoprocessor.Geoprocessor gp = new ESRI.ArcGIS.Geoprocessor.Geoprocessor();
gp.ProgressChanged += new EventHandler<ESRI.ArcGIS.Geoprocessor.ProgressChangedEventArgs>(gpProgressChanged);
gp.ToolExecuted += new EventHandler<ESRI.ArcGIS.Geoprocessor.ToolExecutedEventArgs>(gpToolExecuted);
// Set overwrite option to true.
gp.OverwriteOutput = true;
// Set workspace environment.
gp.SetEnvironmentValue("workspace", "F:\\GIS测试数据\\测试.gdb");
// Create a variant array to hold the parameter values.
IVariantArray parameters = new VarArrayClass();
// Populate the variant array with parameter values.用参数值填充变量数组
parameters.Add("ABC");//parameters.Add(sourceFClass);
parameters.Add("DISS");
parameters.Add("");
parameters.Add(""); //传入空值,保证顺序正确
parameters.Add("SINGLE_PART"); // 等同于parameters.Add("false");
ESRI.ArcGIS.Geoprocessing.IGeoProcessorResult result = (ESRI.ArcGIS.Geoprocessing.IGeoProcessorResult)gp.ExecuteAsync("Dissolve_management", parameters);
//result.Cancel(); //取消
}
public void gpToolExecuted(object sender, ToolExecutedEventArgs e)
{
ESRI.ArcGIS.Geoprocessing.IGeoProcessorResult result = e.GPResult as ESRI.ArcGIS.Geoprocessing.IGeoProcessorResult;
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.
}
}
else
{
//Get all messages.
string ms = "";
IGPMessages msgs = result.GetResultMessages();
for (int i = 0; i < result.MessageCount; i++)
{
IGPMessage2 msg = msgs.GetMessage(i) as IGPMessage2;
//Application specific code.
ms += "$" + result.GetMessage(i) + "\n\n";
}
}
}
public void gpProgressChanged(object sender, ESRI.ArcGIS.Geoprocessor.ProgressChangedEventArgs e)
{
ESRI.ArcGIS.Geoprocessing.IGeoProcessorResult gpResult = (ESRI.ArcGIS.Geoprocessing.IGeoProcessorResult)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):
var v= (int)e.ProgressPercentage;
//progressBar.Value = (int)e.ProgressPercentage;
break;
default:
throw new ApplicationException(
"unexpected ProgressChangedEventsArgs.ProgressChangedType");
}
}
推荐阅读
-
3gp格式转换器怎么用?飞速3gp转换器工具使用教程
-
使用Arcgis Engine 二次开发的使用和总结
-
3gp转换工具-avi/flv/rmvb/3gp格式转换器图文使用教程
-
ArcGIS Engine使用GP工具
-
使用C#配合ArcGIS Engine进行地理信息系统开发
-
3gp格式转换器怎么用?飞速3gp转换器工具使用教程
-
Arcgis object for java 访问栅格数据,使用GP工具,进行栅格矢量化---栅格矢量化面。
-
Arcgis object for java 访问栅格数据,使用GP工具,进行栅格矢量化---栅格矢量化面。
-
3gp转换工具-avi/flv/rmvb/3gp格式转换器图文使用教程
-
使用C#配合ArcGIS Engine进行地理信息系统开发