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:
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 aLAYERS
param is required.STYLES
is''
by default.VERSION
is1.3.0
by default.WIDTH
,HEIGHT
,BBOX
andCRS
(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.
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:
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
,那么你的origin
、 extent
、 firstLevelPixelWidth
随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.
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:
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,否则要指定其它的参数,例如projection
、 tileGrid
, 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:
- GeoServer Docs - Filtering - Supported Filtering Language
- GeoServer Docs - Filtering - Filtering Function References
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:
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:
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:
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:
Let's move the original WMTS tiles to see:
It can be said that the position is the same.
③ Baidu Map
The origin is at 0 degrees longitude, 0 degrees latitude:
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.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。