--- title: GeoServer中的WPS服务 date: 2021-05-10 author: ac tags: - WPS categories: - GIS --- > 本文中示例使用的是GeoServer 服务器,所以请先安装好GeoServer对WPS服务的扩展模块 ## 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共同的接口。 image-20210510175110349 从上面的类图可以看到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文本的形式**: 请求URL:http://localhost:8080/geoserver/ows或http://localhost:8080/geoserver/wps 请求数据: ```xml 1.0.0 ``` ![image-20210512105312901](./images/image-2021001.png) **响应示例**: ```xml Prototype GeoServer WPS WPS 1.0.0 The Ancient Geographers JTS:area Area 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. JTS:boundary Boundary 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. JTS:buffer Buffer Returns a polygonal geometry representing the input geometry enlarged by a given distance around its exterior. JTS:centroid Centroid Returns the geometric centroid of a geometry. Output is a single point. The centroid point may be located outside the geometry. ... en-US en-US ``` 响应结果分析: - `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 JTS:buffer JTS:centroid ``` ![image-20210512113327747](./images/image-20210512113327747.png) > statusSupported="true"表示该Process流程支持异步请求,服务器也会持续更新Process流程的状态,与存储在`ExecuteResponse`XML文档中Process状态的值一致。客户机可以通过`GetExecutions`查看Process状态。 **响应结果**: 响应的XML文档包含有关每个请求的Process流程的元数据,包含以下内容: - Process流程名称、标题和摘要 - 对每个输入和输出参数:标识符、标题、摘要、多重性以及支持的数据类型和格式 ```xml JTS:centroid Centroid Returns the geometric centroid of a geometry. Output is a single point. The centroid point may be located outside the geometry. geom geom Input geometry text/xml; subtype=gml/3.1.1 text/xml; subtype=gml/3.1.1 text/xml; subtype=gml/2.1.2 application/wkt application/gml-3.1.1 application/gml-2.1.2 application/json result result text/xml; subtype=gml/3.1.1 text/xml; subtype=gml/3.1.1 text/xml; subtype=gml/2.1.2 application/wkt application/gml-3.1.1 application/gml-2.1.2 application/json JTS:buffer Buffer Returns a polygonal geometry representing the input geometry enlarged by a given distance around its exterior. geom geom Input geometry text/xml; subtype=gml/3.1.1 text/xml; subtype=gml/3.1.1 text/xml; subtype=gml/2.1.2 application/wkt application/gml-3.1.1 application/gml-2.1.2 application/json distance distance Distance to buffer the input geometry, in the units of the geometry xs:double quadrantSegments quadrantSegments 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. xs:int capStyle capStyle Style for the buffer end caps. Values are: Round - rounded ends (default), Flat - flat ends; Square - square ends. Round Flat Square result result text/xml; subtype=gml/3.1.1 text/xml; subtype=gml/3.1.1 text/xml; subtype=gml/2.1.2 application/wkt application/gml-3.1.1 application/gml-2.1.2 application/json ``` - `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流程描述中确定这个最佳排序需求。 **数据输入类型的数据结构**
InputType data structure
| name | description | data type | m/o | | --------------------- | ----------- | ------------ | ---- | | Identifier | wps服务标识 | ows:CodeType | m | | Title | 标题 | 字符类型 | o | | Abstract | 简介 | 字符类型 | o | | InputData Form Choice | 数据表单 | 详见下表 | m |
InputData Form Choice
| 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 **响应数据格式的数据结构**
ResponseForm data structure
| name | description | Data type | multiplicity | | ------------------ | ------------------------------------------------- | --------- | ------------ | | Response Document | 指示输出应作为WPS响应文档的一部分返回。 | | Zero or one | | RawData Output | 指示输出应直接作为原始数据返回,不应有WPS响应文档 | | Zero or one |
ResponseDocument data structure
| 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 result ``` > asReference属性指定该输出是否应被Process进程存储为Web可访问的资源。
RawDataOutput data structure
| 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 result ``` **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 := > 使用`=`分隔,输入参数和其值,以及分隔参数值的属性和属性值。 > > 例如: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 := \ Value := \ > 注意:字段名和属性名区分大小写。不正确的字段名和属性名将引发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 JTS:buffer geom distance 10 quadrantSegments 2 capStyle Round result ``` > 被``标签所包含的内容将表示为**纯文本**,用来包含不被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`演示工具生成,看得懂就行。 image-20210513115418188 ## 3. WPS状态 当我们发送Execute操作的请求中没有携带`RawDataOutput`参数时,请求默认响应的是`ExecuteResponse`XML文档,里面包含了Process流程执行状态和响应结果。 3938 在首页中的`Process status`可以查看服务器中所有执行的`execute`操作的列表: image-20210513172051814 ![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 | image-20210514101311590 响应结果: ```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的标准安装中包含了用于此示例的数据: - sf:roads:包含道路信息的图层 - sf:restricted:代表保护区的图层 image-20210514115237451 为了计算总长度,我们将需要以下内置的WPS流程: - `gs:IntersectionFeatureCollection`:返回两个要素集合之间的交集,并添加两个要素集合的属性 - `gs:CollectGeometries`:收集要素集中的所有默认几何并将其作为单个几何集合返回 - `JTS:length`:以与几何相同的度量单位计算几何的长度 这些过程的执行顺序很重要。我们先求道路网络与保护区`Intersection`相交,获得保护区内所有道路的要素集合。然后,我们将这些几何形状收集到单个GeometryCollection中,以便可以使用内置的JTS算法来计算长度。 image-20210514151345172 Process流程的顺序是通过将第一个process嵌入到第二个process,再将第二个process嵌入到第三个process,...这种方式来构建整个Process流程的WPS请求。 工作流:一个process流程产生一些输出,这些输出将成为下一个process流程的输入,从而形成一个处理管道,可以通过一个HTTP请求解决复杂的空间分析。这里最开始的输入使用GeoServer的图层layer,优势在于不会在process流程之间来回传送数据,从而获得非常好的性能。 完整的XML格式WPS请求: ```xml JTS:length geom gs:CollectGeometries features gs:IntersectionFeatureCollection first feature collection second feature collection first attributes to retain the_geom cat second attributes to retain cat result result result ``` ![image-20210514152335032](./images/image-20235032.png)