1

This article only introduces the four commonly used WMS, WMTS, WFS, TMS in practical work. For other OGC WebService types such as WCS and WPS, please refer to the official information.


0. Parameter passing method

  • key-value pair
  • RESTful API
  • SOAP

Not all three methods exist for the services listed below, for example, WMS only has the first one.

This article does not cover the SOAP way (because it is too complicated).

1. WMS Quick Check

Take the 1.1.0 version as a reference.

1.1. Capability

  • GetCapabilities
  • GetMap
  • GetFeatureInfo

1.2. Example of getting a map image (GetMap)

Take such a request address as an example:

 http://localhost:4800/geoserver/spatial_base/wms?<queryString>

queryString is the query string, which I have listed as a table:

param value desc
service WMS Service type
version 1.1.0 Service version
request GetMap method
layers spatial_base:guangxi_cities which layer
bbox 104.450889587402, 20.8992862701416, 112.061851501465, 26.3855667114258 how wide
width 768 The width of the image to return in pixels
height 553 the pixel height of the image to be returned
srs EPSG:4326 which coordinate system to use
styles "" What style to use, the default is to give an empty string
format image/png Format
The layers parameter of GeoServer is a combination of "workspace name:layer name".

Then, it returns a picture:

spatial_base-guangxi_cities.png

This is the most common use of WMS to request a map using "key-value pairs", ie queryString.

1.3. Using GeoServer WMS with CesiumJS and OpenLayers6

In CesiumJS:

 new Cesium.WebMapServiceImageryProvider({
  url: 'http://localhost:4800/geoserver/spatial_base/ows',
  layers: 'spatial_base:guangxi_cities',
  parameters: {
    transparent: true,
    format: 'image/png',
  },
})

Just make sure the coordinate system is appropriate. Of course, the url ows can also be changed to wms .

OWS is just a wildcard on GeoServer. If you know what service you want to use, you can leave out ows. For example, in this example, you can directly write ' http://localhost:4800/geoserver/spatial_base/wms '

In OpenLayers6:

 import TileLayer from 'ol/layer/Tile'
import TileWMS from 'ol/source/TileWMS'

new TileLayer({
  extent: [104.4509, 20.8993, 112.0619, 26.3856], // 坐标系保持与 View 一致
  source: new TileWMS({
    url: 'http://localhost:4800/geoserver/spatial_base/wms',
    params: {
      'LAYERS': 'spatial_base:guangxi_cities',
    },
    serverType: 'geoserver', // 有好几种地理服务器,要明确指定
  }),
})

// View 坐标系的设置
import { View } from 'ol'
new View({
  // ...
  projection: get('EPSG:4326') // 返回一个 Projection 实例即可
})

According to OpenLayers documentation:

At least a LAYERS param is required. STYLES is '' by default. VERSION is 1.3.0 by default. WIDTH , HEIGHT , BBOX and CRS ( SRS for WMS version < 1.3.0) will be set dynamically.

That is, at least set the LAYERS parameter. If the coordinate system of the requested layer is the same as that of the View, you do not need to set SRS .

1.4. Obtaining feature information

Although WMS is mainly used to request map images, it is a classic server rendering service, but it also retains the basic element query function, that is, GetFeatureInfo , for example:

 http://localhost:4800/geoserver/spatial_base/ows
?service=WMS
&version=1.1.1
&request=GetFeatureInfo
&layers=spatial_base:guangxi_cities
&bbox=101.25,22.5,112.50,33.75
&width=256
&height=256
&srs=EPSG:4326
&query_layers=spatial_base:guangxi_cities
&info_format=application/json
&x=181
&y=199

GetFeatureInfo is an optional feature that GeoServer has. Briefly explain, the parameters width and height are a small piece of image generated by the parameter bbox range, and then query the pixel position in this image is x , y element information, other parameters are not difficult to understand.

2. WMTS Quick Check

2.1. Axial

The axis orientation of WMTS is shown in the figure below.

2022-07-16-20-44-00-image.png

2.2. Capability

  • GetCapabilities (Get WMTS Metadata Document, also called Get Capability Document)
  • GetTile (Get a tile)
  • GetFeatureInfo (optional capability)

