52°North-WPS-学习-客户端API教程

52°North-WPS-学习-客户端API教程

https://wiki.52north.org/Geoprocessing/ClientAPI

https://wiki.52north.org/Geoprocessing/TutorialClientAPI

1. 获取SDK (maven)

在maven的配置文件的相关profile中,或者项目的pom文件中添加组件仓库

<repository>
<id>n52-releases</id>
<name>52n Releases</name>
<url>http://52north.org/maven/repo/releases</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>

添加项目依赖

<dependency>
<groupId>org.n52.wps</groupId>
<artifactId>52n-wps-client-lib</artifactId>
<version>3.6.1</version>
</dependency>

从github获取wps_config.xml文件(如果直接使用的war包,一般在config目录下已经存在),将其放置到 classpath 目录(maven项目的 resources下面),或者在第一次调用代码时使用它:

WPSConfig.getInstance("path to your wps_config.xml");

2. GetCapabilities

此部分说明如何请求 WPS Capabilities文档并处理响应。示例:

public CapabilitiesDocument requestGetCapabilities(String url) throws WPSClientException {
WPSClientSession wpsClient = WPSClientSession.getInstance(); // 初始化WPSClient session
boolean connected = wpsClient.connect(url);//注册WPS URL
CapabilitiesDocument capabilities = wpsClient.getWPSCaps(url);// 发生capabilities 请求
ProcessBriefType[] processList = capabilities.getCapabilities() .getProcessOfferings().getProcessArray();
for (ProcessBriefType process : processList) {
System.out.println(process.getIdentifier().getStringValue());
}
return capabilities;
}

请求获得的Capabilities Document 结构与WPS规范中的一样。要获取详细信息,例如处理列表( list of processes),需要通过ProcessOfferings :

capabilities.getCapabilities().getProcessOfferings().getProcessArray();

每个处理都是遵循WPS规范的ProcessBriefType 类型。获取处理过程实例标识符的方法:

process.getIdentifier().getStringValue());

3. DescribeProcess

此部分说明如何请求 WPS DescribeProcess 文档并处理响应。示例:

public ProcessDescriptionType requestDescribeProcess(String url, String processID) throws IOException {
WPSClientSession wpsClient = WPSClientSession.getInstance();
// 获取处理方法描述,processID 是上面获得的实例标识符,即 ows:Identifier 的值
ProcessDescriptionType processDescription = wpsClient.getProcessDescription(url, processID);
44System.out.println("Process description:\n" + processDescription.xmlText() + "\n");
// 获取处理过程的所有的输入数据描述
InputDescriptionType[] inputList = processDescription.getDataInputs().getInputArray();
for (InputDescriptionType input : inputList) {
System.out.println(input.getIdentifier().getStringValue());
}
return processDescription;
}

4. Execute

此部分说明如何执行 WPS 处理并处理响应。示例:

// create the request, add literal input
public IData executeProcess(String url, String processID, ProcessDescriptionType processDescription, HashMap<String, Object> inputs) throws Exception {
ExecuteRequestBuilder executeBuilder = new ExecuteRequestBuilder(processDescription);
for (InputDescriptionType input : processDescription.getDataInputs().getInputArray()) {
String inputName = input.getIdentifier().getStringValue();
Object inputValue = inputs.get(inputName);
if (input.getLiteralData() != null) {
if (inputValue instanceof String) {
executeBuilder.addLiteralData(inputName,(String) inputValue);
}
} else if (input.getComplexData() != null) {
// Complexdata by value
if (inputValue instanceof FeatureCollection) {
IData data = new GTVectorDataBinding((FeatureCollection) inputValue);
executeBuilder.addComplexData(inputName,data,
"http://schemas.opengis.net/gml/3.1.1/base/feature.xsd",
null, "text/xml");
}
// Complexdata Reference
if (inputValue instanceof String) {
executeBuilder.addComplexDataReference(inputName, (String) inputValue,
"http://schemas.opengis.net/gml/3.1.1/base/feature.xsd",
null, "text/xml");
}
if (inputValue == null && input.getMinOccurs().intValue() > 0) {
throw new IOException("Property not set, but mandatory: "+ inputName);
}
}
}
executeBuilder.setMimeTypeForOutput("text/xml", "result");
executeBuilder.setSchemaForOutput(
"http://schemas.opengis.net/gml/3.1.1/base/feature.xsd","result");
// build and send the request document
ExecuteDocument execute = executeBuilder.getExecute();
execute.getExecute().setService("WPS");
WPSClientSession wpsClient = WPSClientSession.getInstance();
Object response = wpsClient.execute(url, execute);
if (response instanceof ExecuteResponseDocument) {
ExecuteResponseDocument responseDoc = (ExecuteResponseDocument) responseObject;
ExecuteResponseAnalyser analyser = new ExecuteResponseAnalyser(
execute, responseDoc, processDescription);
IData data = (IData) analyser.getComplexDataByIndex(0,GTVectorDataBinding.class);
return data;
}
throw new Exception("Exception: " + response.toString());
}

