@vcmap/core 6.3.1 → 6.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/index.d.ts +5 -2
  2. package/dist/index.js +4 -1
  3. package/dist/index.js.map +1 -1
  4. package/dist/src/interaction/panoramaFeatureHighlight.d.ts +1 -0
  5. package/dist/src/interaction/panoramaFeatureHighlight.js +18 -11
  6. package/dist/src/interaction/panoramaFeatureHighlight.js.map +1 -1
  7. package/dist/src/interaction/panoramaImageSelection.js +46 -2
  8. package/dist/src/interaction/panoramaImageSelection.js.map +1 -1
  9. package/dist/src/layer/cesium/cogCesiumImpl.js +1 -1
  10. package/dist/src/layer/cesium/cogCesiumImpl.js.map +1 -1
  11. package/dist/src/layer/cesium/imageryProvider/abstractVcsImageryProvider.d.ts +47 -0
  12. package/dist/src/layer/cesium/imageryProvider/abstractVcsImageryProvider.js +71 -0
  13. package/dist/src/layer/cesium/imageryProvider/abstractVcsImageryProvider.js.map +1 -0
  14. package/dist/src/layer/cesium/imageryProvider/cogImageryProvider.d.ts +17 -0
  15. package/dist/src/layer/cesium/{cogImageryProvider.js → imageryProvider/cogImageryProvider.js} +88 -97
  16. package/dist/src/layer/cesium/imageryProvider/cogImageryProvider.js.map +1 -0
  17. package/dist/src/layer/cesium/{mapboxStyleImageryProvider.d.ts → imageryProvider/mapboxStyleImageryProvider.d.ts} +5 -9
  18. package/dist/src/layer/cesium/imageryProvider/mapboxStyleImageryProvider.js +37 -0
  19. package/dist/src/layer/cesium/imageryProvider/mapboxStyleImageryProvider.js.map +1 -0
  20. package/dist/src/layer/cesium/imageryProvider/olImageRenderer.d.ts +18 -0
  21. package/dist/src/layer/cesium/imageryProvider/olImageRenderer.js +144 -0
  22. package/dist/src/layer/cesium/imageryProvider/olImageRenderer.js.map +1 -0
  23. package/dist/src/layer/cesium/imageryProvider/panoramaDatasetImageryProvider.d.ts +12 -0
  24. package/dist/src/layer/cesium/imageryProvider/panoramaDatasetImageryProvider.js +45 -0
  25. package/dist/src/layer/cesium/imageryProvider/panoramaDatasetImageryProvider.js.map +1 -0
  26. package/dist/src/layer/cesium/{vectorTileImageryProvider.d.ts → imageryProvider/vectorTileImageryProvider.d.ts} +12 -26
  27. package/dist/src/layer/cesium/imageryProvider/vectorTileImageryProvider.js +88 -0
  28. package/dist/src/layer/cesium/imageryProvider/vectorTileImageryProvider.js.map +1 -0
  29. package/dist/src/layer/cesium/mapboxStyleCesiumImpl.d.ts +1 -1
  30. package/dist/src/layer/cesium/mapboxStyleCesiumImpl.js +1 -1
  31. package/dist/src/layer/cesium/mapboxStyleCesiumImpl.js.map +1 -1
  32. package/dist/src/layer/cesium/panoramaDatasetCesiumImpl.d.ts +5 -0
  33. package/dist/src/layer/cesium/panoramaDatasetCesiumImpl.js +12 -0
  34. package/dist/src/layer/cesium/panoramaDatasetCesiumImpl.js.map +1 -0
  35. package/dist/src/layer/cesium/vectorRasterTileCesiumImpl.d.ts +4 -2
  36. package/dist/src/layer/cesium/vectorRasterTileCesiumImpl.js +10 -3
  37. package/dist/src/layer/cesium/vectorRasterTileCesiumImpl.js.map +1 -1
  38. package/dist/src/layer/panoramaDatasetLayer.js +11 -1
  39. package/dist/src/layer/panoramaDatasetLayer.js.map +1 -1
  40. package/dist/src/layer/vectorTileLayer.d.ts +1 -0
  41. package/dist/src/layer/vectorTileLayer.js +3 -0
  42. package/dist/src/layer/vectorTileLayer.js.map +1 -1
  43. package/index.ts +11 -2
  44. package/package.json +1 -1
  45. package/src/interaction/panoramaFeatureHighlight.ts +23 -16
  46. package/src/interaction/panoramaImageSelection.ts +58 -5
  47. package/src/layer/cesium/cogCesiumImpl.ts +1 -1
  48. package/src/layer/cesium/imageryProvider/abstractVcsImageryProvider.ts +126 -0
  49. package/src/layer/cesium/{cogImageryProvider.ts → imageryProvider/cogImageryProvider.ts} +111 -119
  50. package/src/layer/cesium/imageryProvider/mapboxStyleImageryProvider.ts +63 -0
  51. package/src/layer/cesium/imageryProvider/olImageRenderer.ts +219 -0
  52. package/src/layer/cesium/imageryProvider/panoramaDatasetImageryProvider.ts +73 -0
  53. package/src/layer/cesium/{vectorTileImageryProvider.ts → imageryProvider/vectorTileImageryProvider.ts} +35 -102
  54. package/src/layer/cesium/mapboxStyleCesiumImpl.ts +1 -1
  55. package/src/layer/cesium/panoramaDatasetCesiumImpl.ts +13 -0
  56. package/src/layer/cesium/vectorRasterTileCesiumImpl.ts +14 -4
  57. package/src/layer/panoramaDatasetLayer.ts +12 -1
  58. package/src/layer/vectorTileLayer.ts +4 -0
  59. package/dist/src/layer/cesium/cogImageryProvider.d.ts +0 -31
  60. package/dist/src/layer/cesium/cogImageryProvider.js.map +0 -1
  61. package/dist/src/layer/cesium/mapboxStyleImageryProvider.js +0 -147
  62. package/dist/src/layer/cesium/mapboxStyleImageryProvider.js.map +0 -1
  63. package/dist/src/layer/cesium/vectorTileImageryProvider.js +0 -133
  64. package/dist/src/layer/cesium/vectorTileImageryProvider.js.map +0 -1
  65. package/src/layer/cesium/mapboxStyleImageryProvider.ts +0 -214
