meface/docs/article/gis/geoserver/geoserverwps.md

318 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: GeoServer二次开发-WPS服务
date: 2021-04-26
author: ac
tags:
- GeoServer
categories:
- GIS
---
> 本文内容主要来源于GeoServer官网二次开发的WPS Serveice篇以及在本地实操的示例。
<!-- more -->
## 1. WPS 规范1.0.0
[WPS规范](http://www.opengeospatial.org/standards/wps)
## 2.基础结构
该模块基于通常的`GeoServer OWS`框架应用程序:
- `KVP`解析器和`KVP`读取器用于解析HTTP GET请求的可以在`org.geoserver.wps.kvp`包中找到);
- `XML`解析器用于解析HTTP POST请求的可在`org.geoserver.wps.xml`和`org.geoserver.wps.xml.v1_0_0`中找到)
- 一个响应各种`WPS`方法的服务对象接口和实现,特别是`org.geoserver.wps.DefaultWebProcessingService`,它依次将大部分工作委托给`GetCapabilities`、`DescribeProcess`和`ExecuteProcess`类
- 输出转换器,将通过`DefaultWebProcessingService`生成的结果转换为适当的响应通常是XML可以在`org.geoserver.wps.response`包中找到其中的一些而另一些是在Spring上下文中已参数化并声明的通用类请参见`applicationContext.xml`文件)
该模块常用的`GeoTools`包有:
- `net.opengis.wps`,它包含`WPS`模式中描述的各种元素和类型的EMF模型。这些对象通常是在KVP解析器、XML解码器、服务实现和输出转换器之间流动的对象。
- `gt-xsd-wps` and `gt-xsd`用于XML编码和解码。
- `gt-process`,它提供了`process`的概念,能够自我描述其输入和输出,当然还能够执行和产生结果。
## 3. Process
该模块依赖于gt-process基于SPI的插件机制来查找和使用类路径中可用的进程。实现一个新process可以归结为以下步骤
1. 创建一个`ProcessFactory`的实现;
2. 创建一个或多个 `Process` 的实现;
3. 通过添加工厂类名到`META-INF/services/org.geotools.processProcessFactory`文件中,实现在`SPI`中注册`ProcessFactory`。
## 4.WPS示例
按照之前的[环境搭建](./devEnvironment.md)的操作已经将 GeoServer的扩展插件部分`extension`也打包到了本地的Maven仓库中了。
现在我们开始来实现一个简单的OWS服务。
1. 新建一个Maven项目
2. 创建process类
3. 在GeoServer中注册process
4. 打包编译
5. 测试
### 新建一个Maven项目
![image-20210429144142378](./images/image-20210429144142378.png)
将项目中的Maven指定为本地的安装路径这样就可以引用之前源码打包的各模块的jar。
![image-20210425140151079](./images/image-20210425140151079.png)
在pom.xml文件中添加依赖以及指定打包方式需要注意gt和gs的版本问题版本可以在之前部署的GeoServer源码根目录下的pom.xml文件中找到
```xml
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.geoserver</groupId>
<artifactId>hello_wps</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>hello_wps</name>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<gs.version>2.20-SNAPSHOT</gs.version>
<gt.version>26-SNAPSHOT</gt.version>
<local.project.version>2.18.2</local.project.version>
</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>
<repositories>
<repository>
<releases>
<enabled>true</enabled>
</releases>
<!-- contains release (including third-party-dependences) -->
<!-- Restlet maven Repository (http://maven.restlet.org) -->
<!-- ucar (https://artifacts.unidata.ucar.edu/content/repositories/unidata-releases) -->
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>osgeo-releases</id>
<name>OSGeo Nexus Release Repository</name>
<url>https://repo.osgeo.org/repository/release/</url>
</repository>
<repository>
<releases>
<enabled>false</enabled>
</releases>
<!-- contains snapshots -->
<snapshots>
<enabled>true</enabled>
</snapshots>
<id>osgeo-snapshots</id>
<name>OSGeo Nexus Snapshot Repository</name>
<url>https://repo.osgeo.org/repository/snapshot/</url>
</repository>
<repository>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
<id>geosolutions</id>
<name>geosolutions repository</name>
<url>https://maven.geo-solutions.it/</url>
</repository>
</repositories>
</project>
```
### 创建process类
```java
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;
}
}
```
### 在GeoServer中注册process
在resource目录中创建`applicationContext.xml`文件将刚创建的process类配置到GeoServer的Spring容器中
```xml
<?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>
```
### 打包编译
项目目录结构:
```yaml
hello_wps/
+ pom.xml
+ src/
+ main/
+ java/
+ resources/
```
在项目根目录下使用maven命令打包项目
```perl
mvn clean install
```
<img src="./images/image-20210429145215.png" alt="image-20210429145215386" style="zoom:50%;" />
将打包好的`hello_wps-1.0-SNAPSHOT.jar`拷贝到GeoServer的`/WEB-INF/lib`中启动或重启GeoServer。
> 如果你部署在免安装的二进制或其他安装程序的GeoServer请确保已添加对WPS服务的扩展。
![image-20210429145851616](./images/image-20210429145.png)
添加扩展模块也很简单直接将下载下来的zip里面的jar拷贝到`/WEB-INF/lib`中即可。
### 测试
启动GeoServer在`演示`中找到`WPS request builder`进行测试:
<img src="./images/image-50504324.png" alt="image-20210429150504324" style="zoom: 50%;" />
![image-20210429150720372](./images/image-29150720372.png)
`http://localhost:8080/geoserver/ows?service=wps&request=execute&version=1.0.0&Identifier=gs:HelloWPS&DataInputs=name="world"&RawDataOutput=result`
![image-20210514171748518](./images/image-2021018.png)
### 接收和返回原始数据
基本的GeoServer WPS体系结构旨在卸载和集中输入解码和输出编码让进程针对Java对象工作并在注册新的匹配PPIO后立即为所有进程自动创建新的输入和输出类型。
不过,也可以让流程同时接受原始输入和输出,并自行进行解析编码。
原始输入和输出由RawData接口表示:
```java
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();
}
```
![image-20210514172454546](./images/image-202546.png)
作为一个输入RawData将被提供给Process流程该流程将发现用户选择的mimeType并将获得对原始输入数据流的访问权。
作为输出该process流程将返回一个RawData, WPS会查看响应结果中的`mimeType`类型,获得对原始内容,并获取一个文件扩展名来构建文件,提供给用户下载。
使用RawData的流程还必须在注释中提供一些额外的元数据以声明支持哪些mime类型并允许流程知道在Execute请求中选择了哪些输出mime类型。注释mimeTypes和chosenMimeType放置在结果和参数注释的位置。
```java
@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) {
```
## 参考文章
[1] WPS design guide https://docs.geoserver.org/latest/en/developer/programming-guide/wps-services/design-guide.html
[2] Implementing a WPS Process https://docs.geoserver.org/latest/en/developer/programming-guide/wps-services/implementing.html