首先需要初始化一个 ExecuteRequestBuilder 对象,用于构建一个真正的WPS Execute请求。其需要的 ProcessDescriptionType 对象可通过第3部分的DescribeProcess 获取。

然后,需要设置输入数据,有3种方式:

Literaldata input

字符型数据,如数字、字符串等。

executeBuilder.addLiteralData(inputName, (String)inputValue);

输入数据的标识符(inputName)可通过ProcessDescription获取。

Complexdata input by value

复合型数据,如GML Features,使用

IData data = new GTVectorDataBinding((FeatureCollection) inputValue);
executeBuilder.addComplexData(inputName, data, "http://schemas.opengis.net/gml/3.1.1/base/feature.xsd", null,"text/xml");

需要一个输入数据标识符和一个IData类型的实际数据。IData 是一个接口,常用的实现类有:

  • Geotools 中用于矢量数据的 GTVectorDataBinding
  • 用于任意文件数据的 GenericFileDataBinding . 同样需要数据模式( schema), 编码(encoding) 和输入数据类型的 mimetype. 支持的数据格式可通过 ProcessDescription查看。

Complexdata input by reference

复合型数据,如只通过URL获取的 GML Features,使用

executeBuilder.addComplexDataReference(inputName, (String) inputValue, "http://schemas.opengis.net/gml/3.1.1/base/feature.xsd", null,"text/xml");

需要输入数据标识符以及一个指向地理数据资源的URL字符串,如 WFS Getlayers 请求(URL). 此外还需要In schema, encoding 和mimetype.

当设置完所有输入数据之后,必须设置输出数据的格式,包括mimetype和 可选的schema(用于矢量数据),例如

executeBuilder.setMimeTypeForOutput("text/xml", "result");
executeBuilder.setSchemaForOutput("http://schemas.opengis.net/gml/3.1.1/base/feature.xsd", "result");

此方法为标识符为“result”的输出数据设置了schema。支持的schema列表可在ProcessDescription 中查询得到。

Note: 编码(encoding)只有在与默认的编码不一致时才需要设置。如果需要参数二进制数据值,可以设置编码为 “base64“ 。

完整示例代码