@@ -1,10 +1,62 @@
1
1
  import type { Feature } from 'ol/index.js';
2
- import type { InteractionEvent } from './abstractInteraction.js';
2
+ import type { EventFeature, InteractionEvent } from './abstractInteraction.js';
3
3
  import AbstractInteraction from './abstractInteraction.js';
4
4
  import { EventType } from './interactionType.js';
5
5
  import PanoramaMap from '../map/panoramaMap.js';
6
6
  import type MapCollection from '../util/mapCollection.js';
7
7
  import { panoramaFeature } from '../layer/vectorSymbols.js';
8
+ import { isProvidedClusterFeature } from '../featureProvider/featureProviderSymbols.js';
9
+ import type { PanoramaDatasetFeatureProperties } from '../layer/panoramaDatasetLayer.js';
10
+ import { vcsLayerName } from '../layer/layerSymbols.js';
11
+
12
+ /**
13
+ * get a panorama dataset associated with the event feature in the following cases:
14
+ * - there is only one feature, and this feature is a panorama feature
15
+ * - there is a cluster feature and the following is true: all features in the cluster belong to the same layer and all features belong to a panorama dataset
16
+ * @param feature
17
+ */
18
+ function getPanoramaDatasetProperties(
19
+ feature?: EventFeature,
20
+ ): PanoramaDatasetFeatureProperties | null {
21
+ if (!feature) {
22
+ return null;
23
+ }
24
+
25
+ if ((feature as Feature)[panoramaFeature]) {
26
+ return (feature as Feature)[panoramaFeature]!;
27
+ }
28
+
29
+ if ((feature as Feature)[isProvidedClusterFeature]) {
30
+ let layerName: string | undefined;
31
+ let firstPanoramaDatasetFeatureProperties: PanoramaDatasetFeatureProperties | null =
32
+ null;
33
+ const features = (feature.getProperty('features') as Feature[]) ?? [];
34
+ for (const f of features) {
35
+ const fLayerName = f[vcsLayerName];
36
+ if (fLayerName == null) {
37
+ return null;
38
+ }
39
+
40
+ if (layerName == null) {
41
+ layerName = fLayerName;
42
+ } else if (layerName !== fLayerName) {
43
+ return null;
44
+ }
45
+
46
+ const fPanoramaDatasetFeatureProperties = f[panoramaFeature];
47
+ if (!fPanoramaDatasetFeatureProperties) {
48
+ return null;
49
+ } else if (!firstPanoramaDatasetFeatureProperties) {
50
+ firstPanoramaDatasetFeatureProperties =
51
+ fPanoramaDatasetFeatureProperties;
52
+ }
53
+ }
54
+
55
+ return firstPanoramaDatasetFeatureProperties;
56
+ }
57
+
58
+ return null;
59
+ }
8
60
 