2.3. Schematic

<img title="" src="./attachments/2022-07-16-20-43-00-image.png" alt="" data-align="center" width="482">

The row and column numbers of WMTS, tile matrix (TileMatrix, similar to the concept of hierarchy, refer to Section 5) are counted from 0, for example TileMatrix=EPSG:4326:0&TileCol=0&TileRow=0 .

2.4. Request tile example (GetTile)

Take the tile "TileRow=55 & TileCol=103" in Section 2.3 as an example:

2022-07-16-23-06-09-image.png

Its request address is:

 http://localhost:4800/geoserver/gwc/service/wmts?layer=spatial_base%3Aguangxi_cities&style=&tilematrixset=EPSG%3A900913&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image%2Fpng&TileMatrix=EPSG%3A900913%3A7&TileCol=103&TileRow=55

The queryString is listed as a table:

param value desc
layer spatial_base:guangxi_cities Consistent with the layers meaning of WMS
style "" Consistent with the style meaning of WMS
tilematrixset EPSG:900913 Tile array set, see Section 5 of this article
TileMatrix EPSG\:900913\:7 The tile array of the current level, see Section 5 of this article
TileCol 103 tile column number
TileRow 55 tile row number
Service WMTS Consistent with the service meaning of WMS
Request GetTile Consistent with the request meaning of WMS
Version 1.0.0 Consistent with the version meaning of WMS
Format image/png Consistent with the format meaning of WMS

You should have noticed that the name of the parameter is case-sensitive, but the parameter value is case-sensitive . For example, "EPSG:900913" written as "epsg:900913" cannot be requested (at least for GeoServer); but " GetTile" written as "gettile" is fine again.

2.5. Request tile example (GetTile) using RESTful

The graph is the same as the one returned in the previous section, using the RESTful style of request like this:

 http://localhost:4800/geoserver/gwc/service/wmts/rest/spatial_base:guangxi_cities/polygon/EPSG:900913/EPSG:900913:7/55/103?format=image/png

2.6. About GeoServer's two interface styles for obtaining tiles

  • Key-value pair: Use OpenLayers to preview in GeoServer, and use browser developer tools to view network requests. The interface style here is in the form of key-value pairs, using queryString;
  • RESTful: To request the WMTS capability document, search for the ResourceURL tag, the address here is in REST style.

2.7. Using GeoServer WMTS with CesiumJS and OpenLayers6

In CesiumJS, you have to be very careful about the name of each level of "TileMatrix", because CesiumJS uses a REST-style request address, which means that the TileMatrix must be the same as the TileMatrix name of the corresponding layer in the capability document to be pieced together correct URL.

CesiumJS default WMTS TileMatrix name of each level is simply "0, 1, 2, 3, 4...", but GeoServer default 900913 and 4326 TileMatrixSet The name is "EPSG" \:4326\:0, EPSG\:4326\:1, EPSG\:4326\:2..." and "EPSG\:900913\:0, EPSG\:900913\:1, EPSG\:900913\: 2...", it is easy to deal with this situation, we can use JavaScript to quickly generate such a regular TileMatrixLabels array:

 const maxLevel = 3 // 别忘了改成你的 WMTS 支持的最大等级,此处演示写个 3
const tileMatrixID = 'EPSG:900913'
const tileMatrixLabels = Object.keys(new Array(maxLevel).fill(0)).map(v => `${tileMatrixID}:${v}`)
// tileMatrixLabels 即 ['EPSG:900913:0', 'EPSG:900913:1', 'EPSG:900913:2']

Now, you can use this tileMatrixLabels array to create WebMapTileServiceImageryProvider :

 new Cesium.WebMapTileServiceImageryProvider({
  url: 'http://localhost:4800/geoserver/gwc/service/wmts/rest/spatial_base:guangxi_cities/{style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}?format=image/png',
  style: 'polygon', // 改 'default' 就是默认的样式
  layer: 'spatial_base:guangxi_cities',
  tileMatrixLabels: tileMatrixLabels,
  tileMatrixSetID: 'EPSG:900913',
  rectangle: Cesium.Rectangle.fromDegrees(104.450889587402,20.8992862701416,112.061851501465,26.3855667114258),
})

