@map-colonies/react-components 3.6.5 → 3.7.4
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 +52 -0
- package/dist/autocomplete/autocomplete.css +25 -0
- package/dist/autocomplete/autocomplete.d.ts +34 -0
- package/dist/autocomplete/autocomplete.d.ts.map +1 -0
- package/dist/autocomplete/autocomplete.js +467 -0
- package/dist/autocomplete/autocomplete.js.map +1 -0
- package/dist/autocomplete/index.d.ts +2 -0
- package/dist/autocomplete/index.d.ts.map +1 -0
- package/dist/autocomplete/index.js +5 -0
- package/dist/autocomplete/index.js.map +1 -0
- package/dist/cesium-map/layers-manager.d.ts +3 -0
- package/dist/cesium-map/layers-manager.d.ts.map +1 -1
- package/dist/cesium-map/layers-manager.js +63 -0
- package/dist/cesium-map/layers-manager.js.map +1 -1
- package/dist/cesium-map/map.d.ts +20 -1
- package/dist/cesium-map/map.d.ts.map +1 -1
- package/dist/cesium-map/map.js +55 -11
- package/dist/cesium-map/map.js.map +1 -1
- package/dist/cesium-map/tools/geojson/point.geojson.d.ts +4 -0
- package/dist/cesium-map/tools/geojson/point.geojson.d.ts.map +1 -0
- package/dist/cesium-map/tools/geojson/point.geojson.js +20 -0
- package/dist/cesium-map/tools/geojson/point.geojson.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +7 -3
- package/src/lib/autocomplete/autocomplete.css +25 -0
- package/src/lib/autocomplete/autocomplete.stories.tsx +101 -0
- package/src/lib/autocomplete/autocomplete.tsx +683 -0
- package/src/lib/autocomplete/get-input-selection.d.ts +1 -0
- package/src/lib/autocomplete/index.ts +1 -0
- package/src/lib/cesium-map/context-menu.stories.tsx +445 -0
- package/src/lib/cesium-map/layers-manager.ts +76 -0
- package/src/lib/cesium-map/map.tsx +94 -3
- package/src/lib/cesium-map/tools/geojson/point.geojson.ts +29 -0
- package/src/lib/index.ts +1 -0
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
import React, { useLayoutEffect, useState } from 'react';
|
|
2
|
+
import { Story, Meta } from '@storybook/react/types-6-0';
|
|
3
|
+
import { Menu, MenuItem, MenuSurfaceAnchor } from '@map-colonies/react-core';
|
|
4
|
+
import { Box } from '../box';
|
|
5
|
+
import { CesiumMap, IContextMenuData, useCesiumMap } from './map';
|
|
6
|
+
import { CesiumSceneMode } from './map.types';
|
|
7
|
+
import { IRasterLayer } from './layers-manager';
|
|
8
|
+
|
|
9
|
+
export default {
|
|
10
|
+
title: 'Cesium Map/Context Menu',
|
|
11
|
+
component: CesiumMap,
|
|
12
|
+
parameters: {
|
|
13
|
+
layout: 'fullscreen',
|
|
14
|
+
},
|
|
15
|
+
} as Meta;
|
|
16
|
+
|
|
17
|
+
interface ILayersMozaikProps {
|
|
18
|
+
layers: IRasterLayer[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const mapDivStyle = {
|
|
22
|
+
height: '90%',
|
|
23
|
+
width: '100%',
|
|
24
|
+
position: 'absolute' as const,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const BASE_MAPS = {
|
|
28
|
+
maps: [
|
|
29
|
+
{
|
|
30
|
+
id: '1st',
|
|
31
|
+
title: '1st Map Title',
|
|
32
|
+
thumbnail:
|
|
33
|
+
'https://nsw.digitaltwin.terria.io/build/3456d1802ab2ef330ae2732387726771.png',
|
|
34
|
+
baseRasteLayers: [
|
|
35
|
+
{
|
|
36
|
+
id: 'GOOGLE_TERRAIN',
|
|
37
|
+
type: 'XYZ_LAYER',
|
|
38
|
+
opacity: 1,
|
|
39
|
+
zIndex: 0,
|
|
40
|
+
options: {
|
|
41
|
+
url: 'https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}',
|
|
42
|
+
layers: '',
|
|
43
|
+
credit: 'GOOGLE',
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: 'INFRARED_RASTER',
|
|
48
|
+
type: 'WMS_LAYER',
|
|
49
|
+
opacity: 0.6,
|
|
50
|
+
zIndex: 1,
|
|
51
|
+
options: {
|
|
52
|
+
url:
|
|
53
|
+
'https://mesonet.agron.iastate.edu/cgi-bin/wms/goes/conus_ir.cgi?',
|
|
54
|
+
layers: 'goes_conus_ir',
|
|
55
|
+
credit: 'Infrared data courtesy Iowa Environmental Mesonet',
|
|
56
|
+
parameters: {
|
|
57
|
+
transparent: 'true',
|
|
58
|
+
format: 'image/png',
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
baseVectorLayers: [],
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
id: '2nd',
|
|
67
|
+
title: '2nd Map Title',
|
|
68
|
+
isCurrent: true,
|
|
69
|
+
thumbnail:
|
|
70
|
+
'https://nsw.digitaltwin.terria.io/build/efa2f6c408eb790753a9b5fb2f3dc678.png',
|
|
71
|
+
baseRasteLayers: [
|
|
72
|
+
{
|
|
73
|
+
id: 'RADAR_RASTER',
|
|
74
|
+
type: 'WMS_LAYER',
|
|
75
|
+
opacity: 0.6,
|
|
76
|
+
zIndex: 1,
|
|
77
|
+
options: {
|
|
78
|
+
url:
|
|
79
|
+
'https://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi?',
|
|
80
|
+
layers: 'nexrad-n0r',
|
|
81
|
+
credit: 'Radar data courtesy Iowa Environmental Mesonet',
|
|
82
|
+
parameters: {
|
|
83
|
+
transparent: 'true',
|
|
84
|
+
format: 'image/png',
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: 'GOOGLE_TERRAIN',
|
|
90
|
+
type: 'XYZ_LAYER',
|
|
91
|
+
opacity: 1,
|
|
92
|
+
zIndex: 0,
|
|
93
|
+
options: {
|
|
94
|
+
url: 'https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}',
|
|
95
|
+
layers: '',
|
|
96
|
+
credit: 'GOOGLE',
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
id: 'VECTOR_TILES_GPS',
|
|
101
|
+
type: 'XYZ_LAYER',
|
|
102
|
+
opacity: 1,
|
|
103
|
+
zIndex: 2,
|
|
104
|
+
options: {
|
|
105
|
+
url: 'https://gps.tile.openstreetmap.org/lines/{z}/{x}/{y}.png',
|
|
106
|
+
layers: '',
|
|
107
|
+
credit: 'openstreetmap',
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
baseVectorLayers: [],
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
id: '3rd',
|
|
115
|
+
title: '3rd Map Title',
|
|
116
|
+
thumbnail:
|
|
117
|
+
'https://nsw.digitaltwin.terria.io/build/d8b97d3e38a0d43e5a06dea9aae17a3e.png',
|
|
118
|
+
baseRasteLayers: [
|
|
119
|
+
{
|
|
120
|
+
id: 'VECTOR_TILES',
|
|
121
|
+
type: 'XYZ_LAYER',
|
|
122
|
+
opacity: 1,
|
|
123
|
+
zIndex: 0,
|
|
124
|
+
options: {
|
|
125
|
+
url:
|
|
126
|
+
'https://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png?apikey=6170aad10dfd42a38d4d8c709a536f38',
|
|
127
|
+
layers: '',
|
|
128
|
+
credit: 'thunderforest',
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
id: 'VECTOR_TILES_GPS',
|
|
133
|
+
type: 'XYZ_LAYER',
|
|
134
|
+
opacity: 1,
|
|
135
|
+
zIndex: 1,
|
|
136
|
+
options: {
|
|
137
|
+
url: 'https://gps.tile.openstreetmap.org/lines/{z}/{x}/{y}.png',
|
|
138
|
+
layers: '',
|
|
139
|
+
credit: 'openstreetmap',
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
id: 'WMTS_POPULATION_TILES',
|
|
144
|
+
type: 'WMTS_LAYER',
|
|
145
|
+
opacity: 0.4,
|
|
146
|
+
zIndex: 2,
|
|
147
|
+
options: {
|
|
148
|
+
url:
|
|
149
|
+
'https://services.arcgisonline.com/arcgis/rest/services/Demographics/USA_Population_Density/MapServer/WMTS/',
|
|
150
|
+
layer: 'USGSShadedReliefOnly',
|
|
151
|
+
style: 'default',
|
|
152
|
+
format: 'image/jpeg',
|
|
153
|
+
tileMatrixSetID: 'default028mm',
|
|
154
|
+
maximumLevel: 19,
|
|
155
|
+
credit: 'U. S. Geological Survey',
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
baseVectorLayers: [],
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const layers = [
|
|
165
|
+
{
|
|
166
|
+
id: '2_raster_ext',
|
|
167
|
+
type: 'XYZ_LAYER',
|
|
168
|
+
opacity: 1,
|
|
169
|
+
zIndex: 0,
|
|
170
|
+
show: false,
|
|
171
|
+
options: {
|
|
172
|
+
url:
|
|
173
|
+
'https://tiles.openaerialmap.org/5a9f90c42553e6000ce5ad6c/0/eee1a570-128e-4947-9ffa-1e69c1efab7c/{z}/{x}/{y}.png',
|
|
174
|
+
},
|
|
175
|
+
details: {
|
|
176
|
+
footprint: {
|
|
177
|
+
type: 'Polygon',
|
|
178
|
+
coordinates: [
|
|
179
|
+
[
|
|
180
|
+
[34.8099445223518, 31.9061345394902],
|
|
181
|
+
[34.8200994167574, 31.9061345394902],
|
|
182
|
+
[34.8200994167574, 31.9106311613979],
|
|
183
|
+
[34.8099445223518, 31.9106311613979],
|
|
184
|
+
[34.8099445223518, 31.9061345394902],
|
|
185
|
+
],
|
|
186
|
+
],
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
id: '3_raster_ext',
|
|
192
|
+
type: 'XYZ_LAYER',
|
|
193
|
+
opacity: 1,
|
|
194
|
+
zIndex: 1,
|
|
195
|
+
show: false,
|
|
196
|
+
options: {
|
|
197
|
+
url:
|
|
198
|
+
'https://tiles.openaerialmap.org/5a8316e22553e6000ce5ac7f/0/c3fcbe99-d339-41b6-8ec0-33d90ccca020/{z}/{x}/{y}.png',
|
|
199
|
+
},
|
|
200
|
+
details: {
|
|
201
|
+
footprint: {
|
|
202
|
+
type: 'Polygon',
|
|
203
|
+
coordinates: [
|
|
204
|
+
[
|
|
205
|
+
[34.8106008249547, 31.9076273723004],
|
|
206
|
+
[34.8137969069015, 31.9076273723004],
|
|
207
|
+
[34.8137969069015, 31.9103791381117],
|
|
208
|
+
[34.8106008249547, 31.9103791381117],
|
|
209
|
+
[34.8106008249547, 31.9076273723004],
|
|
210
|
+
],
|
|
211
|
+
],
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
id: '4_raster1_ext',
|
|
217
|
+
type: 'XYZ_LAYER',
|
|
218
|
+
opacity: 1,
|
|
219
|
+
zIndex: 2,
|
|
220
|
+
show: false,
|
|
221
|
+
options: {
|
|
222
|
+
url:
|
|
223
|
+
'https://tiles.openaerialmap.org/5a831b4a2553e6000ce5ac80/0/d02ddc76-9c2e-4994-97d4-a623eb371456/{z}/{x}/{y}.png',
|
|
224
|
+
},
|
|
225
|
+
details: {
|
|
226
|
+
footprint: {
|
|
227
|
+
type: 'Polygon',
|
|
228
|
+
coordinates: [
|
|
229
|
+
[
|
|
230
|
+
[34.8043847068541, 31.9023297972932],
|
|
231
|
+
[34.8142791322292, 31.9023297972932],
|
|
232
|
+
[34.8142791322292, 31.9108796531516],
|
|
233
|
+
[34.8043847068541, 31.9108796531516],
|
|
234
|
+
[34.8043847068541, 31.9023297972932],
|
|
235
|
+
],
|
|
236
|
+
],
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
];
|
|
241
|
+
|
|
242
|
+
const ContextMenu: React.FC<IContextMenuData> = ({
|
|
243
|
+
data,
|
|
244
|
+
position,
|
|
245
|
+
style,
|
|
246
|
+
size,
|
|
247
|
+
handleClose,
|
|
248
|
+
}) => {
|
|
249
|
+
const layerId =
|
|
250
|
+
data[0]?.meta !== undefined
|
|
251
|
+
? ((data[0]?.meta as Record<string, unknown>).id as string)
|
|
252
|
+
: '';
|
|
253
|
+
|
|
254
|
+
const handleAction = (
|
|
255
|
+
action: string,
|
|
256
|
+
data: Record<string, unknown>[]
|
|
257
|
+
): void => {
|
|
258
|
+
console.log(`ACTION: ${action}`);
|
|
259
|
+
console.log('DATA:', data);
|
|
260
|
+
console.log('SIZE:', size);
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
const emptyStyle = {
|
|
264
|
+
left: `${position.x}px`,
|
|
265
|
+
top: `${position.y}px`,
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
return (
|
|
269
|
+
<>
|
|
270
|
+
{data.length > 0 && (
|
|
271
|
+
<Box
|
|
272
|
+
style={{
|
|
273
|
+
...emptyStyle,
|
|
274
|
+
...style,
|
|
275
|
+
background: 'var(--mdc-theme-surface)',
|
|
276
|
+
position: 'absolute',
|
|
277
|
+
borderRadius: '4px',
|
|
278
|
+
padding: '12px',
|
|
279
|
+
paddingBottom: '220px',
|
|
280
|
+
}}
|
|
281
|
+
>
|
|
282
|
+
<h4>Actions on {layerId}:</h4>
|
|
283
|
+
{data.length > 1 && (
|
|
284
|
+
<h3>
|
|
285
|
+
<span style={{ color: 'red' }}>{data.length}</span> layers
|
|
286
|
+
overlapping
|
|
287
|
+
</h3>
|
|
288
|
+
)}
|
|
289
|
+
<MenuSurfaceAnchor>
|
|
290
|
+
<Menu
|
|
291
|
+
open={true}
|
|
292
|
+
onClose={(evt): void => handleClose()}
|
|
293
|
+
style={{ width: '100%' }}
|
|
294
|
+
>
|
|
295
|
+
{['Top', 'Up', 'Down', 'Bottom'].map((action) => {
|
|
296
|
+
return (
|
|
297
|
+
<MenuItem key={`imageryMenuItemAction_${action}`}>
|
|
298
|
+
<Box
|
|
299
|
+
onClick={(evt): void => {
|
|
300
|
+
handleAction(action, data);
|
|
301
|
+
}}
|
|
302
|
+
>
|
|
303
|
+
{action}
|
|
304
|
+
</Box>
|
|
305
|
+
</MenuItem>
|
|
306
|
+
);
|
|
307
|
+
})}
|
|
308
|
+
</Menu>
|
|
309
|
+
</MenuSurfaceAnchor>
|
|
310
|
+
</Box>
|
|
311
|
+
)}
|
|
312
|
+
{data.length === 0 && (
|
|
313
|
+
<Box
|
|
314
|
+
style={{
|
|
315
|
+
...emptyStyle,
|
|
316
|
+
background: 'var(--mdc-theme-surface)',
|
|
317
|
+
position: 'absolute',
|
|
318
|
+
borderRadius: '4px',
|
|
319
|
+
padding: '12px',
|
|
320
|
+
}}
|
|
321
|
+
>
|
|
322
|
+
No data found
|
|
323
|
+
</Box>
|
|
324
|
+
)}
|
|
325
|
+
</>
|
|
326
|
+
);
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
const LayersMozaik: React.FC<ILayersMozaikProps> = (props) => {
|
|
330
|
+
const mapViewer = useCesiumMap();
|
|
331
|
+
const { layers } = props;
|
|
332
|
+
const [selectedLayer, setSelectedLayer] = useState<string>(layers[0].id);
|
|
333
|
+
const [times, setTimes] = useState<number>(1);
|
|
334
|
+
const [allShow, setAllShow] = useState<boolean>(false);
|
|
335
|
+
|
|
336
|
+
useLayoutEffect(() => {
|
|
337
|
+
const sortedLayers = layers.sort(
|
|
338
|
+
(layer1, layer2) => layer1.zIndex - layer2.zIndex
|
|
339
|
+
);
|
|
340
|
+
sortedLayers.forEach((layer, idx) => {
|
|
341
|
+
mapViewer.layersManager?.addRasterLayer(layer, idx, '');
|
|
342
|
+
});
|
|
343
|
+
}, [layers, mapViewer]);
|
|
344
|
+
|
|
345
|
+
const handleRaise = (): void => {
|
|
346
|
+
mapViewer.layersManager?.raise(selectedLayer, times);
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
const handleLower = (): void => {
|
|
350
|
+
mapViewer.layersManager?.lower(selectedLayer, times);
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
const handleRaiseToTop = (): void => {
|
|
354
|
+
mapViewer.layersManager?.raiseToTop(selectedLayer);
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
const handleLowerToBottom = (): void => {
|
|
358
|
+
mapViewer.layersManager?.lowerToBottom(selectedLayer);
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
const handleToglleAll = (): void => {
|
|
362
|
+
mapViewer.layersManager?.showAllNotBase(!allShow);
|
|
363
|
+
setAllShow(!allShow);
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
return (
|
|
367
|
+
<>
|
|
368
|
+
<select
|
|
369
|
+
defaultValue={selectedLayer}
|
|
370
|
+
onChange={(evt): void => {
|
|
371
|
+
setSelectedLayer(evt.target.value);
|
|
372
|
+
}}
|
|
373
|
+
>
|
|
374
|
+
{layers.map((layer) => (
|
|
375
|
+
<option key={layer.id} defaultValue={layer.id}>
|
|
376
|
+
{layer.id}
|
|
377
|
+
</option>
|
|
378
|
+
))}
|
|
379
|
+
</select>
|
|
380
|
+
<input
|
|
381
|
+
type="number"
|
|
382
|
+
value={times}
|
|
383
|
+
onChange={(evt): void => {
|
|
384
|
+
setTimes(parseInt(evt.target.value));
|
|
385
|
+
}}
|
|
386
|
+
></input>
|
|
387
|
+
<button
|
|
388
|
+
onClick={(): void => {
|
|
389
|
+
handleRaise();
|
|
390
|
+
}}
|
|
391
|
+
>
|
|
392
|
+
Raise
|
|
393
|
+
</button>
|
|
394
|
+
<button
|
|
395
|
+
onClick={(): void => {
|
|
396
|
+
handleLower();
|
|
397
|
+
}}
|
|
398
|
+
>
|
|
399
|
+
Lower
|
|
400
|
+
</button>
|
|
401
|
+
<button
|
|
402
|
+
onClick={(): void => {
|
|
403
|
+
handleRaiseToTop();
|
|
404
|
+
}}
|
|
405
|
+
>
|
|
406
|
+
RaiseToTop
|
|
407
|
+
</button>
|
|
408
|
+
<button
|
|
409
|
+
onClick={(): void => {
|
|
410
|
+
handleLowerToBottom();
|
|
411
|
+
}}
|
|
412
|
+
>
|
|
413
|
+
LowerToBottom
|
|
414
|
+
</button>
|
|
415
|
+
<button
|
|
416
|
+
onClick={(): void => {
|
|
417
|
+
handleToglleAll();
|
|
418
|
+
}}
|
|
419
|
+
>
|
|
420
|
+
Toggle All
|
|
421
|
+
</button>
|
|
422
|
+
</>
|
|
423
|
+
);
|
|
424
|
+
};
|
|
425
|
+
|
|
426
|
+
export const MapWithContextMenu: Story = () => {
|
|
427
|
+
const [center] = useState<[number, number]>([34.811, 31.908]);
|
|
428
|
+
return (
|
|
429
|
+
<div style={mapDivStyle}>
|
|
430
|
+
<CesiumMap
|
|
431
|
+
center={center}
|
|
432
|
+
zoom={14}
|
|
433
|
+
imageryProvider={false}
|
|
434
|
+
sceneModes={[CesiumSceneMode.SCENE3D, CesiumSceneMode.COLUMBUS_VIEW]}
|
|
435
|
+
baseMaps={BASE_MAPS}
|
|
436
|
+
// @ts-ignore
|
|
437
|
+
imageryContextMenu={<ContextMenu />}
|
|
438
|
+
imageryContextMenuSize={{ height: 340, width: 200 }}
|
|
439
|
+
>
|
|
440
|
+
<LayersMozaik layers={layers} />
|
|
441
|
+
</CesiumMap>
|
|
442
|
+
</div>
|
|
443
|
+
);
|
|
444
|
+
};
|
|
445
|
+
MapWithContextMenu.storyName = 'Map Context Menu';
|
|
@@ -6,6 +6,8 @@ import {
|
|
|
6
6
|
WebMapTileServiceImageryProvider,
|
|
7
7
|
} from 'cesium';
|
|
8
8
|
import { get } from 'lodash';
|
|
9
|
+
import { Feature, Point, Polygon } from 'geojson';
|
|
10
|
+
import booleanPointInPolygon from '@turf/boolean-point-in-polygon';
|
|
9
11
|
import {
|
|
10
12
|
RCesiumOSMLayerOptions,
|
|
11
13
|
RCesiumWMSLayerOptions,
|
|
@@ -14,6 +16,10 @@ import {
|
|
|
14
16
|
} from './layers';
|
|
15
17
|
import { CesiumViewer } from './map';
|
|
16
18
|
import { IBaseMap } from './settings/settings';
|
|
19
|
+
import { pointToGeoJSON } from './tools/geojson/point.geojson';
|
|
20
|
+
|
|
21
|
+
const INC = 1;
|
|
22
|
+
const DEC = -1;
|
|
17
23
|
|
|
18
24
|
export interface ICesiumImageryLayer extends InstanceType<typeof ImageryLayer> {
|
|
19
25
|
meta?: Record<string, unknown>;
|
|
@@ -30,6 +36,7 @@ export interface IRasterLayer {
|
|
|
30
36
|
| RCesiumWMSLayerOptions
|
|
31
37
|
| RCesiumWMTSLayerOptions
|
|
32
38
|
| RCesiumXYZLayerOptions;
|
|
39
|
+
details?: Record<string, unknown>;
|
|
33
40
|
}
|
|
34
41
|
|
|
35
42
|
export interface IVectorLayer {
|
|
@@ -150,16 +157,20 @@ class LayerManager {
|
|
|
150
157
|
|
|
151
158
|
public raise(layerId: string, positions = 1): void {
|
|
152
159
|
const layer = this.findLayerById(layerId);
|
|
160
|
+
const order = (layer?.meta as Record<string, unknown>).zIndex as number;
|
|
153
161
|
|
|
154
162
|
if (layer) {
|
|
155
163
|
for (let position = 0; position < positions; position++) {
|
|
156
164
|
this.mapViewer.imageryLayers.raise(layer);
|
|
157
165
|
}
|
|
158
166
|
}
|
|
167
|
+
|
|
168
|
+
this.updateLayersOrder(layerId, order, order + positions);
|
|
159
169
|
}
|
|
160
170
|
|
|
161
171
|
public lower(layerId: string, positions = 1): void {
|
|
162
172
|
const layer = this.findLayerById(layerId);
|
|
173
|
+
const order = (layer?.meta as Record<string, unknown>).zIndex as number;
|
|
163
174
|
const lowerLimit = this.getBaseLayersCount();
|
|
164
175
|
const layerIdx = this.mapViewer.imageryLayers.indexOf(
|
|
165
176
|
layer as ImageryLayer
|
|
@@ -174,18 +185,28 @@ class LayerManager {
|
|
|
174
185
|
this.mapViewer.imageryLayers.lower(layer);
|
|
175
186
|
}
|
|
176
187
|
}
|
|
188
|
+
|
|
189
|
+
this.updateLayersOrder(layerId, order, order - positions);
|
|
177
190
|
}
|
|
178
191
|
|
|
179
192
|
public raiseToTop(layerId: string): void {
|
|
180
193
|
const layer = this.findLayerById(layerId);
|
|
194
|
+
const order = (layer?.meta as Record<string, unknown>).zIndex as number;
|
|
181
195
|
|
|
182
196
|
if (layer) {
|
|
183
197
|
this.mapViewer.imageryLayers.raiseToTop(layer);
|
|
184
198
|
}
|
|
199
|
+
|
|
200
|
+
this.updateLayersOrder(
|
|
201
|
+
layerId,
|
|
202
|
+
order,
|
|
203
|
+
this.mapViewer.imageryLayers.length - this.getBaseLayersCount() - 1
|
|
204
|
+
);
|
|
185
205
|
}
|
|
186
206
|
|
|
187
207
|
public lowerToBottom(layerId: string): void {
|
|
188
208
|
const layer = this.findLayerById(layerId);
|
|
209
|
+
// const order = (layer?.meta as Record<string, unknown>).zIndex as number;
|
|
189
210
|
const lowerLimit = this.getBaseLayersCount();
|
|
190
211
|
const layerIdx = this.mapViewer.imageryLayers.indexOf(
|
|
191
212
|
layer as ImageryLayer
|
|
@@ -195,6 +216,8 @@ class LayerManager {
|
|
|
195
216
|
// if (layer) {
|
|
196
217
|
// this.mapViewer.imageryLayers.lowerToBottom(layer);
|
|
197
218
|
// }
|
|
219
|
+
|
|
220
|
+
// this.updateLayersOrder(layerId, order, 0);
|
|
198
221
|
}
|
|
199
222
|
|
|
200
223
|
public length(): number {
|
|
@@ -228,6 +251,40 @@ class LayerManager {
|
|
|
228
251
|
return layerIdx ? this.mapViewer.imageryLayers.get(layerIdx) : undefined;
|
|
229
252
|
}
|
|
230
253
|
|
|
254
|
+
public findLayerByPOI(
|
|
255
|
+
x: number,
|
|
256
|
+
y: number
|
|
257
|
+
): ICesiumImageryLayer[] | undefined {
|
|
258
|
+
const position = pointToGeoJSON(this.mapViewer, x, y) as Feature<Point>;
|
|
259
|
+
|
|
260
|
+
const nonBaseLayers = this.layers.filter((layer) => {
|
|
261
|
+
const parentId = get(layer.meta, 'parentBasetMapId') as string;
|
|
262
|
+
return parentId ? false : true;
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
const selectedVisibleLayers = nonBaseLayers.filter((layer) => {
|
|
266
|
+
const layerFootprint = get(layer.meta, 'details.footprint') as
|
|
267
|
+
| Polygon
|
|
268
|
+
| undefined;
|
|
269
|
+
if (layerFootprint !== undefined) {
|
|
270
|
+
const isInLayer = booleanPointInPolygon(position.geometry, {
|
|
271
|
+
type: 'Feature',
|
|
272
|
+
properties: {},
|
|
273
|
+
geometry: layerFootprint,
|
|
274
|
+
});
|
|
275
|
+
return isInLayer && layer.show;
|
|
276
|
+
} else {
|
|
277
|
+
console.warn('CesiumImageryLayer has no defined footprint', layer.meta);
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
return selectedVisibleLayers.sort((layer1, layer2) => {
|
|
283
|
+
// @ts-ignore
|
|
284
|
+
return layer2.meta?.zIndex - layer1.meta?.zIndex;
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
|
|
231
288
|
private getBaseLayersCount(): number {
|
|
232
289
|
const baseLayers = this.layers.filter((layer) => {
|
|
233
290
|
const parentId = get(layer.meta, 'parentBasetMapId') as string;
|
|
@@ -242,6 +299,25 @@ class LayerManager {
|
|
|
242
299
|
return layer.meta !== undefined ? layer.meta.id === layerId : false;
|
|
243
300
|
});
|
|
244
301
|
}
|
|
302
|
+
|
|
303
|
+
private updateLayersOrder(id: string, from: number, to: number): void {
|
|
304
|
+
const move = from > to ? INC : DEC;
|
|
305
|
+
const min = from < to ? from : to;
|
|
306
|
+
const max = from < to ? to : from;
|
|
307
|
+
|
|
308
|
+
this.layers.forEach((layer) => {
|
|
309
|
+
const parentId = get(layer.meta, 'parentBasetMapId') as string;
|
|
310
|
+
if (!parentId) {
|
|
311
|
+
const layerOrder = layer.meta?.zIndex as number;
|
|
312
|
+
(layer.meta as Record<string, unknown>).zIndex =
|
|
313
|
+
layerOrder >= min && layerOrder <= max && layerOrder !== from
|
|
314
|
+
? layerOrder + move
|
|
315
|
+
: layerOrder === from
|
|
316
|
+
? to
|
|
317
|
+
: layerOrder;
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
}
|
|
245
321
|
}
|
|
246
322
|
|
|
247
323
|
export default LayerManager;
|