9
61
  export default class PanoramaImageSelection extends AbstractInteraction {
10
62
  constructor(private _mapCollection: MapCollection) {
@@ -12,10 +64,11 @@ export default class PanoramaImageSelection extends AbstractInteraction {
12
64
  }
13
65
 
14
66
  override async pipe(event: InteractionEvent): Promise<InteractionEvent> {
15
- if (event.feature && (event.feature as Feature)[panoramaFeature]) {
16
- const { dataset, name, time } = (event.feature as Feature)[
17
- panoramaFeature
18
- ]!;
67
+ const panoramaDatasetProperties = getPanoramaDatasetProperties(
68
+ event.feature,
69
+ );
70
+ if (panoramaDatasetProperties) {
71
+ const { dataset, name, time } = panoramaDatasetProperties;
19
72
  const panoramaImage = await dataset.createPanoramaImage(name, time);
20
73
  event.stopPropagation = true;
21
74
 
@@ -1,7 +1,7 @@
1
1
  import type GeoTIFFSource from 'ol/source/GeoTIFF.js';
2
2
  import { ImageryLayer as CesiumImageryLayer } from '@vcmap-cesium/engine';
3
3
  import RasterLayerCesiumImpl from './rasterLayerCesiumImpl.js';
4
- import COGImageryProvider from './cogImageryProvider.js';
4
+ import COGImageryProvider from './imageryProvider/cogImageryProvider.js';
5
5
  import type { COGLayerImplementationOptions } from '../cogLayer.js';
6
6
  import type CesiumMap from '../../map/cesiumMap.js';
7
7
 
@@ -0,0 +1,126 @@
1
+ import {
2
+ Event as CesiumEvent,
3
+ type ImageryTypes,
4
+ type Rectangle,
5
+ type TilingScheme,
6
+ } from '@vcmap-cesium/engine';
7
+ import type { Size } from 'ol/size.js';
8
+
9
+ export type AbstractVcsImageryProviderOptions = {
10
+ tilingScheme: TilingScheme;
11
+ tileSize: Size;
12
+ minLevel: number;
13
+ maxLevel: number;
14
+ headers?: Record<string, string>;
15
+ };
16
+
17
+ export default abstract class AbstractVcsImageryProvider {
18
+ protected _tilingScheme: TilingScheme;
19
+
20
+ private _tileSize: Size;
21
+
22
+ private _errorEvent = new CesiumEvent();
23
+
24
+ headers?: Record<string, string>;
25
+
26
+ emptyCanvas: HTMLCanvasElement;
27
+
28
+ minLevel: number;
29
+
30
+ maxLevel: number;
31
+
32
+ // eslint-disable-next-line @typescript-eslint/naming-convention
33
+ _reload: undefined | (() => void) = undefined;
34
+
35
+ constructor(options: AbstractVcsImageryProviderOptions) {
36
+ this._tilingScheme = options.tilingScheme;
37
+ this._tileSize = options.tileSize;
38
+ this.minLevel = options.minLevel;
39
+ this.maxLevel = options.maxLevel;
40
+ this._errorEvent = new CesiumEvent();
41
+
42
+ this.emptyCanvas = document.createElement('canvas');
43
+ this.emptyCanvas.width = this.tileWidth;
44
+ this.emptyCanvas.height = this.tileHeight;
45
+ this.headers = options.headers;
46
+ }
47
+
48
+ // eslint-disable-next-line class-methods-use-this,@typescript-eslint/naming-convention
49
+ get _ready(): boolean {
50
+ return true;
51
+ }
52
+
53
+ // eslint-disable-next-line class-methods-use-this
54
+ get ready(): boolean {
55
+ return true;
56
+ }
57
+
58
+ get rectangle(): Rectangle {
59
+ return this._tilingScheme.rectangle;
60
+ }
61
+
62
+ get tileWidth(): number {
63
+ return this._tileSize[0];
64
+ }
65
+
66
+ get tileHeight(): number {
67
+ return this._tileSize[1];
68
+ }
69
+
70
+ get maximumLevel(): number {
71
+ return this.maxLevel;
72
+ }
73
+
74
+ get minimumLevel(): number {
75
+ return this.minLevel;
76
+ }
77
+
78
+ get tilingScheme(): TilingScheme {
79
+ return this._tilingScheme;
80
+ }
81
+
82
+ // eslint-disable-next-line class-methods-use-this
83
+ get tileDiscardPolicy(): undefined {
84
+ return undefined;
85
+ }
86
+
87
+ get errorEvent(): CesiumEvent {
88
+ return this._errorEvent;
89
+ }
90
+
91
+ // eslint-disable-next-line class-methods-use-this
92
+ get credit(): undefined {
93
+ return undefined;
94
+ }
95
+
96
+ // eslint-disable-next-line class-methods-use-this
97
+ get proxy(): undefined {
98
+ return undefined;
99
+ }
100
+
101
+ // eslint-disable-next-line class-methods-use-this
102
+ get hasAlphaChannel(): boolean {
103
+ return true;
104
+ }
105
+
106
+ /**
107
+ * Requests the image for a given tile. This function should
108
+ * not be called before returns true.
109
+ *
110
+ * @param x The tile X coordinate.
111
+ * @param y The tile Y coordinate.
112
+ * @param level The tile level.
113
+ * @returns A promise for the image that will resolve when the image is available, or
114
+ * undefined if there are too many active requests to the server, and the request
115
+ * should be retried later. The resolved image may be either an
116
+ * Image or a Canvas DOM object.
117
+ */
118
+ abstract requestImage(
119
+ x: number,
120
+ y: number,
121
+ level: number,
122
+ ): Promise<ImageryTypes> | undefined;
123
+
124
+ // eslint-disable-next-line class-methods-use-this
125
+ destroy(): void {}
126
+ }
@@ -7,10 +7,10 @@ import {
7
7
  getHeight as getExtentHeight,
8
8
  getTopLeft as getTopLeftExtent,
9
9
  } from 'ol/extent.js';
10
+ import type { Size } from 'ol/size.js';
10
11
  import TileState from 'ol/TileState.js';
11
12
  import {
12
13
  Cartesian2,
13
- Event as CesiumEvent,
14
14
  GeographicTilingScheme,
15
15
  type ImageryTypes,
16
16
  Math as CesiumMath,
@@ -23,7 +23,8 @@ import type TileGrid from 'ol/tilegrid/TileGrid.js';
23
23
  import {
24
24
  mercatorExtentToRectangle,
25
25
  rectangleToMercatorExtent,
26
- } from '../../util/math.js';
26
+ } from '../../../util/math.js';
27
+ import AbstractVcsImageryProvider from './abstractVcsImageryProvider.js';
27
28
 
28
29
  export function createEmptyCanvas(
29
30
  width: number,
@@ -38,17 +39,40 @@ export function createEmptyCanvas(
38
39
  function areGridsAligned(
39
40
  tileGrid: TileGrid,
40
41
  tilingScheme: TilingScheme,
42
+ source: GeoTIFFSource,
41
43
  ): boolean {
42
44
  const olRectangle = mercatorExtentToRectangle(
43
45
  tileGrid.getTileCoordExtent([0, 0, 0]),
44
46
  );
45
47
  const cesiumRectangle = tilingScheme.tileXYToRectangle(0, 0, 0);
46
48
 
47
- return Rectangle.equalsEpsilon(
49
+ const rectanglesEqual = Rectangle.equalsEpsilon(
48
50
  cesiumRectangle,
49
51
  olRectangle,
50
52
  CesiumMath.EPSILON8,
51
53
  );
54
+
55
+ if (rectanglesEqual) {
56
+ let width = 0;
57
+ let height = 0;
58
+ const numResolutions = tileGrid.getResolutions().length;
59
+ for (let i = 0; i < numResolutions; i++) {
60
+ // @ts-expect-error protected
61
+ const size = source.getTileSize(i);
62
+ if (!width) {
63
+ width = Math.round(size[0]);
64
+ } else if (width !== Math.round(size[0])) {
65
+ return false;
66
+ }
67
+
68
+ if (!height) {
69
+ height = Math.round(size[1]);
70
+ } else if (height !== Math.round(size[1])) {
71
+ return false;
72
+ }
73
+ }
74
+ }
75
+ return rectanglesEqual;
52
76
  }
53
77
 
54
78
  function getTilingSchemeFromSource(source: GeoTIFFSource): TilingScheme {
@@ -80,16 +104,58 @@ function getTilingSchemeFromSource(source: GeoTIFFSource): TilingScheme {
80
104
  return tilingScheme;
81
105
  }
82
106
 
83
- export default class COGImageryProvider {
84
- private _emptyCanvas: HTMLCanvasElement;
107
+ function drawData(
108
+ ctx: CanvasRenderingContext2D,
109
+ data: Uint8Array,
110
+ size: [number, number],
111
+ offsetX = 0,
112
+ offsetY = 0,
113
+ ): void {
114
+ const imageData = ctx.createImageData(size[0], size[1]);
115
+ let usedData = data;
116
+ // this is a grey image
117
+ if (data.length === imageData.data.length / 2) {
118
+ usedData = new Uint8Array(imageData.data.length);
119
+ for (let i = 0; i < data.length; i++) {
120
+ const value = data[i];
121
+ if (i % 2 === 0) {
122
+ const pixelOffset = (i / 2) * 4;
123
+ usedData[pixelOffset] = value;
124
+ usedData[pixelOffset + 1] = value;
125
+ usedData[pixelOffset + 2] = value;
126
+ } else {
127
+ const pixelOffset = ((i - 1) / 2) * 4;
128
+ usedData[pixelOffset + 3] = value;
129
+ }
130
+ }
131
+ }
132
+
133
+ imageData.data.set(usedData);
134
+ ctx.putImageData(imageData, offsetX, offsetY);
135
+ }
136
+
137
+ function getMaximumTileSize(source: GeoTIFFSource): Size {
138
+ let width = 0;
139
+ let height = 0;
140
+ const numResolutions = source.getTileGrid()!.getResolutions().length;
141
+ for (let i = 0; i < numResolutions; i++) {
142
+ // @ts-expect-error protected
143
+ const size = source.getTileSize(i);
144
+ if (width < size[0] && height < size[1]) {
145
+ width = Math.round(size[0]);
146
+ height = Math.round(size[1]);
147
+ }
148
+ }
149
+
150
+ return [width, height];
151
+ }
85
152
 
153
+ export default class COGImageryProvider extends AbstractVcsImageryProvider {
86
154
  // eslint-disable-next-line @typescript-eslint/naming-convention
87
155
  _reload: undefined | (() => void) = undefined;
88
156
 
89
157
  private _projection: Projection;
90
158
 
91
- private _tilingScheme: TilingScheme;
92
-
93
159
  private _tileGrid: TileGrid;
94
160
 
95
161
  private _boundTileLoader: (
@@ -98,85 +164,30 @@ export default class COGImageryProvider {
98
164
  level: number,
99
165
  ) => Promise<ImageryTypes>;
100
166
 
101
- readonly tileWidth: number = 256;
102
-
103
- readonly tileHeight: number = 256;
104
-
105
167
  constructor(private _source: GeoTIFFSource) {
106
- this._emptyCanvas = createEmptyCanvas(this.tileWidth, this.tileHeight);
168
+ const tileSize = getMaximumTileSize(_source);
169
+ const maxLevel = _source.getTileGrid()?.getMaxZoom?.() ?? 26;
170
+
171
+ super({
172
+ tilingScheme: getTilingSchemeFromSource(_source),
173
+ tileSize,
174
+ minLevel: 0,
175
+ maxLevel,
176
+ });
177
+
107
178
  this._projection = this._source.getProjection()!;
108
179
  this._tileGrid = this._source.getTileGrid()!;
109
- this._tilingScheme = getTilingSchemeFromSource(this._source);
110
- if (areGridsAligned(this._tileGrid, this._tilingScheme)) {
180
+ if (areGridsAligned(this._tileGrid, this._tilingScheme, this._source)) {
111
181
  this._boundTileLoader = this._loadAlignedTile.bind(this);
112
182
  } else {
113
183
  this._boundTileLoader = this._loadUnalignedTile.bind(this);
114
184
  }
115
-
116
- // @ts-expect-error protected
117
- const [width, height] = this._source.getTileSize(0);
118
- this.tileWidth = Math.round(width);
119
- this.tileHeight = Math.round(height);
120
- }
121
-
122
- // eslint-disable-next-line class-methods-use-this,@typescript-eslint/naming-convention
123
- get _ready(): boolean {
124
- return true;
125
- }
126
-
127
- // eslint-disable-next-line class-methods-use-this
128
- get ready(): boolean {
129
- return true;
130
- }
131
-
132
- get rectangle(): Rectangle {
133
- return this._tilingScheme.rectangle;
134
185
  }
135
186
 
136
- get tilingScheme(): TilingScheme {
137
- return this._tilingScheme;
138
- }
139
-
140
- readonly errorEvent: CesiumEvent = new CesiumEvent();
141
-
142
- // eslint-disable-next-line class-methods-use-this
143
- get credit(): undefined {
144
- return undefined;
145
- }
146
-
147
- // eslint-disable-next-line class-methods-use-this
148
- get proxy(): undefined {
149
- return undefined;
150
- }
151
-
152
- get maximumLevel(): number {
153
- const tileGrid = this._source.getTileGrid();
154
- if (tileGrid) {
155
- return tileGrid.getMaxZoom();
156
- } else {
157
- return 18; // some arbitrary value
158
- }
159
- }
160
-
161
- // eslint-disable-next-line class-methods-use-this
162
- get minimumLevel(): number {
163
- // WARNING: Do not use the minimum level (at least until the extent is
164
- // properly set). Cesium assumes the minimumLevel to contain only
165
- // a few tiles and tries to load them all at once -- this can
166
- // freeze and/or crash the browser !
167
- return 0;
168
- //var tg = this._source.getTileGrid();
169
- //return tg ? tg.getMinZoom() : 0;
170
- }
171
-
172
- // eslint-disable-next-line class-methods-use-this
173
- get tileDiscardPolicy(): undefined {
174
- return undefined;
175
- }
176
-
177
- // eslint-disable-next-line class-methods-use-this
178
- get hasAlphaChannel(): boolean {
179
- return true;
187
+ private _getTileSizeForLevel(level: number): [number, number] {
188
+ // @ts-expect-error protected
189
+ const [width, height] = this._source.getTileSize(level);
190
+ return [Math.round(width), Math.round(height)];
180
191
  }
181
192
 
182
193
  private async _loadOLTile(
@@ -218,35 +229,6 @@ export default class COGImageryProvider {
218
229
  return Promise.resolve(undefined);
219
230
  }
220
231
 
221
- private _drawData(
222
- ctx: CanvasRenderingContext2D,
223
- data: Uint8Array,
224
- offsetX = 0,
225
- offsetY = 0,
226
- ): void {
227
- const imageData = ctx.createImageData(this.tileWidth, this.tileHeight);
228
- let usedData = data;
229
- // this is a grey image
230
- if (data.length === imageData.data.length / 2) {
231
- usedData = new Uint8Array(imageData.data.length);
232
- for (let i = 0; i < data.length; i++) {
233
- const value = data[i];
234
- if (i % 2 === 0) {
235
- const pixelOffset = (i / 2) * 4;
236
- usedData[pixelOffset] = value;
237
- usedData[pixelOffset + 1] = value;
238
- usedData[pixelOffset + 2] = value;
239
- } else {
240
- const pixelOffset = ((i - 1) / 2) * 4;
241
- usedData[pixelOffset + 3] = value;
242
- }
243
- }
244
- }
245
-
246
- imageData.data.set(usedData);
247
- ctx.putImageData(imageData, offsetX, offsetY);
248
- }
249
-
250
232
  private async _loadAlignedTile(
251
233
  x: number,
252
234
  y: number,
@@ -257,12 +239,12 @@ export default class COGImageryProvider {
257
239
  const canvas = createEmptyCanvas(this.tileWidth, this.tileHeight);
258
240
  const ctx = canvas.getContext('2d');
259
241
  if (ctx) {
260
- this._drawData(ctx, tileData);
242
+ drawData(ctx, tileData, [this.tileWidth, this.tileHeight]);
261
243
  }
262
244
  return canvas;
263
245
  }
264
246
 
265
- return this._emptyCanvas;
247
+ return this.emptyCanvas;
266
248
  }
267
249
 
268
250
  private async _loadUnalignedTile(
@@ -281,13 +263,17 @@ export default class COGImageryProvider {
281
263
  extent,
282
264
  levelResolution,
283
265
  );
266
+
267
+ const [levelWidth, levelHeight] =
268
+ this._getTileSizeForLevel(levelResolution);
284
269
  const canvas = createEmptyCanvas(
285
- this.tileWidth * tileRange.getWidth(),
286
- this.tileHeight * tileRange.getHeight(),
270
+ levelWidth * tileRange.getWidth(),
271
+ levelHeight * tileRange.getHeight(),
287
272
  );
273
+
288
274
  const ctx = canvas.getContext('2d');
289
275
  if (!ctx) {
290
- return this._emptyCanvas;
276
+ return this.emptyCanvas;
291
277
  }
292
278
 
293
279
  const promises: Promise<void>[] = [];
@@ -314,11 +300,12 @@ export default class COGImageryProvider {
314
300
  this._loadOLTile(partialX, partialY, levelResolution).then(
315
301
  (tileData) => {
316
302
  if (tileData) {
317
- this._drawData(
303
+ drawData(
318
304
  ctx,
319
305
  tileData,
320
- (partialX - tileRange.minX) * this.tileWidth,
321
- (partialY - tileRange.minY) * this.tileHeight,
306
+ [levelWidth, levelHeight],
307
+ (partialX - tileRange.minX) * levelWidth,
308
+ (partialY - tileRange.minY) * levelHeight,
322
309
  );
323
310
  }
324
311
  },
@@ -328,11 +315,12 @@ export default class COGImageryProvider {
328
315
  }
329
316
  await Promise.all(promises);
330
317
 
318
+ // TODO if canvas has same height and width early escape
319
+
331
320
  const unitsPerPixelX =
332
- getExtentWidth(tileRangeExtent) / (this.tileWidth * tileRange.getWidth());
321
+ getExtentWidth(tileRangeExtent) / (levelWidth * tileRange.getWidth());
333
322
  const unitsPerPixelY =
334
- getExtentHeight(tileRangeExtent) /
335
- (this.tileHeight * tileRange.getHeight());
323
+ getExtentHeight(tileRangeExtent) / (levelHeight * tileRange.getHeight());
336
324
 
337
325
  const tileRangeTopLeft = getTopLeftExtent(tileRangeExtent);
338
326
  const extentTopLeft = getTopLeftExtent(extent);
@@ -363,10 +351,14 @@ export default class COGImageryProvider {
363
351
  return windowCanvas;
364
352
  }
365
353
 
366
- return this._emptyCanvas;
354
+ return this.emptyCanvas;
367
355
  }
368
356
 
369
- requestImage(x: number, y: number, level: number): Promise<ImageryTypes> {
357
+ requestImage(
358
+ x: number,
359
+ y: number,
360
+ level: number,
361
+ ): Promise<ImageryTypes> | undefined {
370
362
  return this._boundTileLoader(x, y, level);
371
363
  }
372
364
  }
@@ -0,0 +1,63 @@
1
+ import type LayerGroup from 'ol/layer/Group.js';
2
+ import type { VectorTileImageryProviderOptions } from './vectorTileImageryProvider.js';
3
+ import {
4
+ createOLImageRenderer,
5
+ type OLImageRenderer,
6
+ } from './olImageRenderer.js';
7
+ import AbstractVcsImageryProvider from './abstractVcsImageryProvider.js';
8
+ import type TileProvider from '../../tileProvider/tileProvider.js';
9
+
10
+ export type MapboxStyleImageryProviderOptions =
11
+ VectorTileImageryProviderOptions & {
12
+ styledMapboxLayerGroup: LayerGroup;
13
+ minimumTerrainLevel?: number;
14
+ maximumTerrainLevel?: number;
15
+ tileCacheSize?: number;
16
+ };
17
+
18
+ /**
19
+ * Implementation of Cesium ImageryProvider Interface for Mapbox Style Tiles
20
+ */
21
+ class MapboxStyleImageryProvider extends AbstractVcsImageryProvider {
22
+ static get className(): string {
23
+ return 'MapboxStyleImageryProvider';
24
+ }
25
+
26
+ tileProvider: TileProvider;
27
+
28
+ private _olImageRenderer: OLImageRenderer;
29
+
30
+ constructor(options: MapboxStyleImageryProviderOptions) {
31
+ super({
32
+ tilingScheme: options.tileProvider.tilingScheme,
33
+ tileSize: options.tileSize,
34
+ minLevel: 0,
35
+ maxLevel: 26,
36
+ });
37
+
38
+ this.tileProvider = options.tileProvider;
39
+
40
+ this._olImageRenderer = createOLImageRenderer({
41
+ tilingScheme: this.tileProvider.tilingScheme,
42
+ tileWidth: this.tileWidth,
43
+ tileHeight: this.tileHeight,
44
+ tileCacheSize: options.tileCacheSize,
45
+ emptyCanvas: this.emptyCanvas,
46
+ });
47
+ this._olImageRenderer.map.addLayer(options.styledMapboxLayerGroup);
48
+ }
49
+
50
+ requestImage(
51
+ x: number,
52
+ y: number,
53
+ level: number,
54
+ ): Promise<HTMLImageElement | HTMLCanvasElement> | undefined {
55
+ return this._olImageRenderer.requestImage(x, y, level);
56
+ }
57
+
58
+ destroy(): void {
59
+ this._olImageRenderer.destroy();
60
+ }
61
+ }
62
+
63
+ export default MapboxStyleImageryProvider;