You can even wrap a function to get the names of these TileMatrix:

 /**
 * 创建 TileMatrix 的名称
 * @param {string} tileMatrixID 即 `TileMatrixSet` 的名称
 * @param {number} maxLevel 即 WMTS 的最大等级
 * @returns {string[]}
 */
const createTileMatrixLabels = (tileMatrixID, maxLevel) => 
  Object.keys(new Array(maxLevel).fill(0)).map(v => `${tileMatrixID}:${v}`)

As for loading WMTS in OpenLayers6, it also needs to calculate the resolution and TileMatrixIDs, which is a little troublesome. Taking EPSG:4326 as an example, you need to calculate the resolution list of the layer and the list of TileMatrix names:

 // 计算 22 级别,够用就行
const resolutions = new Array(22)
// EPSG:4326 一级宽度跨 2 个 256 像素的瓦片
const firstLevelPixelWidth = 360 / (256 * 2)
for (let z = 0; z < 22; ++z) {
  // 逐级除以 2
  resolutions[z] = firstLevelPixelWidth / Math.pow(2, z)
}
const tileMatrixLabels = createTileMatrixLabels('EPSG:4326', 22)

Then, you can use resolutions and tileMatrixLabels to create a WMTSTileGrid to create a WMTS layer:

 const wmtsTileGrid = new WMTSTileGrid({
  origin: [-180, 90], // origin 即当前坐标系的的左上角
  resolutions: resolutions,
  matrixIds: tileMatrixLabels,
})

new TileLayer({
  extent: [104.4509, 20.8993, 112.0619, 26.3856],
  source: new WMTS({
    // 和 CesiumJS 不太一样,这里不用到模板那么细
    url: 'http://localhost:4800/geoserver/gwc/service/wmts',
    layer: 'spatial_base:guangxi_cities',
    matrixSet: 'EPSG:4326', // 与能力文档中此图层的 TileMatrixSet 一致
    format: 'image/png',
    // 也可以用 `ol/proj` 包导出的 get('EPSG:4326'),返回 Projection 实例即可
    projection: 'EPSG:4326',
    tileGrid: wmtsTileGrid,
    style: 'polygon',
    wrapX: true,
  }),
})

EPSG:3857 ,也EPSG:900913 ,那么你的originextentfirstLevelPixelWidth随It changed:

 const origin = [-20037508.34, 2003708.34]
const extent = [11627419.84177403,2379873.5953122815,12474668.246494522,3046913.9333698303]
const firstLevelPixelWidth = 40075016.68557849 / 256

As for why these numbers are, please check the values of the related Gridset in GeoServer, you need to have a basis related to the Web Mercator coordinate system.

3. TMS Quick Check

TMS is a map tile dataset that is very close to static resources. Common tile formats include jpeg , png , pbf and so on. This standard is relatively old, but it is better than simplicity.

3.1. Axial

The TMS axis is oriented as shown below.

2022-07-15-17-31-31-image.png

3.2. Metadata XML Documents

Typically, the TMS address will point to a document with the name tilemapresource.xml . Of course, GeoServer is an exception, just returning an XML document and the address does not point to an XML document.

This XML document is the most distinctive feature of TMS and records the metadata for this tile atlas:

 <TileMap version="1.0.0" tilemapservice="...">
  <!-->...<-->
</TileMap>

3.3. Request tile example

Request address:

 http://localhost:4800/geoserver/gwc/service/tms/1.0.0
/spatial_base:guangxi_cities@EPSG:900913@png
/7/103/72.png

As shown below:

2022-07-16-23-06-09-image.png

3.3. Loading GeoServer's TMS in QGIS

You can add an XYZ layer, but the template link should be filled with {z}/{x}/{-y}.imageExt instead of {z}/{x}/{y}.imageExt .

3.4. Using GeoServer's TMS with CesiumJS and OpenLayers6

CesiumJS has found in testing that TMS loading for EPSG4326 or 3857 coordinate systems that are not full range is problematic. Layers published by GeoServer generally do not have this problem.

