下面对如何在GeoServer中进行发布一个WPS服务的英文文档进行实践,并将采坑之后的结果发布。

WPS 服务

WPS服务(Web Processing Service )用于做地理信息处理的服务规范。在GeoServer中又实现。需要安装WPS插件,具体请参照自己的版本去GeoServer官网下载,下载完成之后放到geoserver 的WEB-INF/lib 目录中,然后重启即可。

下面的文章基本上是GeoServer上的文档的翻译,另外加上不同的版本以及采坑的注意事项。

创建Maven工程

1 、开头的第一步就是创建一个Maven的工程,我们叫他 hello_wps
2 、第二部找到或者添加pom.xml文件(这个根据你是手动写的还是Eclipse写的注意只要目录对就行)。
由于版本变化,原文档的仓库有两个包找不到,我从geotools 那边找到两个仓库,之后成功了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.geoserver</groupId>
<artifactId>hello_wps</artifactId>
<packaging>jar</packaging><!-- jar包形式打包 -->
<version>2.13.0</version><!-- 这里貌似是geoserver的版本,,我之后还要测试 -->
<name>hello_wps</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<gt.version>18.0</gt.version> <!-- GeoTools 对应的要使用的版本 -->
<gs.version>2.13.0</gs.version> <!-- GeoServer 要使用的版本 -->
</properties>
<dependencies>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-process</artifactId>
<version>${gt.version}</version>
</dependency>
<dependency>
<groupId>org.geoserver.extension</groupId>
<artifactId>gs-wps-core</artifactId>
<version>${gs.version}</version>
</dependency>
<dependency>
<groupId>org.geoserver</groupId>
<artifactId>gs-main</artifactId>
<version>${gs.version}</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.mockrunner</groupId>
<artifactId>mockrunner</artifactId>
<version>0.3.6</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>

<repositories>
<repository>
<id>boundless</id>
<name>Boundless Maven Repository</name>
<url>http://repo.boundlessgeo.com/main</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository><!-- 额外的仓库 当上面的找不到的时候-->
<id>osgeo</id>
<name>Open Source Geospatial Foundation Repository</name>
<url>http://download.osgeo.org/webdav/geotools/</url>
</repository>
<repository>
<id>maven2-repository.dev.java.net</id>
<name>Java.net repository</name>
<url>http://download.java.net/maven/2</url>
</repository>
</repositories>


</project>

3 、在src/main/java 目录下创建一个类 叫做HelloWPS.java

注意对应的包名和位置!!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//HelloWPS.java
package org.geoserver.hello.wps;

import org.geotools.process.factory.DescribeParameter;
import org.geotools.process.factory.DescribeProcess;
import org.geotools.process.factory.DescribeResult;
import org.geoserver.wps.gs.GeoServerProcess;

@DescribeProcess(title="helloWPS", description="Hello WPS Sample")
public class HelloWPS implements GeoServerProcess {

@DescribeResult(name="result", description="output result")
public String execute(@DescribeParameter(name="name", description="name to return") String name) {
return "Hello, " + name;
}
}

准备注册

src/main/resources位置准备一个文件 applicationContext.xml内容如下:

1
2
3
4
5
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="helloWPS" class="org.geoserver.hello.wps.HelloWPS"/>
</beans>

编译

运行命令

mvn clean install

找到编译好的jar包在target目录下的。然后将其复制到geoserver目录的/WEB-INF/lib中,然后在geoserver的/WEB-INF/dispatcher-servlet.xml 文件中也要写清楚上面的内容。

查看

之后打开GeoServer我们可以在WPS Request Builder模块中进行实验。如图:

接收和查看原始输入

基本Geoserver WPS体系结构的目的是将输入解码和输出编码集中到GeoServer中进行,让进程针对Java对象工作,并在注册新的匹配PPIO后立即为所有进程自动创建新的输入和输出类型。(也就是输入输出和其分离,但是这个鬼的输入输出类型是xml类型很不爽)

但是,也可以让流程同时接受原始输入和输出,并完成解析编码本身。这非常适合绑定到已经将解析和编码作为正常活动的外部网络或命令行工具。

原始输入和输出由RawData接口表示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public interface RawData {

/**
* Returns the mime type of the stream's contents
*
* @return
*/
public String getMimeType();

/**
* Gives access to the raw data contents.
*
* @return
* @throws FileNotFoundException
*/
public InputStream getInputStream() throws IOException;

/**
* Optional field for output raw data, used by
* WPS to generate a file extension
*
* @return
*/
public String getFileExtension();
}

作为输入,RawData将提供给process,这将发现用户选择的mimeType,并将访问数据的原始输入流。作为输出,流程将返回一个RawData,WPS将查看结果将在哪些mimeType中,获得对原始内容的访问,并获取一个文件扩展名以构建用户文件下载的文件名。

使用RawData的流程还必须在注释中提供一些额外的元数据,以便声明支持哪些MIME类型,并允许流程知道在执行请求中选择了哪些输出MIME类型。
额外的注释mimeTypes和chosenMimeType放在结果和参数注释的元部分:

1
2
3
4
5
6
7
8
9
@DescribeResult(name = "result", description = "Output raster",
meta = {"mimeTypes=application/json,text/xml",
"chosenMimeType=outputMimeType" })
public RawData execute(
@DescribeParameter(name = "data",
meta = { "mimeTypes=text/plain" })
final RawData input,
@DescribeParameter(name = "outputMimeType", min = 0)
final String outputMimeType) {

The above instructs GeoServer WPS about raw data handling:
以上的结构是如何自己处理WPS服务的输入输出:

结果输出可以是application/json or text/xml,以application/json为默认值;
被用户选择的mime类型,将会被提供给WPS进行作为outputMimeType参数,而这个参数将隐藏在DescribeProcess输出中。
输入参数将被公告为支持text/plainMIME类型;

在构建RawData方面,如果需要,流程可以自由地创建自己的类,或者可以使用现有的FileRawData、StringRawData、StreamRawData实现之一。

下面是我根据上面测试成功的一个版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package org.geoserver.hello.wps;

import org.geotools.process.factory.DescribeParameter;
import org.geotools.process.factory.DescribeProcess;
import org.geotools.process.factory.DescribeResult;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.geoserver.wps.gs.GeoServerProcess;

@DescribeProcess(title="helloWPS", description="Hello WPS Sample")
public class HelloWPS implements GeoServerProcess {

public String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "/n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}


@DescribeResult(name = "result", description = "Output raster",
meta = {"mimeTypes=application/json,text/xml",
"chosenMimeType=outputMimeType" })
public String execute(@DescribeParameter(name = "data",
meta = { "mimeTypes=application/json" },description="data to input")
final org.geoserver.wps.process.RawData input, @DescribeParameter(name = "outputMimeType", min = 0)
final String outputMimeType) throws IOException {
return this.convertStreamToString(input.getInputStream());
}
}

总结

WPS服务好烦人,通过XML解析。这里还要想办法解决问题。