@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.
- package/dist/index.d.ts +5 -2
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/src/interaction/panoramaFeatureHighlight.d.ts +1 -0
- package/dist/src/interaction/panoramaFeatureHighlight.js +18 -11
- package/dist/src/interaction/panoramaFeatureHighlight.js.map +1 -1
- package/dist/src/interaction/panoramaImageSelection.js +46 -2
- package/dist/src/interaction/panoramaImageSelection.js.map +1 -1
- package/dist/src/layer/cesium/cogCesiumImpl.js +1 -1
- package/dist/src/layer/cesium/cogCesiumImpl.js.map +1 -1
- package/dist/src/layer/cesium/imageryProvider/abstractVcsImageryProvider.d.ts +47 -0
- package/dist/src/layer/cesium/imageryProvider/abstractVcsImageryProvider.js +71 -0
- package/dist/src/layer/cesium/imageryProvider/abstractVcsImageryProvider.js.map +1 -0
- package/dist/src/layer/cesium/imageryProvider/cogImageryProvider.d.ts +17 -0
- package/dist/src/layer/cesium/{cogImageryProvider.js → imageryProvider/cogImageryProvider.js} +88 -97
- package/dist/src/layer/cesium/imageryProvider/cogImageryProvider.js.map +1 -0
- package/dist/src/layer/cesium/{mapboxStyleImageryProvider.d.ts → imageryProvider/mapboxStyleImageryProvider.d.ts} +5 -9
- package/dist/src/layer/cesium/imageryProvider/mapboxStyleImageryProvider.js +37 -0
- package/dist/src/layer/cesium/imageryProvider/mapboxStyleImageryProvider.js.map +1 -0
- package/dist/src/layer/cesium/imageryProvider/olImageRenderer.d.ts +18 -0
- package/dist/src/layer/cesium/imageryProvider/olImageRenderer.js +144 -0
- package/dist/src/layer/cesium/imageryProvider/olImageRenderer.js.map +1 -0
- package/dist/src/layer/cesium/imageryProvider/panoramaDatasetImageryProvider.d.ts +12 -0
- package/dist/src/layer/cesium/imageryProvider/panoramaDatasetImageryProvider.js +45 -0
- package/dist/src/layer/cesium/imageryProvider/panoramaDatasetImageryProvider.js.map +1 -0
- package/dist/src/layer/cesium/{vectorTileImageryProvider.d.ts → imageryProvider/vectorTileImageryProvider.d.ts} +12 -26
- package/dist/src/layer/cesium/imageryProvider/vectorTileImageryProvider.js +88 -0
- package/dist/src/layer/cesium/imageryProvider/vectorTileImageryProvider.js.map +1 -0
- package/dist/src/layer/cesium/mapboxStyleCesiumImpl.d.ts +1 -1
- package/dist/src/layer/cesium/mapboxStyleCesiumImpl.js +1 -1
- package/dist/src/layer/cesium/mapboxStyleCesiumImpl.js.map +1 -1
- package/dist/src/layer/cesium/panoramaDatasetCesiumImpl.d.ts +5 -0
- package/dist/src/layer/cesium/panoramaDatasetCesiumImpl.js +12 -0
- package/dist/src/layer/cesium/panoramaDatasetCesiumImpl.js.map +1 -0
- package/dist/src/layer/cesium/vectorRasterTileCesiumImpl.d.ts +4 -2
- package/dist/src/layer/cesium/vectorRasterTileCesiumImpl.js +10 -3
- package/dist/src/layer/cesium/vectorRasterTileCesiumImpl.js.map +1 -1
- package/dist/src/layer/panoramaDatasetLayer.js +11 -1
- package/dist/src/layer/panoramaDatasetLayer.js.map +1 -1
- package/dist/src/layer/vectorTileLayer.d.ts +1 -0
- package/dist/src/layer/vectorTileLayer.js +3 -0
- package/dist/src/layer/vectorTileLayer.js.map +1 -1
- package/index.ts +11 -2
- package/package.json +1 -1
- package/src/interaction/panoramaFeatureHighlight.ts +23 -16
- package/src/interaction/panoramaImageSelection.ts +58 -5
- package/src/layer/cesium/cogCesiumImpl.ts +1 -1
- package/src/layer/cesium/imageryProvider/abstractVcsImageryProvider.ts +126 -0
- package/src/layer/cesium/{cogImageryProvider.ts → imageryProvider/cogImageryProvider.ts} +111 -119
- package/src/layer/cesium/imageryProvider/mapboxStyleImageryProvider.ts +63 -0
- package/src/layer/cesium/imageryProvider/olImageRenderer.ts +219 -0
- package/src/layer/cesium/imageryProvider/panoramaDatasetImageryProvider.ts +73 -0
- package/src/layer/cesium/{vectorTileImageryProvider.ts → imageryProvider/vectorTileImageryProvider.ts} +35 -102
- package/src/layer/cesium/mapboxStyleCesiumImpl.ts +1 -1
- package/src/layer/cesium/panoramaDatasetCesiumImpl.ts +13 -0
- package/src/layer/cesium/vectorRasterTileCesiumImpl.ts +14 -4
- package/src/layer/panoramaDatasetLayer.ts +12 -1
- package/src/layer/vectorTileLayer.ts +4 -0
- package/dist/src/layer/cesium/cogImageryProvider.d.ts +0 -31
- package/dist/src/layer/cesium/cogImageryProvider.js.map +0 -1
- package/dist/src/layer/cesium/mapboxStyleImageryProvider.js +0 -147
- package/dist/src/layer/cesium/mapboxStyleImageryProvider.js.map +0 -1
- package/dist/src/layer/cesium/vectorTileImageryProvider.js +0 -133
- package/dist/src/layer/cesium/vectorTileImageryProvider.js.map +0 -1
- 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
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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 '
|
|
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
|
-
|
|
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
|
-
|
|
84
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
137
|
-
|
|
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
|
-
|
|
242
|
+
drawData(ctx, tileData, [this.tileWidth, this.tileHeight]);
|
|
261
243
|
}
|
|
262
244
|
return canvas;
|
|
263
245
|
}
|
|
264
246
|
|
|
265
|
-
return this.
|
|
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
|
-
|
|
286
|
-
|
|
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.
|
|
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
|
-
|
|
303
|
+
drawData(
|
|
318
304
|
ctx,
|
|
319
305
|
tileData,
|
|
320
|
-
|
|
321
|
-
(
|
|
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) / (
|
|
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.
|
|
354
|
+
return this.emptyCanvas;
|
|
367
355
|
}
|
|
368
356
|
|
|
369
|
-
requestImage(
|
|
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;
|