Example:

 new Cesium.TileMapServiceImageryProvider({
  url: "http://localhost:4800/geoserver/gwc/service/tms/1.0.0/spatial_base%3Aguangxi_cities@EPSG%3A900913@png",
  minimumLevel: 0,
  maximumLevel: 15,
  rectangle: Cesium.Rectangle.fromDegrees(104.450889587402,20.8992862701416,112.061851501465,26.3855667114258)
})

If the TileMapServiceImageryProvider class is used, then it follows the correct z,x,y order. If you are using UrlTemplateImageryProvider , then you need to change the ---80dcd84046be69479ff408c2a6aafd94 {y} in the template to {reverseY} :

 new Cesium.UrlTemplateImageryProvider({
  url: "http://localhost:4800/geoserver/gwc/service/tms/1.0.0/spatial_base%3Aguangxi_cities@EPSG%3A900913@png/{z}/{x}/{reverseY}.png",
  minimumLevel: 0,
  maximumLevel: 15,
  rectangle: Cesium.Rectangle.fromDegrees(104.450889587402,20.8992862701416,112.061851501465,26.3855667114258)
})

CesiumJS will judge the default TMS description file "tilemapresource.xml", and if the request fails, it will be downgraded to {z}/{x}/{reverseY}.imageExt

In OpenLayers6, using TMS is achieved by XYZ :

 new TileLayer({
  source: new XYZ({
    url: 'http://localhost:4800/geoserver/gwc/service/tms/1.0.0/spatial_base%3Aguangxi_cities@EPSG%3A900913@png/{z}/{x}/{y}.png'
  }),
})

这只是最简单的用法, EPSG:3857 EPSG:900913的TMS,否则要指定其它的参数,例如projectiontileGrid , tileSize , etc., please refer to the official documentation for details. If you don't want the console to report the error that the tile cannot be found where there is no tile, you must also add the extent parameter to the ol/layer/Tile class:

 import TileLayer from 'ol/layer/Tile'

const tmslayer = new TileLayer({
  extent: [11627419.84177403,2379873.5953122815,12474668.246494522,3046913.9333698303],
  // ...
})

3.5. Can GeoServer connect to an existing TMS?

Temporarily not possible.

Reference: Can I use external TMS service as a store in Geoserver?

GeoServer can only connect to WMS and WMTS of other servers at present. TMS is a relatively static tile data service. It is recommended to use the Web server to publish directly without going through GeoServer.

4. WFS Quick Check

Even when WFS reaches version 2.0.0, there are still only two ways to initiate requests:

  • Simple type requests using key-value pairs, usually a Get request, but also a Post request
  • For complex data requests using XML bodies, only Post requests can be used

This is problematic, what are the front-end friends familiar with? What do they want? JSON ah!

Without limitation, WFS returns the XML-based GML format. In short,

4.1. Capability

  • GetFeature : Get vector feature data
  • DescribeFeatureType : Query the metadata of the vector layer
  • GetCapabilities : Obtain the capability document
  • Transaction : Initiate vector graphics interactive transactions, such as additions, deletions, changes, etc.

This is just the main capability. 2.0.0 also adds other capabilities. If you are interested, you can go to the specification, or you can directly refer to the GeoServer help manual, which is very detailed:

I'm just curious, why can't GeoServer integrate a help document natively?

4.2. Get Features and Common Parameters

Take WFS 2.0.0 as an example here.

A simplest request to get all vector features is as follows:

 http://localhost:4800/geoserver/spatial_base/ows
?service=WFS
&version=2.0.0
&request=GetFeature
&typeNames=spatial_base:guangxi_cities
&outputFormat=application/json

The specification of the parameter outputFormat is very important. If not specified, the data in GML format will be returned by default.

Several commonly used parameters are as follows

parameter name value type describe
count int Limit the number of returned items, take the first count
featureid string Specify the ID of the feature to query, the format is "layer name.id"
typeNames string Which "layer" to query, GeoServer is "workspace": "layer name"
propertyName string What attribute fields need to be returned, connected with commas
filter string An XML text, the query information
outputFormat string The format type of the data to be returned, the capability documentation has

Among them, the XML of filter is the most criticized point of WFS, because this XML is more troublesome to construct.

