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
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
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());
}
}