Skip to content

Commit

Permalink
#8872 WMTS - No persistency for TileMatrixSetLimits il TileMatrixSet …
Browse files Browse the repository at this point in the history
…is within a layer (#8881)
  • Loading branch information
allyoucanmap authored Dec 14, 2022
1 parent 7d01b1c commit e8ee504
Show file tree
Hide file tree
Showing 15 changed files with 901 additions and 330 deletions.
223 changes: 171 additions & 52 deletions docs/developer-guide/maps-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -297,9 +297,24 @@ in `localConfig.json`

#### WMTS

WMTS Layer require a source object in the `sources` object of the map configuration where to retrieve the `tileMatrixSet`. The source is identified by the `capabilitiesURL`. (if `capabilitiesURL` is not present it will use the `url`, in case of multiple URLs, the first one.).
The WMTS Layer configuration has a `availableTileMatrixSets` object that lists all the available tile matrix sets for the specific layer.
Every entry of `availableTileMatrixSets`, identified by the ID of the tile matrix set, contains the `crs` and one of `tileMatrixSet` or `tileMatrixSetLink`. The first contains the definition of the tile matrix set, while the second contain the path to the tile matrix set definition in the JSON of the map configuration.
This object can also optionally contain a `limits` entry, containing the specific limits of the layer inside the tile matrix set.

A WMTS layer can have a `requestEncoding` that is RESTful or KVP. In case of RESTful the URL is a template where to place the request parameters ( see the example below ), while in the KVP the request parameters are in the query string. See the WMTS standard for more details.
```json
{
"type": "wmts",
"availableTileMatrixSets": {
"google3857": {
"crs": "EPSG:3857",
"tileMatrixSetLink": "sources['https://sampleServer.org/wmts/1.0.0/WMTSCapabilities.xml'].tileMatrixSet['EPSG:3857']"
}
}
```

The `sources` entry of the map configuration usually contains the tile matrix sets definitions of the layers of the map, stored by their `capabilitiesURL` (if `capabilitiesURL` is not present it will use the `url` of the layer, in case of multiple URLs, the first one.).

A WMTS layer has also a `requestEncoding` entry that can be valued with `RESTful` or `KVP`. In case of `RESTful` the URL is a template where to place the request parameters ( see the example below ), while in the `KVP` case the request parameters will be passed in the query string. See the WMTS standard for more details.

e.g. (RESTful):

Expand Down Expand Up @@ -327,11 +342,12 @@ e.g. (RESTful):
"allowedSRS": {
"EPSG:3857": true
},
"matrixIds": [
"google3857",
"EPSG:3857"
],
"tileMatrixSet": true,
"availableTileMatrixSets": {
"google3857": {
"crs": "EPSG:3857",
"tileMatrixSetLink": "sources['https://sampleServer.org/wmts/1.0.0/WMTSCapabilities.xml'].tileMatrixSet['EPSG:3857']"
}
},
// KVP (By default) or RESTful
"requestEncoding": "RESTful",
// identifier for the source
Expand Down Expand Up @@ -417,16 +433,74 @@ e.g. (KVP)
"EPSG:3857": true,
"EPSG:900913": true
},
// list of the available matrixes for the layer
"matrixIds": [
"EPSG:3395",
"EPSG:32761",
"EPSG:3857",
"EPSG:4326",
"EPSG:900913",
"EPSG:32661"
],
"tileMatrixSet": true
"availableTileMatrixSets": {
"EPSG:32761": {
"crs": "EPSG:32761",
"tileMatrixSetLink": "sources['http://some.domain/geoserver/gwc/service/wmts'].tileMatrixSet['EPSG:32761']"
},
"EPSG:3857": {
"crs": "EPSG:3857",
"tileMatrixSetLink": "sources['http://some.domain/geoserver/gwc/service/wmts'].tileMatrixSet['EPSG:3857']"
},
"EPSG:4326": {
"crs": "EPSG:4326",
"tileMatrixSetLink": "sources['http://some.domain/geoserver/gwc/service/wmts'].tileMatrixSet['EPSG:4326']"
},
"EPSG:32661": {
"crs": "EPSG:32661",
"tileMatrixSetLink": "sources['http://some.domain/geoserver/gwc/service/wmts'].tileMatrixSet['EPSG:32661']"
},
"EPSG:3395": {
"crs": "EPSG:3395",
"tileMatrixSetLink": "sources['http://some.domain/geoserver/gwc/service/wmts'].tileMatrixSet['EPSG:3395']"
},
"EPSG:900913": {
"crs": "EPSG:900913",
// these ranges limit the tiles available for the grid level
"limits": [
{
"identifier": "EPSG:900913:0",
"ranges": {
"cols": {
"min": "0",
"max": "0"
},
"rows": {
"min": "0",
"max": "0"
}
}
},
{
"identifier": "EPSG:900913:1",
"ranges": {
"cols": {
"min": "0",
"max": "1"
},
"rows": {
"min": "0",
"max": "1"
}
}
},
{
"identifier": "EPSG:900913:2",
"ranges": {
"cols": {
"min": "0",
"max": "3"
},
"rows": {
"min": "0",
"max": "3"
}
}
}
],
"tileMatrixSetLink": "sources['http://some.domain/geoserver/gwc/service/wmts'].tileMatrixSet['EPSG:900913']"
}
}
}
],
// ...
Expand All @@ -450,18 +524,7 @@ e.g. (KVP)
"TileWidth": "256",
"TileHeight": "256",
"MatrixWidth": "1",
"MatrixHeight": "1",

