在 Web 应用程序中使用地理处理任务
ArcGIS Web 制图 API
Web GIS 框架有助于初步了解基于 GIS 的 Web 应用程序。通过 ArcGIS Web API,Web 浏览器可以与 ArcGIS Server GIS 服务进行通信、渲染(绘制)地理数据并执行分析。ArcGIS Web API 具有三种不同形式。分别是:
- ArcGIS API for JavaScript
- ArcGIS API for Flex
- ArcGIS API for Microsoft Silverlight/WPF
这三种 API 具有类似的功能,但分别针对不同的开发语言。要开始使用 Flex 或 Silverlight 开发 Web 应用程序,需要从 ArcGIS 资源中心下载相关库。然而,对于 JavaScript Web API 而言,由于可通过 Web URL 访问库,因此无需下载此库。ArcGIS 资源中心提供示例和解释文档,以便启动 ArcGIS Web API,并且可通过 ArcGIS 资源中心选择适合于具体环境的 Web API。
Web 应用程序中的地理处理任务
使用 ArcGIS 地理处理服务,可将地理处理功能和数据分析添加至 Web 应用程序。每个地理处理服务包含一个或多个地理处理任务。浏览 ArcGIS 服务目录时,可以查找地理处理服务、地理处理任务及其参数和属性。地理处理 REST 服务主题提供有关 REST 资源等级的信息,而地理处理任务介绍主题提供有关地理处理任务、参数和访问方式的详细信息。Web API 提供了合适的对象和方法,以便访问地理处理任务和执行功能。
要在 Web 应用程序中添加某个任务提供的地理处理功能,请遵循以下四个步骤:
- 初始化地理处理任务。
- 设置任务参数。
- 运行任务。
- 渲染结果。
通过这四个步骤,应用程序可以与服务器进行通信、成功执行任务并在应用程序中显示所需结果。下面将介绍如何执行这四个步骤,从而使用 ArcGIS Web API for Javascript 成功添加地理处理功能。虽然对象声明、方法语法和事件处理在其他两个 Web API 中有所不同,但此四步模式是共用的,适用于所有 Web API。这些步骤有助于了解在 Web 应用程序中使用地理处理任务的最佳做法。
在 JavaScript 应用程序中使用地理处理任务
ArcGIS Web API for JavaScript 是其中一个 ArcGIS Web API。如果不熟悉 JavaScript API,获取 ArcGIS API for JavaScript 主题和在 ArcGIS JavaScript 中创建第一个应用程序主题在线 SDK 将帮助您开始使用 JavaScript API。此外,还可以浏览 SDK 中的多个地理处理任务示例和概念。此主题将引导您完成上述四个步骤,从而使用 ArcGIS JavaScript API 将地理处理任务置于 Web 应用程序中。
步骤 1:初始化地理处理任务
要初始化地理处理任务,需要了解任务 URL。地理处理任务 URL 的模板为 http://<arcgis-host>/<gpservicename>/GPServer/<gptask-name>。将以下代码添加到 JavaScript 应用程序中,用于初始化地理处理任务。
执行初始化时,确保将地理处理任务实例的 OutSpatialReference 属性设置为 Web 地图空间参考。地理处理任务数据集可能位于不同的空间参考中,因此其输出所位于的空间参考也有所不同。然而,Web 应用程序假设任务输出与地图的空间参考相同。这可能导致绘制输出时发生异常行为。因此,必须设置地理处理任务的输出空间参考属性。服务器将在由 OutSpatialReference 属性指定的空间参考中返回输出。
初始化地理处理任务
//esri.tasks.gp is required for using Geoprocessor.
//Add along with other dojo.require statements.
dojo.require(esri.tasks.gp);
/*Step 1: Initialize Geoprocessing Task as a global variable
(i.e) declare the variable outside a function definition
since we will be using gpTask variable in other methods */
var gpTaskUrl="http://myserver/ArcGIS/rest/services/" +
"BufferPoints/GPServer/BufferPoints";
var gpTask = new esri.tasks.Geoprocessor(gpTaskUrl);
//set output spatial reference property to map's spatial reference
//myMap is assumed to be an instance of map container esri.map.
gpTask.outSpatialReference=myMap.spatialReference;
步骤 2:设置任务参数
执行地理处理任务时,Web 应用程序必须提供地理处理任务的参数值。要了解任务的参数要求,请复制任务 URL,并将其粘贴到 Web 浏览器地址栏,打开服务目录的“任务”页面。“任务”页面列出了所有任务参数及其数据类型。此外,任务页面还包含帮助 URL,在此可以查找有关地理处理功能、访问和使用的详细信息。
为了成功执行任务,必须为该任务所需的所有输入参数 (EsriGPParameterTypeRequired) 指定值,如“任务”页面所示。通常,任务值来自于以下一个或多个来源:
- 用户使用 Web 应用程序输入的值
- 当前其中一个 Web 地图要素图层或图形图层的值
- 其他任务的结果,如查询、路径任务等
- 其他地理处理任务的结果
以下 JavaScript 代码显示了从添加到 Web 地图的 FeatureLayer 创建输入要素 GPFeatureRecordsetLayer 参数,以及使用 id="distance" 派生于 Dojo 文本输入的 GPLinearUnit 参数 BuffDistance 的示例。此示例假设用户将交互输入距离值。创建任务参数后,构建具有参数名称-值对的 JSON 结构,然后发送至服务器。
设置参数
//Step 2: Setup Parameters of the task
function setupParameters(){
/*The code below assumes that the web map
has a featurelayer with id fLayer.*/
//Get Input Parameter 1 GPFeatureRecordSetLayer from a fLayer.
var inputFeatures = new esri.tasks.FeatureSet();
inputFeatures.features = map.getLayer("fLayer").graphics;
inputFeatures.fields=map.getLayer("fLayer").fields;
//Get Input Parameter 2 : GPLinearunit from a dojo UI element
var buffDistance = new esri.tasks.LinearUnit();
buffDistance.distance=dojo.byId(“distance”).value;
buffDistance.units=”esriMiles”;
//Create Parameter list with name-value pairs.
//Names must match the parameter name in Task page.
//Parameters must be in the same-order as in Task page
var params= { "Input_Features":inputFeatures,
"Distance":buffDistance};
//return name-value pairs of parameters
return params;
}
GPFeatureRecordSetLayer 和 GPRecordSetLayer 参数具有由任务定义的默认方案。您可以在“任务”页面查找参数方案。GPFeatureRecordSetLayer 方案包含几何、空间参考、字段和要素。最好确保 GPFeatureRecordSetLayer 参数具有在方案中定义的所有属性,以获得成功结果。
步骤 3:运行任务
要运行任务,应使用基于地理处理任务支持操作的地理处理器实例 (gpTask) 的 execute 或 submitJob 方法。您可以在“任务”页面查找任务所支持的操作。任务操作:execute 和任务操作:submitJob 主题介绍了各种操作之间的区别以及操作时服务器与客户端之间的通信。
任务操作:execute
如果任务所支持的操作为执行任务,则必须使用地理处理器实例的 execute 方法并传递参数。必须定义事件处理程序,用以根据成功和失败的请求操纵应用程序。当任务成功执行时,触发 onExecuteComplete 事件,并返回结果和地理处理消息。任务执行失败时,触发 onError 事件。任务失败时,服务器将返回错误实例,包含 HTML 错误代码和地理处理消息(如果有)。
任务操作:execute
function myGPExecuteTask(){
//get params from setupParameters method described above.
var params=setupParameters();
//setup onTaskSuccess and onTaskFailure event handlers.
dojo.connect(gpTask, "onExecuteComplete",onTaskSuccess);
dojo.connect(gpTask, "onError",onTaskFailure);
//execute gpTask with params
gpTask.execute(params);
}
//Callback when the Task operation succeeded
function onTaskSuccess(results, messages) {
//do something with the results,
//see more info on Rendering the results section
}
//Handler that is invoked when the Task operation has failed
function onTaskFailure(error) {
//report error to the user appropriately
alert("Error:"+ error);
}
任务操作:submitJob
如果任务所支持的操作是 submitJob 操作,则必须使用 Geoprocessor.submitJob 方法,并传递参数。如果是 submitJob,则触发三个事件,这三个事件必须在 Web 应用程序中进行相应处理。
onStatusUpdate | 接收作业的当前状态时 |
onJobComplete | 作业成功完成时 |
onError | 作业失败时 |
- onStatusUpdate:与 execute 不同,如果是 submitJob,服务器将创建作业,并分配作业 Id。submitJob 操作不会在作业完成时通知客户端,因此,客户端将自行检查服务以确定作业状态。默认情况下,Web 应用程序每秒向服务器发送一次状态请求,以确定任务状态。每次收到状态响应时,都会触发 onStatusUpdate 事件。如果需要,可以通过 Geoprocessor.setUpdateDelay 方法增加或减少状态检查的时间间隔。每次检查作业状态时,都会触发 onStatusUpdate 事件。事件处理程序接收到由服务器返回的 JobInfo 实例,其中包含作业 ID、作业状态和任何 GPMessages。您可以使用此信息保持跟踪任务进程。
- onJobComplete:当 JobInfo.jobStatus = STATUS_SUCCEEDED 时,将触发 onJobComplete 事件。操作完成时,结果不会自动返回至客户端,而是存储在服务器上,客户端必须必须发送请求才能检索结果。在 onJobComplete 事件处理程序中,可以调用 Geoprocessor.getResultData 方法以获取结果。每个输出参数都是独立的资源,因此必须为任务的每个输出参数调用地理处理器实例的 GetResultData 方法。必须提供由事件处理程序返回的作业 Id 以及 GetResultData 方法中的输出参数名称。此外,还必须为 onGetResultDataComplete 事件创建事件处理程序。当 Web 应用程序接收输出参数的结果值时,将触发 onGetResultDataComplete 事件。
- onError:如果 submitJob 请求或状态请求超时或地理处理任务失败,则触发 onError 事件。该事件将返回包含 HTML 错误代码的错误实例。
任务操作:submitJob
function myGPSubmitJob(){
//get params from setupParameters method described above.
var params=setupParameters();
//setup event handlers.
dojo.connect(gpTask, "onJobComplete",onTaskComplete);
dojo.connect(gpTask, "onError",onTaskFailure);
dojo.connect(gpTask, "onStatusUpdate",onTaskStatus);
gpTask.submitJob(params);
}
//Event handler for onJobComplete event
function onTaskComplete(jobInfo) {
/*get the value of an output parameter Buffer_polygons
using getResultData. The name of the output
may vary in your gpTask*/
dojo.connect(gpTask, "onGetResultDataComplete",
onTaskResultComplete);
gpTask.getResultData(jobInfo.jobId,
"Buffer_polygons");
}
//Event handler for onStatusUpdate event
function onTaskStatus(jobInfo) {
//write status to console to help debugging
console.log(jobInfo.jobStatus);
}
//Event handler for onError event
function onTaskFailure(error) {
//report error to the user appropriately
alert("Error:"+ error);
}
步骤 4:渲染结果
根据输出参数的数据类型渲染地理处理任务的结果。
GPFeatureRecordSetLayer | 输出要素在 Web 地图中通常绘制为图形图层,用于显示地理处理结果。 |
GPRecordSet | 在格网中显示输出记录,或者将这些值用于创建图表和图形。 |
GPRasterDataLayer | 输出栅格可以下载,但无法在地图中绘制。然而,可以使用结果地图服务显示栅格数据。 了解有关结果地图服务和在 Web 应用程序中使用结果地图服务的详细信息 |
GPDataFile | 输出文件可以下载,或者诸如 .gpx 和 .csv 之类的文件可通过 Web 应用程序进行处理。 |
GPBoolean、GPDataFile、GPLong、GPDouble、GPString、GPLinearUnit、GPDate | 使用 HTML 或其他微件显示输出。 |
从 onExecuteComplete 事件处理程序中获得的结果
如果是 execute 操作,onExecuteComplete 事件将返回地理处理任务的结果和消息。结果实例是任务的所有输出参数的数组,数组中的条目始终按照“任务”页面列出的顺序排列。因此,可以通过数组中参数值的位置来识别各个参数值。数组中的每个输出参数都具有参数名称、数据类型和值。下列代码显示了如何访问结果中的第一个输出参数。在以下代码中,输出参数称为 GPFeatureRecordSetLayer 输出,因此该代码可说明如何将参数渲染为图形图层并将其添加到 Web 应用程序中。
渲染 onExecuteComplete 事件处理程序中的结果
function onTaskSuccess(results, messages) {
/*retrieve the output parameter value based
on its position from the result instance.
In the case shown below, the output is the first output
parameter of the task and it
is a GPFeatureRecordSetLayer.*/
var featureset = results[0].value;
//create a graphics layer with features
var taskResultLayer= new esri.layers.GraphicsLayer
({id:"MyGPExecuteResultLayer"});
//Create a symbol based on the geometry.
//The geometry is assumed to be polygons in the code below
var simplePolySymbol = new esri.symbol.SimpleFillSymbol();
simplePolySymbol.setOutline(new esri.symbol.SimpleLineSymbol(
esri.symbol.SimpleLineSymbol.STYLE_SOLID,
new dojo.Color([0,0,0,0.5]), 1));
simplePolySymbol.setColor(new dojo.Color([255,0,0,0.7]));
//Create graphics from features and add it graphicslayer
dojo.forEach(featureset.features,function(feature){
feature.setSymbol(simplePolySymbol);
//Add feature to the graphics layer
taskResultLayer.add(feature);});
}
//add graphicslayer to webmap
//myMap is assumed to be an instance of map container esri.map
myMap.addLayer(taskResultLayer)
}
从 onGetResultDataComplete 事件处理程序中获得的结果
onGetResultDataComplete 事件提供了结果实例。与 onExecuteComplete 事件中的结果不同,该结果实例仅具有请求参数值。参数结果将包含请求参数的名称、数据类型和值。从结果中检索参数值,并根据需要使用。以下代码显示了如何渲染参数结果实例中 GPFeatureRecordSetLayer 参数的结果。
从 OnGetResultDataComplete 事件处理程序中获得的结果
function onTaskResultComplete(paramResult) {
//retrieve the value of the parameter from the paramresult
var featureSet = paramResult.value;
//create a graphics layer with features
var taskResultLayer= new esri.layers.GraphicsLayer
({id:"MyGPSubmitJobResultLayer"});
//Create a symbol based on the geometry.
//The geometry is assumed to be polygons in the code below
var simplePolySymbol = new esri.symbol.SimpleFillSymbol();
simplePolySymbol.setOutline(new esri.symbol.SimpleLineSymbol(
esri.symbol.SimpleLineSymbol.STYLE_SOLID,
new dojo.Color([0,0,0,0.5]), 1));
simplePolySymbol.setColor(new dojo.Color([255,0,0,0.7]));
//Create graphics from features and add it graphicslayer
dojo.forEach(featureset.features,function(feature){
feature.setSymbol(simplePolySymbol);
//Add feature to the graphics layer
taskResultLayer.add(feature);});
}
//add graphicslayer to webmap
//myMap is assumed to be an instance of map container esri.map.
myMap.addLayer(taskResultLayer)
}
Flex 和 Silverlight API
JavaScript 应用程序的上述四个步骤也适用于 Flex 和 Silverlight API。可以使用相应在线 SDK 中的 Flex API 和 Silverlight API 的地理处理任务查找代码示例。