学习在 ArcEngine 中使用 Geoprocessing

 Geoprocessing对于ArcGIS使用者来说,是一种非常方便实用的工具,它可以利用ArcToolbox中的各种工具为我们的地理空间工作流进行框架建模,自动执行空间分析与处理。

    过去我们可以在ArcToolbox中新建Model,或是写python脚本、AML来构建新的模型,现在ArcEngine 9.2单独提供了com.esri.arcgis.geoprocessing.tools工具包,使得在二次开发中通过Geoprocessing构建应用模型,将ArcGIS众多分析工具集成到我们的应用中成为现实。

    我们就在ArcEngine 9.2 for Java环境中看看如何使用Geoprocessing。

import com.esri.arcgis.geoprocessing.GeoProcessor;
import com.esri.arcgis.geoprocessing.tools.analysistools.Clip;
// Initialize the GeoProcessor 
GeoProcessor gp = new GeoProcessor();
Clip clip
= new Clip("c:/data/mjrroads.shp""c:/data/coasts.shp",  "c:/output/clipOutput.shp");

   
    设置参数

Clip clip = new Clip();
clip.setInFeatures 
= "c:/data/mjrroads.shp";
clip.setClipFeatures 
= "c:/data/coasts.shp";
clip.setOutFeatureClass 
= "c:/output/clipOutput.shp";

   
    代码中Clip构造方法,以及clip对象参数的设置,均和ArcToolbox-->Clip工具相对应。


    Geoprocessor类用来执行Geoprocessing相关工具的操作,geoprocessor的角色是一种helper对象,它的重载方法execute用来运行之前所定义的操作集。

GP.execute(clip, null);

 

    com.esri.arcgis.geoprocessing.IGeoProcessorResult接口的对象可以捕获execute执行后的结果。

// Intialize the Geoprocessor
GeoProcessor gp = new GeoProcessor();
// 使用web service中的toolbox
gp.addToolbox("http://flame7:8399/arcgis/services;GP/Bestpathtoolbox");
// 导入本地的shape文件 
ArrayList parameters = new ArrayList;
parameters.add(
"C:\\sandiego\\source.shp"); 
parameters.add(
"C:\\sandiego\\destination.shp");
// 捕获execute执行结果
IGeoProcessorResult result;
result 
= gp.execute("CalculateBestPath", parameters, null);

 

    名字冲突

    和OO语言处理名字冲突一样,当可能出现名字冲突时,可以使用全名来唯一指定所使用的工具:

ArcToolbox-->Analysis Tools-->Extract-->Clip
ArcToolbox-->Data Management-->Raster-->Clip

com.esri.arcgis.geoprocessing.tools.analysistools.Clip
com.esri.arcgis.geoprocessing.tools.datamanagementtools.Clip

 

    Geoprocessing编程的时候,还可以使用AO作为输入的工具

// Initialize the Geoprocessor 
GPUtilities gpUtilities = new GPUtilities();
IFeatureClass inputFeatureClass 
= gpUtilities.openFeatureClassFromString(inputData+"/canada/mjrroads.shp");
IFeatureClass clipFeatureClass 
= gpUtilities.openFeatureClassFromString(inputData+"/canada/coasts.shp");
Clip clip 
= new Clip(inputFeatureClass, clipFeatureClass, outputDirectory+"/clipOutput.shp");
gp.execute(clip, 
null);

 

    关于GPUtilities和Geoprocessor区别,可以看看这两段描述以及各自的类方法:

The GPUtilities object is mainly intended for developers building custom tools. For more information about building custom tools, refer to the technical document Building Geoprocessing Function Tools.

A geoprocessing tool is executed by a geoprocessor. The geoprocessor is a helper object that simplifies the task of executing tools. Toolboxes define the set of tools available for the geoprocessor. Toolboxes can be added and removed from the geoprocessor.

    ArcToolbox工具都有自己的环境设置,一般情况下我们使用默认值,在AE中可以用setEnvironmentValue方法来设置环境变量的值

