--- title: GeoServer二次开发-WPS服务 date: 2021-04-26 author: ac tags: - GeoServer categories: - GIS --- > 本文内容主要来源于GeoServer官网二次开发的WPS Serveice篇,以及在本地实操的示例。 ## 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 4.0.0 org.geoserver hello_wps 1.0-SNAPSHOT jar hello_wps 8 8 2.20-SNAPSHOT 26-SNAPSHOT 2.18.2 org.geotools gt-process ${gt.version} org.geoserver.extension gs-wps-core ${gs.version} org.geoserver gs-main ${gs.version} tests test junit junit 4.11 test com.mockrunner mockrunner 0.3.6 test true false osgeo-releases OSGeo Nexus Release Repository https://repo.osgeo.org/repository/release/ false true osgeo-snapshots OSGeo Nexus Snapshot Repository https://repo.osgeo.org/repository/snapshot/ true true geosolutions geosolutions repository https://maven.geo-solutions.it/ ``` ### 创建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 ``` ### 打包编译 项目目录结构: ```yaml hello_wps/ + pom.xml + src/ + main/ + java/ + resources/ ``` 在项目根目录下使用maven命令打包项目: ```perl mvn clean install ``` image-20210429145215386 将打包好的`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`进行测试: image-20210429150504324 ![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