@map-colonies/react-components 3.10.4 → 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.
Files changed (53) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/dist/cesium-map/layers/3d.tileset.js +11 -7
  3. package/dist/cesium-map/layers/3d.tileset.with.update.d.ts +6 -0
  4. package/dist/cesium-map/layers/3d.tileset.with.update.js +115 -0
  5. package/dist/cesium-map/layers/imagery.layer.js +9 -5
  6. package/dist/cesium-map/layers-manager.d.ts +10 -2
  7. package/dist/cesium-map/layers-manager.js +19 -1
  8. package/dist/cesium-map/map-legend/MapLegend.css +135 -0
  9. package/dist/cesium-map/map-legend/MapLegend.d.ts +15 -0
  10. package/dist/cesium-map/map-legend/MapLegend.js +57 -0
  11. package/dist/cesium-map/map-legend/MapLegendList.d.ts +13 -0
  12. package/dist/cesium-map/map-legend/MapLegendList.js +43 -0
  13. package/dist/cesium-map/map-legend/MapLegendSidebar.d.ts +16 -0
  14. package/dist/cesium-map/map-legend/MapLegendSidebar.js +20 -0
  15. package/dist/cesium-map/map-legend/MapLegendToggle.d.ts +7 -0
  16. package/dist/cesium-map/map-legend/MapLegendToggle.js +20 -0
  17. package/dist/cesium-map/map-legend/index.d.ts +3 -0
  18. package/dist/cesium-map/map-legend/index.js +14 -0
  19. package/dist/cesium-map/map.css +6 -1
  20. package/dist/cesium-map/map.d.ts +16 -1
  21. package/dist/cesium-map/map.js +51 -21
  22. package/dist/cesium-map/settings/settings.css +5 -2
  23. package/dist/cesium-map/tools/terranian-height.tool.js +1 -0
  24. package/dist/file-picker/file-picker.css +2 -1
  25. package/package.json +3 -3
  26. package/src/lib/cesium-map/layers/3d.tileset.stories.tsx +60 -6
  27. package/src/lib/cesium-map/layers/3d.tileset.tsx +13 -9
  28. package/src/lib/cesium-map/layers/3d.tileset.with.update.tsx +120 -0
  29. package/src/lib/cesium-map/layers/imagery.layer.tsx +12 -7
  30. package/src/lib/cesium-map/layers-manager.ts +35 -2
  31. package/src/lib/cesium-map/map-legend/MapLegend.css +135 -0
  32. package/src/lib/cesium-map/map-legend/MapLegend.tsx +91 -0
  33. package/src/lib/cesium-map/map-legend/MapLegendList.tsx +46 -0
  34. package/src/lib/cesium-map/map-legend/MapLegendSidebar.tsx +55 -0
  35. package/src/lib/cesium-map/map-legend/MapLegendToggle.tsx +31 -0
  36. package/src/lib/cesium-map/map-legend/index.tsx +3 -0
  37. package/src/lib/cesium-map/map-legend/legends-sidebar.stories.tsx +201 -0
  38. package/src/lib/cesium-map/map.css +6 -1
  39. package/src/lib/cesium-map/map.tsx +86 -20
  40. package/src/lib/cesium-map/settings/settings.css +5 -2
  41. package/src/lib/cesium-map/terrain-providers/terrain-provider-heights-tool.stories.tsx +41 -26
  42. package/src/lib/cesium-map/terrain-providers/terrain-provider.stories.tsx +3 -1
  43. package/src/lib/cesium-map/tools/terranian-height.tool.tsx +4 -0
  44. package/src/lib/file-picker/file-picker.css +2 -1
  45. package/dist/cesium-map/layers/3d.tileset.update.d.ts +0 -1
  46. package/dist/cesium-map/layers/3d.tileset.update.js +0 -5
  47. package/src/lib/cesium-map/layers/3d.tileset.update.ts +0 -72
  48. package/storybook-static/mock/tileset_1/ll.b3dm +0 -0
  49. package/storybook-static/mock/tileset_1/lr.b3dm +0 -0
  50. package/storybook-static/mock/tileset_1/parent.b3dm +0 -0
  51. package/storybook-static/mock/tileset_1/tileset.json +0 -124
  52. package/storybook-static/mock/tileset_1/ul.b3dm +0 -0
  53. package/storybook-static/mock/tileset_1/ur.b3dm +0 -0
