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

iTowns / itowns / 5390187276

pending completion
5390187276

push

github

gchoqueux
fix(CRS): more robust parameter tests

3402 of 5132 branches covered (66.29%)

Branch coverage included in aggregate %.

12 of 12 new or added lines in 1 file covered. (100.0%)

7377 of 9030 relevant lines covered (81.69%)

1467.12 hits per line

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

96.92
/src/Source/TMSSource.js
1
import Source from 'Source/Source';
1✔
2
import URLBuilder from 'Provider/URLBuilder';
1✔
3
import Extent, { globalExtentTMS } from 'Core/Geographic/Extent';
1✔
4
import CRS from 'Core/Geographic/Crs';
1✔
5

6
const extent = new Extent(CRS.tms_4326, 0, 0, 0);
1✔
7

8
/**
9
 * @classdesc
10
 * An object defining the source of resources to get from a [TMS]{@link
11
 * https://wiki.osgeo.org/wiki/Tile_Map_Service_Specification} server. It
12
 * inherits from {@link Source}.
13
 *
14
 * @extends Source
15
 *
16
 * @property {boolean} isTMSSource - Used to checkout whether this source is a
17
 * TMSSource. Default is true. You should not change this, as it is used
18
 * internally for optimisation.
19
 * @property {boolean} isInverted - The isInverted property is to be set to the
20
 * correct value, true or false (default being false) if the computation of the
21
 * coordinates needs to be inverted to match the same scheme as OSM, Google Maps
22
 * or other system. See [this link]{@link
23
 * https://alastaira.wordpress.com/2011/07/06/converting-tms-tile-coordinates-to-googlebingosm-tile-coordinates/}
24
 * for more information.
25
 * @property {Object} tileMatrixSetLimits - it describes the available tile for this layer
26
 * @property {Object} extentSetlimits - these are the extents of the set of identical zoom tiles.
27
 * @property {Object} zoom - Object containing the minimum and maximum values of
28
 * the level, to zoom in the source.
29
 * @property {number} zoom.min - The minimum level of the source. Default value
30
 * is 0.
31
 * @property {number} zoom.max - The maximum level of the source. Default value
32
 * is 20.
33
 * @property {function} tileMatrixCallback - a method that create a TileMatrix
34
 * identifier from the zoom level. For example, if set to `(zoomLevel) => 'EPSG:4326:' + zoomLevel`,
35
 * the TileMatrix that will be fetched at zoom level 5 will be the one with identifier `EPSG:4326:5`.
36
 * By default, the method returns the input zoom level.
37
 *
38
 * @example <caption><b>Source from OpenStreetMap server :</b></caption>
39
 * // Create the source
40
 * const tmsSource = new itowns.TMSSource({
41
 *     format: 'image/png',
42
 *     url: 'http://osm.io/styles/${z}/${x}/${y}.png',
43
 *     attribution: {
44
 *         name: 'OpenStreetMap',
45
 *         url: 'http://www.openstreetmap.org/',
46
 *     },
47
 *     crs: 'EPSG:3857',
48
 * });
49
 *
50
 * // Create the layer
51
 * const colorLayer = new itowns.ColorLayer('OPENSM', {
52
 *     source: tmsSource,
53
 * });
54
 *
55
 * // Add the layer
56
 * view.addLayer(colorLayer);
57
 *
58
 * @example <caption><b>Source from Mapbox server :</b></caption>
59
 * // Create the source
60
 * const orthoSource = new itowns.TMSSource({
61
 *     url: 'https://api.mapbox.com/v4/mapbox.satellite/${z}/${x}/${y}.jpg?access_token=' + accessToken,
62
 *     crs: 'EPSG:3857',
63
 * };
64
 *
65
 * // Create the layer
66
 * const imageryLayer = new itowns.ColorLayer("Ortho", {
67
 *     source: orthoSource,
68
 * };
69
 *
70
 * // Add the layer to the view
71
 * view.addLayer(imageryLayer);
72
 */
73
class TMSSource extends Source {
74
    /**
75
     * @param {Object} source - An object that can contain all properties of a
76
     * TMSSource and {@link Source}. Only `url` is mandatory.
77
     *
78
     * @constructor
79
     */
80
    constructor(source) {
32✔
81
        source.format = source.format || 'image/png';
16✔
82

83
        super(source);
16✔
84

85
        if (!source.crs) {
16!
86
            throw new Error('New TMSSource/WMTSSource: crs is required');
×
87
        }
88

89
        this.isTMSSource = true;
16✔
90

91
        if (!source.extent) {
16✔
92
            // default to the global extent
93
            this.extent = globalExtentTMS.get(source.crs);
14✔
94
        }
95

96
        this.zoom = source.zoom;
16✔
97

98
        this.isInverted = source.isInverted || false;
16✔
99
        this.url = source.url;
16✔
100
        this.crs = CRS.formatToTms(source.crs);
16✔
101
        this.tileMatrixSetLimits = source.tileMatrixSetLimits;
16✔
102
        this.extentSetlimits = {};
16✔
103
        this.tileMatrixCallback = source.tileMatrixCallback || (zoomLevel => zoomLevel);
16✔
104

105
        if (!this.zoom) {
16✔
106
            if (this.tileMatrixSetLimits) {
13✔
107
                const arrayLimits = Object.keys(this.tileMatrixSetLimits);
3✔
108
                const size = arrayLimits.length;
3✔
109
                const maxZoom = Number(arrayLimits[size - 1]);
3✔
110
                const minZoom = maxZoom - size + 1;
111

112
                this.zoom = {
3✔
113
                    min: minZoom,
114
                    max: maxZoom,
115
                };
116
            } else {
117
                this.zoom = { min: 0, max: Infinity };
10✔
118
            }
119
        }
120
    }
121

122
    urlFromExtent(extent) {
123
        return URLBuilder.xyz(extent, this);
8✔
124
    }
125

126
    onLayerAdded(options) {
127
        super.onLayerAdded(options);
6✔
128
        // Build extents of the set of identical zoom tiles.
129
        const parent = options.out.parent;
6✔
130
        // The extents crs is chosen to facilitate in raster tile process.
131
        const crs = parent ? parent.extent.crs : options.out.crs;
6✔
132
        if (this.tileMatrixSetLimits && !this.extentSetlimits[crs]) {
6✔
133
            this.extentSetlimits[crs] = {};
2✔
134
            extent.crs = this.crs;
2✔
135
            for (let i = this.zoom.max; i >= this.zoom.min; i--) {
2✔
136
                const tmsl = this.tileMatrixSetLimits[i];
7✔
137
                const { west, north } = extent.set(i, tmsl.minTileRow, tmsl.minTileCol).as(crs);
7✔
138
                const { east, south } = extent.set(i, tmsl.maxTileRow, tmsl.maxTileCol).as(crs);
7✔
139
                this.extentSetlimits[crs][i] = new Extent(crs, west, east, south, north);
7✔
140
            }
141
        }
142
    }
143

144
    extentInsideLimit(extent, zoom) {
145
        // This layer provides data starting at level = layer.source.zoom.min
146
        // (the zoom.max property is used when building the url to make
147
        //  sure we don't use invalid levels)
148
        return zoom >= this.zoom.min && zoom <= this.zoom.max &&
11✔
149
                (this.extentSetlimits[extent.crs] == undefined || this.extentSetlimits[extent.crs][zoom].intersectsExtent(extent));
150
    }
151
}
152

153
export default TMSSource;
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