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

1009 lines
44 KiB
Markdown
Raw Normal View History

2023-11-17 10:54:23 +08:00
---
title: GeoServer中的WPS服务
date: 2021-05-10
author: ac
tags:
- WPS
categories:
- GIS
---
> 本文中示例使用的是GeoServer 服务器所以请先安装好GeoServer对WPS服务的扩展模块
<!-- more -->
## 1. WPS简介
`Web Processing Service`(WPS)最初被称为`Geoprocessing Service`。在其发展初期,该名称被改为`Web Processing Service`以避免首字母缩写GPS因为这可能会与全球定位系统(Global Positioning System)这个缩写的传统用法相混淆。
自从`WPS`成为OGC的规范以来术语`geospatial`变得有点冗余。
WPS定义了一个标准化接口该接口有助于发布`Publishing`)地理处理的流程(`Processes`),以及客户机发现和绑定这些流程。
- `Processes`:这些流程包括任何运行在空间参考数据上的算法,计算和模型。
- `Publishing`:发布意味着提供机器可读的绑定信息以及人类可读的元数据,从而允许服务被发现和使用。
WPS可以通过网络为客户端配置和提供任何类型的GIS功能。
Web处理服务(WPS)向客户端提供对预先编程的空间数据进行操作的计算模型的访问。服务所需的数据可以通过网络传递也可以在服务器上获取。这些数据可以是使用图像数据格式或数据交换标准如GML。计算可以是简单到从一组空间参考数据中减去另一组数据(例如,确定两个不同季节流感病例的差异),也可以是复杂到全球气候变化的模型。
在网络上实现地理空间处理需要开发各种各样的web服务来支持原子地理空间操作以及复杂的建模能力。标准化这些流程的调用方式非常重要以减少所需的编程量并促进新服务的实现和采用。WPS旨在帮助OGC成员实现这些目标。
## 2. WPS 操作
WPS接口指定了客户端可以请求并由WPS服务器执行的三种操作这些操作都是所有服务器必须实现的。操作如下
- `GetCapabilities` :此操作允许客户端请求并接收描述服务器实现能力的服务元数据(或能力)文档。GetCapabilities操作提供了WPS实例提供的每个进程的名称和一般描述。
- `DescribeProcess` :此操作允许客户端请求并接收关于可在服务实例上运行的流程的详细信息,包括所需的输入、允许的格式和可生成的输出。
- `Execute` 此操作允许客户端运行由WPS实现的指定进程使用提供的输入参数值并返回生成的输出
这些操作与其他OGC Web服务WMS、WFS、WCS有许多相似之处。OWS规范中指定了与这些其他OpenGIS Web Services共同的接口。
<img src="./images/image-0349.png" alt="image-20210510175110349" style="zoom:50%;" />
从上面的类图可以看到WPS服务也实现了OWS接口所以也遵循OWS规范中的请求和响应相关的规则。
> 每个server服务只实例化该服务类一个实例对象当服务可用时该对象始终存在。
举个栗子考虑一个简单的Process流程求两个面的交集`intersect`)。
- `GetCapabilities`请求返回的结果可以查看该WPS服务是否支持`intersect`操作,以及操作的限制,如`intersect`仅限于一个多边形与另一个多边形相交;
- `DescribeProcess`请求返回的结果可以查看到`intersect`流程需要两个输入,"FirstPolygon"和"SecondPolygon"需要是GML2.2版本的面要素结果还描述了WPS服务的输出结果和版本格式GML2.2或GML3.1它可以作为Web可访问资源进行传输
- 客户端将通过调用`Execute`操作来运行流程并且可以选择将提供的两个输入多边形直接嵌入在请求中并确定输出应该作为web可访问的资源存储。
完成后,流程将返回一个`ExecuteResponse` XML文档该文档标识输入和输出指示流程是否成功执行如果成功则包含对web可访问资源的引用。
![image-20210511111129140](./images/image-20219140.png)
上述表格是WPS各操作支持的请求编码格式。
### 2.1 GetCapabilities
`GetCapabilities`操作允许客户端从服务器检索服务元数据。
对GetCapabilities请求的响应应该是一个XML文档其中包含关于服务器的服务元数据包括描述所有已实现的Process进程的简短元数据以及描述其功能。
`GetCapabilities`操作请求参数:
| name | multiplicity |
| -------------- | --------------------- |
| service | One(mandatory) |
| Request | One(mandatory) |
| AcceptVersions | Zero or one(optional) |
| language | Zero or one(optional) |
示例:
**KVP的形式**
`http://localhost:8080/geoserver/wps?service=WPS&Request=GetCapabilities&AcceptVersions=1.0.0`
> GeoServer 安装完WPS扩展后发起上述请求可以得到下面结果。
>
> 注意WPS扩展模块实现的是WPS1.0.0规范
**XML文本的形式**
请求URLhttp://localhost:8080/geoserver/ows或http://localhost:8080/geoserver/wps
请求数据:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<wps:GetCapabilities language="cz" service="WPS" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsGetCapabilities_request.xsd">
<wps:AcceptVersions>
<ows:Version>1.0.0</ows:Version>
</wps:AcceptVersions>
</wps:GetCapabilities>
```
![image-20210512105312901](./images/image-2021001.png)
**响应示例**
```xml
<?xml version="1.0" encoding="UTF-8"?>
<wps:Capabilities xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xml:lang="en" service="WPS" version="1.0.0" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd">
<ows:ServiceIdentification>
<ows:Title>Prototype GeoServer WPS</ows:Title>
<ows:Abstract/>
<ows:ServiceType>WPS</ows:ServiceType>
<ows:ServiceTypeVersion>1.0.0</ows:ServiceTypeVersion>
</ows:ServiceIdentification>
<ows:ServiceProvider>
<ows:ProviderName>The Ancient Geographers</ows:ProviderName>
<ows:ProviderSite xlink:href="http://geoserver.org"/>
<ows:ServiceContact/>
</ows:ServiceProvider>
<ows:OperationsMetadata>
<ows:Operation name="GetCapabilities">
<ows:DCP>
<ows:HTTP>
<ows:Get xlink:href="http://localhost:8080/geoserver/wps"/>
<ows:Post xlink:href="http://localhost:8080/geoserver/wps"/>
</ows:HTTP>
</ows:DCP>
</ows:Operation>
<ows:Operation name="DescribeProcess">
<ows:DCP>
<ows:HTTP>
<ows:Get xlink:href="http://localhost:8080/geoserver/wps"/>
<ows:Post xlink:href="http://localhost:8080/geoserver/wps"/>
</ows:HTTP>
</ows:DCP>
</ows:Operation>
<ows:Operation name="Execute">
<ows:DCP>
<ows:HTTP>
<ows:Get xlink:href="http://localhost:8080/geoserver/wps"/>
<ows:Post xlink:href="http://localhost:8080/geoserver/wps"/>
</ows:HTTP>
</ows:DCP>
</ows:Operation>
</ows:OperationsMetadata>
<wps:ProcessOfferings>
<wps:Process wps:processVersion="1.0.0">
<ows:Identifier>JTS:area</ows:Identifier>
<ows:Title>Area</ows:Title>
<ows:Abstract>Returns the area of a geometry, in the units of the geometry. Assumes a Cartesian plane, so this process is only recommended for non-geographic CRSes.</ows:Abstract>
</wps:Process>
<wps:Process wps:processVersion="1.0.0">
<ows:Identifier>JTS:boundary</ows:Identifier>
<ows:Title>Boundary</ows:Title>
<ows:Abstract>Returns a geometry boundary. For polygons, returns a linear ring or multi-linestring equal to the boundary of the polygon(s). For linestrings, returns a multipoint equal to the endpoints of the linestring. For points, returns an empty geometry collection.</ows:Abstract>
</wps:Process>
<wps:Process wps:processVersion="1.0.0">
<ows:Identifier>JTS:buffer</ows:Identifier>
<ows:Title>Buffer</ows:Title>
<ows:Abstract>Returns a polygonal geometry representing the input geometry enlarged by a given distance around its exterior.</ows:Abstract>
</wps:Process>
<wps:Process wps:processVersion="1.0.0">
<ows:Identifier>JTS:centroid</ows:Identifier>
<ows:Title>Centroid</ows:Title>
<ows:Abstract>Returns the geometric centroid of a geometry. Output is a single point. The centroid point may be located outside the geometry.</ows:Abstract>
</wps:Process>
...
</wps:ProcessOfferings>
<wps:Languages>
<wps:Default>
<ows:Language>en-US</ows:Language>
</wps:Default>
<wps:Supported>
<ows:Language>en-US</ows:Language>
</wps:Supported>
</wps:Languages>
</wps:Capabilities>
```
响应结果分析:
- `Service Identification`:关于服务的元数据,服务类型和版本。
- `OperationsMetadata`关于服务支持的由服务器端实现的操作的元数据信息包括用于操作请求的url。
- `ProcessOfferings`:提供服务器端已经实现了的`Process`进程的简要描述的无序列表。
### 2.2 DescribeProcess
`DescribeProcess`操作允许WPS客户端请求可由Execute操作执行的一个或多个进程的完整描述。这个描述包括输入和输出参数和格式。此描述可用于自动构建用户界面以捕获用于执行流程实例的参数值。
`DescribeProcess`操作请求的参数:
| name | descirption | m/o |
| ---------- | --------------------------------------------------------- | ---- |
| service | 服务类型,值是"WPS" | m |
| request | 操作名称,值为"DescribeProcess" | m |
| version | 操作的版本不能为空值由每个WPS实现的规范和模式版本决定 | m |
| language | 语言标识 | o |
| Identifier | Process流程的标识 | m |
示例:
**KVP的形式**
`http://localhost:8080/geoserver/wps?service=WPS&Request=DescribeProcess&version=1.0.0&language=en-US&Identifier=JTS:centroid,JTS:buffer`
> 多个Process流程用`,`号隔开
**XML文本的形式**
请求URL地址http://localhost:8080/geoserver/ows
```xml
<?xml version="1.0" encoding="UTF-8"?>
<DescribeProcess service="WPS" version="1.0.0" xmlns="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ows:Identifier>JTS:buffer</ows:Identifier>
<ows:Identifier>JTS:centroid</ows:Identifier>
</DescribeProcess>
```
![image-20210512113327747](./images/image-20210512113327747.png)
> statusSupported="true"表示该Process流程支持异步请求服务器也会持续更新Process流程的状态与存储在`ExecuteResponse`XML文档中Process状态的值一致。客户机可以通过`GetExecutions`查看Process状态。
**响应结果**
响应的XML文档包含有关每个请求的Process流程的元数据包含以下内容
- Process流程名称、标题和摘要
- 对每个输入和输出参数:标识符、标题、摘要、多重性以及支持的数据类型和格式
```xml
<?xml version="1.0" encoding="UTF-8"?>
<wps:ProcessDescriptions xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xml:lang="en" service="WPS" version="1.0.0" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd">
<ProcessDescription wps:processVersion="1.0.0" statusSupported="true" storeSupported="true">
<ows:Identifier>JTS:centroid</ows:Identifier>
<ows:Title>Centroid</ows:Title>
<ows:Abstract>Returns the geometric centroid of a geometry. Output is a single point. The centroid point may be located outside the geometry.</ows:Abstract>
<DataInputs>
<Input maxOccurs="1" minOccurs="1">
<ows:Identifier>geom</ows:Identifier>
<ows:Title>geom</ows:Title>
<ows:Abstract>Input geometry</ows:Abstract>
<ComplexData>
<Default>
<Format>
<MimeType>text/xml; subtype=gml/3.1.1</MimeType>
</Format>
</Default>
<Supported>
<Format>
<MimeType>text/xml; subtype=gml/3.1.1</MimeType>
</Format>
<Format>
<MimeType>text/xml; subtype=gml/2.1.2</MimeType>
</Format>
<Format>
<MimeType>application/wkt</MimeType>
</Format>
<Format>
<MimeType>application/gml-3.1.1</MimeType>
</Format>
<Format>
<MimeType>application/gml-2.1.2</MimeType>
</Format>
<Format>
<MimeType>application/json</MimeType>
</Format>
</Supported>
</ComplexData>
</Input>
</DataInputs>
<ProcessOutputs>
<Output>
<ows:Identifier>result</ows:Identifier>
<ows:Title>result</ows:Title>
<ComplexOutput>
<Default>
<Format>
<MimeType>text/xml; subtype=gml/3.1.1</MimeType>
</Format>
</Default>
<Supported>
<Format>
<MimeType>text/xml; subtype=gml/3.1.1</MimeType>
</Format>
<Format>
<MimeType>text/xml; subtype=gml/2.1.2</MimeType>
</Format>
<Format>
<MimeType>application/wkt</MimeType>
</Format>
<Format>
<MimeType>application/gml-3.1.1</MimeType>
</Format>
<Format>
<MimeType>application/gml-2.1.2</MimeType>
</Format>
<Format>
<MimeType>application/json</MimeType>
</Format>
</Supported>
</ComplexOutput>
</Output>
</ProcessOutputs>
</ProcessDescription>
<ProcessDescription wps:processVersion="1.0.0" statusSupported="true" storeSupported="true">
<ows:Identifier>JTS:buffer</ows:Identifier>
<ows:Title>Buffer</ows:Title>
<ows:Abstract>Returns a polygonal geometry representing the input geometry enlarged by a given distance around its exterior.</ows:Abstract>
<DataInputs>
<Input maxOccurs="1" minOccurs="1">
<ows:Identifier>geom</ows:Identifier>
<ows:Title>geom</ows:Title>
<ows:Abstract>Input geometry</ows:Abstract>
<ComplexData>
<Default>
<Format>
<MimeType>text/xml; subtype=gml/3.1.1</MimeType>
</Format>
</Default>
<Supported>
<Format>
<MimeType>text/xml; subtype=gml/3.1.1</MimeType>
</Format>
<Format>
<MimeType>text/xml; subtype=gml/2.1.2</MimeType>
</Format>
<Format>
<MimeType>application/wkt</MimeType>
</Format>
<Format>
<MimeType>application/gml-3.1.1</MimeType>
</Format>
<Format>
<MimeType>application/gml-2.1.2</MimeType>
</Format>
<Format>
<MimeType>application/json</MimeType>
</Format>
</Supported>
</ComplexData>
</Input>
<Input maxOccurs="1" minOccurs="1">
<ows:Identifier>distance</ows:Identifier>
<ows:Title>distance</ows:Title>
<ows:Abstract>Distance to buffer the input geometry, in the units of the geometry</ows:Abstract>
<LiteralData>
<ows:DataType>xs:double</ows:DataType>
<ows:AnyValue/>
</LiteralData>
</Input>
<Input maxOccurs="1" minOccurs="0">
<ows:Identifier>quadrantSegments</ows:Identifier>
<ows:Title>quadrantSegments</ows:Title>
<ows:Abstract>Number determining the style and smoothness of buffer corners. Positive numbers create round corners with that number of segments per quarter-circle, 0 creates flat corners.</ows:Abstract>
<LiteralData>
<ows:DataType>xs:int</ows:DataType>
<ows:AnyValue/>
</LiteralData>
</Input>
<Input maxOccurs="1" minOccurs="0">
<ows:Identifier>capStyle</ows:Identifier>
<ows:Title>capStyle</ows:Title>
<ows:Abstract>Style for the buffer end caps. Values are: Round - rounded ends (default), Flat - flat ends; Square - square ends.</ows:Abstract>
<LiteralData>
<ows:AllowedValues>
<ows:Value>Round</ows:Value>
<ows:Value>Flat</ows:Value>
<ows:Value>Square</ows:Value>
</ows:AllowedValues>
</LiteralData>
</Input>
</DataInputs>
<ProcessOutputs>
<Output>
<ows:Identifier>result</ows:Identifier>
<ows:Title>result</ows:Title>
<ComplexOutput>
<Default>
<Format>
<MimeType>text/xml; subtype=gml/3.1.1</MimeType>
</Format>
</Default>
<Supported>
<Format>
<MimeType>text/xml; subtype=gml/3.1.1</MimeType>
</Format>
<Format>
<MimeType>text/xml; subtype=gml/2.1.2</MimeType>
</Format>
<Format>
<MimeType>application/wkt</MimeType>
</Format>
<Format>
<MimeType>application/gml-3.1.1</MimeType>
</Format>
<Format>
<MimeType>application/gml-2.1.2</MimeType>
</Format>
<Format>
<MimeType>application/json</MimeType>
</Format>
</Supported>
</ComplexOutput>
</Output>
</ProcessOutputs>
</ProcessDescription>
</wps:ProcessDescriptions>
```
- `ProcessDescription`Process流程的完整信息的描述包含流程标识Identifier、输入参数类型DataInputs、输出参数ProcessOutputs以及数据格式类型和约束等。
- `ComplexData`:复合数据类型,表示该数据是`Supported`标签内支持的数据类型中的组合。
- `LiteralData`:文字数据,可以是任何文本字符串。用于传递单个参数,如数字和文本参数(数据类型常是整数、浮点、字符串)
### 2.3 Execute
`Execute`操作允许WPS客户机运行由服务器实现的指定`Process`流程,使用提供的输入参数值并返回生成的输出值。
- 输入参数可以直接包含在Execute请求中或者引用web可访问的资源。
- 输出可以以XML响应文档的形式返回可以嵌入在响应文档中也可以作为web可访问资源存储。
如果存储输出则响应结果应该为包含每个存储输出的URL的XML文档这样客户机可以使用这些URL来检索那些输出。或者对于单个输出可以指示服务器返回原始形式的输出而不需要包装在XML响应文档中。
`Execute`请求参数:
| name | description | m/o |
| ------------- | ---------------------------------------- | :--: |
| service | 服务类型标识,值为"WPS" | m |
| request | 操作名称,值为"Execute" | m |
| version | 服务版本,不能为空 | m |
| Identifier | Process流程的标识 | m |
| DataInputs | 执行Process需要的输入参数 | o |
| Response Form | Process结果的响应格式Raw data or XML | o |
| language | 语言标识 | o |
操作请求提供对多个输入的支持。每个输入都引用单个Execute请求可能需要的一种输入形式。
向WPS提供大型输入的通常方法是提供一个或多个输入值的uri(通常是url),除非输入是简单标量值。这不是用来促进批处理的(例如,通过一个算法处理多个图像)。如果一个流程要运行多次(可能每次使用不同的输入)那么每次运行都应作为单独的Execute操作的请求来提交。
> java中标量可以理解为是Date、String、基本类型等。
注意Process的输入和输出是无序的。当一个Process需要大量输入或有较多输出数据时服务端或客户端花在数据解析上的时间会很多所以建议接口实现者以一种有效的方式打包和对输入/输出进行排序并在Process流程描述中确定这个最佳排序需求。
**数据输入类型的数据结构**
<div style="text-align:center">InputType data structure</div>
| name | description | data type | m/o |
| --------------------- | ----------- | ------------ | ---- |
| Identifier | wps服务标识 | ows:CodeType | m |
| Title | 标题 | 字符类型 | o |
| Abstract | 简介 | 字符类型 | o |
| InputData Form Choice | 数据表单 | 详见下表 | m |
<div style="text-align:center">InputData Form Choice</div>
| name | description | Multiplicity | data type |
| --------- | --------------------------------------------- | ------------ | -------------- |
| Reference | 将输入数据标识为web可访问的资源并引用该资源 | Zero or one | InputReference |
| Data | 将此输入数据标识为封装在Execute请求中 | Zero or one | DataType |
`InputReference`类型更多的是使用URL引用Web资源可以指定`href`属性和`method`属性来标识资源和请求资源的方式。
`DataType`类型是之前介绍的`ComplexData`和`LiteralData`,以及`BoundingBoxData`。
> `BoundingBoxData`是指定两对坐标用于2d和3d空间描述边界的矩形使用左下角最小值和右上角最大值的坐标、空间参考CRS以及描述边界维度的值组成。如46,102,47,103,urn:ogc:def:crs:EPSG:6.6:4326,2
**响应数据格式的数据结构**
<div style="text-align:center">ResponseForm data structure</div>
| name | description | Data type | multiplicity |
| ------------------ | ------------------------------------------------- | --------- | ------------ |
| Response Document | 指示输出应作为WPS响应文档的一部分返回。 | | Zero or one |
| RawData Output | 指示输出应直接作为原始数据返回不应有WPS响应文档 | | Zero or one |
<div style="text-align:center">ResponseDocument data structure</div>
| name | description | datatype | Multiplicity |
| -------------------- | ------------------------------------------------------------ | -------- | ------------ |
| storeExecuteResponse | 指示execute请求的响应结果是否存储 | boolean | Zero or one |
| lineage | 指示Execute操作的响应结果是否包含DataInputs和OutputDefinitions元素 | boolean | Zero or one |
| status | 指示是否更新Process流程的状态 | boolean | Zero or one |
| Output | 指定响应结果的格式、编码和schema约束 | | One or more |
示例:
```xml
<wps:ResponseForm>
<wps:ResponseDocument lineage="true" storeExecuteResponse="true" status="true">
<wps:Output asReference="false">
<ows:Identifier>result</ows:Identifier>
</wps:Output>
</wps:ResponseDocument>
</wps:ResponseForm>
```
> asReference属性指定该输出是否应被Process进程存储为Web可访问的资源。
<div style="text-align:center">RawDataOutput data structure</div>
| name | description | datatype | Multiplicity |
| ---------- | ----------------------- | -------- | ------------ |
| Identifier | 指示输出结果的参数 | | One |
| mimeType | 响应结果类型 | 字符串 | Zero or one |
| encoding | 响应结果的编码 | uri | Zero or one |
| schema | RawDataOutput结果的约束 | uri | Zero or one |
| uom | 单位 | uri | Zero or one |
示例:
```xml
<wps:ResponseForm>
<wps:RawDataOutput mimeType="application/gml-3.1.1">
<ows:Identifier>result</ows:Identifier>
</wps:RawDataOutput>
</wps:ResponseForm>
```
**Execute操作的请求方式**
- KVP键值对get请求。
- XML文本post请求。
Execute 操作的URL请求参数
| name | Optionality and use | description |
| ------------------------- | ------------------- | ------------ |
| service=WPS | m | 服务类型标识 |
| request=Execute | m | 操作名称 |
| version=1.0.0 | m | 操作版本 |
| language=en-CA | o | |
| Identifier=JST:buffer | m | Process标识 |
| DataInputs | o | |
| ResponseDocument | o | |
| RawDataOutput | o | |
| storeExecuteResponse=true | o | |
| lineage=true | o | |
| status=true | o | |
KVP请求方式中**DataInputs** 、ResponseDocument 和 RawDataOutput 参数的语法:
DataInputs := Input *( “;” Input )
Input := BoundingBox | Literal | Complex | Reference
> DataInputs的值是零个或多个`Input`类型BoundingBox、Literal、Complex、Reference多个`Input`之间使用`;`隔开
BoundingBox := InputId “=” BoundingBoxValue
BoundingBoxValue := <As defined in OGC # 06-121r3 Subclause 10.2.3>
> 使用`=`分隔,输入参数和其值,以及分隔参数值的属性和属性值。
>
> 例如bboxInput=46,102,47,103,urn:ogc:def:crs:EPSG:6.6:4326,2
Literal := InputId “=” Value *( “@” LiteralAttribute )
LiteralAttribute := LiteralAttributeName “=” Value
LiteralAttributeName := “datatype” | “uom”
> 使用`@`符号将输入值中的多个属性分隔开
>
> 例如width=35@datatype=xs:integer@uom=meter
Complex := InputId “=” Value *( “@” ComplexAttribute )
ComplexAttribute:= ComplexAttributeName “=” Value
ComplexAttributeName := “mimetype” | “encoding” | “schema”
Reference := InputId “=” Value *( “@” ReferenceAttribute )
ReferenceAttribute:= ReferenceAttributeName “=” Value
ReferenceAttributeName := “href” | ComplexAttributeName
InputId := \<Identifier of the input from the process description>
Value := \<URL Encoded value being sent>
> 注意字段名和属性名区分大小写。不正确的字段名和属性名将引发InvalidParameterException
示例:
**KVP请求方式**
`http://localhost:8080/geoserver/ows?service=wps&request=execute&version=1.0.0&Identifier=JTS:buffer&DataInputs=geom=POINT(0 0)@mimeType="application/wkt";distance=10@datatype=xs:integer@uom=meter;quadrantSegments=2;capStyle=Round&RawDataOutput=result`
![image-20210513104832309](./images/image-20210832309.png)
**XML文本的方式**
请求地址http://localhost:8080/geoserver/wps 或 http://localhost:8080/geoserver/ows
body:
```xml
<?xml version="1.0" encoding="UTF-8"?><wps:Execute version="1.0.0" service="WPS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opengis.net/wps/1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:wcs="http://www.opengis.net/wcs/1.1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd">
<ows:Identifier>JTS:buffer</ows:Identifier>
<wps:DataInputs>
<wps:Input>
<ows:Identifier>geom</ows:Identifier>
<wps:Data>
<wps:ComplexData mimeType="application/wkt"><![CDATA[POINT(0 0)]]></wps:ComplexData>
</wps:Data>
</wps:Input>
<wps:Input>
<ows:Identifier>distance</ows:Identifier>
<wps:Data>
<wps:LiteralData>10</wps:LiteralData>
</wps:Data>
</wps:Input>
<wps:Input>
<ows:Identifier>quadrantSegments</ows:Identifier>
<wps:Data>
<wps:LiteralData>2</wps:LiteralData>
</wps:Data>
</wps:Input>
<wps:Input>
<ows:Identifier>capStyle</ows:Identifier>
<wps:Data>
<wps:LiteralData>Round</wps:LiteralData>
</wps:Data>
</wps:Input>
</wps:DataInputs>
<wps:ResponseForm>
<wps:RawDataOutput mimeType="application/wkt">
<ows:Identifier>result</ows:Identifier>
</wps:RawDataOutput>
</wps:ResponseForm>
</wps:Execute>
```
> 被`<![CDATA[]]>`标签所包含的内容将表示为**纯文本**用来包含不被xml解析器解析的内容。
在`JTS:buffer`的WPS服务描述中可以看到默认的输出格式是`gml/3.1.1`。使用KVP方式请求的时候将`RawDataOutput`设置为`result=geometry@mimeType="application/wkt"`结果并没有效果但在使用XML方式请求时设置`RawDataOutput`标签中的`mimeType`属性才有效。所以遗留一个问题如何在KVP的请求方式中设置WPS服务结果的输出格式呢
虽然XML文本使用上看起来比较复杂对于一些复杂的请求使用XML文本通常更安全和高效。而kvp方式特别是wps的execute请求可能会很棘手并导致不可预测的错误。
什么WPS服务的XML文本请求不会写没关系可以不用写直接使用GeoServer中的`WPS request builder`演示工具生成,看得懂就行。
<img src="./images/image-202118188.png" alt="image-20210513115418188" style="zoom:50%;" />
## 3. WPS状态
当我们发送Execute操作的请求中没有携带`RawDataOutput`参数时,请求默认响应的是`ExecuteResponse`XML文档里面包含了Process流程执行状态和响应结果。
<img src="./images/wpsout.jpg" alt="3938" style="zoom: 50%;" />
在首页中的`Process status`可以查看服务器中所有执行的`execute`操作的列表:
<img src="./images/image-20251814.png" alt="image-20210513172051814" style="zoom:50%;" />
![image-20210513172158869](./images/image-202158869.png)
## 4. GeoServer提供的Process
Web Processing Service描述了发布地理处理Process流程的方法但没有指定这些Process流程应该是什么。因此实现WPS的服务器在实现什么类型的流程以及如何实现这些流程方面有完全的灵活性。
GeoServer根据主题将过程分为几个不同的类别。这些类别按前缀分组:
- geo: geometry processes
- ras: raster processes
- vec: Vector processes
- gs: GeoServer-specific processes
> GeoServer以前的版本不是按主题而是按负责实现的内部库对进程进行分组。`JTS`和`gt`前缀可以被启用以保持向后兼容性,它们的功能被存储到`vec`和`geo`中了。
### 4.1 geometry processes
geometry processes使用的是[JTS Topology Suite](http://www.tsusiatsoftware.net/jts/main.html)构建的用于处理二维几何拓扑关系的Process。
JTS符合OGC的` Simple Features Specification for SQL`规范类似于PostGIS。JTS包括常见的空间功能如区域、缓冲区、交叉点和简化。
geo:area
geo:boundary
geo:buffer
geo:centroid
geo:contains
geo:convexHull
geo:crosses
geo:densify
geo:difference
geo:dimension
geo:disjoint
geo:distance
geo:endPoint
geo:envelope
geo:equalsExact
geo:equalsExactTolerance
geo:exteriorRing
geo:geometryType
geo:getGeometryN
geo:getX
geo:getY
geo:interiorPoint
geo:interiorRingN
geo:intersection
geo:intersects
geo:isClosed
geo:isEmpty
geo:isRing
geo:isSimple
geo:isValid
geo:isWithinDistance
geo:length
geo:numGeometries
geo:numInteriorRing
geo:numPoints
geo:overlaps
geo:pointN
geo:polygonize
geo:relate
geo:relatePattern
geo:reproject
geo:simplify
geo:splitPolygon
geo:startPoint
geo:symDifference
geo:touches
geo:union
geo:within
### 4.2 geoserver processes
GeoServer中的WPS包含一些专门为GeoServer创建的Process流程。这些通常是特定于geoserver的函数比如边界和重投影。它们使用到GeoServer `WFS`/`WCS`的内部连接来读写数据而不是WPS规范的一部分。
gs:AddCoverages
gs:Aggregate
gs:AreaGrid
gs:BarnesSurface
gs:Bounds
gs:BufferFeatureCollection
gs:Centroid
gs:Clip
gs:CollectGeometries
gs:Contour
gs:Count
gs:CropCoverage
gs:Feature
gs:GeorectifyCoverage
gs:GetFullCoverage
gs:Grid
gs:Heatmap
gs:Import
gs:InclusionFeatureCollection
gs:IntersectionFeatureCollection
gs:LRSGeocode
gs:LRSMeasure
gs:LRSSegment
gs:MultiplyCoverages
gs:Nearest
gs:PagedUnique
gs:PointBuffers
gs:PointStacker
gs:PolygonExtraction
gs:Query
gs:RangeLookup
gs:RasterAsPointCollection
gs:RasterZonalStatistics
gs:RectangularClip
gs:Reproject
gs:ReprojectGeometry
gs:ScaleCoverage
gs:Simplify
gs:Snap
gs:StoreCoverage
gs:StyleCoverage
gs:Transform
gs:UnionFeatureCollection
gs:Unique
gs:VectorZonalStatistics
gt:VectorToRaster
官网在这段介绍了`gs:Aggregate`聚合函数计算要素属性上的一个或多个聚合函数包括Count, Average, Max, Median, Min, StdDev, Sum。
| **Parameter** | **Description** | **Mandatory** | **Multiple** |
| ---------------------- | ------------------------------------------------------------ | ------------- | ------------ |
| `features` | 输入要素的集合 | yes | no |
| `aggregationAttribute` | 用于聚合计算的属性 | yes | no |
| `function` | 具体的聚合操作,可选值: Count, Average, Max, Median, Min, StdDev, Sum. | yes | yes |
| `singlePass` | 如果为true则在一次传递中计算所有聚合值。这将阻碍特定于dbms的优化。如果提供了group by属性则将忽略此参数。 | yes | no |
| `groupByAttributes` | 分组属性 | no | yes |
<img src="./images/image-20210590.png" alt="image-20210514101311590" style="zoom:50%;" />
响应结果:
```json
{
"GroupByAttributes":["SUB_REGION"],
"AggregationResults":[
[
"N Eng",2201157.1666666665
],
[
"W N Cen",2522812.8571428573
],
[
"Pacific","1.2489678E7"
],
[
"Mtn",1690408.25
],
[
"E S Cen",3998821.25
],
[
"S Atl",4837695.666666667
],
[
"E N Cen",8209477.2
],
[
"Mid Atl","1.2534095333333334E7"
],
[
"W S Cen",6709575.75
]
],
"AggregationFunctions":["Average"],
"AggregationAttribute":"PERSONS"
}
```
## 5. Process chaining
从上面GeoServer提供的Process中可以看出这些Process流程更多的是单一的几何服务类似ArcGIS Server中的`geometry service`或ArcMap中的工具箱。虽然GeoServer中没有像ArcGIS中的model builder 那样niubility的可视化建模工具但还是可以将多个Process流程组合实现空间建模分析的。
> 其实如果不是比较复杂的需求可以直接通过空间数据库中的空间函数解决如PostGIS。
WPS服务的好处之一是其固有的链接流程的能力。就像函数如何调用其他函数一样WPS进程可以将另一个进程的输出用作其输入。因此许多复杂的功能可以组合成一个强大的请求。
例如让我们采用GeoServer随附的一些示例数据并使用WPS引擎链接一些内置过程这将允许用户即时执行地理空间分析。
**示例**:保护区内的道路一共有几英里?
GeoServer的标准安装中包含了用于此示例的数据
- sfroads包含道路信息的图层
- sfrestricted代表保护区的图层
<img src="./images/imag115237451.png" alt="image-20210514115237451" style="zoom:67%;" />
为了计算总长度我们将需要以下内置的WPS流程
- `gs:IntersectionFeatureCollection`:返回两个要素集合之间的交集,并添加两个要素集合的属性
- `gs:CollectGeometries`:收集要素集中的所有默认几何并将其作为单个几何集合返回
- `JTS:length`:以与几何相同的度量单位计算几何的长度
这些过程的执行顺序很重要。我们先求道路网络与保护区`Intersection`相交获得保护区内所有道路的要素集合。然后我们将这些几何形状收集到单个GeometryCollection中以便可以使用内置的JTS算法来计算长度。
<img src="./images/image-20251345172.png" alt="image-20210514151345172" style="zoom: 67%;" />
Process流程的顺序是通过将第一个process嵌入到第二个process再将第二个process嵌入到第三个process...这种方式来构建整个Process流程的WPS请求。
工作流一个process流程产生一些输出这些输出将成为下一个process流程的输入从而形成一个处理管道可以通过一个HTTP请求解决复杂的空间分析。这里最开始的输入使用GeoServer的图层layer优势在于不会在process流程之间来回传送数据从而获得非常好的性能。
完整的XML格式WPS请求
```xml
<?xml version="1.0" encoding="UTF-8"?>
<wps:Execute version="1.0.0" service="WPS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opengis.net/wps/1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:wcs="http://www.opengis.net/wcs/1.1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd">
<ows:Identifier>JTS:length</ows:Identifier>
<wps:DataInputs>
<wps:Input>
<ows:Identifier>geom</ows:Identifier>
<wps:Reference mimeType="text/xml; subtype=gml/3.1.1"
xlink:href="http://geoserver/wps" method="POST">
<wps:Body>
<wps:Execute version="1.0.0" service="WPS">
<ows:Identifier>gs:CollectGeometries</ows:Identifier>
<wps:DataInputs>
<wps:Input>
<ows:Identifier>features</ows:Identifier>
<wps:Reference mimeType="text/xml; subtype=wfs-collection/1.0" xlink:href="http://geoserver/wps" method="POST">
<wps:Body>
<wps:Execute version="1.0.0" service="WPS">
<ows:Identifier>gs:IntersectionFeatureCollection</ows:Identifier>
<wps:DataInputs>
<wps:Input>
<ows:Identifier>first feature collection</ows:Identifier>
<wps:Reference mimeType="text/xml; subtype=wfs-collection/1.0" xlink:href="http://geoserver/wfs" method="POST">
<wps:Body>
<wfs:GetFeature service="WFS" version="1.0.0" outputFormat="GML2">
<wfs:Query typeName="sf:roads"/>
</wfs:GetFeature>
</wps:Body>
</wps:Reference>
</wps:Input>
<wps:Input>
<ows:Identifier>second feature collection</ows:Identifier>
<wps:Reference mimeType="text/xml; subtype=wfs-collection/1.0" xlink:href="http://geoserver/wfs" method="POST">
<wps:Body>
<wfs:GetFeature service="WFS" version="1.0.0" outputFormat="GML2">
<wfs:Query typeName="sf:restricted"/>
</wfs:GetFeature>
</wps:Body>
</wps:Reference>
</wps:Input>
<wps:Input>
<ows:Identifier>first attributes to retain</ows:Identifier>
<wps:Data>
<wps:LiteralData>the_geom cat</wps:LiteralData>
</wps:Data>
</wps:Input>
<wps:Input>
<ows:Identifier>second attributes to retain</ows:Identifier>
<wps:Data>
<wps:LiteralData>cat</wps:LiteralData>
</wps:Data>
</wps:Input>
</wps:DataInputs>
<wps:ResponseForm>
<wps:RawDataOutput mimeType="text/xml;
subtype=wfs-collection/1.0">
<ows:Identifier>result</ows:Identifier>
</wps:RawDataOutput>
</wps:ResponseForm>
</wps:Execute>
</wps:Body>
</wps:Reference>
</wps:Input>
</wps:DataInputs>
<wps:ResponseForm>
<wps:RawDataOutput mimeType="text/xml; subtype=gml/3.1.1">
<ows:Identifier>result</ows:Identifier>
</wps:RawDataOutput>
</wps:ResponseForm>
</wps:Execute>
</wps:Body>
</wps:Reference>
</wps:Input>
</wps:DataInputs>
<wps:ResponseForm>
<wps:RawDataOutput>
<ows:Identifier>result</ows:Identifier>
</wps:RawDataOutput>
</wps:ResponseForm>
</wps:Execute>
```
![image-20210514152335032](./images/image-20235032.png)