// Get the Cell Size environment value
gp.setEnvironmentValue("cellsize", Double.valueOf(10.0));
String env 
= (String) gp.getEnvironmentValue("cellsize");

// Set the output Coordinate System environment            
gp.setEnvironmentValue("outputCoordinateSystem""c:/Program Files/ArcGIS/Coordinate Systems/Projected Coordinate Systems/UTM/Nad 1983/NAD 1983 UTM Zone 21N.prj");

// Reset the environment values to their defaults.
gp.resetEnvironments();

 

    需要注意的是,在使用Geoprocessing建模进行各种空间操作时,我们需要相应的license授权来完成这些操作,如Spatial Join需要ArcInfo License,各种级别License描述可以参考下图:

Flyingis @ China

 

作者:Flyingis

    ArcGIS使用者经常要面对大量的数据处理工作,如果要在自己的程序中使用Geoprocessing,更多的时候我们是要进行对数据进行批处理分析,Geoprocessing为我们提供了丰富的支持批处理的功能。

1.工作空间中查询所需数据

2.模型处理过程中各种输入、环境参数、字段映射的处理

3.枚举、循环执行

--------------------

1.工作空间中查询所需数据

    要对数据进行批处理操作,首先需要知道工作空间中有哪些数据,怎么从工作空间大量数据中提取出我们所需要的数据。GeoProcessor类为我们提供了一些提取数据的方法。

listDatasets (string wildCard, string datasetType)
listFeatureClasses (string wildCard, string featureType, string dataset)
listRasters (string wildCard, string rasterType)
listTables (string wildCard, string tableType)
listToolboxes(string wildCard)
listWorkspaces (string wildCard, string workspaceType)

    看看代码段怎么写:

 

