• 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

95.74
/web/client/api/WFS.js
1
/**
2
 * Copyright 2016, 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
import axios from '../libs/ajax';
9
import urlUtil from 'url';
10
import xml2js from 'xml2js';
11
import ConfigUtils from '../utils/ConfigUtils';
12
import requestBuilder from '../utils/ogc/WFS/RequestBuilder';
13
import {toOGCFilterParts} from '../utils/FilterUtils';
14
import { getDefaultUrl } from '../utils/URLUtils';
15
import { castArray } from 'lodash';
16
import { isValidGetFeatureInfoFormat } from '../utils/WMSUtils';
17
import { getAuthorizationBasic } from '../utils/SecurityUtils';
18

19
const capabilitiesCache = {};
1✔
20

21
export const toDescribeURL = (url, typeName) => {
1✔
22
    const parsed = urlUtil.parse(getDefaultUrl(url), true);
6✔
23
    return urlUtil.format(
6✔
24
        {
25
            ...parsed,
26
            search: undefined, // this allows to merge parameters correctly
27
            query: {
28
                ...parsed.query,
29

30
                service: "WFS",
31
                version: "1.1.0",
32
                typeName,
33
                outputFormat: 'application/json',
34
                request: "DescribeFeatureType"
35
            }
36
        });
37
};
38
/**
39
 * Simple getFeature using http GET method with json format
40
 */
41
export const getFeatureSimple = function(baseUrl, params) {
1✔
42
    return axios.get(baseUrl + '?service=WFS&version=1.1.0&request=GetFeature', {
22✔
43
        params: Object.assign({
44
            outputFormat: "application/json"
45
        }, params)
46
    }).then((response) => {
47
        if (typeof response.data !== 'object') {
21!
UNCOV
48
            return JSON.parse(response.data);
×
49
        }
50
        return response.data;
21✔
51
    });
52
};
53

54
export const getCapabilitiesURL = (url, {version = "1.1.0"} = {}) => {
1✔
55
    const parsed = urlUtil.parse(getDefaultUrl(url), true);
7✔
56
    return urlUtil.format(Object.assign({}, parsed, {
7✔
57
        search: undefined, // this allows to merge parameters correctly
58
        query: Object.assign({
59
            version,
60
            ...parsed.query,
61
            service: "WFS",
62
            request: "GetCapabilities"
63
        })
64
    }));
65
};
66

67
export const getFeatureURL = (url, typeName, { version = "1.1.0", ...params } = {}) => {
1✔
68
    const parsed = urlUtil.parse(getDefaultUrl(url), true);
19✔
69
    return urlUtil.format(Object.assign({}, parsed, {
19✔
70
        search: undefined, // this allows to merge parameters correctly
71
        query: Object.assign({
72
            typeName,
73
            version,
74
            ...parsed.query,
75
            service: "WFS",
76
            request: "GetFeature",
77
            ...params
78
        })
79
    }));
80
};
81
/**
82
 * Performs a getFeature request (using axios POST) to a WFS service for a given MapStore layer WFS layer object.
83
 * @param {object} layer MapStore layer object
84
 * @param {object} requestOptions additional request options. Can include:
85
 * - `version`: WFS version. Default: `1.1.0`
86
 * - `filter`: optional array of mapstore filters. If the layer has a `layerFilter` property or filterObj, it will be added to the filter in a logic AND.
87
 * - `proj`: projection string
88
 * - `outputFormat`: output format string. Default: `application/json`
89
 * - `resultType`: result type string. Default: `results`
90
 * @param {object} config axios request config (headers, etc...)
91
 */
