@map-colonies/react-components 3.13.1 → 3.15.0
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/CHANGELOG.md +46 -11
- package/dist/assets/img/transparent-tile.png +0 -0
- package/dist/cesium-map/helpers/customImageryProviders.d.ts +34 -0
- package/dist/cesium-map/helpers/customImageryProviders.js +106 -0
- package/dist/cesium-map/helpers/utils.d.ts +17 -0
- package/dist/cesium-map/helpers/utils.js +142 -0
- package/dist/cesium-map/layers/wms.layer.js +7 -1
- package/dist/cesium-map/layers/wmts.layer.js +7 -1
- package/dist/cesium-map/layers/xyz.layer.js +7 -1
- package/dist/cesium-map/layers-manager.d.ts +4 -0
- package/dist/cesium-map/layers-manager.js +169 -12
- package/dist/cesium-map/map.d.ts +5 -0
- package/dist/cesium-map/map.js +40 -12
- package/dist/cesium-map/tools/scale-tracker.tool.js +4 -1
- package/dist/cesium-map/tools/zoom_level-tracker.tool.css +19 -0
- package/dist/cesium-map/tools/zoom_level-tracker.tool.d.ts +8 -0
- package/dist/cesium-map/tools/zoom_level-tracker.tool.js +131 -0
- package/package.json +2 -2
- package/public/assets/img/transparent-tile.png +0 -0
- package/src/lib/cesium-map/helpers/customImageryProviders.ts +173 -0
- package/src/lib/cesium-map/helpers/utils.ts +135 -0
- package/src/lib/cesium-map/layers/optimized-tile-requests.stories.tsx +279 -0
- package/src/lib/cesium-map/layers/wms.layer.tsx +10 -4
- package/src/lib/cesium-map/layers/wmts.layer.tsx +9 -4
- package/src/lib/cesium-map/layers/xyz.layer.tsx +9 -4
- package/src/lib/cesium-map/layers-manager.ts +223 -19
- package/src/lib/cesium-map/map.stories.tsx +1 -0
- package/src/lib/cesium-map/map.tsx +33 -0
- package/src/lib/cesium-map/settings/settings.stories.tsx +5 -1
- package/src/lib/cesium-map/tools/coordinates-tracker.tool.tsx +6 -1
- package/src/lib/cesium-map/tools/scale-tracker.tool.tsx +4 -1
- package/src/lib/cesium-map/tools/zoom_level-tracker.tool.css +19 -0
- package/src/lib/cesium-map/tools/zoom_level-tracker.tool.tsx +142 -0
- package/src/lib/date-range-picker/date-range-picker.spec.tsx +81 -81
- package/jest_html_reporters.html +0 -78
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Request,
|
|
3
|
+
ImageryProvider,
|
|
4
|
+
UrlTemplateImageryProvider,
|
|
5
|
+
WebMapServiceImageryProvider,
|
|
6
|
+
WebMapTileServiceImageryProvider,
|
|
7
|
+
ImageryLayer,
|
|
8
|
+
} from 'cesium';
|
|
9
|
+
import { get, isEmpty } from 'lodash';
|
|
10
|
+
import { ICesiumImageryLayer } from '../layers-manager';
|
|
11
|
+
import { CesiumViewer } from '../map';
|
|
12
|
+
import { imageHasTransparency } from './utils';
|
|
13
|
+
|
|
14
|
+
export interface CustomImageryProvider extends ImageryProvider {
|
|
15
|
+
readonly layerListInstance: ICesiumImageryLayer[];
|
|
16
|
+
tileTransparencyCheckedCounter: number;
|
|
17
|
+
mapViewer: CesiumViewer;
|
|
18
|
+
readonly maxTilesForTransparencyCheck: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const NUMBER_OF_TILES_TO_CHECK = 3;
|
|
22
|
+
export const HAS_TRANSPARENCY_META_PROP = 'hasTransparency';
|
|
23
|
+
|
|
24
|
+
function customCommonRequestImage(
|
|
25
|
+
this: CustomImageryProvider,
|
|
26
|
+
requestImageFn: ImageryProvider['requestImage'],
|
|
27
|
+
x: number,
|
|
28
|
+
y: number,
|
|
29
|
+
level: number,
|
|
30
|
+
request?: Request | undefined
|
|
31
|
+
): Promise<HTMLImageElement | HTMLCanvasElement> | undefined {
|
|
32
|
+
// custom Logic
|
|
33
|
+
setTimeout(() => {
|
|
34
|
+
const requestedLayerMeta = this.layerListInstance.find(
|
|
35
|
+
/* eslint-disable */
|
|
36
|
+
(layer: ImageryLayer): boolean => {
|
|
37
|
+
return (
|
|
38
|
+
(layer as any)._imageryProvider._resource._url ===
|
|
39
|
+
(this as any)._resource._url
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
/* eslint-enable */
|
|
43
|
+
)?.meta;
|
|
44
|
+
|
|
45
|
+
const layerHasTransparency =
|
|
46
|
+
get(requestedLayerMeta, HAS_TRANSPARENCY_META_PROP) === true;
|
|
47
|
+
|
|
48
|
+
if (
|
|
49
|
+
this.tileTransparencyCheckedCounter < NUMBER_OF_TILES_TO_CHECK &&
|
|
50
|
+
!layerHasTransparency
|
|
51
|
+
) {
|
|
52
|
+
void imageHasTransparency(request?.url as string, this).then(
|
|
53
|
+
(hasTransparency) => {
|
|
54
|
+
this.mapViewer.layersManager?.addMetaToLayer(
|
|
55
|
+
{ [HAS_TRANSPARENCY_META_PROP]: hasTransparency },
|
|
56
|
+
/* eslint-disable */
|
|
57
|
+
(layer: ImageryLayer): boolean => {
|
|
58
|
+
return (
|
|
59
|
+
(layer as any)._imageryProvider._resource._url ===
|
|
60
|
+
(this as any)._resource._url
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
/* eslint-enable */
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
}, 0);
|
|
69
|
+
|
|
70
|
+
return requestImageFn(x, y, level, request);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export class CustomUrlTemplateImageryProvider extends UrlTemplateImageryProvider {
|
|
74
|
+
public readonly layerListInstance: ICesiumImageryLayer[];
|
|
75
|
+
public readonly mapViewer: CesiumViewer;
|
|
76
|
+
public readonly maxTilesForTransparencyCheck = NUMBER_OF_TILES_TO_CHECK;
|
|
77
|
+
|
|
78
|
+
public tileTransparencyCheckedCounter = 0;
|
|
79
|
+
|
|
80
|
+
public constructor(
|
|
81
|
+
opts: UrlTemplateImageryProvider.ConstructorOptions,
|
|
82
|
+
mapViewer: CesiumViewer
|
|
83
|
+
) {
|
|
84
|
+
super(opts);
|
|
85
|
+
this.layerListInstance = mapViewer.layersManager
|
|
86
|
+
?.layerList as ICesiumImageryLayer[];
|
|
87
|
+
this.mapViewer = mapViewer;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
public requestImage(
|
|
91
|
+
x: number,
|
|
92
|
+
y: number,
|
|
93
|
+
level: number,
|
|
94
|
+
request?: Request | undefined
|
|
95
|
+
): Promise<HTMLImageElement | HTMLCanvasElement> | undefined {
|
|
96
|
+
return customCommonRequestImage.call(
|
|
97
|
+
this,
|
|
98
|
+
super.requestImage.bind(this),
|
|
99
|
+
x,
|
|
100
|
+
y,
|
|
101
|
+
level,
|
|
102
|
+
request
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export class CustomWebMapServiceImageryProvider extends WebMapServiceImageryProvider {
|
|
108
|
+
public readonly layerListInstance: ICesiumImageryLayer[];
|
|
109
|
+
public readonly mapViewer: CesiumViewer;
|
|
110
|
+
public readonly maxTilesForTransparencyCheck = NUMBER_OF_TILES_TO_CHECK;
|
|
111
|
+
|
|
112
|
+
public tileTransparencyCheckedCounter = 0;
|
|
113
|
+
|
|
114
|
+
public constructor(
|
|
115
|
+
opts: WebMapServiceImageryProvider.ConstructorOptions,
|
|
116
|
+
mapViewer: CesiumViewer
|
|
117
|
+
) {
|
|
118
|
+
super(opts);
|
|
119
|
+
this.layerListInstance = mapViewer.layersManager
|
|
120
|
+
?.layerList as ICesiumImageryLayer[];
|
|
121
|
+
this.mapViewer = mapViewer;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
public requestImage(
|
|
125
|
+
x: number,
|
|
126
|
+
y: number,
|
|
127
|
+
level: number,
|
|
128
|
+
request?: Request | undefined
|
|
129
|
+
): Promise<HTMLImageElement | HTMLCanvasElement> | undefined {
|
|
130
|
+
return customCommonRequestImage.call(
|
|
131
|
+
this,
|
|
132
|
+
super.requestImage.bind(this),
|
|
133
|
+
x,
|
|
134
|
+
y,
|
|
135
|
+
level,
|
|
136
|
+
request
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export class CustomWebMapTileServiceImageryProvider extends WebMapTileServiceImageryProvider {
|
|
142
|
+
public readonly layerListInstance: ICesiumImageryLayer[];
|
|
143
|
+
public readonly mapViewer: CesiumViewer;
|
|
144
|
+
public readonly maxTilesForTransparencyCheck = NUMBER_OF_TILES_TO_CHECK;
|
|
145
|
+
|
|
146
|
+
public tileTransparencyCheckedCounter = 0;
|
|
147
|
+
|
|
148
|
+
public constructor(
|
|
149
|
+
opts: WebMapTileServiceImageryProvider.ConstructorOptions,
|
|
150
|
+
mapViewer: CesiumViewer
|
|
151
|
+
) {
|
|
152
|
+
super(opts);
|
|
153
|
+
this.layerListInstance = mapViewer.layersManager
|
|
154
|
+
?.layerList as ICesiumImageryLayer[];
|
|
155
|
+
this.mapViewer = mapViewer;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
public requestImage(
|
|
159
|
+
x: number,
|
|
160
|
+
y: number,
|
|
161
|
+
level: number,
|
|
162
|
+
request?: Request | undefined
|
|
163
|
+
): Promise<HTMLImageElement | HTMLCanvasElement> | undefined {
|
|
164
|
+
return customCommonRequestImage.call(
|
|
165
|
+
this,
|
|
166
|
+
super.requestImage.bind(this),
|
|
167
|
+
x,
|
|
168
|
+
y,
|
|
169
|
+
level,
|
|
170
|
+
request
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { Rectangle } from 'cesium';
|
|
2
|
+
import { CustomImageryProvider } from './customImageryProviders';
|
|
3
|
+
|
|
4
|
+
const canvasElem = document.createElement('canvas');
|
|
5
|
+
const canvasCtx = canvasElem.getContext('2d');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @param image Image data to check
|
|
9
|
+
* @returns `true` if image data has at least one transparent pixel, `false` otherwise.
|
|
10
|
+
*/
|
|
11
|
+
const imageDataHasTransparency = (image: ImageData | undefined): boolean => {
|
|
12
|
+
const ALPHA_CHANNEL_OFFSET = 4; // [R,G,B,A, R,G,B,A] => FLAT ARRAY OF THIS SHAPE; (Uint8ClampedArray)
|
|
13
|
+
const OPAQUE_PIXEL_ALPHA_VALUE = 255;
|
|
14
|
+
const imgData = image?.data ?? [];
|
|
15
|
+
|
|
16
|
+
// Iterate through alpha channels only.
|
|
17
|
+
for (let i = 3; i < imgData?.length; i += ALPHA_CHANNEL_OFFSET) {
|
|
18
|
+
if (imgData[i] < OPAQUE_PIXEL_ALPHA_VALUE) {
|
|
19
|
+
// Transparent pixel found.
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return false;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* An async function to detect images with transparency.
|
|
28
|
+
* @param image The image to resolve. if value is `string (url)` it tries to fetch the image data first.
|
|
29
|
+
* Could also be `HTMLImageElement` or `ImageBitmap`
|
|
30
|
+
* @param context `optional` `CustomImageryProvider` context in which the function will automatically increase
|
|
31
|
+
* the `tileTransparencyCheckedCounter`. Sets to `maxTilesForTransparencyCheck` when layer detected as transparent.
|
|
32
|
+
* @returns
|
|
33
|
+
*/
|
|
34
|
+
export const imageHasTransparency = async (
|
|
35
|
+
image: string | HTMLImageElement | ImageBitmap,
|
|
36
|
+
context?: CustomImageryProvider
|
|
37
|
+
): Promise<boolean> => {
|
|
38
|
+
if (context) {
|
|
39
|
+
context.tileTransparencyCheckedCounter++;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return new Promise<boolean>((resolve, reject) => {
|
|
43
|
+
try {
|
|
44
|
+
canvasCtx?.clearRect(0, 0, canvasElem.width, canvasElem.height);
|
|
45
|
+
let imageElement: HTMLImageElement;
|
|
46
|
+
|
|
47
|
+
// Init Image instance.
|
|
48
|
+
if (image instanceof HTMLImageElement) {
|
|
49
|
+
imageElement = image;
|
|
50
|
+
} else if (image instanceof ImageBitmap) {
|
|
51
|
+
canvasElem.width = image.width;
|
|
52
|
+
canvasElem.height = image.height;
|
|
53
|
+
canvasCtx?.drawImage(image, 0, 0);
|
|
54
|
+
|
|
55
|
+
const canvasImg = canvasCtx?.getImageData(
|
|
56
|
+
0,
|
|
57
|
+
0,
|
|
58
|
+
canvasElem.width,
|
|
59
|
+
canvasElem.height
|
|
60
|
+
);
|
|
61
|
+
const hasTransparency = imageDataHasTransparency(canvasImg);
|
|
62
|
+
if (hasTransparency) {
|
|
63
|
+
if (context) {
|
|
64
|
+
context.tileTransparencyCheckedCounter =
|
|
65
|
+
context.maxTilesForTransparencyCheck;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
resolve(hasTransparency);
|
|
70
|
+
return;
|
|
71
|
+
} else {
|
|
72
|
+
imageElement = new Image();
|
|
73
|
+
imageElement.crossOrigin = 'anonymous'; // Disable CORS errors on canvas image load.
|
|
74
|
+
imageElement.src = image;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
imageElement.onload = (): void => {
|
|
78
|
+
// Image loaded, set canvas size to image size.
|
|
79
|
+
canvasElem.width = imageElement.width;
|
|
80
|
+
canvasElem.height = imageElement.height;
|
|
81
|
+
|
|
82
|
+
canvasCtx?.drawImage(imageElement, 0, 0);
|
|
83
|
+
|
|
84
|
+
const canvasImg = canvasCtx?.getImageData(
|
|
85
|
+
0,
|
|
86
|
+
0,
|
|
87
|
+
canvasElem.width,
|
|
88
|
+
canvasElem.height
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
const hasTransparency = imageDataHasTransparency(canvasImg);
|
|
92
|
+
|
|
93
|
+
if (hasTransparency) {
|
|
94
|
+
if (context) {
|
|
95
|
+
context.tileTransparencyCheckedCounter =
|
|
96
|
+
context.maxTilesForTransparencyCheck;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
resolve(true);
|
|
100
|
+
} else {
|
|
101
|
+
resolve(false);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
} catch (e) {
|
|
105
|
+
console.error('Could not determine image transparency. Error => ', e);
|
|
106
|
+
reject(e);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Checks if `rect` is contained inside `anotherRect`
|
|
113
|
+
* @param rect
|
|
114
|
+
* @param anotherRect
|
|
115
|
+
*/
|
|
116
|
+
export const cesiumRectangleContained = (
|
|
117
|
+
rect: Rectangle,
|
|
118
|
+
anotherRect: Rectangle
|
|
119
|
+
): boolean => {
|
|
120
|
+
const { west, east, north, south } = rect;
|
|
121
|
+
const {
|
|
122
|
+
west: anotherWest,
|
|
123
|
+
east: anotherEast,
|
|
124
|
+
north: anotherNorth,
|
|
125
|
+
south: anotherSouth,
|
|
126
|
+
} = anotherRect;
|
|
127
|
+
|
|
128
|
+
const isRectInsideAnother =
|
|
129
|
+
west >= anotherWest &&
|
|
130
|
+
east <= anotherEast &&
|
|
131
|
+
north <= anotherNorth &&
|
|
132
|
+
south >= anotherSouth;
|
|
133
|
+
|
|
134
|
+
return isRectInsideAnother;
|
|
135
|
+
};
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import React, { ReactNode, useEffect, useState } from 'react';
|
|
2
|
+
import bbox from '@turf/bbox';
|
|
3
|
+
import { Story, Meta } from '@storybook/react/types-6-0';
|
|
4
|
+
import { Rectangle } from 'cesium';
|
|
5
|
+
import { CesiumMap, CesiumMapProps, useCesiumMap } from '../map';
|
|
6
|
+
import { CesiumSceneMode } from '../map.types';
|
|
7
|
+
import { IBaseMaps } from '../settings/settings';
|
|
8
|
+
import { CesiumXYZLayer } from './xyz.layer';
|
|
9
|
+
|
|
10
|
+
export default {
|
|
11
|
+
title: 'Cesium Map/Map Optimizations',
|
|
12
|
+
component: CesiumMap,
|
|
13
|
+
parameters: {
|
|
14
|
+
layout: 'fullscreen',
|
|
15
|
+
},
|
|
16
|
+
args: {
|
|
17
|
+
useOptimizedTileRequests: true,
|
|
18
|
+
},
|
|
19
|
+
argTypes: {
|
|
20
|
+
useOptimizedTileRequests: {
|
|
21
|
+
description:
|
|
22
|
+
'Should the viewer determine layer relevancy based on its visibility and presence in scene. (Improves bandwidth usage and overall performance)',
|
|
23
|
+
table: {
|
|
24
|
+
defaultValue: { summary: 'false' },
|
|
25
|
+
},
|
|
26
|
+
control: 'boolean',
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
} as Meta;
|
|
30
|
+
|
|
31
|
+
const BASE_MAPS = {
|
|
32
|
+
maps: [
|
|
33
|
+
{
|
|
34
|
+
id: '3rd',
|
|
35
|
+
title: '3rd Map Title',
|
|
36
|
+
isCurrent: true,
|
|
37
|
+
thumbnail:
|
|
38
|
+
'https://nsw.digitaltwin.terria.io/build/d8b97d3e38a0d43e5a06dea9aae17a3e.png',
|
|
39
|
+
baseRasteLayers: [
|
|
40
|
+
{
|
|
41
|
+
id: 'Opaque Base world wide layer',
|
|
42
|
+
type: 'XYZ_LAYER',
|
|
43
|
+
opacity: 1,
|
|
44
|
+
zIndex: 0,
|
|
45
|
+
options: {
|
|
46
|
+
url:
|
|
47
|
+
'https://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png?apikey=6170aad10dfd42a38d4d8c709a536f38',
|
|
48
|
+
layers: '',
|
|
49
|
+
credit: 'thunderforest',
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
id: 'Transparent Base Roads world wide layer ',
|
|
54
|
+
type: 'XYZ_LAYER',
|
|
55
|
+
opacity: 1,
|
|
56
|
+
zIndex: 1,
|
|
57
|
+
options: {
|
|
58
|
+
url: 'https://gps.tile.openstreetmap.org/lines/{z}/{x}/{y}.png',
|
|
59
|
+
layers: '',
|
|
60
|
+
credit: 'openstreetmap',
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
baseVectorLayers: [],
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const mapDivStyle = {
|
|
70
|
+
height: '100%',
|
|
71
|
+
width: '100%',
|
|
72
|
+
position: 'absolute' as const,
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const mapViewProps: CesiumMapProps = {
|
|
76
|
+
center: [-117.30644008676421, 33.117098433617564],
|
|
77
|
+
zoom: 14,
|
|
78
|
+
imageryProvider: false,
|
|
79
|
+
sceneModes: [CesiumSceneMode.SCENE3D, CesiumSceneMode.COLUMBUS_VIEW],
|
|
80
|
+
baseMaps: BASE_MAPS as IBaseMaps,
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
interface OptimizedTileRequestingMapStoryProps {
|
|
84
|
+
useOptimizedTileRequests: boolean;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
interface LayerRelevancy {
|
|
88
|
+
layerId?: string;
|
|
89
|
+
isRelevant?: boolean;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const RelevancyPresentor: React.FC<OptimizedTileRequestingMapStoryProps> = ({
|
|
93
|
+
useOptimizedTileRequests,
|
|
94
|
+
}) => {
|
|
95
|
+
const viewer = useCesiumMap();
|
|
96
|
+
const [layersRelevancy, setLayersRelevancy] = useState<LayerRelevancy[]>([]);
|
|
97
|
+
|
|
98
|
+
const updateLayerRelevancy = (): void => {
|
|
99
|
+
if (viewer.layersManager?.layerList) {
|
|
100
|
+
setLayersRelevancy(
|
|
101
|
+
viewer.layersManager?.layerList
|
|
102
|
+
.filter(
|
|
103
|
+
(layer): boolean => layer.meta?.id !== 'TRANSPARENT_BASE_LAYER'
|
|
104
|
+
)
|
|
105
|
+
.map(
|
|
106
|
+
(layer): LayerRelevancy => ({
|
|
107
|
+
layerId: layer.meta?.id as string | undefined,
|
|
108
|
+
isRelevant: layer.meta?.relevantToExtent as boolean,
|
|
109
|
+
})
|
|
110
|
+
)
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
useEffect(() => {
|
|
116
|
+
const removeTileLoad = viewer.scene.globe.tileLoadProgressEvent.addEventListener(
|
|
117
|
+
(tilesLoadingCount) => {
|
|
118
|
+
if (tilesLoadingCount === 0) {
|
|
119
|
+
updateLayerRelevancy();
|
|
120
|
+
removeTileLoad();
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
const removeMoveEnd = viewer.camera.moveEnd.addEventListener(() => {
|
|
126
|
+
updateLayerRelevancy();
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
return (): void => {
|
|
130
|
+
removeMoveEnd();
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
134
|
+
}, []);
|
|
135
|
+
|
|
136
|
+
return (
|
|
137
|
+
<>
|
|
138
|
+
<div
|
|
139
|
+
style={{
|
|
140
|
+
position: 'absolute',
|
|
141
|
+
left: 0,
|
|
142
|
+
top: 0,
|
|
143
|
+
zIndex: 999,
|
|
144
|
+
background: 'white',
|
|
145
|
+
padding: '20px',
|
|
146
|
+
fontFamily: 'Helvetica',
|
|
147
|
+
minWidth: '200px',
|
|
148
|
+
minHeight: '200px',
|
|
149
|
+
}}
|
|
150
|
+
>
|
|
151
|
+
<h3>
|
|
152
|
+
{`Optimized Tile Requesting: ${
|
|
153
|
+
useOptimizedTileRequests ? 'enabled' : 'disabled'
|
|
154
|
+
}`}
|
|
155
|
+
</h3>
|
|
156
|
+
{layersRelevancy.map((layer) => {
|
|
157
|
+
return (
|
|
158
|
+
<div>
|
|
159
|
+
<p>Layer Id: {layer.layerId}</p>
|
|
160
|
+
<p>Requesting tiles: {layer.isRelevant?.toString()}</p>
|
|
161
|
+
</div>
|
|
162
|
+
);
|
|
163
|
+
})}
|
|
164
|
+
</div>
|
|
165
|
+
</>
|
|
166
|
+
);
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
const LayersContainer: React.FC = () => {
|
|
170
|
+
const [layer, setLayer] = useState<ReactNode>(null);
|
|
171
|
+
const btnStyle = {
|
|
172
|
+
position: 'absolute',
|
|
173
|
+
top: 50,
|
|
174
|
+
left: '50%',
|
|
175
|
+
zIndex: 1000,
|
|
176
|
+
transform: 'translate(0, -50%)',
|
|
177
|
+
} as React.CSSProperties;
|
|
178
|
+
|
|
179
|
+
const optionsXYZTransparency = {
|
|
180
|
+
url:
|
|
181
|
+
'https://tiles.openaerialmap.org/5d73614588556200055f10d6/0/5d73614588556200055f10d7/{z}/{x}/{y}',
|
|
182
|
+
footprint: {
|
|
183
|
+
coordinates: [
|
|
184
|
+
[
|
|
185
|
+
[-117.30976118375267, 33.116454006568205],
|
|
186
|
+
[-117.30976118375267, 33.11330462707964],
|
|
187
|
+
[-117.30513526140776, 33.11330462707964],
|
|
188
|
+
[-117.30513526140776, 33.116454006568205],
|
|
189
|
+
[-117.30976118375267, 33.116454006568205],
|
|
190
|
+
],
|
|
191
|
+
],
|
|
192
|
+
type: 'Polygon',
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
const optionsXYZOpaque = {
|
|
197
|
+
url: 'http://stamen-tiles-b.a.ssl.fastly.net/toner/{z}/{x}/{y}.png',
|
|
198
|
+
footprint: {
|
|
199
|
+
coordinates: [
|
|
200
|
+
[
|
|
201
|
+
[-117.31921599064628, 33.1210849388296],
|
|
202
|
+
[-117.31921599064628, 33.1094152732627],
|
|
203
|
+
[-117.29986251692546, 33.1094152732627],
|
|
204
|
+
[-117.29986251692546, 33.1210849388296],
|
|
205
|
+
[-117.31921599064628, 33.1210849388296],
|
|
206
|
+
],
|
|
207
|
+
],
|
|
208
|
+
type: 'Polygon',
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
return (
|
|
213
|
+
<>
|
|
214
|
+
<div
|
|
215
|
+
className="buttonsContainer"
|
|
216
|
+
style={{ display: 'flex', gap: '10px', ...btnStyle }}
|
|
217
|
+
>
|
|
218
|
+
<button
|
|
219
|
+
onClick={(): void =>
|
|
220
|
+
setLayer(
|
|
221
|
+
<CesiumXYZLayer
|
|
222
|
+
key="Transparent"
|
|
223
|
+
meta={{
|
|
224
|
+
id: 'Transparent Layer',
|
|
225
|
+
options: { ...optionsXYZTransparency },
|
|
226
|
+
}}
|
|
227
|
+
rectangle={Rectangle.fromDegrees(
|
|
228
|
+
...bbox(optionsXYZTransparency.footprint)
|
|
229
|
+
)}
|
|
230
|
+
options={optionsXYZTransparency}
|
|
231
|
+
/>
|
|
232
|
+
)
|
|
233
|
+
}
|
|
234
|
+
>
|
|
235
|
+
Layer With Transparency
|
|
236
|
+
</button>
|
|
237
|
+
|
|
238
|
+
<button
|
|
239
|
+
onClick={(): void =>
|
|
240
|
+
setLayer(
|
|
241
|
+
<CesiumXYZLayer
|
|
242
|
+
key="Opaque"
|
|
243
|
+
meta={{ id: 'Opaque Layer', options: { ...optionsXYZOpaque } }}
|
|
244
|
+
rectangle={Rectangle.fromDegrees(
|
|
245
|
+
...bbox(optionsXYZOpaque.footprint)
|
|
246
|
+
)}
|
|
247
|
+
options={optionsXYZOpaque}
|
|
248
|
+
/>
|
|
249
|
+
)
|
|
250
|
+
}
|
|
251
|
+
>
|
|
252
|
+
Opaque layer
|
|
253
|
+
</button>
|
|
254
|
+
</div>
|
|
255
|
+
{layer}
|
|
256
|
+
</>
|
|
257
|
+
);
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
export const OptimizedTileRequestingMap: Story<OptimizedTileRequestingMapStoryProps> = (
|
|
261
|
+
args
|
|
262
|
+
) => {
|
|
263
|
+
return (
|
|
264
|
+
<div style={mapDivStyle}>
|
|
265
|
+
<CesiumMap
|
|
266
|
+
{...mapViewProps}
|
|
267
|
+
useOptimizedTileRequests={args.useOptimizedTileRequests}
|
|
268
|
+
key={args.useOptimizedTileRequests ? 'OPTIMIZED_MAP' : 'REGULAR_MAP'}
|
|
269
|
+
>
|
|
270
|
+
<LayersContainer />
|
|
271
|
+
<RelevancyPresentor
|
|
272
|
+
useOptimizedTileRequests={args.useOptimizedTileRequests}
|
|
273
|
+
/>
|
|
274
|
+
</CesiumMap>
|
|
275
|
+
</div>
|
|
276
|
+
);
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
OptimizedTileRequestingMap.storyName = 'Optimized Tile Requesting';
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
3
|
import { WebMapServiceImageryProvider } from 'cesium';
|
|
4
|
+
import { CustomWebMapServiceImageryProvider } from '../helpers/customImageryProviders';
|
|
5
|
+
import { useCesiumMap } from '../map';
|
|
6
|
+
import { ICesiumImageryLayer } from '../layers-manager';
|
|
4
7
|
import { CesiumImageryLayer, RCesiumImageryLayerProps } from './imagery.layer';
|
|
5
8
|
|
|
6
9
|
export interface RCesiumWMSLayerOptions
|
|
@@ -13,10 +16,13 @@ export interface RCesiumWMSLayerProps
|
|
|
13
16
|
|
|
14
17
|
export const CesiumWMSLayer: React.FC<RCesiumWMSLayerProps> = (props) => {
|
|
15
18
|
const { options, ...restProps } = props;
|
|
19
|
+
const mapViewer = useCesiumMap();
|
|
20
|
+
|
|
21
|
+
const providerInstance = mapViewer.shouldOptimizedTileRequests
|
|
22
|
+
? new CustomWebMapServiceImageryProvider(options, mapViewer)
|
|
23
|
+
: new WebMapServiceImageryProvider(options);
|
|
24
|
+
|
|
16
25
|
return (
|
|
17
|
-
<CesiumImageryLayer
|
|
18
|
-
{...restProps}
|
|
19
|
-
imageryProvider={new WebMapServiceImageryProvider(options)}
|
|
20
|
-
/>
|
|
26
|
+
<CesiumImageryLayer {...restProps} imageryProvider={providerInstance} />
|
|
21
27
|
);
|
|
22
28
|
};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
3
|
import { WebMapTileServiceImageryProvider } from 'cesium';
|
|
4
|
+
import { CustomWebMapTileServiceImageryProvider } from '../helpers/customImageryProviders';
|
|
5
|
+
import { useCesiumMap } from '../map';
|
|
4
6
|
import { CesiumImageryLayer, RCesiumImageryLayerProps } from './imagery.layer';
|
|
5
7
|
|
|
6
8
|
export interface RCesiumWMTSLayerOptions
|
|
@@ -13,10 +15,13 @@ export interface RCesiumWMTSLayerProps
|
|
|
13
15
|
|
|
14
16
|
export const CesiumWMTSLayer: React.FC<RCesiumWMTSLayerProps> = (props) => {
|
|
15
17
|
const { options, ...restProps } = props;
|
|
18
|
+
const mapViewer = useCesiumMap();
|
|
19
|
+
|
|
20
|
+
const providerInstance = mapViewer.shouldOptimizedTileRequests
|
|
21
|
+
? new CustomWebMapTileServiceImageryProvider(options, mapViewer)
|
|
22
|
+
: new WebMapTileServiceImageryProvider(options);
|
|
23
|
+
|
|
16
24
|
return (
|
|
17
|
-
<CesiumImageryLayer
|
|
18
|
-
{...restProps}
|
|
19
|
-
imageryProvider={new WebMapTileServiceImageryProvider(options)}
|
|
20
|
-
/>
|
|
25
|
+
<CesiumImageryLayer {...restProps} imageryProvider={providerInstance} />
|
|
21
26
|
);
|
|
22
27
|
};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
3
|
import { UrlTemplateImageryProvider } from 'cesium';
|
|
4
|
+
import { CustomUrlTemplateImageryProvider } from '../helpers/customImageryProviders';
|
|
5
|
+
import { useCesiumMap } from '../map';
|
|
4
6
|
import { CesiumImageryLayer, RCesiumImageryLayerProps } from './imagery.layer';
|
|
5
7
|
|
|
6
8
|
export interface RCesiumXYZLayerOptions
|
|
@@ -13,10 +15,13 @@ export interface RCesiumXYZLayerProps
|
|
|
13
15
|
|
|
14
16
|
export const CesiumXYZLayer: React.FC<RCesiumXYZLayerProps> = (props) => {
|
|
15
17
|
const { options, ...restProps } = props;
|
|
18
|
+
const mapViewer = useCesiumMap();
|
|
19
|
+
|
|
20
|
+
const providerInstance = mapViewer.shouldOptimizedTileRequests
|
|
21
|
+
? new CustomUrlTemplateImageryProvider(options, mapViewer)
|
|
22
|
+
: new UrlTemplateImageryProvider(options);
|
|
23
|
+
|
|
16
24
|
return (
|
|
17
|
-
<CesiumImageryLayer
|
|
18
|
-
{...restProps}
|
|
19
|
-
imageryProvider={new UrlTemplateImageryProvider(options)}
|
|
20
|
-
/>
|
|
25
|
+
<CesiumImageryLayer {...restProps} imageryProvider={providerInstance} />
|
|
21
26
|
);
|
|
22
27
|
};
|