@@ -4,6 +4,7 @@ import {
4
4
  UrlTemplateImageryProvider,
5
5
  WebMapServiceImageryProvider,
6
6
  WebMapTileServiceImageryProvider,
7
+ Event,
7
8
  } from 'cesium';
8
9
  import { get } from 'lodash';
9
10
  import { Feature, Point, Polygon } from 'geojson';
@@ -17,6 +18,7 @@ import {
17
18
  import { CesiumViewer } from './map';
18
19
  import { IBaseMap } from './settings/settings';
19
20
  import { pointToGeoJSON } from './tools/geojson/point.geojson';
21
+ import { IMapLegend } from './map-legend';
20
22
 
21
23
  const INC = 1;
22
24
  const DEC = -1;
@@ -48,15 +50,38 @@ export interface IVectorLayer {
48
50
  url: string;
49
51
  }
50
52
 
53
+ export type LegendExtractor = (
54
+ layers: (any & {
55
+ meta: any;
56
+ })[]
57
+ ) => IMapLegend[];
51
58
  class LayerManager {
52
59
  public mapViewer: CesiumViewer;
53
60
 
54
61
  private readonly layers: ICesiumImageryLayer[];
55
-
56
- public constructor(mapViewer: CesiumViewer) {
62
+ public legendsList: IMapLegend[];
63
+ public layerUpdated: Event;
64
+ private readonly legendsExtractor?: LegendExtractor;
65
+
66
+ public constructor(
67
+ mapViewer: CesiumViewer,
68
+ legendsExtractor?: LegendExtractor,
69
+ onLayersUpdate?: () => void
70
+ ) {
57
71
  this.mapViewer = mapViewer;
58
72
  // eslint-disable-next-line
59
73
  this.layers = (this.mapViewer.imageryLayers as any)._layers;
74
+ this.legendsList = [];
75
+ this.legendsExtractor = legendsExtractor;
76
+ this.layerUpdated = new Event();
77
+ if (onLayersUpdate) {
78
+ this.layerUpdated.addEventListener(onLayersUpdate, this);
79
+ }
80
+
81
+ this.mapViewer.imageryLayers.layerRemoved.addEventListener(() => {
82
+ this.setLegends();
83
+ this.layerUpdated.raiseEvent();
84
+ });
60
85
  }
61
86
 
62
87
  /* eslint-disable */
@@ -67,6 +92,8 @@ class LayerManager {
67
92
  const layer = this.layers.find(layerPredicate);
68
93
  if (layer) {
69
94
  layer.meta = meta;
95
+ this.setLegends();
96
+ this.layerUpdated.raiseEvent();
70
97
  }
71
98
  }
72
99
  /* eslint-enable */
@@ -287,6 +314,12 @@ class LayerManager {
287
314
  });
288
315
  }
289
316
 
317
+ private setLegends(): void {
318
+ if (typeof this.legendsExtractor !== 'undefined') {
319
+ this.legendsList = this.legendsExtractor(this.layers);
320
+ }
321
+ }
322
+
290
323
  private getBaseLayersCount(): number {
291
324
  const baseLayers = this.layers.filter((layer) => {
292
325
  const parentId = get(layer.meta, 'parentBasetMapId') as string;
@@ -0,0 +1,135 @@
1
+ .mapLegendSidebarContainer {
2
+ width: 340px;
3
+ height: 100%;
4
+ position: relative;
5
+ overflow-y: auto;
6
+ overflow-x: hidden;
7
+ font-size: 16px;
8
+ }
9
+
10
+ /* Disable drawer animation */
11
+
12
+ .mapLegendSidebarContainer.mdc-drawer--animate {
13
+ transform: translateX(0) !important;
14
+ transition: none !important;
15
+ }
16
+
17
+ .mapLegendSidebarContainer.mdc-drawer--dismissible {
18
+ position: relative;
19
+ }
20
+
21
+ div.MuiPaper-root {
22
+ transition: none !important;
23
+ }
24
+
25
+ .mapLegendCloseBtn {
26
+ position: absolute;
27
+ top: 0;
28
+ right: 0;
29
+ cursor: pointer;
30
+ width: 50px;
31
+ height: 50px;
32
+ padding: 20px;
33
+ font-size: 24px;
34
+ }
35
+
36
+ body[dir='rtl'] .mapLegendCloseBtn {
37
+ right: unset;
38
+ left: 0;
39
+ }
40
+
41
+ .mapLegendToggleContainer {
42
+ display: flex;
43
+ align-items: center;
44
+ justify-content: center;
45
+ }
46
+
47
+ .mapLegendIcon {
48
+ width: 2.5rem;
49
+ height: 2.5rem;
50
+ }
51
+
52
+ .sidebarHeaderContainer {
53
+ text-align: center;
54
+ margin-top: 40px;
55
+ }
56
+
57
+ .sidebarTitle {
58
+ font-size: 1.5rem;
59
+ font-weight: bold;
60
+ }
61
+
62
+ .mapLegend {
63
+ display: flex;
64
+ flex-direction: column;
65
+ align-items: center;
66
+ justify-content: center;
67
+ gap: 4px;
68
+ padding: 10px 14px;
69
+ }
70
+
71
+ .layerNameContainer {
72
+ width: 90%;
73
+ display: flex;
74
+ justify-content: center;
75
+ align-items: center;
76
+ }
77
+
78
+ .layerName {
79
+ overflow: hidden;
80
+ text-overflow: ellipsis;
81
+ white-space: nowrap;
82
+ }
83
+
84
+ .legendImg {
85
+ width: 90%;
86
+ height: 150px;
87
+ border: 1px solid black;
88
+ border-radius: 5px;
89
+ object-fit: cover;
90
+ cursor: pointer;
91
+ }
92
+
93
+ .legendActionsContainer {
94
+ display: flex;
95
+ flex-direction: row;
96
+ align-self: center;
97
+ }
98
+
99
+ .legendAction:not(:last-child)::after {
100
+ content: '|';
101
+ margin: 0px 4px;
102
+ }
103
+
104
+ .mapLegendsList {
105
+ display: flex;
106
+ flex-direction: column;
107
+ padding: 20px 0px;
108
+ width: 100%;
109
+ height: 90%;
110
+ }
111
+
112
+ .legendAction {
113
+ text-decoration: underline;
114
+ cursor: pointer;
115
+ font-size: 1.1rem;
116
+ transition: all 0.1s ease-in-out;
117
+ width: max-content;
118
+ }
119
+
120
+ .legendAction:hover {
121
+ filter: brightness(1.2);
122
+ }
123
+
124
+ .noLegendsContainer {
125
+ width: 100%;
126
+ height: 100%;
127
+ display: flex;
128
+ flex-direction: column;
129
+ justify-content: center;
130
+ align-items: center;
131
+ }
132
+
133
+ .noLegendsMsg {
134
+ text-align: center;
135
+ }
@@ -0,0 +1,91 @@
1
+ import { Tooltip } from '@map-colonies/react-core';
2
+ import React, { useCallback } from 'react';
3
+ import { Box } from '../../box';
4
+ import './MapLegend.css';
5
+
6
+ export interface IMapLegend {
7
+ layer?: string;
8
+ legendDoc?: string;
9
+ legendImg?: string;
10
+ legend?: Record<string, unknown>[];
11
+ }
12
+ interface MapLegendProps {
13
+ legend: IMapLegend;
14
+ docText?: string;
15
+ imgText?: string;
16
+ }
17
+
18
+ export const MapLegend: React.FC<MapLegendProps> = ({
19
+ legend: { legendImg, legendDoc, layer },
20
+ docText,
21
+ imgText,
22
+ }) => {
23
+ const handleLegendImgOpen = useCallback(() => {
24
+ // Open image in a new tab.
25
+ window.open(legendImg, '_blank');
26
+ }, [legendImg]);
27
+
28
+ const handleLegendDocOpen = useCallback(() => {
29
+ // Open doc in a new tab.
30
+ window.open(legendDoc, '_blank');
31
+ }, [legendDoc]);
32
+
33
+ const renderLayerName = useCallback(() => {
34
+ const MAX_LAYER_NAME_LENGTH = 15;
35
+
36
+ const layerNameContainer = (
37
+ <Box className="layerNameContainer">
38
+ <h3
39
+ style={{ maxWidth: `${MAX_LAYER_NAME_LENGTH}ch` }}
40
+ className="layerName"
41
+ >
42
+ {layer}
43
+ </h3>
44
+ </Box>
45
+ );
46
+
47
+ if ((layer ?? '').length > MAX_LAYER_NAME_LENGTH) {
48
+ return <Tooltip content={layer}>{layerNameContainer}</Tooltip>;
49
+ }
50
+
51
+ return layerNameContainer;
52
+ }, [layer]);
53
+
54
+ const renderLinks = useCallback(() => {
55
+ return [
56
+ typeof legendImg === 'string' && (
57
+ <a
58
+ className="legendAction"
59
+ href={legendImg}
60
+ target="_blank"
61
+ referrerPolicy="noreferrer"
62
+ >
63
+ {imgText}
64
+ </a>
65
+ ),
66
+ typeof legendDoc === 'string' && (
67
+ <a
68
+ className="legendAction"
69
+ href={legendDoc}
70
+ target="_blank"
71
+ referrerPolicy="noreferrer"
72
+ >
73
+ {docText}
74
+ </a>
75
+ ),
76
+ ];
77
+ }, [legendImg, imgText, legendDoc, docText]);
78
+
79
+ return (
80
+ <Box className="mapLegend">
81
+ {renderLayerName()}
82
+ <img
83
+ alt="Map Legend"
84
+ className="legendImg"
85
+ src={legendImg}
86
+ onClick={handleLegendImgOpen}
87
+ />
88
+ <Box className="legendActionsContainer">{renderLinks()}</Box>
89
+ </Box>
90
+ );
91
+ };
@@ -0,0 +1,46 @@
1
+ import React, { useCallback } from 'react';
2
+ import { Box } from '../../box';
3
+ import { IMapLegend, MapLegend } from './MapLegend';
4
+ import './MapLegend.css';
5
+
6
+ interface MapLegendListProps {
7
+ legends: IMapLegend[];
8
+ actionsTexts: {
9
+ docText: string;
10
+ imgText: string;
11
+ };
12
+ noLegendsText: string;
13
+ }
14
+
15
+ export const MapLegendList: React.FC<MapLegendListProps> = ({
16
+ legends,
17
+ actionsTexts: { docText, imgText },
18
+ noLegendsText,
19
+ }) => {
20
+ const handleNoLegends = useCallback(() => {
21
+ return (
22
+ <Box className="noLegendsContainer">
23
+ <h2 className="noLegendsMsg">{noLegendsText}</h2>
24
+ </Box>
25
+ );
26
+ }, [noLegendsText]);
27
+
28
+ const renderList = useCallback(() => {
29
+ if (!legends.length) {
30
+ return handleNoLegends();
31
+ }
32
+
33
+ return legends.map((legend, i) => {
34
+ return (
35
+ <MapLegend
36
+ key={`${legend.layer as string}_${i}`}
37
+ legend={legend}
38
+ docText={docText}
39
+ imgText={imgText}
40
+ />
41
+ );
42
+ });
43
+ }, [legends]);
44
+
45
+ return <Box className="mapLegendsList">{renderList()}</Box>;
46
+ };
@@ -0,0 +1,55 @@
1
+ import {
2
+ Icon,
3
+ Drawer,
4
+ DrawerHeader,
5
+ DrawerTitle,
6
+ DrawerContent,
7
+ } from '@map-colonies/react-core';
8
+ import React from 'react';
9
+ import { Box } from '../../box';
10
+ import { IMapLegend } from './MapLegend';
11
+ import './MapLegend.css';
12
+ import { MapLegendList } from './MapLegendList';
13
+
14
+ interface MapLegendSidebarProps {
15
+ isOpen: boolean;
16
+ toggleSidebar: () => void;
17
+ title?: string;
18
+ noLegendsText?: string;
19
+ legends?: IMapLegend[];
20
+ actionsTexts?: { docText: string; imgText: string };
21
+ }
22
+
23
+ export const MapLegendSidebar: React.FC<MapLegendSidebarProps> = ({
24
+ isOpen,
25
+ toggleSidebar,
26
+ title = 'Map Legends',
27
+ noLegendsText = 'No legends to display...',
28
+ legends = [],
29
+ actionsTexts = { docText: 'Docs', imgText: 'View Image' },
30
+ }) => {
31
+ return isOpen ? (
32
+ <Drawer
33
+ className="mapLegendSidebarContainer"
34
+ modal={false}
35
+ dismissible={true}
36
+ open={isOpen}
37
+ >
38
+ <DrawerHeader className="sidebarHeaderContainer">
39
+ <DrawerTitle className="sidebarTitle">{title}</DrawerTitle>
40
+ </DrawerHeader>
41
+ <DrawerContent className="sidebarContent">
42
+ <Icon
43
+ onClick={toggleSidebar}
44
+ className="mapLegendCloseBtn"
45
+ icon={{ icon: 'close', size: 'small' }}
46
+ />
47
+ <MapLegendList
48
+ noLegendsText={noLegendsText}
49
+ legends={legends}
50
+ actionsTexts={actionsTexts}
51
+ />
52
+ </DrawerContent>
53
+ </Drawer>
54
+ ) : null;
55
+ };
@@ -0,0 +1,31 @@
1
+ import React from 'react';
2
+ import { Icon } from '@map-colonies/react-core';
3
+ import { Box } from '../../box';
4
+ import './MapLegend.css';
5
+
6
+ interface MapLegendProps {
7
+ onClick: () => void;
8
+ }
9
+
10
+ const legendIcon = (
11
+ <svg
12
+ xmlns="http://www.w3.org/2000/svg"
13
+ enable-background="new 0 0 24 24"
14
+ height="24"
15
+ width="24"
16
+ viewBox="0 0 612 612"
17
+ >
18
+ <g xmlns="http://www.w3.org/2000/svg">
19
+ <path d="M322.4,173.9l-129,16.2l-4.6,21.4l25.3,4.7c16.5,3.9,19.8,9.9,16.2,26.4l-41.5,195.3c-10.9,50.5,5.9,74.3,45.5,74.3 c30.7,0,66.3-14.2,82.5-33.6l4.9-23.4c-11.3,9.9-27.7,13.9-38.6,13.9c-15.5,0-21.1-10.9-17.1-30L322.4,173.9z" />
20
+ <circle cx="270.1" cy="56.3" r="56.3" />
21
+ </g>
22
+ </svg>
23
+ );
24
+
25
+ export const MapLegendToggle: React.FC<MapLegendProps> = ({ onClick }) => {
26
+ return (
27
+ <Box onClick={onClick} className="mapLegendToggleContainer">
28
+ <Icon icon={legendIcon} className="mapLegendIcon" />
29
+ </Box>
30
+ );
31
+ };
@@ -0,0 +1,3 @@
1
+ export * from './MapLegendToggle';
2
+ export * from './MapLegendSidebar';
3
+ export type { IMapLegend } from './MapLegend';
@@ -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: column;
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
+ }