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

iTowns / itowns / 10635241580

30 Aug 2024 03:26PM UTC coverage: 86.966% (-2.8%) from 89.766%
10635241580

push

github

jailln
feat(3dtiles): add new OGC3DTilesLayer using 3d-tiles-renderer-js

Deprecate C3DTilesLayer (replaced by OGC3DTilesLayer).
Add new iGLTFLoader that loads gltf 1.0 and 2.0 files.

2791 of 3694 branches covered (75.55%)

Branch coverage included in aggregate %.

480 of 644 new or added lines in 8 files covered. (74.53%)

2144 existing lines in 111 files now uncovered.

24319 of 27479 relevant lines covered (88.5%)

1024.72 hits per line

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

92.5
/src/Source/WFSSource.js
1
import Source from 'Source/Source';
1✔
2
import URLBuilder from 'Provider/URLBuilder';
1✔
3
import CRS from 'Core/Geographic/Crs';
1✔
4

1✔
5
/**
1✔
6
 * @classdesc
1✔
7
 * An object defining the source of resources to get from a
1✔
8
 * [WFS]{@link http://www.opengeospatial.org/standards/wfs} server. It inherits
1✔
9
 * from {@link Source}.
1✔
10
 *
1✔
11
 * @extends Source
1✔
12
 *
1✔
13
 * @property {boolean} isWFSSource - Used to checkout whether this source is a
1✔
14
 * WFSSource. Default is true. You should not change this, as it is used
1✔
15
 * internally for optimisation.
1✔
16
 * @property {string} typeName - The name of the feature to get, used in the
1✔
17
 * generation of the url.
1✔
18
 * @property {string} version - The version of the WFS server to request on.
1✔
19
 * Default value is '2.0.2'.
1✔
20
 * @property {Object} zoom - Object containing the minimum and maximum values of
1✔
21
 * the level, to zoom in the source.
1✔
22
 * @property {number} zoom.min - The minimum level of the source. Default value
1✔
23
 * is 0.
1✔
24
 * @property {number} zoom.max - The maximum level of the source. Default value
1✔
25
 * is 21.
1✔
26
 * @property {string} bboxDigits - The bbox digits precision used in URL
1✔
27
 * @property {Object} vendorSpecific - An object containing vendor specific
1✔
28
 * parameters. See for example a [list of these parameters for GeoServer]{@link
1✔
29
 * https://docs.geoserver.org/latest/en/user/services/wfs/vendor.html}. This
1✔
30
 * object is read simply with the `key` being the name of the parameter and
1✔
31
 * `value` being the value of the parameter. If used, this property should be
1✔
32
 * set in the constructor parameters.
1✔
33
 *
1✔
34
 * @example
1✔
35
 * // Add color layer with WFS source
1✔
36
 * // Create the source
1✔
37
 * const wfsSource = new itowns.WFSSource({
1✔
38
 *     url: 'https://data.geopf.fr/wfs/ows?',
1✔
39
 *     version: '2.0.0',
1✔
40
 *     typeName: 'BDTOPO_BDD_WLD_WGS84G:bati_remarquable',
1✔
41
 *     crs: 'EPSG:4326',
1✔
42
 *     extent: {
1✔
43
 *         west: 4.568,
1✔
44
 *         east: 5.18,
1✔
45
 *         south: 45.437,
1✔
46
 *         north: 46.03,
1✔
47
 *     },
1✔
48
 *     zoom: { min: 14, max: 14 },
1✔
49
 *     format: 'application/json',
1✔
50
 * });
1✔
51
 *
1✔
52
 * // Create the layer
1✔
53
 * const colorlayer = new itowns.ColorLayer('color_build', {
1✔
54
 *     style: {
1✔
55
 *         fill: 'red',
1✔
56
 *         fillOpacity: 0.5,
1✔
57
 *         stroke: 'white',
1✔
58
 *     },
1✔
59
 *     source: wfsSource,
1✔
60
 * });
1✔
61
 *
1✔
62
 * // Add the layer
1✔
63
 * view.addLayer(colorlayer);
1✔
64
 *
1✔
65
 * @example
1✔
66
 * // Add geometry layer with WFS source
1✔
67
 * // Create the source
1✔
68
 * const wfsSource = new itowns.WFSSource({
1✔
69
 *     url: 'https://data.geopf.fr/wfs/ows?',
1✔
70
 *     version: '2.0.0',
1✔
71
 *     typeName: 'BDTOPO_BDD_WLD_WGS84G:bati_remarquable',
1✔
72
 *     crs: 'EPSG:4326',
1✔
73
 *     extent: {
1✔
74
 *         west: 4.568,
1✔
75
 *         east: 5.18,
1✔
76
 *         south: 45.437,
1✔
77
 *         north: 46.03,
1✔
78
 *     },
1✔
79
 *     zoom: { min: 14, max: 14 },
1✔
80
 *     format: 'application/json',
1✔
81
 * });
1✔
82
 *
1✔
83
 * // Create the layer
1✔
84
 * const geometryLayer = new itowns.FeatureGeometryLayer('mesh_build', {
1✔
85
 *     style: {
1✔
86
 *         fill: {
1✔
87
 *             color: new itowns.THREE.Color(0xffcc00),
1✔
88
 *             base_altitude: (p) => p.altitude,
1✔
89
 *             extrusion_height: (p) => p.height,
1✔
90
 *         }
1✔
91
 *     },
1✔
92
 *     source: wfsSource,
1✔
93
 *     zoom: { min: 14 },
1✔
94
 * };
1✔
95
 *
1✔
96
 * // Add the layer
1✔
97
 * view.addLayer(geometryLayer);
1✔
98
 */
