@map-colonies/react-components 3.11.0 → 3.12.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 +26 -0
- package/dist/cesium-map/layers/imagery.layer.js +9 -5
- package/dist/cesium-map/layers-manager.d.ts +10 -2
- package/dist/cesium-map/layers-manager.js +19 -1
- package/dist/cesium-map/map-legend/MapLegend.css +135 -0
- package/dist/cesium-map/map-legend/MapLegend.d.ts +15 -0
- package/dist/cesium-map/map-legend/MapLegend.js +57 -0
- package/dist/cesium-map/map-legend/MapLegendList.d.ts +13 -0
- package/dist/cesium-map/map-legend/MapLegendList.js +43 -0
- package/dist/cesium-map/map-legend/MapLegendSidebar.d.ts +16 -0
- package/dist/cesium-map/map-legend/MapLegendSidebar.js +20 -0
- package/dist/cesium-map/map-legend/MapLegendToggle.d.ts +7 -0
- package/dist/cesium-map/map-legend/MapLegendToggle.js +20 -0
- package/dist/cesium-map/map-legend/index.d.ts +3 -0
- package/dist/cesium-map/map-legend/index.js +14 -0
- package/dist/cesium-map/map.css +6 -1
- package/dist/cesium-map/map.d.ts +16 -1
- package/dist/cesium-map/map.js +51 -21
- package/dist/cesium-map/settings/settings.css +5 -2
- package/package.json +3 -3
- package/src/lib/cesium-map/layers/imagery.layer.tsx +12 -7
- package/src/lib/cesium-map/layers-manager.ts +35 -2
- package/src/lib/cesium-map/map-legend/MapLegend.css +135 -0
- package/src/lib/cesium-map/map-legend/MapLegend.tsx +91 -0
- package/src/lib/cesium-map/map-legend/MapLegendList.tsx +46 -0
- package/src/lib/cesium-map/map-legend/MapLegendSidebar.tsx +55 -0
- package/src/lib/cesium-map/map-legend/MapLegendToggle.tsx +31 -0
- package/src/lib/cesium-map/map-legend/index.tsx +3 -0
- package/src/lib/cesium-map/map-legend/legends-sidebar.stories.tsx +201 -0
- package/src/lib/cesium-map/map.css +6 -1
- package/src/lib/cesium-map/map.tsx +86 -20
- package/src/lib/cesium-map/settings/settings.css +5 -2
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { Story, Meta } from '@storybook/react/types-6-0';
|
|
3
|
+
import { CesiumMap } from '../map';
|
|
4
|
+
import { CesiumXYZLayer } from '../layers/xyz.layer';
|
|
5
|
+
import { CesiumSceneMode } from '../map.types';
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
title: 'Cesium Map',
|
|
9
|
+
component: CesiumMap,
|
|
10
|
+
parameters: {
|
|
11
|
+
layout: 'fullscreen',
|
|
12
|
+
},
|
|
13
|
+
} as Meta;
|
|
14
|
+
|
|
15
|
+
const mapDivStyle = {
|
|
16
|
+
height: '100%',
|
|
17
|
+
width: '100%',
|
|
18
|
+
position: 'absolute' as const,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const optionsXYZSanDiego = {
|
|
22
|
+
url:
|
|
23
|
+
'https://tiles.openaerialmap.org/5d73614588556200055f10d6/0/5d73614588556200055f10d7/{z}/{x}/{y}',
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const BASE_MAPS = {
|
|
27
|
+
maps: [
|
|
28
|
+
{
|
|
29
|
+
id: '1st',
|
|
30
|
+
title: '1st Map Title',
|
|
31
|
+
isCurrent: true,
|
|
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
|
+
thumbnail:
|
|
69
|
+
'https://nsw.digitaltwin.terria.io/build/efa2f6c408eb790753a9b5fb2f3dc678.png',
|
|
70
|
+
baseRasteLayers: [
|
|
71
|
+
{
|
|
72
|
+
id: 'RADAR_RASTER',
|
|
73
|
+
type: 'WMS_LAYER',
|
|
74
|
+
opacity: 0.6,
|
|
75
|
+
zIndex: 1,
|
|
76
|
+
options: {
|
|
77
|
+
url:
|
|
78
|
+
'https://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi?',
|
|
79
|
+
layers: 'nexrad-n0r',
|
|
80
|
+
credit: 'Radar data courtesy Iowa Environmental Mesonet',
|
|
81
|
+
parameters: {
|
|
82
|
+
transparent: 'true',
|
|
83
|
+
format: 'image/png',
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
id: 'GOOGLE_TERRAIN',
|
|
89
|
+
type: 'XYZ_LAYER',
|
|
90
|
+
opacity: 1,
|
|
91
|
+
zIndex: 0,
|
|
92
|
+
options: {
|
|
93
|
+
url: 'https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}',
|
|
94
|
+
layers: '',
|
|
95
|
+
credit: 'GOOGLE',
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
id: 'VECTOR_TILES_GPS',
|
|
100
|
+
type: 'XYZ_LAYER',
|
|
101
|
+
opacity: 1,
|
|
102
|
+
zIndex: 2,
|
|
103
|
+
options: {
|
|
104
|
+
url: 'https://gps.tile.openstreetmap.org/lines/{z}/{x}/{y}.png',
|
|
105
|
+
layers: '',
|
|
106
|
+
credit: 'openstreetmap',
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
baseVectorLayers: [],
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
id: '3rd',
|
|
114
|
+
title: '3rd Map Title',
|
|
115
|
+
thumbnail:
|
|
116
|
+
'https://nsw.digitaltwin.terria.io/build/d8b97d3e38a0d43e5a06dea9aae17a3e.png',
|
|
117
|
+
baseRasteLayers: [
|
|
118
|
+
{
|
|
119
|
+
id: 'VECTOR_TILES',
|
|
120
|
+
type: 'XYZ_LAYER',
|
|
121
|
+
opacity: 1,
|
|
122
|
+
zIndex: 0,
|
|
123
|
+
options: {
|
|
124
|
+
url:
|
|
125
|
+
'https://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png?apikey=6170aad10dfd42a38d4d8c709a536f38',
|
|
126
|
+
layers: '',
|
|
127
|
+
credit: 'thunderforest',
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
id: 'VECTOR_TILES_GPS',
|
|
132
|
+
type: 'XYZ_LAYER',
|
|
133
|
+
opacity: 1,
|
|
134
|
+
zIndex: 1,
|
|
135
|
+
options: {
|
|
136
|
+
url: 'https://gps.tile.openstreetmap.org/lines/{z}/{x}/{y}.png',
|
|
137
|
+
layers: '',
|
|
138
|
+
credit: 'openstreetmap',
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
id: 'WMTS_POPULATION_TILES',
|
|
143
|
+
type: 'WMTS_LAYER',
|
|
144
|
+
opacity: 0.4,
|
|
145
|
+
zIndex: 2,
|
|
146
|
+
options: {
|
|
147
|
+
url:
|
|
148
|
+
'https://services.arcgisonline.com/arcgis/rest/services/Demographics/USA_Population_Density/MapServer/WMTS/',
|
|
149
|
+
layer: 'USGSShadedReliefOnly',
|
|
150
|
+
style: 'default',
|
|
151
|
+
format: 'image/jpeg',
|
|
152
|
+
tileMatrixSetID: 'default028mm',
|
|
153
|
+
maximumLevel: 19,
|
|
154
|
+
credit: 'U. S. Geological Survey',
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
baseVectorLayers: [],
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
export const MapWithLegends: Story = () => {
|
|
164
|
+
const [center] = useState<[number, number]>([
|
|
165
|
+
-117.30644008676421,
|
|
166
|
+
33.117098433617564,
|
|
167
|
+
]); //Sandiego Poinsettia Park
|
|
168
|
+
return (
|
|
169
|
+
<div style={mapDivStyle}>
|
|
170
|
+
<CesiumMap
|
|
171
|
+
center={center}
|
|
172
|
+
zoom={14}
|
|
173
|
+
imageryProvider={false}
|
|
174
|
+
sceneModes={[CesiumSceneMode.SCENE3D, CesiumSceneMode.COLUMBUS_VIEW]}
|
|
175
|
+
// @ts-ignore
|
|
176
|
+
baseMaps={BASE_MAPS}
|
|
177
|
+
legends={{
|
|
178
|
+
legendsList: [
|
|
179
|
+
{
|
|
180
|
+
layer: 'bluemarble',
|
|
181
|
+
legendImg:
|
|
182
|
+
'https://c8.alamy.com/comp/F5HF5D/map-icon-legend-symbol-sign-toolkit-element-F5HF5D.jpg',
|
|
183
|
+
legendDoc: 'http://www.africau.edu/images/default/sample.pdf',
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
layer: 'bluemarble2',
|
|
187
|
+
legendImg:
|
|
188
|
+
'https://i.pinimg.com/564x/55/cf/a1/55cfa147dfef99d231ec95ab8cd3652d--outdoor-code-cub-scouts-brownie-hiking-badge.jpg',
|
|
189
|
+
legendDoc: 'http://www.africau.edu/images/default/sample.pdf',
|
|
190
|
+
},
|
|
191
|
+
],
|
|
192
|
+
title: 'Map Legends',
|
|
193
|
+
emptyText: 'No legends for this basemap',
|
|
194
|
+
}}
|
|
195
|
+
>
|
|
196
|
+
<CesiumXYZLayer options={optionsXYZSanDiego} />
|
|
197
|
+
</CesiumMap>
|
|
198
|
+
</div>
|
|
199
|
+
);
|
|
200
|
+
};
|
|
201
|
+
MapWithLegends.storyName = 'Map with legends sidebar';
|
|
@@ -40,7 +40,7 @@ body[dir='rtl'] .toolsContainer {
|
|
|
40
40
|
|
|
41
41
|
.sideToolsContainer {
|
|
42
42
|
display: flex;
|
|
43
|
-
flex-direction:
|
|
43
|
+
flex-direction: row;
|
|
44
44
|
gap: 8px;
|
|
45
45
|
z-index: 2000;
|
|
46
46
|
position: absolute;
|
|
@@ -52,3 +52,8 @@ body[dir='rtl'] .sideToolsContainer {
|
|
|
52
52
|
left: 40px;
|
|
53
53
|
right: unset;
|
|
54
54
|
}
|
|
55
|
+
|
|
56
|
+
.viewer {
|
|
57
|
+
display: flex;
|
|
58
|
+
flex-direction: row;
|
|
59
|
+
}
|
|
@@ -4,7 +4,9 @@ import React, {
|
|
|
4
4
|
useEffect,
|
|
5
5
|
useState,
|
|
6
6
|
useRef,
|
|
7
|
+
useCallback,
|
|
7
8
|
} from 'react';
|
|
9
|
+
import { createPortal } from 'react-dom';
|
|
8
10
|
import { Viewer, CesiumComponentRef } from 'resium';
|
|
9
11
|
import { ViewerProps } from 'resium/dist/types/src/Viewer/Viewer';
|
|
10
12
|
import {
|
|
@@ -26,7 +28,8 @@ import { Proj } from '../utils/projections';
|
|
|
26
28
|
import { CoordinatesTrackerTool } from './tools/coordinates-tracker.tool';
|
|
27
29
|
import { ScaleTrackerTool } from './tools/scale-tracker.tool';
|
|
28
30
|
import { CesiumSettings, IBaseMap, IBaseMaps } from './settings/settings';
|
|
29
|
-
import
|
|
31
|
+
import { IMapLegend, MapLegendSidebar, MapLegendToggle } from './map-legend';
|
|
32
|
+
import LayerManager, { LegendExtractor } from './layers-manager';
|
|
30
33
|
import { CesiumSceneMode, CesiumSceneModeEnum } from './map.types';
|
|
31
34
|
|
|
32
35
|
import './map.css';
|
|
@@ -80,6 +83,14 @@ export interface IContextMenuData {
|
|
|
80
83
|
handleClose: () => void;
|
|
81
84
|
}
|
|
82
85
|
|
|
86
|
+
interface ILegends {
|
|
87
|
+
legendsList?: IMapLegend[];
|
|
88
|
+
emptyText?: string;
|
|
89
|
+
title?: string;
|
|
90
|
+
actionsTexts?: { docText: string; imgText: string };
|
|
91
|
+
mapLegendsExtractor?: LegendExtractor;
|
|
92
|
+
}
|
|
93
|
+
|
|
83
94
|
export interface CesiumMapProps extends ViewerProps {
|
|
84
95
|
showMousePosition?: boolean;
|
|
85
96
|
showScale?: boolean;
|
|
@@ -96,6 +107,9 @@ export interface CesiumMapProps extends ViewerProps {
|
|
|
96
107
|
width: number;
|
|
97
108
|
dynamicHeightIncrement?: number;
|
|
98
109
|
};
|
|
110
|
+
legendSidebarTitle?: string;
|
|
111
|
+
noLegendsText?: string;
|
|
112
|
+
legends?: ILegends;
|
|
99
113
|
}
|
|
100
114
|
|
|
101
115
|
export const useCesiumMap = (): CesiumViewer => {
|
|
@@ -119,11 +133,15 @@ export const CesiumMap: React.FC<CesiumMapProps> = (props) => {
|
|
|
119
133
|
const [sceneModes, setSceneModes] = useState<
|
|
120
134
|
CesiumSceneModeEnum[] | undefined
|
|
121
135
|
>();
|
|
136
|
+
const [legendsList, setLegendsList] = useState<IMapLegend[]>([]);
|
|
122
137
|
const [baseMaps, setBaseMaps] = useState<IBaseMaps | undefined>();
|
|
123
138
|
const [showImageryMenu, setShowImageryMenu] = useState<boolean>(false);
|
|
124
139
|
const [imageryMenuPosition, setImageryMenuPosition] = useState<
|
|
125
140
|
Record<string, unknown> | undefined
|
|
126
141
|
>(undefined);
|
|
142
|
+
const [isLegendsSidebarOpen, setIsLegendsSidebarOpen] = useState<boolean>(
|
|
143
|
+
false
|
|
144
|
+
);
|
|
127
145
|
|
|
128
146
|
const viewerProps = {
|
|
129
147
|
fullscreenButton: true,
|
|
@@ -163,7 +181,7 @@ export const CesiumMap: React.FC<CesiumMapProps> = (props) => {
|
|
|
163
181
|
useEffect(() => {
|
|
164
182
|
if (ref.current) {
|
|
165
183
|
const viewer = ref.current.cesiumElement as CesiumViewer;
|
|
166
|
-
|
|
184
|
+
|
|
167
185
|
if (props.imageryContextMenu) {
|
|
168
186
|
viewer.screenSpaceEventHandler.setInputAction(
|
|
169
187
|
(evt: Record<string, unknown>) => {
|
|
@@ -179,6 +197,20 @@ export const CesiumMap: React.FC<CesiumMapProps> = (props) => {
|
|
|
179
197
|
setMapViewRef(ref.current?.cesiumElement);
|
|
180
198
|
}, [ref, props.imageryContextMenu]);
|
|
181
199
|
|
|
200
|
+
useEffect(() => {
|
|
201
|
+
if (mapViewRef) {
|
|
202
|
+
mapViewRef.layersManager = new LayerManager(
|
|
203
|
+
mapViewRef,
|
|
204
|
+
props.legends?.mapLegendsExtractor,
|
|
205
|
+
() => {
|
|
206
|
+
setLegendsList(
|
|
207
|
+
mapViewRef?.layersManager?.legendsList as IMapLegend[]
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
}, [mapViewRef]);
|
|
213
|
+
|
|
182
214
|
useEffect(() => {
|
|
183
215
|
setSceneModes(
|
|
184
216
|
props.sceneModes ?? [
|
|
@@ -326,27 +358,61 @@ export const CesiumMap: React.FC<CesiumMapProps> = (props) => {
|
|
|
326
358
|
}
|
|
327
359
|
}, [props.zoom, props.center, mapViewRef]);
|
|
328
360
|
|
|
361
|
+
const bindCustomToolsToViewer = useCallback((): JSX.Element | undefined => {
|
|
362
|
+
return (
|
|
363
|
+
mapViewRef &&
|
|
364
|
+
createPortal(
|
|
365
|
+
<>
|
|
366
|
+
<Box className="sideToolsContainer">
|
|
367
|
+
<CesiumSettings
|
|
368
|
+
sceneModes={sceneModes as CesiumSceneModeEnum[]}
|
|
369
|
+
baseMaps={baseMaps}
|
|
370
|
+
locale={locale}
|
|
371
|
+
/>
|
|
372
|
+
<MapLegendToggle
|
|
373
|
+
onClick={() => setIsLegendsSidebarOpen(!isLegendsSidebarOpen)}
|
|
374
|
+
/>
|
|
375
|
+
</Box>
|
|
376
|
+
<Box className="toolsContainer">
|
|
377
|
+
{showMousePosition === true ? (
|
|
378
|
+
<CoordinatesTrackerTool
|
|
379
|
+
projection={projection}
|
|
380
|
+
></CoordinatesTrackerTool>
|
|
381
|
+
) : (
|
|
382
|
+
<></>
|
|
383
|
+
)}
|
|
384
|
+
{showScale === true ? <ScaleTrackerTool locale={locale} /> : <></>}
|
|
385
|
+
</Box>
|
|
386
|
+
</>,
|
|
387
|
+
document.querySelector('.cesium-viewer') as Element
|
|
388
|
+
)
|
|
389
|
+
);
|
|
390
|
+
}, [
|
|
391
|
+
baseMaps,
|
|
392
|
+
locale,
|
|
393
|
+
mapViewRef,
|
|
394
|
+
projection,
|
|
395
|
+
sceneModes,
|
|
396
|
+
showMousePosition,
|
|
397
|
+
showScale,
|
|
398
|
+
isLegendsSidebarOpen,
|
|
399
|
+
]);
|
|
400
|
+
|
|
329
401
|
return (
|
|
330
|
-
<Viewer full ref={ref} {...viewerProps}>
|
|
402
|
+
<Viewer className="viewer" full ref={ref} {...viewerProps}>
|
|
331
403
|
<MapViewProvider value={mapViewRef as CesiumViewer}>
|
|
404
|
+
<MapLegendSidebar
|
|
405
|
+
title={props.legends?.title}
|
|
406
|
+
isOpen={isLegendsSidebarOpen}
|
|
407
|
+
toggleSidebar={(): void =>
|
|
408
|
+
setIsLegendsSidebarOpen(!isLegendsSidebarOpen)
|
|
409
|
+
}
|
|
410
|
+
noLegendsText={props.legends?.emptyText}
|
|
411
|
+
legends={props.legends?.legendsList ?? legendsList}
|
|
412
|
+
actionsTexts={props.legends?.actionsTexts}
|
|
413
|
+
/>
|
|
332
414
|
{props.children}
|
|
333
|
-
|
|
334
|
-
<CesiumSettings
|
|
335
|
-
sceneModes={sceneModes as CesiumSceneModeEnum[]}
|
|
336
|
-
baseMaps={baseMaps}
|
|
337
|
-
locale={locale}
|
|
338
|
-
/>
|
|
339
|
-
</Box>
|
|
340
|
-
<Box className="toolsContainer">
|
|
341
|
-
{showMousePosition === true ? (
|
|
342
|
-
<CoordinatesTrackerTool
|
|
343
|
-
projection={projection}
|
|
344
|
-
></CoordinatesTrackerTool>
|
|
345
|
-
) : (
|
|
346
|
-
<></>
|
|
347
|
-
)}
|
|
348
|
-
{showScale === true ? <ScaleTrackerTool locale={locale} /> : <></>}
|
|
349
|
-
</Box>
|
|
415
|
+
{bindCustomToolsToViewer()}
|
|
350
416
|
{props.imageryContextMenu &&
|
|
351
417
|
showImageryMenu &&
|
|
352
418
|
imageryMenuPosition &&
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
gap: 8px;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
-
.settingsIconContainer
|
|
6
|
+
.settingsIconContainer,
|
|
7
|
+
.mapLegendToggleContainer {
|
|
7
8
|
fill: #fff;
|
|
8
9
|
width: 40px;
|
|
9
10
|
height: 40px;
|
|
@@ -12,7 +13,8 @@
|
|
|
12
13
|
border-radius: 4px;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
.settingsIconContainer:hover
|
|
16
|
+
.settingsIconContainer:hover,
|
|
17
|
+
.mapLegendToggleContainer:hover {
|
|
16
18
|
background: #48b;
|
|
17
19
|
border-color: #aef;
|
|
18
20
|
}
|
|
@@ -35,6 +37,7 @@
|
|
|
35
37
|
.settingsDialogPortal .mdc-dialog__container {
|
|
36
38
|
align-items: unset;
|
|
37
39
|
}
|
|
40
|
+
|
|
38
41
|
.settingsDialogPortal .mdc-dialog .mdc-dialog__surface {
|
|
39
42
|
max-height: unset;
|
|
40
43
|
}
|