Skip to content

Commit e0dec28

Browse files
committed
feat: add TmsSource docs and cleanup
1 parent 38c6514 commit e0dec28

5 files changed

Lines changed: 124 additions & 17 deletions

File tree

packages/Main/src/Layer/Layer.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as THREE from 'three';
22
import { STRATEGY_MIN_NETWORK_TRAFFIC } from 'Layer/LayerUpdateStrategy';
33
import InfoLayer from 'Layer/InfoLayer';
4-
import Source from 'Source/Source';
4+
import { Source } from 'Source/Source';
55
import { LRUCache } from 'lru-cache';
66
import Style from 'Core/Style';
77

@@ -149,7 +149,7 @@ class Layer extends THREE.EventDispatcher {
149149
* @type {number}
150150
*/
151151
this.subdivisionThreshold = subdivisionThreshold;
152-
this.sizeDiagonalTexture = (2 * (this.subdivisionThreshold * this.subdivisionThreshold)) ** 0.5;
152+
this.sizeDiagonalTexture = (2 * (this.subdivisionThreshold * this.subdivisionThreshold)) ** 0.5;
153153

154154
this.addLabelLayer = addLabelLayer;
155155

@@ -189,7 +189,7 @@ class Layer extends THREE.EventDispatcher {
189189
this._reject = rj;
190190
}).then(() => {
191191
this.ready = true;
192-
this.source.onLayerAdded({ out: this });
192+
this.source.capabilities.layerEventHandler?.onLayerAdded(this);
193193
return this;
194194
});
195195

packages/Main/src/Main.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ export { default as GeoidLayer } from 'Layer/GeoidLayer';
7878
export { Source } from 'Source/Source';
7979
// export { default as FileSource } from 'Source/FileSource';
8080
export { TmsSource } from 'Source/TmsSource';
81+
export { default as WmtsSource } from 'Source/WmtsSource';
8182
// export { default as WFSSource } from 'Source/WFSSource';
8283
// export { default as WMSSource } from 'Source/WMSSource';
8384
// export { default as WMTSSource } from 'Source/WMTSSource';

packages/Main/src/Source/RemoteSource.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,19 @@ export abstract class RemoteSource<Key, Data> implements Source<Key, Promise<Dat
1616
public readonly isSource = true as const;
1717
public readonly isRemoteSource = true as const;
1818

19-
declare public capabilities: SourceCapabilities;
19+
public abstract readonly capabilities: SourceCapabilities;
2020

2121
protected loader: Loader<Data>;
2222

23+
public url: string;
2324
public readonly crs: CRS.ProjectionLike;
24-
public readonly url: string;
2525
public readonly format: string;
2626
public networkOptions: RequestInit;
2727

2828
public constructor(options: RemoteSourceOptions<Data>) {
2929
this.loader = options.loader;
30-
this.crs = options.crs;
3130
this.url = options.url;
31+
this.crs = options.crs;
3232
this.format = options.format;
3333
this.networkOptions = options.networkOptions;
3434
}

packages/Main/src/Source/TmsSource.ts

Lines changed: 77 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import Tile from 'Core/Tile/Tile';
22
import URLBuilder from 'Provider/URLBuilder';
33
import { Extent } from '@itowns/geographic';
4-
import * as THREE from 'three';
54
import Layer from 'Layer/Layer';
65
import { RemoteSource, RemoteSourceOptions } from './RemoteSource';
6+
import { SourceCapabilities } from './SourceCapabilities';
77