4.3. Using Filtering when getting features

Taking a simple box selection query as an example, you need to construct the following XML:

 <Filter xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml">
  <Intersects>
    <PropertyName>geom</PropertyName>
    <gml:Envelope srsName="EPSG:4326">
      <gml:lowerCorner>109 20</gml:lowerCorner>
      <gml:upperCorner>120 30</gml:upperCorner>
    </gml:Envelope>
  </Intersects>
</Filter>

For my data, such a box-select query would return 11 features. Note that the value of <Intersects> under <PropertyName> , that is, "geom", refers to the geometric field name of the feature layer to be intersected. If it is a Shapefile, its geometry field may be "SHAPE" or something else.

About what space query this filter can perform, please refer to:


The above XML filtering parameters are passed to WFS by sending QueryString through GET request. If the size of the filtered XML is too large and exceeds the maximum size of the GET request (depending on the browser, it is generally smaller), then it needs to be changed to POST request and send this XML as the request body to server.

Request path:

 POST http://localhost:4800/geoserver/spatial_base/ows

The request body is slightly different from the above filter , and other request parameters should also be included:

 <?xml version='1.0' encoding='UTF-8'?>
<wfs:GetFeature 
  service="WFS"
  version="2.0.0"
  outputFormat="json"
  xmlns:wfs="http://www.opengis.net/wfs/2.0"
  xmlns:fes="http://www.opengis.net/fes/2.0"
  xmlns:gml="http://www.opengis.net/gml/3.2"
  xmlns:sf="http://www.openplans.org/spearfish"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.opengis.net/wfs/2.0
                      http://schemas.opengis.net/wfs/2.0/wfs.xsd
                      http://www.opengis.net/gml/3.2
                      http://schemas.opengis.net/gml/3.2.1/gml.xsd"
>
  <wfs:Query typeNames='spatial_base:guangxi_cities'>
  <wfs:PropertyName>geom</wfs:PropertyName>
  <wfs:PropertyName>name</wfs:PropertyName>
    <fes:Filter>
      <fes:PropertyIsEqualTo matchAction="OR">
        <fes:ValueReference>name</fes:ValueReference>
        <fes:Literal>梧州市</fes:Literal>
      </fes:PropertyIsEqualTo>
    </fes:Filter>
  </wfs:Query>
</wfs:GetFeature>

WFS 1.0.0 and 1.1.0 are slightly different, see:

WFS reference materials are complex, with few Chinese tutorials and examples. In fact, it is forgivable that people who pay attention to efficiency do not want to use it.

The official example is in the Annex B chapter of the standard document (Annex B).

For online documentation, you can refer to the OGC Standard Examples page and find the WFS directory.

4.4. Briefly describe transactions (Transaction)

WFS transactions allow you to add, delete, and modify data on the server, including attribute data, and of course graphics data.

In WFS 2.0.0, transactions support the following actions:

  • delete
  • insert
  • replace
  • update

Taking the update as an example, still requesting the address in section 4.3, the sent XML request body is:

 <?xml version='1.0' encoding='UTF-8'?>
<wfs:Transaction 
  version="2.0.0"
  service="WFS"
  xmlns:fes="http://www.opengis.net/fes/2.0"
  xmlns:wfs="http://www.opengis.net/wfs/2.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0.0/wfs.xsd">
  <!-->要 Update 的要素是 spatial_base:guangxi_cities<-->
  <wfs:Update typeName="spatial_base:guangxi_cities">
    <!-->更新名称属性为“梧州市_重命名”<-->
    <wfs:Property>
      <wfs:ValueReference>name</wfs:ValueReference>
      <wfs:Value>梧州市_重命名</wfs:Value>
    </wfs:Property>
    <!-->使用 Filtering 只修改第4个要素<-->
    <fes:Filter>
      <fes:ResourceId rid="guangxi_cities.4"/>
    </fes:Filter>
  </wfs:Update>
</wfs:Transaction>

Sometimes you can't send the Transaction request, the returned error is "XXX is readonly", it should be that GeoServer has restricted editing requests, you can go to "Security - Data" on the management page, set "* .*.w" rules (that is, write rules) are assigned the appropriate roles to get the permission to edit and write.

