• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

geosolutions-it / MapStore2 / 19933858499

04 Dec 2025 01:54PM UTC coverage: 76.636% (-0.03%) from 76.661%
19933858499

Pull #11648

github

web-flow
Update User Guide - Itinerary plugin (#11768)

* add_11664

* Update docs/user-guide/itinerary.md

Co-authored-by: Suren <dsuren1@gmail.com>

* Update docs/user-guide/itinerary.md

Co-authored-by: Suren <dsuren1@gmail.com>

* Update docs/user-guide/itinerary.md

Co-authored-by: Suren <dsuren1@gmail.com>

* Update docs/user-guide/itinerary.md

Co-authored-by: Suren <dsuren1@gmail.com>

---------

Co-authored-by: Suren <dsuren1@gmail.com>
Pull Request #11648: #11644: Implement dynamic request configurations

32316 of 50296 branches covered (64.25%)

132 of 155 new or added lines in 40 files covered. (85.16%)

283 existing lines in 32 files now uncovered.

40207 of 52465 relevant lines covered (76.64%)

37.89 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

78.87
/web/client/components/map/cesium/plugins/WMTSLayer.js
1
/**
2
 * Copyright 2015, GeoSolutions Sas.
3
 * All rights reserved.
4
 *
5
 * This source code is licensed under the BSD-style license found in the
6
 * LICENSE file in the root directory of this source tree.
7
 */
8

9
import Layers from '../../../../utils/cesium/Layers';
10
import * as Cesium from 'cesium';
11
import ConfigUtils from '../../../../utils/ConfigUtils';
12
import {
13
    getProxyUrl
14
} from '../../../../utils/ProxyUtils';
15
import * as WMTSUtils from '../../../../utils/WMTSUtils';
16
import { creditsToAttribution, getAuthenticationParam, getURLs } from '../../../../utils/LayersUtils';
17
import { isEqual, isObject, isArray, slice, get, head} from 'lodash';
18

19
import urlParser from 'url';
20
import { isVectorFormat } from '../../../../utils/VectorTileUtils';
21
import { getCredentials } from '../../../../utils/SecurityUtils';
22

23
function splitUrl(originalUrl) {
24
    let url = originalUrl;
26✔
25
    let queryString = "";
26✔
26
    if (originalUrl.indexOf('?') !== -1) {
26✔
27
        url = originalUrl.substring(0, originalUrl.indexOf('?') + 1);
16✔
28
        if (originalUrl.indexOf('%') !== -1) {
16!
29
            url = decodeURIComponent(url);
16✔
30
        }
31
        queryString = originalUrl.substring(originalUrl.indexOf('?') + 1);
16✔
32
    }
33
    return {url, queryString};
26✔
34
}
35

36
function WMTSProxy(proxy) {
37
    this.proxy = proxy;
×
38
}
39

40
const isValidTile = (tileMatrixSet) => (x, y, level) =>
24✔
41
    tileMatrixSet && tileMatrixSet[level] && !tileMatrixSet[level].ranges ||
5✔
42
    (x <= parseInt(get(tileMatrixSet[level], "ranges.cols.max"), 10) &&
43
    x >= parseInt(get(tileMatrixSet[level], "ranges.cols.min"), 10) &&
44
    y <= parseInt(get(tileMatrixSet[level], "ranges.rows.max"), 10) &&
45
    y >= parseInt(get(tileMatrixSet[level], "ranges.rows.min"), 10));
46

47

48
WMTSProxy.prototype.getURL = function(resource) {
1✔
49
    let {url, queryString} = splitUrl(resource);
×
50
    return getProxyUrl() + encodeURIComponent(url + queryString);
×
51
};
52

53
function NoProxy() {
54
}
55

56
NoProxy.prototype.getURL = function(resource) {
1✔
57
    let {url, queryString} = splitUrl(resource);
26✔
58
    return url + queryString;
26✔
59
};
60
function getMatrixIds(matrix = [], setId) {
×
61
    return ((isObject(matrix) && matrix[setId]) || isArray(matrix) && matrix || []).map((el) => el.identifier);
46!
62
}
63

64
function getDefaultMatrixId(options) {
65
    let matrixIds = new Array(30);
×
66
    for (let z = 0; z < 30; ++z) {
×
67
        // generate matrixIds arrays for this WMTS
68
        matrixIds[z] = options.tileMatrixPrefix + z;
×
69
    }
70
    return matrixIds;
×
71
}
72

73
const limitMatrix = (matrix, len) => {
1✔
74
    if (matrix.length > len) {
46!
75
        return slice(matrix, 0, len);
×
76
    }
77
    if (matrix.length < len) {
46!
78
        return matrix.concat(new Array(len - matrix.length));
×
79
    }
80
    return matrix;
46✔
81
};
82

83
const getTilingSchema = (srs) => {
1✔
84
    if (srs.indexOf("EPSG:4326") >= 0) {
24✔
85
        return new Cesium.GeographicTilingScheme();
2✔
86
    } else if (srs.indexOf("EPSG:3857") >= 0) {
22!
87
        return new Cesium.WebMercatorTilingScheme();
22✔
88
    }
89
    return null;
×
90
};
91

92
const getMatrixOptions = (options, srs) => {
1✔
93
    const tileMatrixSet = WMTSUtils.getTileMatrixSet(options.tileMatrixSet, srs, options.allowedSRS, options.matrixIds);
46✔
94
    const matrixIds = limitMatrix(options.matrixIds && getMatrixIds(options.matrixIds, tileMatrixSet) || getDefaultMatrixId(options));
46!
95
    return {tileMatrixSet, matrixIds};
46✔
96
};
97

98
function wmtsToCesiumOptions(_options) {
99
    const options = WMTSUtils.parseTileMatrixSetOption(_options);
24✔
100
    let srs = 'EPSG:4326';
24✔
101
    let { tileMatrixSet: tileMatrixSetID, matrixIds} = getMatrixOptions(options, srs);
24✔
102
    if (matrixIds.length === 0) {
24✔
103
        srs = 'EPSG:3857';
22✔
104
        const matrixOptions = getMatrixOptions(options, srs);
22✔
105
        tileMatrixSetID = matrixOptions.tileMatrixSet;
22✔
106
        matrixIds = matrixOptions.matrixIds;
22✔
107
    }
108
    // NOTE: can we use opacity to manage visibility?
109
    // var opacity = options.opacity !== undefined ? options.opacity : 1;
110
    let proxyUrl = ConfigUtils.getProxyUrl({});
24✔
111
    let proxy;
112
    if (proxyUrl) {
24!
113
        proxy = options.forceProxy;
24✔
114
    }
115
    const isValid = isValidTile(options.matrixIds && options.matrixIds[tileMatrixSetID]);
24✔
116
    const queryParametersString = urlParser.format({ query: {...getAuthenticationParam(options)}});
24✔
117
    const cr = options.credits;
24✔
118
    const credit = cr ? new Cesium.Credit(creditsToAttribution(cr)) : '';
24✔
119

120
    let headersOpts;
121
    if (options.security) {
24!
NEW
122
        const storedProtectedService = getCredentials(options.security?.sourceId) || {};
×
NEW
123
        headersOpts = {
×
124
            headers: {
125
                "Authorization": `Basic ${btoa(storedProtectedService.username + ":" + storedProtectedService.password)}`
126
            }
127
        };
128
    }
129
    return Object.assign({
24✔
130
        // TODO: multi-domain support, if use {s} switches to RESTFul mode
131
        url: new Cesium.Resource({
132
            url: head(getURLs(isArray(options.url) ? options.url : [options.url], queryParametersString)),
24!
133
            proxy: proxy && new WMTSProxy(proxy) || new NoProxy(),
48!
134
            ...(headersOpts)
135
        }),
136
        // set image format to png if vector to avoid errors while switching between map type
137
        format: isVectorFormat(options.format) && 'image/png' || options.format || 'image/png',
48!
138
        isValid,
139
        // tileDiscardPolicy: {
140
        //    isReady: () => true,
141
        //    shouldDiscardImage: ({x, y, level}) => !isValid(x, y, level)
142
        // }, // not supported yet
143
        credit,
144
        layer: options.name,
145
        style: options.style || "",
48✔
146
        tileMatrixLabels: matrixIds,
147
        tilingScheme: getTilingSchema(srs, options.matrixIds[tileMatrixSetID]),
148
        enablePickFeatures: false,
149
        tileWidth: options.tileWidth || options.tileSize || 256,
72✔
150
        tileHeight: options.tileHeight || options.tileSize || 256,
72✔
151
        tileMatrixSetID: tileMatrixSetID,
152
        maximumLevel: 30,
153
        parameters: {...getAuthenticationParam(options)}
154
    });
155
}
156

157
const createLayer = options => {
1✔
158
    let layer;
159
    const cesiumOptions = wmtsToCesiumOptions(options);
24✔
160
    layer = new Cesium.WebMapTileServiceImageryProvider(cesiumOptions);
24✔
161
    const orig = layer.requestImage;
24✔
162
    layer.requestImage = (x, y, level) => cesiumOptions.isValid(x, y, level) ? orig.bind(layer)( x, y, level) : new Promise( () => undefined);
24✔
163
    layer.updateParams = (params) => {
24✔
164
        const newOptions = Object.assign({}, options, {
×
165
            params: Object.assign({}, options.params || {}, params)
×
166
        });
167
        return createLayer(newOptions);
×
168
    };
169
    return layer;
24✔
170
};
171

172
const updateLayer = (layer, newOptions, oldOptions) => {
1✔
173
    if (newOptions.securityToken !== oldOptions.securityToken
17!
174
    || oldOptions.format !== newOptions.format
175
    || !isEqual(oldOptions.security, newOptions.security)
176
    || oldOptions.credits !== newOptions.credits || newOptions.forceProxy !== oldOptions.forceProxy) {
177
        return createLayer(newOptions);
17✔
178
    }
179
    return null;
×
180
};
181

182
Layers.registerType('wmts', {create: createLayer, update: updateLayer});
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc