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

iTowns / itowns / 12377290384

17 Dec 2024 04:31PM UTC coverage: 87.057% (-0.008%) from 87.065%
12377290384

push

github

web-flow
chore: remove istanbul and editor comments (#2479)

2781 of 3692 branches covered (75.33%)

Branch coverage included in aggregate %.

11 of 11 new or added lines in 3 files covered. (100.0%)

6 existing lines in 5 files now uncovered.

24971 of 28186 relevant lines covered (88.59%)

992.64 hits per line

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

96.56
/src/Source/Source.js
1
import * as CRS from 'Core/Geographic/Crs';
1✔
2
import Extent from 'Core/Geographic/Extent';
1✔
3
import GeoJsonParser from 'Parser/GeoJsonParser';
1✔
4
import KMLParser from 'Parser/KMLParser';
1✔
5
import GDFParser from 'Parser/GDFParser';
1✔
6
import GpxParser from 'Parser/GpxParser';
1✔
7
import GTXParser from 'Parser/GTXParser';
1✔
8
import ISGParser from 'Parser/ISGParser';
1✔
9
import VectorTileParser from 'Parser/VectorTileParser';
1✔
10
import Fetcher from 'Provider/Fetcher';
1✔
11
import Cache from 'Core/Scheduler/Cache';
1✔
12

1✔
13
/** @private */
1✔
14
export const supportedParsers = new Map([
1✔
15
    ['application/geo+json', GeoJsonParser.parse],
1✔
16
    ['application/json', GeoJsonParser.parse],
1✔
17
    ['application/kml', KMLParser.parse],
1✔
18
    ['application/gpx', GpxParser.parse],
1✔
19
    ['application/x-protobuf;type=mapbox-vector', VectorTileParser.parse],
1✔
20
    ['application/gtx', GTXParser.parse],
1✔
21
    ['application/isg', ISGParser.parse],
1✔
22
    ['application/gdf', GDFParser.parse],
1✔
23
]);
1✔
24

1✔
25
const noCache = { getByArray: () => { }, setByArray: a => a, clear: () => { } };
1✔
26

1✔
27
/**
1✔
28
 * @property {string} crs - data crs projection.
1✔
29
 * @property {boolean} isInverted - This option is to be set to the
1✔
30
 * correct value, true or false (default being false), if the computation of
1✔
31
 * the coordinates needs to be inverted to same scheme as OSM, Google Maps
1✔
32
 * or other system. See [this link](
1✔
33
 * https://alastaira.wordpress.com/2011/07/06/converting-tms-tile-coordinates-to-googlebingosm-tile-coordinates)
1✔
34
 * for more informations.
1✔
35
 *
1✔
36
 */
1✔
37
class InformationsData {
1✔
38
    constructor(options) {
1✔
39
        if (options.projection) {
128!
UNCOV
40
            console.warn('Source projection parameter is deprecated, use crs instead.');
×
41
            options.crs = options.crs || options.projection;
×
42
        }
×
43
        if (options.crs) {
128✔
44
            CRS.isValid(options.crs);
44✔
45
        }
44✔
46
        this.crs = options.crs;
128✔
47
    }
128✔
48
}
1✔
49
/**
1✔
50
 * This interface describes parsing options.
1✔
51
 * @typedef {Object} ParsingOptions
1✔
52
 * @property {Source} in - data informations contained in the file.
1✔
53
 * @property {FeatureBuildingOptions|Layer} out - options indicates how the features should be built.
1✔
54
 */
1✔
55

1✔
56
let uid = 0;
1✔
57

1✔
58
/**
1✔
59
 * Sources are object containing informations on how to fetch resources, from a
1✔
60
 * set source.
1✔
61
 *
1✔
62
 * To extend a Source, it is necessary to implement two functions:
1✔
63
 * `urlFromExtent` and `extentInsideLimit`.
1✔
64
 *
1✔
65
 * @extends InformationsData
1✔
66
 *
1✔
67
 * @property {boolean} isSource - Used to checkout whether this source is a
1✔
68
 * Source. Default is true. You should not change this, as it is used internally
1✔
69
 * for optimisation.
1✔
70
 * @property {number} uid - Unique uid mainly used to store data linked to this
1✔
71
 * source into Cache.
1✔
72
 * @property {string} url - The url of the resources that are fetched.
1✔
73
 * @property {string} format - The format of the resources that are fetched.
1✔
74
 * @property {function} fetcher - The method used to fetch the resources from
1✔
75
 * the source. iTowns provides some methods in {@link Fetcher}, but it can be
1✔
76
 * specified a custom one. This method should return a `Promise` containing the
1✔
77
 * fetched resource. If this property is set, it overrides the chosen fetcher
1✔
78
 * method with `format`.
1✔
79
 * @property {Object} networkOptions - Fetch options (passed directly to
1✔
80
 * `fetch()`), see [the syntax for more information](
1✔
81
 * https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Syntax).
1✔
82
 * By default, set to `{ crossOrigin: 'anonymous' }`.
1✔
83
 * @property {string} crs - The crs projection of the resources.
1✔
84
 * @property {string} attribution - The intellectual property rights for the
1✔
85
 * resources.
1✔
86
 * @property {Extent} extent - The extent of the resources.
1✔
87
 * @property {function} parser - The method used to parse the resources attached
1✔
88
 * to the layer. iTowns provides some parsers, visible in the `Parser/` folder.
1✔
89
 * If the method is custom, it should return a `Promise` containing the parsed
1✔
90
 * resource. If this property is set, it overrides the default selected parser
1✔
91
 * method with `source.format`. If `source.format` is also empty, no parsing
1✔
92
 * action is done.
1✔
93
 * <br><br>
1✔
94
 * When calling this method, two parameters are passed:
1✔
95
 * <ul>
1✔
96
 *  <li>the fetched data, i.e. the data to parse</li>
1✔
97
 *  <li>an {@link ParsingOptions}  containing severals properties, set when this method is
1✔
98
 *  called: it is specific to each call, so the value of each property can vary
1✔
99
 *  depending on the current fetched tile for example</li>
1✔
100
 * </ul>
1✔
101
 */
1✔
102
class Source extends InformationsData {
1✔
103
    /**
1✔
104
     * @param {Object} source - An object that can contain all properties of a
1✔
105
     * Source. Only the `url` property is mandatory.
1✔
106
     */
1✔
107
    constructor(source) {
1✔
108
        super(source);
128✔
109
        this.isSource = true;
128✔
110

128✔
111
        if (!source.url) {
128✔
112
            throw new Error('New Source: url is required');
2✔
113
        }
2✔
114

126✔
115
        this.uid = uid++;
126✔
116

126✔
117
        this.url = source.url;
126✔
118
        this.format = source.format;
126✔
119
        this.fetcher = source.fetcher || Fetcher.get(source.format);
128✔
120
        this.parser = source.parser || supportedParsers.get(source.format) || ((d, opt) => { d.extent = opt.extent; return d; });
128✔
121
        this.isVectorSource = (source.parser || supportedParsers.get(source.format)) != undefined;
128✔
122
        this.networkOptions = source.networkOptions || { crossOrigin: 'anonymous' };
128✔
123
        this.attribution = source.attribution;
128✔
124
        /** @type {Promise<any>} */
128✔
125
        this.whenReady = Promise.resolve();
128✔
126
        this._featuresCaches = {};
128✔
127
        if (source.extent && !(source.extent.isExtent)) {
128✔
128
            this.extent = new Extent(this.crs, source.extent);
3✔
129
        } else {
128✔
130
            this.extent = source.extent;
123✔
131
        }
123✔
132
    }
128✔
133

1✔
134
    handlingError(err) {
1✔
135
        throw new Error(err);
2✔
136
    }
2✔
137

1✔
138
    /**
1✔
139
     * Generates an url from an extent. This url is a link to fetch the
1✔
140
     * resources inside the extent.
1✔
141
     *
1✔
142
     * @param {Extent} extent - Extent to convert in url.
1✔
143

1✔
144
     * @return {string} The URL constructed from the extent.
1✔
145
     */
1✔
146
    // eslint-disable-next-line
1✔
147
    urlFromExtent(extent) {
1✔
148
        throw new Error('In extended Source, you have to implement the method urlFromExtent!');
1✔
149
    }
1✔
150

1✔
151
    requestToKey(extent) {
1✔
152
        return [extent.zoom, extent.row, extent.col];
28✔
153
    }
28✔
154

1✔
155
    /**
1✔
156
     * Load  data from cache or Fetch/Parse data.
1✔
157
     * The loaded data is a Feature or Texture.
1✔
158
     *
1✔
159
     * @param      {Extent}  extent   extent requested parsed data.
1✔
160
     * @param      {FeatureBuildingOptions|Layer}  out     The feature returned options
1✔
161
     * @return     {FeatureCollection|Texture}  The parsed data.
1✔
162
     */
1✔
163
    loadData(extent, out) {
1✔
164
        const cache = this._featuresCaches[out.crs];
8✔
165
        const key = this.requestToKey(extent);
8✔
166
        // try to get parsed data from cache
8✔
167
        let features = cache.getByArray(key);
8✔
168
        if (!features) {
8✔
169
            // otherwise fetch/parse the data
8✔
170
            features = cache.setByArray(
8✔
171
                this.fetcher(this.urlFromExtent(extent), this.networkOptions)
8✔
172
                    .then(file => this.parser(file, { out, in: this, extent }))
8✔
173
                    .catch(err => this.handlingError(err)),
8✔
174
                key);
8✔
175

8✔
176
            if (this.onParsedFile) {
8✔
177
                features.then((feat) => {
3✔
178
                    this.onParsedFile(feat);
3✔
179
                    console.warn('Source.onParsedFile was deprecated');
3✔
180
                    return feat;
3✔
181
                });
3✔
182
            }
3✔
183
        }
8✔
184
        return features;
8✔
185
    }
8✔
186

1✔
187
    /**
1✔
188
     * Called when layer added.
1✔
189
     *
1✔
190
     * @param {object} options
1✔
191
     */
1✔
192
    onLayerAdded(options) {
1✔
193
        // Added new cache by crs
91✔
194
        if (!this._featuresCaches[options.out.crs]) {
91✔
195
            // Cache feature only if it's vector data, the feature are cached in source.
83✔
196
            // It's not necessary to cache raster in Source,
83✔
197
            // because it's already cached on layer.
83✔
198
            this._featuresCaches[options.out.crs] = this.isVectorSource ? new Cache() : noCache;
83✔
199
        }
83✔
200
    }
91✔
201

1✔
202
    /**
1✔
203
     * Called when layer removed.
1✔
204
     *
1✔
205
     * @param {options}  [options={}] options
1✔
206
     */
1✔
207
    onLayerRemoved(options = {}) {
1!
208
        // delete unused cache
2✔
209
        const unusedCache = this._featuresCaches[options.unusedCrs];
2✔
210
        if (unusedCache) {
2!
211
            unusedCache.clear();
×
212
            delete this._featuresCaches[options.unusedCrs];
×
213
        }
×
214
    }
2✔
215

1✔
216
    /**
1✔
217
     * Tests if an extent is inside the source limits.
1✔
218
     *
1✔
219
     * @param {Extent} extent - Extent to test.
1✔
220

1✔
221
     * @return {boolean} True if the extent is inside the limit, false otherwise.
1✔
222
     */
1✔
223
    // eslint-disable-next-line
1✔
224
    extentInsideLimit(extent) {
1✔
225
        throw new Error('In extented Source, you have to implement the method extentInsideLimit!');
1✔
226
    }
1✔
227
}
1✔
228

1✔
229
export default Source;
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