88
export type TmsLimit = {
99
minTileRow: number;
@@ -19,21 +19,94 @@ export interface TmsSourceOptions<Data> extends RemoteSourceOptions<Data> {
1919
zoom?: { min: number; max: number; };
2020
}
2121

22-
export class TmsSource<Data extends THREE.Texture>
23-
extends RemoteSource<Tile, Data> {
22+
/**
23+
* An object defining the source of resources to get from a
24+
* [TMS](https://wiki.osgeo.org/wiki/Tile_Map_Service_Specification) server.
25+
*
26+
* @example
27+
*
28+
* **Source from OpenStreetMap server:**
29+
* ```ts
30+
* // Create the source
31+
* const tmsSource = new itowns.TMSSource({
32+
* format: 'image/png',
33+
* url: 'http://osm.io/styles/${z}/${x}/${y}.png',
34+
* attribution: {
35+
* name: 'OpenStreetMap',
36+
* url: 'http://www.openstreetmap.org/',
37+
* },
38+
* crs: 'EPSG:3857',
39+
* });
40+
*
41+
* // Create the layer
42+
* const colorLayer = new itowns.ColorLayer('OPENSM', {
43+
* source: tmsSource,
44+
* });
45+
*
46+
* // Add the layer
47+
* view.addLayer(colorLayer);
48+
* ```
49+
*
50+
* @example
51+
*
52+
* **Source from Mapbox server:**
53+
* ```ts
54+
* // Create the source
55+
* const orthoSource = new itowns.TMSSource({
56+
* url: 'https://api.mapbox.com/v4/mapbox.satellite/${z}/${x}/${y}.jpg?access_token=' + accessToken,
57+
* crs: 'EPSG:3857',
58+
* };
59+
*
60+
* // Create the layer
61+
* const imageryLayer = new itowns.ColorLayer("Ortho", {
62+
* source: orthoSource,
63+
* };
64+
*
65+
* // Add the layer to the view
66+
* view.addLayer(imageryLayer);
67+
* ```
68+
*/
69+
export class TmsSource<Data> extends RemoteSource<Tile, Data> {
70+
/** Used to checkout whether this source is a TMSSource. */
2471
public readonly isTMSSource = true as const;
2572
public readonly isSourceEventHandler = true as const;
2673

74+
public readonly capabilities: SourceCapabilities = {
75+
layerEventHandler: {
76+
onLayerAdded: this.onLayerAdded,
77+
onLayerRemoved: this.onLayerRemoved,
78+
},
79+
};
80+
81+
/**
82+
* Minimum and maximum values of the zoom level.
83+
* Defaults are 0 and Infinity.
84+
*/
2785
public zoom: { min: number; max: number; };
86+
/**
87+
* The isInverted property is to be set to the correct value, true or false
88+
* (default being false) if the computation of the coordinates needs to be
89+
* inverted to match the same scheme as OSM, Google Maps or other system.
90+
* See [this link](https://alastaira.wordpress.com/2011/07/06/converting-tms-tile-coordinates-to-googlebingosm-tile-coordinates/)
91+
* for more information.
92+
*/
2893
public isInverted: boolean;
2994

95+
/** Describes the available tile for this layer. */
3096
public tileMatrixSetLimits?: Record<number, TmsLimit>;
3197

98+
/** These are the extents of the set of identical zoom tiles. */
3299
public extentSetLimits: Record<string, Record<number, Extent>>;
33100

101+
/**
102+
* Creates a TileMatrix identifier from the zoom level. For example, if set
103+
* to `(zoomLevel) => 'EPSG:4326:' + zoomLevel`, the TileMatrix that will be
104+
* fetched at zoom level 5 will be the one with identifier `EPSG:4326:5`.
105+
* By default, the method returns the input zoom level.
106+
*/
34107
public tileMatrixCallback: (level: number) => string;
35108

36-
protected constructor(
109+
public constructor(
37110
options: TmsSourceOptions<Data>,
38111
) {
39112
super(options);
@@ -60,13 +133,6 @@ export class TmsSource<Data extends THREE.Texture>
60133
max: Infinity,
61134
};
62135
}
63-
64-
this.capabilities = {
65-
layerEventHandler: {
66-
onLayerAdded: this.onLayerAdded,
67-
onLayerRemoved: this.onLayerRemoved,
68-
},
69-
};
70136
}
71137

72138
public async load(tile: Tile): Promise<Data> {
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { TmsSource } from 'Main';
2+
import { TmsSourceOptions } from './TmsSource';
3+
4+
export interface WmtsSourceOptions<Data> extends TmsSourceOptions<Data> {
5+
name: string,
6+
version?: string,
7+
style?: string,
8+
tileMatrixSet?: string,
9+
vendorSpecific?: Record<string, unknown>,
10+
}
11+
12+
export class WmtsSource<Data> extends TmsSource<Data> {
13+
public readonly isWmtsSource = true as const;
14+
15+
public constructor(options: WmtsSourceOptions<Data>) {
16+
super(options);
17+
18+
const urlObj = new URL(this.url);
19+
urlObj.searchParams.set('LAYER', options.name);
20+
urlObj.searchParams.set('FORMAT', this.format);
21+
urlObj.searchParams.set('SERVICE', 'WMTS');
22+
urlObj.searchParams.set('VERSION', options.version ?? '1.0.0');
23+
urlObj.searchParams.set('REQUEST', 'GetTile');
24+
urlObj.searchParams.set('STYLE', options.style ?? 'normal');
25+
urlObj.searchParams.set('TILEMATRIXSET', options.tileMatrixSet ?? 'WGS84');
26+
urlObj.searchParams.set('TILEMATRIX', '%TILEMATRIX');
27+
urlObj.searchParams.set('TILEROW', '%ROW');
28+
urlObj.searchParams.set('TILECOL', '%COL');
29+
30+
const vendorSpecific: Record<string, string> = Object.fromEntries(
31+
Object.entries(options.vendorSpecific ?? {}).map(([k, v]) => [k, String(v)]));
32+
for (const name in vendorSpecific) {
33+
if (Object.prototype.hasOwnProperty.call(vendorSpecific, name)) {
34+
urlObj.searchParams.set(name, vendorSpecific[name]);
35+
}
36+
}
37+
38+
this.url = decodeURIComponent(urlObj.toString());
39+
}
40+
}

0 commit comments

Comments
 (0)