1✔
99
class WFSSource extends Source {
1✔
100
    /**
1✔
101
     * @param {Object} source - An object that can contain all properties of a
1✔
102
     * WFSSource and {@link Source}. `url`, `typeName` and `crs` are
1✔
103
     * mandatory.
1✔
104
     *
1✔
105
     * @constructor
1✔
106
     */
1✔
107
    constructor(source) {
1✔
108
        if (source.projection) {
7!
109
            console.warn('WFSSource projection parameter is deprecated, use crs instead.');
×
UNCOV
110
            source.crs = source.crs || source.projection;
×
UNCOV
111
        }
×
112
        if (!source.typeName) {
7✔
113
            throw new Error('source.typeName is required in wfs source.');
1✔
114
        }
1✔
115

6✔
116
        if (!source.crs) {
7✔
117
            throw new Error('source.crs is required in wfs source');
1✔
118
        }
1✔
119

5✔
120
        source.format = source.format || 'application/json';
7✔
121

7✔
122
        super(source);
7✔
123

7✔
124
        this.isWFSSource = true;
7✔
125
        this.typeName = source.typeName;
7✔
126
        this.version = source.version || '2.0.2';
7✔
127
        this.bboxDigits = source.bboxDigits;
7✔
128

7✔
129
        // Add ? at the end of the url if it is not already in the given URL
7✔
130
        if (!this.url.endsWith('?')) {
7✔
131
            this.url = `${this.url}?`;
5✔
132
        }
5✔
133
        this.url = `${source.url
5✔
134
        }SERVICE=WFS&REQUEST=GetFeature&typeName=${this.typeName
5✔
135
        }&VERSION=${this.version
5✔
136
        }&SRSNAME=${this.crs
5✔
137
        }&outputFormat=${this.format
5✔
138
        }&BBOX=%bbox,${this.crs}`;
5✔
139

5✔
140
        this.zoom = { min: 0, max: Infinity };
5✔
141

5✔
142
        this.vendorSpecific = source.vendorSpecific;
5✔
143
        for (const name in this.vendorSpecific) {
7✔
144
            if (Object.prototype.hasOwnProperty.call(this.vendorSpecific, name)) {
9✔
145
                this.url = `${this.url}&${name}=${this.vendorSpecific[name]}`;
9✔
146
            }
9✔
147
        }
9✔
148
    }
3✔
149

1✔
150
    handlingError(err) {
1✔
151
        if (err.response && err.response.status == 400) {
1!
152
            return err.response.text().then((text) => {
×
153
                const getCapUrl = `${this.url}SERVICE=WFS&REQUEST=GetCapabilities&VERSION=${this.version}`;
×
154
                const xml = new DOMParser().parseFromString(text, 'application/xml');
×
155
                const errorElem = xml.querySelector('Exception');
×
156
                const errorCode = errorElem.getAttribute('exceptionCode');
×
UNCOV
157
                const errorMessage = errorElem.querySelector('ExceptionText').textContent;
×
UNCOV
158
                console.error(`Source ${this.typeName}: bad request when fetching data. Server says: "${errorCode}: ${errorMessage}". \nReviewing ${getCapUrl} may help.`, err);
×
UNCOV
159
            });
×
UNCOV
160
        }
×
161
        return super.handlingError(err);
1✔
162
    }
1✔
163

1✔
164
    requestToKey(extent) {
1✔
165
        if (CRS.isTms(extent.crs)) {
8✔
166
            return super.requestToKey(extent);
7✔
167
        } else {
8✔
168
            return [extent.zoom, extent.south, extent.west];
1✔
169
        }
1✔
170
    }
8✔
171

1✔
172
    urlFromExtent(extent) {
1✔
173
        return URLBuilder.bbox(extent, this);
4✔
174
    }
4✔
175

1✔
176
    extentInsideLimit(extent) {
1✔
177
        return this.extent.intersectsExtent(extent);
4✔
178
    }
4✔
179
}
1✔
180

1✔
181
export default WFSSource;
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