• 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

93.45
/src/Source/VectorTilesSource.js
1
import { featureFilter } from '@mapbox/mapbox-gl-style-spec';
1✔
2
import Style from 'Core/Style';
1✔
3
import TMSSource from 'Source/TMSSource';
1✔
4
import URLBuilder from 'Provider/URLBuilder';
1✔
5
import Fetcher from 'Provider/Fetcher';
1✔
6
import urlParser from 'Parser/MapBoxUrlParser';
1✔
7

1✔
8
function toTMSUrl(url) {
9✔
9
    return url.replace(/\{/g, '${');
9✔
10
}
9✔
11

1✔
12
function mergeCollections(collections) {
1✔
13
    const collection = collections[0];
1✔
14
    collections.forEach((col, index) => {
1✔
15
        if (index === 0) { return; }
2✔
16
        col.features.forEach((feature) => {
1✔
17
            collection.features.push(feature);
1✔
18
        });
1✔
19
    });
1✔
20
    return collection;
1✔
21
}
1✔
22

1✔
23
/**
1✔
24
 * @classdesc
1✔
25
 * VectorTilesSource are object containing informations on how to fetch vector
1✔
26
 * tiles resources.
1✔
27
 *
1✔
28
 * @property {function} filter - function to filter vector tiles layers, the
1✔
29
 * parameter function is a layer.
1✔
30
 * @property {boolean} [symbolToCircle=false] - If true, all symbols from a tile
1✔
31
 * will be considered as circle, and render as circles.
1✔
32
 */
1✔
33
class VectorTilesSource extends TMSSource {
1✔
34
    /**
1✔
35
     * @param {Object} source - An object that can contain all properties of a
1✔
36
     * VectorTilesSource and {@link Source}.
1✔
37
     * @param {string|Object} source.style - The URL of the JSON style, of the
1✔
38
     * JSON style directly.
1✔
39
     * @param {string} [source.sprite] - The base URL to load informations about
1✔
40
     * the sprite of the style. If this is set, it overrides the `sprite` value
1✔
41
     * of the `source.style`. A style's sprite property supplies a URL template
1✔
42
     * for loading small images.
1✔
43
     * ```js
1✔
44
     * {
1✔
45
     *      sprite: 'http//:xxxxx/maps/sprites/'
1✔
46
     * }
1✔
47
     * ```
1✔
48
     * A valid sprite source must supply two types of files:
1✔
49
     * * An index file, which is a JSON document containing a description of each image contained in the sprite.
1✔
50
     * * Image files, which are PNG images containing the sprite data.
1✔
51
     *
1✔
52
     * For more specification : [the Mapbox sprite Specification](https://docs.mapbox.com/mapbox-gl-js/style-spec/sprite/)
1✔
53
     *
1✔
54
     * @param {string} [source.url] - The base URL to load the tiles. If no url
1✔
55
     * is specified, it reads it from the loaded style. Read [the Mapbox Style
1✔
56
     * Specification](https://docs.mapbox.com/mapbox-gl-js/style-spec/sources/)
1✔
57
     * for more informations.
1✔
58
     * @param {string} [source.accessToken] - Mapbox access token
1✔
59
     * @constructor
1✔
60
     */
1✔
61
    constructor(source) {
1✔
62
        source.format = 'application/x-protobuf;type=mapbox-vector';
10✔
63
        source.crs = 'EPSG:3857';
10✔
64
        source.isInverted = true;
10✔
65
        source.url = source.url || '.';
10✔
66
        super(source);
10✔
67
        const ffilter = source.filter || (() => true);
10✔
68
        this.urls = [];
10✔
69
        this.layers = {};
10✔
70
        this.styles = {};
10✔
71
        let promise;
10✔
72
        this.isVectorTileSource = true;
10✔
73

10✔
74
        this.accessToken = source.accessToken;
10✔
75

10✔
76
        if (source.style) {
10✔
77
            if (typeof source.style == 'string') {
9✔
78
                const styleUrl = urlParser.normalizeStyleURL(source.style, this.accessToken);
1✔
79
                promise = Fetcher.json(styleUrl, this.networkOptions);
1✔
80
            } else {
9✔
81
                promise = Promise.resolve(source.style);
8✔
82
            }
8✔
83
        } else {
10✔
84
            throw new Error('New VectorTilesSource: style is required');
1✔
85
        }
1✔
86

9✔
87
        this.whenReady = promise.then((style) => {
9✔
88
            this.jsonStyle = style;
9✔
89
            const baseurl = source.sprite || style.sprite;
9✔
90
            if (baseurl) {
9✔
91
                const spriteUrl = urlParser.normalizeSpriteURL(baseurl, '', '.json', this.accessToken);
1✔
92
                return Fetcher.json(spriteUrl, this.networkOptions).then((sprites) => {
1✔
93
                    this.sprites = sprites;
1✔
94
                    const imgUrl = urlParser.normalizeSpriteURL(baseurl, '', '.png', this.accessToken);
1✔
95
                    this.sprites.source = imgUrl;
1✔
96
                    return style;
1✔
97
                });
1✔
98
            }
1✔
99

8✔
100
            return style;
8✔
101
        }).then((style) => {
9✔
102
            style.layers.forEach((layer, order) => {
9✔
103
                layer.sourceUid = this.uid;
11✔
104
                if (layer.type === 'background') {
11✔
105
                    this.backgroundLayer = layer;
2✔
106
                } else if (ffilter(layer)) {
11✔
107
                    const style = Style.setFromVectorTileLayer(layer, this.sprites, order, this.symbolToCircle);
9✔
108
                    this.styles[layer.id] = style;
9✔
109

9✔
110
                    if (!this.layers[layer['source-layer']]) {
9✔
111
                        this.layers[layer['source-layer']] = [];
5✔
112
                    }
5✔
113
                    this.layers[layer['source-layer']].push({
9✔
114
                        id: layer.id,
9✔
115
                        order,
9✔
116
                        filterExpression: featureFilter(layer.filter),
9✔
117
                        zoom: {
9✔
118
                            min: layer.minzoom || 0,
9✔
119
                            max: layer.maxzoom || 24,
9✔
120
                        },
9✔
121
                    });
9✔
122
                }
9✔
123
            });
9✔
124

9✔
125
            if (this.url == '.') {
9✔
126
                const TMSUrlList = Object.values(style.sources).map((sourceVT) => {
6✔
127
                    if (sourceVT.url) {
9✔
128
                        const urlSource = urlParser.normalizeSourceURL(sourceVT.url, this.accessToken);
2✔
129
                        return Fetcher.json(urlSource, this.networkOptions).then((tileJSON) => {
2✔
130
                            if (tileJSON.tiles[0]) {
2✔
131
                                return toTMSUrl(tileJSON.tiles[0]);
2✔
132
                            }
2✔
133
                        });
2✔
134
                    } else if (sourceVT.tiles) {
9✔
135
                        return Promise.resolve(toTMSUrl(sourceVT.tiles[0]));
7✔
136
                    }
7!
137
                    return Promise.reject();
×
138
                });
6✔
139
                return Promise.all(TMSUrlList);
6✔
140
            }
6✔
141
            return (Promise.resolve([this.url]));
3✔
142
        }).then((TMSUrlList) => {
9✔
143
            this.urls = Array.from(new Set(TMSUrlList));
9✔
144
        });
9✔
145
    }
9✔
146

1✔
147
    urlFromExtent(extent, url) {
1✔
148
        return URLBuilder.xyz(extent, { tileMatrixCallback: this.tileMatrixCallback, url });
2✔
149
    }
2✔
150

1✔
151
    onLayerAdded(options) {
1✔
152
        super.onLayerAdded(options);
1✔
153
        if (options.out.style) {
1!
UNCOV
154
            if (options.out.isFeatureGeometryLayer && options.out.accurate) {
×
UNCOV
155
                console.warn('With VectorTilesSource and FeatureGeometryLayer, the accurate option is always false');
×
156
                options.out.accurate = false;
×
157
            }
×
158
        }
×
159
    }
1✔
160

1✔
161
    loadData(extent, out) {
1✔
162
        const cache = this._featuresCaches[out.crs];
1✔
163
        const key = this.requestToKey(extent);
1✔
164
        // try to get parsed data from cache
1✔
165
        let features = cache.getByArray(key);
1✔
166
        if (!features) {
1✔
167
            // otherwise fetch/parse the data
1✔
168
            features = cache.setByArray(
1✔
169
                Promise.all(this.urls.map(url =>
1✔
170
                    this.fetcher(this.urlFromExtent(extent, url), this.networkOptions)
2✔
171
                        .then(file => this.parser(file, { out, in: this, extent }))))
1✔
172
                    .then(collections => mergeCollections(collections))
1✔
173
                    .catch(err => this.handlingError(err)),
1✔
174
                key);
1✔
175

1✔
176
            /* istanbul ignore next */
1✔
177
            if (this.onParsedFile) {
1!
UNCOV
178
                features.then((feat) => {
×
UNCOV
179
                    this.onParsedFile(feat);
×
UNCOV
180
                    console.warn('Source.onParsedFile was deprecated');
×
UNCOV
181
                    return feat;
×
UNCOV
182
                });
×
UNCOV
183
            }
×
184
        }
1✔
185
        return features;
1✔
186
    }
1✔
187
}
1✔
188

1✔
189
export default VectorTilesSource;
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

© 2025 Coveralls, Inc