92
export const getFeatureLayer = (layer, {version =  "1.1.0", filters, proj, outputFormat = 'application/json', resultType = 'results'} = {}, config) => {
1✔
93
    const {url, name: typeName, params } = layer;
11✔
94
    const {layerFilter, filterObj: featureGridFilter} = layer; // TODO: add
11✔
95
    const {getFeature: wfsGetFeature, query, filter, and} = requestBuilder({wfsVersion: version});
11✔
96
    const allFilters = []
11✔
97
        .concat(filters ?? [])
13✔
98
        .concat(layerFilter ? layerFilter : [])
11✔
99
        .concat(featureGridFilter ? featureGridFilter : []);
11!
100
    const reqBody = wfsGetFeature(query(
11✔
101
        typeName,
102
        // TODO: insert propertyName before filter to limit attributes to return
103
        allFilters.length > 0
11✔
104
            ? filter(
105
                and(
106
                    allFilters
107
                        .map(f => toOGCFilterParts(f, version, "ogc"))
14✔
108
                )
109

110
            ) : "",
111
        {srsName: proj} // 3rd for query is optional
112
    ),
113
    {outputFormat, resultType}
114
    );
115
    return axios.post(url, reqBody, {
11✔
116
        ...config,
117
        params,
118
        headers: {
119
            ...config?.headers,
120
            'Content-Type': 'application/xml'
121
        }
122
    });
123
};
124

125
/**
126
 * Performs a WFS GetFeature request (using axios GET) with the given parameters.
127
 * @param {string} url URL of the WFS service
128
 * @param {string} typeName layer name
129
 * @param {object} params the params to add to the request
130
 * @param {object} config axios request config (headers, etc...)
131
 * @returns {Promise} the axios promise
132
 */
133
export const getFeature = (url, typeName, params, config) => {
1✔
134
    return axios.get(getFeatureURL(url, typeName, params), config);
16✔
135
};
136

137
export const getCapabilities = function(url, info) {
1✔
138
    const cached = capabilitiesCache[url];
8✔
139
    if (cached && new Date().getTime() < cached.timestamp + (ConfigUtils.getConfigProp('cacheExpire') || 60) * 1000) {
8✔
140
        return Promise.resolve(cached.data);
2✔
141
    }
142
    const protectedId = info?.options?.service?.protectedId;
6✔
143
    let headers = getAuthorizationBasic(protectedId);
6✔
144
    return axios.get(getCapabilitiesURL(url, {headers}))
6✔
145
        .then((response) => {
146
            let json;
147
            xml2js.parseString(response.data, { explicitArray: false, stripPrefix: true }, (ignore, result) => {
5✔
148
                json = { ...result, url };
5✔
149
            });
150
            capabilitiesCache[url] = {
5✔
151
                timestamp: new Date().getTime(),
152
                data: json
153
            };
154
            return json;
5✔
155
        });
156
};
157

158
export const describeFeatureType = function(url, typeName) {
1✔
159
    return axios.get(toDescribeURL(url, typeName)).then(({data}) => data);
5✔
160
};
161

162
/**
163
 * Fetch the supported formats of the WFS service
164
 * @param url
165
 * @return {object} { infoFormats }
166
 */
167
export const getSupportedFormat = (url) => {
1✔
168
    return getCapabilities(url)
3✔
169
        .then((response) => {
170
            const operations = castArray(response?.['wfs:WFS_Capabilities']?.['ows:OperationsMetadata']?.['ows:Operation'] || []);
3✔
171
            const getFeatureOperation = operations.find(operation => operation?.$?.name === 'GetFeature');
3✔
172
            const parameters = castArray(getFeatureOperation?.['ows:Parameter'] || []);
3✔
173
            const outputFormats = parameters.find((parameter) => parameter?.$?.name === 'outputFormat')?.['ows:Value'] || [];
3✔
174
            const infoFormats = outputFormats.filter(isValidGetFeatureInfoFormat);
3✔
175
            return {
3✔
176
                infoFormats: infoFormats?.length ? infoFormats : ['application/json']
3✔
177
            };
178
        })
UNCOV
179
        .catch(() => ({ infoFormats: ['application/json'] }));
×
180
};
181

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