File : data/MapLayer.js

1
/*
2
Copyright - 2017 2023 - wwwouaiebe - Contact: https://www.ouaie.be/
3
4
This  program is free software;
5
you can redistribute it and/or modify it under the terms of the
6
GNU General Public License as published by the Free Software Foundation;
7
either version 3 of the License, or any later version.
8
This program is distributed in the hope that it will be useful,
9
but WITHOUT ANY WARRANTY; without even the implied warranty of
10
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
15
*/
16
/*
17
Changes:
18
    - v4.0.0:
19
        - created from v3.6.0
20
Doc reviewed 202208
21
 */
22
23
import theHTMLSanitizer from '../core/htmlSanitizer/HTMLSanitizer.js';
24
import MapLayerToolbarButtonData from './MapLayerToolbarButtonData.js';
25
import { ZERO, ONE } from '../main/Constants.js';
26
27
/* ------------------------------------------------------------------------------------------------------------------------- */
28
/**
29
This class represent a background map
30
*/
31
/* ------------------------------------------------------------------------------------------------------------------------- */
32
33
class MapLayer    {
34
35
    /**
36
    The name of the map
37
    @type {String}
38
    */
39
40
    #name = null;
41
42
    /**
43
    The type of service: wms or wmts
44
    @type {String}
45
    */
46
47
    #service = null;
48
49
    /**
50
    The url to use to get the map
51
    @type {String}
52
    */
53
54
    #url = null;
55
56
    /**
57
    The wmsOptions for this mapLayer
58
    See the Leaflet TileLayer.WMS documentation
59
    @type {LeafletObject}
60
    */
61
62
    #wmsOptions = null;
63
64
    /**
65
    The lower left and upper right corner of the mapLayer
66
    @type {Array.<Number>}
67
    */
68
69
    #bounds = null;
70
71
    /**
72
    The smallest possible zoom for this mapLayer
73
    @type {Number}
74
    */
75
76
    #minZoom = null;
77
78
    /**
79
    The largest possible zoom for this mapLayer
80
    @type {Number}
81
    */
82
83
    #maxZoom = null;
84
85
    /**
86
    An object with text, color and backgroundColor properties used to create the button in the toolbar
87
    @type {LayerToolbarButtonData}
88
    */
89
90
    #toolbarButtonData = null;
91
92
    /**
93
    The name of the service provider.
94
    @type {String}
95
    */
96
97
    #providerName = null;
98
99
    /**
100
    When true, an access key is required to get the map.
101
    @type {Boolean}
102
    */
103
104
    #providerKeyNeeded = false;
105
106
    /**
107
    The map attributions.
108
    @type {String}
109
    */
110
111
    #attribution = null;
112
113
    /**
114
    A temporary variable to store the layer data
115
    @type {JsonObject}
116
    */
117
118
    #jsonLayer = null;
119
120
    /**
121
    Set the name of the map layer
122
    */
123
124
    #setLayerName ( ) {
125
        if ( 'string' === typeof ( this.#jsonLayer?.name ) ) {
126
            this.#name = theHTMLSanitizer.sanitizeToJsString ( this.#jsonLayer.name );
127
        }
128
        else {
129
            throw new Error ( 'invalid name for layer' );
130
        }
131
    }
132
133
    /**
134
    Set the type of service: wms or wmts
135
    */
136
137
    #setService ( ) {
138
        if ( 'wms' === this.#jsonLayer?.service || 'wmts' === this.#jsonLayer?.service ) {
139
            this.#service = this.#jsonLayer.service;
140
        }
141
        else {
142
            throw new Error ( 'invalid service for layer ' + this.#name );
143
        }
144
    }
145
146
    /**
147
    Set the url to use to get the map
148
    */
149
150
    #setUrl ( ) {
151
        if ( 'string' === typeof ( this.#jsonLayer?.url ) ) {
152
            this.#url = this.#jsonLayer.url;
153
        }
154
        else {
155
            throw new Error ( 'invalid url for layer ' + this.#name );
156
        }
157
    }
158
159
    /**
160
    Set the wmsOptions for this mapLayer
161
    */
162
163
    #setWmsOptions ( ) {
164
        if ( 'wms' === this.#service ) {
165
            if (
166
                'string' === typeof ( this.#jsonLayer?.wmsOptions?.layers )
167
                &&
168
                'string' === typeof ( this.#jsonLayer?.wmsOptions?.format )
169
                &&
170
                'boolean' === typeof ( this.#jsonLayer?.wmsOptions?.transparent )
171
            ) {
172
                this.#wmsOptions = this.#jsonLayer.wmsOptions;
173
                this.#wmsOptions.layers = theHTMLSanitizer.sanitizeToJsString ( this.#wmsOptions.layers );
174
                this.#wmsOptions.format = theHTMLSanitizer.sanitizeToJsString ( this.#wmsOptions.format );
175
            }
176
            else {
177
                throw new Error ( 'invalid wmsOptions for layer ' + this.#name );
178
            }
179
        }
180
    }
181
182
    /**
183
    Set the lower left and upper right corner of the mapLayer
184
    */
185
186
    #setBounds ( ) {
187
        try {
188
            if (
189
                this.#jsonLayer.bounds
190
                &&
191
                'number' === typeof this.#jsonLayer.bounds [ ZERO ] [ ZERO ]
192
                &&
193
                'number' === typeof this.#jsonLayer.bounds [ ZERO ] [ ONE ]
194
                &&
195
                'number' === typeof this.#jsonLayer.bounds [ ONE ] [ ZERO ]
196
                &&
197
                'number' === typeof this.#jsonLayer.bounds [ ONE ] [ ONE ]
198
            ) {
199
                this.#bounds = this.#jsonLayer.bounds;
200
            }
201
        }
202
        catch ( err ) {
203
            throw new Error ( 'invalid bounds for layer ' + this.#name );
204
        }
205
    }
206
207
    /**
208
    Set the min and max zoom for the map
209
    */
210
211
    #setMinMaxZoom ( ) {
212
        if ( this.#jsonLayer.minZoom ) {
213
            if ( 'number' === typeof ( this.#jsonLayer.minZoom ) ) {
214
                this.#minZoom = this.#jsonLayer.minZoom;
215
            }
216
            else {
217
                throw new Error ( 'invalid minZoom for layer ' + this.#name );
218
            }
219
        }
220
        if ( this.#jsonLayer.maxZoom ) {
221
            if ( 'number' === typeof ( this.#jsonLayer.maxZoom ) ) {
222
                this.#maxZoom = this.#jsonLayer.maxZoom;
223
            }
224
            else {
225
                throw new Error ( 'invalid maxZoom for layer ' + this.#name );
226
            }
227
        }
228
    }
229
230
    /**
231
    Set the toolbar data
232
    */
233
234
    #setToolbarButtonData ( ) {
235
        this.#toolbarButtonData = new MapLayerToolbarButtonData ( this.#jsonLayer.toolbar );
236
    }
237
238
    /**
239
    Set the name of the service provider
240
    */
241
242
    #setProviderName ( ) {
243
        if ( 'string' === typeof ( this.#jsonLayer?.providerName ) ) {
244
            this.#providerName = theHTMLSanitizer.sanitizeToJsString ( this.#jsonLayer.providerName );
245
        }
246
        else {
247
            throw new Error ( 'invalid providerName for layer ' + this.#name );
248
        }
249
    }
250
251
    /**
252
    Set the providerKeyNeeded value
253
    */
254
255
    #setProviderKeyNeeded ( ) {
256
        if ( 'boolean' === typeof ( this.#jsonLayer.providerKeyNeeded ) ) {
257
            this.#providerKeyNeeded = this.#jsonLayer.providerKeyNeeded;
258
        }
259
        else {
260
            throw new Error ( 'invalid providerKeyNeeded for layer ' + this.#name );
261
        }
262
    }
263
264
    /**
265
    Set the map attributions.
266
    */
267
268
    #setAttributions ( ) {
269
        if ( '' === this.#jsonLayer.attribution ) {
270
            this.#attribution = '';
271
        }
272
        else if ( 'string' === typeof ( this.#jsonLayer?.attribution ) ) {
273
            this.#attribution = theHTMLSanitizer.sanitizeToHtmlString ( this.#jsonLayer.attribution ).htmlString;
274
        }
275
        else {
276
            throw new Error ( 'invalid attribution for map layer ' + this.#name );
277
        }
278
    }
279
280
    /**
281
    The constructor
282
    @param {JsonObject} jsonLayer A json object from TravelNotesLayers.json
283
    */
284
285
    constructor ( jsonLayer ) {
286
        Object.freeze ( this );
287
        this.#jsonLayer = jsonLayer;
288
        this.#setLayerName ( );
289
        this.#setService ( );
290
        this.#setUrl ( );
291
        this.#setWmsOptions ( );
292
        this.#setBounds ( );
293
        this.#setMinMaxZoom ( );
294
        this.#setToolbarButtonData ( );
295
        this.#setProviderName ( );
296
        this.#setProviderKeyNeeded ( );
297
        this.#setAttributions ( );
298
        this.#jsonLayer = null;
299
    }
300
301
    /**
302
    The name of the map
303
    @type {String}
304
    */
305
306
    get name ( ) { return this.#name; }
307
308
    /**
309
    The type of service: wms or wmts
310
    @type {String}
311
    */
312
313
    get service ( ) { return this.#service; }
314
315
    /**
316
    The url to use to get the map
317
    @type {String}
318
    */
319
320
    get url ( ) { return this.#url; }
321
322
    /**
323
    The wmsOptions for this mapLayer
324
    See the Leaflet TileLayer.WMS documentation
325
    @type {LeafletObject}
326
    */
327
328
    get wmsOptions ( ) { return this.#wmsOptions; }
329
330
    /**
331
    The lower left and upper right corner of the mapLayer
332
    @type {Array.<Number>}
333
    */
334
335
    get bounds ( ) { return this.#bounds; }
336
337
    /**
338
    The smallest possible zoom for this mapLayer
339
    @type {Number}
340
    */
341
342
    get minZoom ( ) { return this.#minZoom; }
343
344
    /**
345
    The largest possible zoom for this mapLayer
346
    @type {Number}
347
    */
348
349
    get maxZoom ( ) { return this.#maxZoom; }
350
351
    /**
352
    An object with text, color and backgroundColor properties used to create the button in the toolbar
353
    @type {LayerToolbarButtonData}
354
    */
355
356
    get toolbarButtonData ( ) { return this.#toolbarButtonData; }
357
358
    /**
359
    The name of the service provider. This name will be used to find the access key to the service.
360
    @type {String}
361
    */
362
363
    get providerName ( ) { return this.#providerName; }
364
365
    /**
366
    When true, an access key is required to get the map.
367
    @type {Boolean}
368
    */
369
370
    get providerKeyNeeded ( ) { return this.#providerKeyNeeded; }
371
372
    /**
373
    The map attributions. For maps based on OpenStreetMap, it is not necessary to add
374
    the attributions of OpenStreetMap because they are always present in Travel & Notes.
375
    @type {String}
376
    */
377
378
    get attribution ( ) { return this.#attribution; }
379
380
}
381
382
export default MapLayer;
383
384
/* --- End of file --------------------------------------------------------------------------------------------------------- */
385