"ranges": {
"cols": {
"min": "0",
"max": "0"
},
"rows": {
"min": "0",
"max": "0"
}
}
"MatrixHeight": "1"
},
{
"ows:Identifier": "EPSG:900913:1",
Expand All @@ -470,18 +533,7 @@ e.g. (KVP)
"TileWidth": "256",
"TileHeight": "256",
"MatrixWidth": "2",
"MatrixHeight": "2",
// these ranges limit the tiles available for the grid level
"ranges": {
"cols": {
"min": "0",
"max": "1"
},
"rows": {
"min": "0",
"max": "1"
}
}
"MatrixHeight": "2"
},
{
"ows:Identifier": "EPSG:900913:2",
Expand All @@ -490,17 +542,7 @@ e.g. (KVP)
"TileWidth": "256",
"TileHeight": "256",
"MatrixWidth": "4",
"MatrixHeight": "4",
"ranges": {
"cols": {
"min": "0",
"max": "3"
},
"rows": {
"min": "0",
"max": "3"
}
}
"MatrixHeight": "4"
}
]
}
Expand All @@ -510,6 +552,83 @@ e.g. (KVP)
}
```

e.g. (embed tileMatrixSet without link to sources)

```javascript
{
"version": 2,
"map": {
// ...
"projection": "EPSG:900913",
"layers": [
// ...
{
// requestEncoding is KVP by default
"id": "EMSA:S52 Standard__6",
"name": "EMSA:S52 Standard",
"description": "S52 Standard",
"title": "S52 Standard",
"type": "wmts",
// if the capabilitiesURL is not present, the `url` will be used to identify the source.
// (for retro-compatibility with existing layers)
"url": "http://some.domain/geoserver/gwc/service/wmts",
"bbox": {
"crs": "EPSG:4326",
"bounds": {
"minx": "-180.0",
"miny": "-79.99999999999945",
"maxx": "180.0",
"maxy": "83.99999999999999"
}
},
// list of allowed SRS
"allowedSRS": {
"EPSG:3857": true,
"EPSG:900913": true
},
"availableTileMatrixSets": {
"EPSG:900913": {
"crs": "EPSG:900913",
"tileMatrixSet": {
"ows:Identifier": "EPSG:900913",
"ows:SupportedCRS": "urn:ogc:def:crs:EPSG::900913",
"TileMatrix": [
{
"ows:Identifier": "EPSG:900913:0",
"ScaleDenominator": "5.590822639508929E8",
"TopLeftCorner": "-2.003750834E7 2.0037508E7",
"TileWidth": "256",
"TileHeight": "256",
"MatrixWidth": "1",
"MatrixHeight": "1"
},
{
"ows:Identifier": "EPSG:900913:1",
"ScaleDenominator": "2.7954113197544646E8",
"TopLeftCorner": "-2.003750834E7 2.0037508E7",
"TileWidth": "256",
"TileHeight": "256",
"MatrixWidth": "2",
"MatrixHeight": "2"
},
{
"ows:Identifier": "EPSG:900913:2",
"ScaleDenominator": "1.3977056598772323E8",
"TopLeftCorner": "-2.003750834E7 2.0037508E7",
"TileWidth": "256",
"TileHeight": "256",
"MatrixWidth": "4",
"MatrixHeight": "4"
}
]
}
}
}
}
]
}
```

#### Bing

TODO
Expand Down
67 changes: 37 additions & 30 deletions web/client/api/catalog/WMTS.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,14 @@
*/

import { getConfigProp, cleanDuplicatedQuestionMarks } from '../../utils/ConfigUtils';
import assign from 'object-assign';

import { castArray, isObject, head, isArray, isNil } from 'lodash';
import { castArray, isObject, isArray, isNil } from 'lodash';
import { getEPSGCode } from '../../utils/CoordinatesUtils';

import {
getTileMatrixSet,
getGetTileURL,
getCapabilitiesURL
getCapabilitiesURL,
parseTileMatrixSetOption
} from '../../utils/WMTSUtils';

import {
Expand Down Expand Up @@ -102,9 +101,8 @@ const recordToLayer = (record, {
dimensions: record.dimensions || [],
name: ogcServiceReference.params && ogcServiceReference.params.name,
title: record.title || ogcServiceReference.params && ogcServiceReference.params.name,
matrixIds: record.matrixIds || [],
description: record.description || "",
tileMatrixSet: record.tileMatrixSet || [],
availableTileMatrixSets: record.availableTileMatrixSets || [],
credits: !getConfigProp("noCreditsFromCatalog") && record.credits,
bbox: {
crs: record.boundingBox.crs,
Expand Down Expand Up @@ -136,30 +134,40 @@ export const getCatalogRecords = (records, options) => {
if (urls.length === 1) {
urls = urls[0];
}

const capabilitiesURL = getCapabilitiesURL(record);
const matrixIds = castArray(record.TileMatrixSetLink || []).reduce((previous, current) => {
const tileMatrix = head((record.TileMatrixSet && castArray(record.TileMatrixSet) || []).filter((matrix) => matrix["ows:Identifier"] === current.TileMatrixSet));
const tileMatrixSRS = tileMatrix && getEPSGCode(tileMatrix["ows:SupportedCRS"]);
const levels = current.TileMatrixSetLimits && (current.TileMatrixSetLimits.TileMatrixLimits || []).map((limit) => ({
identifier: limit.TileMatrix,
ranges: {
cols: {
min: limit.MinTileCol,
max: limit.MaxTileCol
},
rows: {
min: limit.MinTileRow,
max: limit.MaxTileRow
const availableTileMatrixSets = castArray(record?.TileMatrixSetLink || [])
.reduce((acc, tileMatrixSetLink) => {
const tileMatrix = castArray(record?.TileMatrixSet || [])
.find((matrix) => matrix['ows:Identifier'] === tileMatrixSetLink.TileMatrixSet);
const tileMatrixSRS = tileMatrix && getEPSGCode(tileMatrix['ows:SupportedCRS']);
const limits = tileMatrixSetLink?.TileMatrixSetLimits
? castArray(tileMatrixSetLink?.TileMatrixSetLimits?.TileMatrixLimits || [])
.map((limit) => ({
identifier: limit.TileMatrix,
ranges: {
cols: {
min: limit.MinTileCol,
max: limit.MaxTileCol
},
rows: {
min: limit.MinTileRow,
max: limit.MaxTileRow
}
}
}))
: null;
return {
...acc,
[tileMatrix['ows:Identifier']]: {
crs: tileMatrixSRS,
...(limits && { limits }),
tileMatrixSet: tileMatrix
}
}
})) || tileMatrix.TileMatrix.map((matrix) => ({
identifier: matrix["ows:Identifier"]
}));
return assign(previous, {
[tileMatrix["ows:Identifier"]]: levels,
[tileMatrixSRS]: levels
});
}, {});
};
}, {});

const { matrixIds } = parseTileMatrixSetOption({ availableTileMatrixSets });

const bbox = getWMTSBBox(record);
const references = [{
Expand All @@ -183,8 +191,7 @@ export const getCatalogRecords = (records, options) => {
capabilitiesURL: capabilitiesURL,
queryable: record.queryable,
requestEncoding: record.requestEncoding,
tileMatrixSet: record.TileMatrixSet,
matrixIds,
availableTileMatrixSets,
format: record.format,
TileMatrixSetLink: castArray(record.TileMatrixSetLink),
boundingBox: {
Expand Down
3 changes: 2 additions & 1 deletion web/client/components/map/cesium/plugins/WMTSLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ const getMatrixOptions = (options, srs) => {
return {tileMatrixSet, matrixIds};
};

function wmtsToCesiumOptions(options) {
function wmtsToCesiumOptions(_options) {
const options = WMTSUtils.parseTileMatrixSetOption(_options);
let srs = 'EPSG:4326';
let { tileMatrixSet: tileMatrixSetID, matrixIds} = getMatrixOptions(options, srs);
if (matrixIds.length === 0) {
Expand Down
3 changes: 2 additions & 1 deletion web/client/components/map/leaflet/plugins/WMTSLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ function getWMSURLs(urls) {
return urls.map((url) => url.split("\?")[0]);
}

const createLayer = options => {
const createLayer = _options => {
const options = WMTSUtils.parseTileMatrixSetOption(_options);
const urls = getWMSURLs(isArray(options.url) ? options.url : [options.url]);
const queryParameters = wmtsToLeafletOptions(options) || {};
urls.forEach(url => addAuthenticationParameter(url, queryParameters, options.securityToken));
Expand Down
Loading

0 comments on commit e8ee504

Please sign in to comment.