//list all the featureClasses starting with c
gp.setEnvironmentValue("workspace", inputWorkspace);
IGpEnumList featureClasses 
= gp.listFeatureClasses("c*""""");
String featureClass 
= featureClasses.next();
System.out.println(
"-----------Feature Classes starting with c-----------");
while (! "".equals(featureClass)) {
     System.out.println(featureClass);
     featureClass 
= featureClasses.next();
}

 

    通过指定wildCard字符串,搜索所有"c"开头的feature class,将结果存放在com.esri.arcgis.geoprocessing.IGpEnumList枚举List中。看到IGpEnumList千万不要将它和Java数据结构中各种List相提并论,它仅仅具有顺序枚举next和重置查询指针reset的功能,可以被序列化。

    再参考另外两个例子,相信对在工作空间中查询数据会有更多的认识。

    返回所有面状要素

 

System.out.println("\n-----------Polygon Feature Classes-----------");
gp.setEnvironmentValue(
"workspace", inputWorkspace);
featureClasses 
= gp.listFeatureClasses("""polygon""");
featureClass 
= featureClasses.next();
    
while (! "".equals(featureClass)) {            
    System.out.println(featureClass);
    featureClass 
= featureClasses.next();
}

 

    返回所有TIF格式的Raster数据

 

// List all TIF files in the workspace and build pyramids
gp.setEnvironmentValue("workspace", inputWorkspace);
IGpEnumList rasters 
= gp.listRasters("""TIF");
String raster 
= rasters.next();
                  
BuildPyramids buildPyramids 
= new BuildPyramids(raster);
while (! "".equals(raster)) {
    System.out.println(
"\n------------Building pyramids for: " + raster + "----------");
    gp.execute(buildPyramids, 
null);
    raster 
= rasters.next();
}

 

    关于各种list方法TYPE类型,可以参考下表

Method Type Keywords
ListDatasets All, Feature, Coverage, RasterCatalog, CAD, VPF, TIN, Topology
ListFeatureClasses All, Point, Label, Node, Line, Arc, Route, Polygon, Region
ListFields All, SmallInteger, Integer, Single, Double, String, Date, OID, Geometry, Blob
ListWorkspaces All, Coverage, Access, SDE, Folder
ListTables All, dBASE, INFO
ListRasters  All, ADRG, BIL, BIP, BSQ, BMP, CADRG, CIB, ERS, GIF, GIS, GRID, STACK, IMG, JPEG, LAN, SID, SDE, TIF, RAW, PNG, NITF

2.模型处理过程中各种输入、环境参数的处理

    Geoprocessing计算过程中会要求多个输入,通常可以用IGpEnumList来捕获。

 

gp.setEnvironmentValue("workspace", multiWorkspace);
IGpEnumList polygonFCs 
= gp.listFeatureClasses("""polygon""");
String polygon 
= polygonFCs.next();
String polygonsToUnion 
= "";
while (! "".equals(polygon)){
 polygonsToUnion 
+= polygon;
 polygon 
= polygonFCs.next();
 
if (! "".equals(polygon)){
  polygonsToUnion 
+= ";";
 }

}

    
Union union 
= new Union(polygonsToUnion,outputWorkspace+"/unioned.shp");
gp.execute(union, 
null);

 

    另外,可以使用表结构来保存每个输入的参数值,避免全部feature保存在一个字符串中。

 

// List all feature classes in the workspace.
gp.setEnvironmentValue("workspace", multiWorkspace);
IGpEnumList polygonFCs 
= gp.listFeatureClasses("""polygon""");
   
//make the value table
GPValueTable gpValueTable = new GPValueTable();
  
String polygon 
= polygonFCs.next();
String row 
= null;
while (! "".equals(polygon)){
 
if ("center".equals(polygon)){     
     row 
= polygon + " 1";     
 }
 else {
     row 
= polygon + " 2";
 }
      
 gpValueTable.addRow(row);
 polygon 
= polygonFCs.next();
 }

      
Union union 
= new Union(gpValueTable, outputWorkspace+"/unionedValueTable.shp");
gp.execute(union, 
null);

 

3.枚举、循环执行

    前面两点都是针对一个Geoprocessing操作而言,如果需要多个操作,可以用基本程序语言来描述,这分为两种情况,一是多种Geoprocessing的数据处理,一种是同一Geoprocessing循环执行,相比ArcToolbox而言,这里体现的是程序代码带给我们的方便。

Flyingis @ China

 作者:Flyingis

    ArcToolbox每个工具执行之后,都会向Geoprocessor返回消息,包括操作何时开始,使用哪些参数,操作的进度,以及可能出现的问题和错误。消息的种类包括常规消息、警告、错误,GPMessage类可以包含消息的文本及严重等级。

    首先,Geoprocessor.getMessage()方法可以捕获最后一个工具执行后返回的错误消息

String messages = gp.getMessages(2);
System.out.println(messages);

    如何使用GPMessage

//if there was an error then you want to loop the messages
//returned by the geoprocessor to look for the error
GPMessages gpMessages = (GPMessages)gp.getReturnMessages();
for(int i = 0;  i gpMessages.getCount(); i++{
 System.out.println(gpMessages.getMessage(i).getDescription());
}

    可以看出,上面都是通过GeoProcessor的方法来获取消息,除此之外还可以使用IGeoProcessorResult接口,从功能上来说它们没有多少区别。

// Execute Union
IGeoProcessorResult pResult = gp.execute(uniontool, null); 
if (pResult.getMessageCount() > 0)  
 
for(int i = 0;  i <= pResult.getMessageCount() - 1; i++){
  System.out.println(pResult.getMessageCount());
 }

}

    另外我们还可以自定义输出的方法,根据程序执行的过程,可以添加的方法有AddMessage、AddWarning、AddError。下面的示例将feature class从一个工作区复制到另外一个工作区,并跟踪显示每个文件复制的情况。

// Execute Union
IGeoProcessorResult pResult = gp.execute(uniontool, null); 
if (pResult.getMessageCount() > 0)  
 
for(int i = 0;  i <= pResult.getMessageCount() - 1; i++){
  System.out.println(pResult.getMessageCount());
 }

}

Flyingis @ China

posted @ 2009-01-14 09:35  尤文之鹤  阅读(3534)  评论(3编辑  收藏  举报