import net.opengis.wps.x100.CapabilitiesDocument;
import net.opengis.wps.x100.ExecuteDocument;
import net.opengis.wps.x100.ExecuteResponseDocument;
import net.opengis.wps.x100.InputDescriptionType;
import net.opengis.wps.x100.ProcessBriefType;
import net.opengis.wps.x100.ProcessDescriptionType;
import org.geotools.feature.FeatureCollection;
import org.n52.wps.client.ExecuteResponseAnalyser;
import org.n52.wps.client.WPSClientException;
import org.n52.wps.client.WPSClientSession;
import org.n52.wps.io.data.IData;
import org.n52.wps.io.data.binding.complex.GTVectorDataBinding;
public class WPSClientExample {
public void testExecute() {
String wpsURL = "http://localhost:8080/wps/WebProcessingService";
String processID = "org.n52.wps.server.algorithm.SimpleBufferAlgorithm";
try {
ProcessDescriptionType describeProcessDocument = requestDescribeProcess(
wpsURL, processID);
System.out.println(describeProcessDocument);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
CapabilitiesDocument capabilitiesDocument = requestGetCapabilities(wpsURL);
ProcessDescriptionType describeProcessDocument = requestDescribeProcess(
wpsURL, processID);
// define inputs
HashMap<String, Object> inputs = new HashMap<String, Object>();
// complex data by reference
inputs.put(
"data",
"http://geoprocessing.demo.52north.org:8080/geoserver/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=topp:tasmania_roads&outputFormat=GML3");
// literal data
inputs.put("width", "0.05");
IData data = executeProcess(wpsURL, processID,
describeProcessDocument, inputs);
if (data instanceof GTVectorDataBinding) {
FeatureCollection featureCollection = ((GTVectorDataBinding) data)
.getPayload();
System.out.println(featureCollection.size());
}
} catch (WPSClientException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public CapabilitiesDocument requestGetCapabilities(String url)
throws WPSClientException {
WPSClientSession wpsClient = WPSClientSession.getInstance();
wpsClient.connect(url);
CapabilitiesDocument capabilities = wpsClient.getWPSCaps(url);
ProcessBriefType[] processList = capabilities.getCapabilities()
.getProcessOfferings().getProcessArray();
for (ProcessBriefType process : processList) {
System.out.println(process.getIdentifier().getStringValue());
}
return capabilities;
}
public ProcessDescriptionType requestDescribeProcess(String url,
String processID) throws IOException {
WPSClientSession wpsClient = WPSClientSession.getInstance();
ProcessDescriptionType processDescription = wpsClient.getProcessDescription(url, processID);
InputDescriptionType[] inputList = processDescription.getDataInputs()
.getInputArray();
for (InputDescriptionType input : inputList) {
System.out.println(input.getIdentifier().getStringValue());
}
return processDescription;
}
public IData executeProcess(String url, String processID,
ProcessDescriptionType processDescription,
HashMap<String, Object> inputs) throws Exception {
org.n52.wps.client.ExecuteRequestBuilder executeBuilder = new org.n52.wps.client.ExecuteRequestBuilder(processDescription);
for (InputDescriptionType input : processDescription.getDataInputs()
.getInputArray()) {
String inputName = input.getIdentifier().getStringValue();
Object inputValue = inputs.get(inputName);
if (input.getLiteralData() != null) {
if (inputValue instanceof String) {
executeBuilder.addLiteralData(inputName,
(String) inputValue);
}
} else if (input.getComplexData() != null) {
// Complexdata by value
if (inputValue instanceof FeatureCollection) {
IData data = new GTVectorDataBinding(
(FeatureCollection) inputValue);
executeBuilder
.addComplexData(
inputName,
data,
"http://schemas.opengis.net/gml/3.1.1/base/feature.xsd",
null, "text/xml");
}
// Complexdata Reference
if (inputValue instanceof String) {
executeBuilder
.addComplexDataReference(
inputName,
(String) inputValue,
"http://schemas.opengis.net/gml/3.1.1/base/feature.xsd",
null, "text/xml");
}
if (inputValue == null && input.getMinOccurs().intValue() > 0) {
throw new IOException("Property not set, but mandatory: "
+ inputName);
}
}
}
executeBuilder.setMimeTypeForOutput("text/xml", "result");
executeBuilder.setSchemaForOutput(
"http://schemas.opengis.net/gml/3.1.1/base/feature.xsd",
"result");
ExecuteDocument execute = executeBuilder.getExecute();
execute.getExecute().setService("WPS");
WPSClientSession wpsClient = WPSClientSession.getInstance();
Object responseObject = wpsClient.execute(url, execute);
if (responseObject instanceof ExecuteResponseDocument) {
ExecuteResponseDocument response = (ExecuteResponseDocument) responseObject;
ExecuteResponseAnalyser analyser = new ExecuteResponseAnalyser(
execute, response, processDescription);
IData data = (IData) analyser.getComplexDataByIndex(0,
GTVectorDataBinding.class);
return data;
}
throw new Exception("Exception: " + responseObject.toString());
}
public static void main(String[] args) {
WPSClientExample client = new WPSClientExample();
client.testExecute();
}
}

测试中出现的问题

出现org.n52.wps.commons.WPSConfig - Can not get java:comp/env context

并报错

ERROR org.n52.wps.client.ExecuteResponseAnalyser - Could not find suitable parser

解决方法

  1. 使用wps_config_geotools.xml文件,不要用wps_config.xml

  2. 默认会查找src/main/resources下的wps_config.xml,所有可以将wps_config_geotools.xml文件放到resources下并改名为wps_config.xml

  3. 或者

    // testExecute 方法中
    String path = this.getClass().getResource("/").getPath();
    // 此处放在 src/main/resources/config 下
    WPSConfig.getInstance(path + "config/wps_config_geotools.xml");

文章目录
  1. 1. 52°North-WPS-学习-客户端API教程
    1. 1.1. 1. 获取SDK (maven)
    2. 1.2. 2. GetCapabilities
    3. 1.3. 3. DescribeProcess
    4. 1.4. 4. Execute
      1. 1.4.0.1. Literaldata input
      2. 1.4.0.2. Complexdata input by value
      3. 1.4.0.3. Complexdata input by reference
    5. 1.4.1. 完整示例代码
    6. 1.4.2. 测试中出现的问题
      1. 1.4.2.1. 解决方法
|