For more examples, please refer to the example link given at the end of this article, or directly refer to the Examples content in the standard document of the corresponding WFS version.

4.5. Recommended and not recommended

The main task of WFS is not to display a large amount of vector data. A large amount of vector graphics data has very high performance requirements for network transmission and browser rendering. Even if the browser has more than 1000 regular JavaScript objects, it is difficult to control the fluency of the rAF program ( One is that the traversal performance may be insufficient, and the other is that the browser may not have enough operating system memory).

Therefore, WFS is not recommended for full display of vector graphics data .

For the requirement of "both display and query", the task can be decomposed:

  • Display graphics using WMTS/TMS/VectorTiles;
  • Use GetFeatureInfo of WMS/WMTS or store non-spatial data independently, and write request interface to query non-spatial data;
  • For spatial graph analysis or complex spatial query needs, please use geographic database;
  • For editing needs, it is not recommended to use WFS Transaction operation, it is recommended to use geodatabase + customizable back-end query interface

OpenLayers6 has several examples of WFS, and the complexity of using JavaScript functions to concatenate request parameters is troubling, and it really makes me want to use standard WFS.

CesiumJS does not directly consider this OGC service, and allows users to choose whether to load vector graphics data (you can use GeoJsonDataSource to load after requesting vector graphics data).

5. What is TileMatrixSet / TileMatrix

You're bound to see these two things in the WMTS capability documentation. But I think the official documentation is too much nonsense, so I simply wrote my own understanding.

TileMatrixSet I translated it as "tile array set", and TileMatrix that is, "tile array".

Many people may see this word for the first time, and they can't figure out why it is "Matrix" for a while. Literally, "Matrix" is a matrix:

2022-07-16-20-48-31-image.png

It would be understandable if each element block of this matrix was filled with map tiles.

So, TileMatrix refers to all the tiles of a certain level; naturally, TileMatrixSet is the TileMatrix "set" of all levels.

For example, one of the built-in tile arrays in GeoServer is EPSG:4326 , then the seventh-level tile array is EPSG:4326:7 .

There is a similar word in GeoServer Gridset which can be found under TileCaching - Gridsets.

6. Axis orientation of common map service interfaces

① Microsoft Bing Map using Z-order dimensionality reduction coding

Z-order , sometimes called 莫顿曲线 , refer to wiki - Z-order or wikigis - Z-order ).

This curve is used in the numbering of Microsoft Bing Maps tiles. This curve is usually used for encoding quadtrees.

② Google and OSM similar to WMTS

A tile's axis and origin are the same as WMTS, but there is a semantic equivalence:

  • TileCol → x (column Col value, ie horizontal direction)
  • TileRow → y (row Row value, i.e. vertical direction)
  • TileMatrix = z (current tile matrix, ie tile level)

As shown below:

2022-07-16-22-32-36-image.png

The Z, X, Y of OSM and Google Maps are also counted from 0 like WMTS.

Take the TileMatrix=EPSG:900913:7 , TileCol=103 , TileRow=55 tiles of WMTS as an example, then the OSM tiles should be:

 https://a.tile.openstreetmap.org/7/103/55.png

Resulting tiles:

2022-07-17-03-04-26-image.png

The corresponding Google Maps tile link is:

 http://mt2.google.com/vt/lyrs=m@167000000&hl=zh-CN&gl=cn&x=103&y=55&z=7

The resulting graph:

2022-07-17-03-19-54-image.png

Let's move the original WMTS tiles to see:

2022-07-16-23-06-09-image.png

It can be said that the position is the same.

③ Baidu Map

The origin is at 0 degrees longitude, 0 degrees latitude:

2022-07-15-18-48-14-image.png

Baidu's X and Y values are shown in the figure above, both positive and negative.

Tile level, starting from level 3, up to level 21.

Regarding Baidu's N coordinates, please refer to the map coordinate system of Baidu Map API in this article. LBS manufacturers such as AutoNavi, Baidu, and Tencent are not used much in business, so they will not be listed. Friends who need it can use it on the Internet. Find.

References


岭南灯火
83 声望60 粉丝

一介草民