@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
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MapLegendToggle = void 0;
7
+ var react_1 = __importDefault(require("react"));
8
+ var react_core_1 = require("@map-colonies/react-core");
9
+ var box_1 = require("../../box");
10
+ require("./MapLegend.css");
11
+ var legendIcon = (react_1.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", "enable-background": "new 0 0 24 24", height: "24", width: "24", viewBox: "0 0 612 612" },
12
+ react_1.default.createElement("g", { xmlns: "http://www.w3.org/2000/svg" },
13
+ react_1.default.createElement("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" }),
14
+ react_1.default.createElement("circle", { cx: "270.1", cy: "56.3", r: "56.3" }))));
15
+ var MapLegendToggle = function (_a) {
16
+ var onClick = _a.onClick;
17
+ return (react_1.default.createElement(box_1.Box, { onClick: onClick, className: "mapLegendToggleContainer" },
18
+ react_1.default.createElement(react_core_1.Icon, { icon: legendIcon, className: "mapLegendIcon" })));
19
+ };
20
+ exports.MapLegendToggle = MapLegendToggle;
@@ -0,0 +1,3 @@
1
+ export * from './MapLegendToggle';
2
+ export * from './MapLegendSidebar';
3
+ export type { IMapLegend } from './MapLegend';
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ __exportStar(require("./MapLegendToggle"), exports);
14
+ __exportStar(require("./MapLegendSidebar"), exports);
@@ -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
+ }
@@ -3,7 +3,8 @@ import { ViewerProps } from 'resium/dist/types/src/Viewer/Viewer';
3
3
  import { Viewer as CesiumViewerCls, TerrainProvider } from 'cesium';
4
4
  import { Proj } from '../utils/projections';
5
5
  import { IBaseMaps } from './settings/settings';
6
- import LayerManager from './layers-manager';
6
+ import { IMapLegend } from './map-legend';
7
+ import LayerManager, { LegendExtractor } from './layers-manager';
7
8
  import { CesiumSceneModeEnum } from './map.types';
8
9
  import './map.css';
9
10
  export declare class CesiumViewer extends CesiumViewerCls {
@@ -23,6 +24,16 @@ export interface IContextMenuData {
23
24
  };
24
25
  handleClose: () => void;
25
26
  }
27
+ interface ILegends {
28
+ legendsList?: IMapLegend[];
29
+ emptyText?: string;
30
+ title?: string;
31
+ actionsTexts?: {
32
+ docText: string;
33
+ imgText: string;
34
+ };
35
+ mapLegendsExtractor?: LegendExtractor;
36
+ }
26
37
  export interface CesiumMapProps extends ViewerProps {
27
38
  showMousePosition?: boolean;
28
39
  showScale?: boolean;
@@ -41,6 +52,10 @@ export interface CesiumMapProps extends ViewerProps {
41
52
  width: number;
42
53
  dynamicHeightIncrement?: number;
43
54
  };
55
+ legendSidebarTitle?: string;
56
+ noLegendsText?: string;
57
+ legends?: ILegends;
44
58
  }
45
59
  export declare const useCesiumMap: () => CesiumViewer;
46
60
  export declare const CesiumMap: React.FC<CesiumMapProps>;
61
+ export {};
@@ -50,6 +50,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
50
50
  Object.defineProperty(exports, "__esModule", { value: true });
51
51
  exports.CesiumMap = exports.useCesiumMap = exports.CesiumViewer = void 0;
52
52
  var react_1 = __importStar(require("react"));
53
+ var react_dom_1 = require("react-dom");
53
54
  var resium_1 = require("resium");
54
55
  var cesium_1 = require("cesium");
55
56
  var lodash_1 = require("lodash");
@@ -59,6 +60,7 @@ var projections_1 = require("../utils/projections");
59
60
  var coordinates_tracker_tool_1 = require("./tools/coordinates-tracker.tool");
60
61
  var scale_tracker_tool_1 = require("./tools/scale-tracker.tool");
61
62
  var settings_1 = require("./settings/settings");
63
+ var map_legend_1 = require("./map-legend");
62
64
  var layers_manager_1 = __importDefault(require("./layers-manager"));
63
65
  var map_types_1 = require("./map.types");
64
66
  require("./map.css");
@@ -85,18 +87,20 @@ var useCesiumMap = function () {
85
87
  };
86
88
  exports.useCesiumMap = useCesiumMap;
87
89
  var CesiumMap = function (props) {
88
- var _a, _b, _c, _d, _e, _f, _g, _h;
90
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
89
91
  var ref = react_1.useRef(null);
90
- var _j = react_1.useState(), mapViewRef = _j[0], setMapViewRef = _j[1];
91
- var _k = react_1.useState(), projection = _k[0], setProjection = _k[1];
92
- var _l = react_1.useState(), showMousePosition = _l[0], setShowMousePosition = _l[1];
93
- var _m = react_1.useState(), showScale = _m[0], setShowScale = _m[1];
94
- var _o = react_1.useState(), locale = _o[0], setLocale = _o[1];
95
- var _p = react_1.useState(), cameraState = _p[0], setCameraState = _p[1];
96
- var _q = react_1.useState(), sceneModes = _q[0], setSceneModes = _q[1];
97
- var _r = react_1.useState(), baseMaps = _r[0], setBaseMaps = _r[1];
98
- var _s = react_1.useState(false), showImageryMenu = _s[0], setShowImageryMenu = _s[1];
99
- var _t = react_1.useState(undefined), imageryMenuPosition = _t[0], setImageryMenuPosition = _t[1];
92
+ var _p = react_1.useState(), mapViewRef = _p[0], setMapViewRef = _p[1];
93
+ var _q = react_1.useState(), projection = _q[0], setProjection = _q[1];
94
+ var _r = react_1.useState(), showMousePosition = _r[0], setShowMousePosition = _r[1];
95
+ var _s = react_1.useState(), showScale = _s[0], setShowScale = _s[1];
96
+ var _t = react_1.useState(), locale = _t[0], setLocale = _t[1];
97
+ var _u = react_1.useState(), cameraState = _u[0], setCameraState = _u[1];
98
+ var _v = react_1.useState(), sceneModes = _v[0], setSceneModes = _v[1];
99
+ var _w = react_1.useState([]), legendsList = _w[0], setLegendsList = _w[1];
100
+ var _x = react_1.useState(), baseMaps = _x[0], setBaseMaps = _x[1];
101
+ var _y = react_1.useState(false), showImageryMenu = _y[0], setShowImageryMenu = _y[1];
102
+ var _z = react_1.useState(undefined), imageryMenuPosition = _z[0], setImageryMenuPosition = _z[1];
103
+ var _0 = react_1.useState(false), isLegendsSidebarOpen = _0[0], setIsLegendsSidebarOpen = _0[1];
100
104
  var viewerProps = __assign({ fullscreenButton: true, timeline: false, animation: false, baseLayerPicker: false, geocoder: false, navigationHelpButton: false, homeButton: false, sceneModePicker: false }, props);
101
105
  var getImageryMenuStyle = function (x, y, menuWidth, menuHeight, menuDynamicHeightIncrement) {
102
106
  var container = mapViewRef.container;
@@ -114,7 +118,6 @@ var CesiumMap = function (props) {
114
118
  var _a;
115
119
  if (ref.current) {
116
120
  var viewer = ref.current.cesiumElement;
117
- viewer.layersManager = new layers_manager_1.default(viewer);
118
121
  if (props.imageryContextMenu) {
119
122
  viewer.screenSpaceEventHandler.setInputAction(function (evt) {
120
123
  // console.log('RIGHT click', evt.position);
@@ -126,6 +129,15 @@ var CesiumMap = function (props) {
126
129
  }
127
130
  setMapViewRef((_a = ref.current) === null || _a === void 0 ? void 0 : _a.cesiumElement);
128
131
  }, [ref, props.imageryContextMenu]);
132
+ react_1.useEffect(function () {
133
+ var _a;
134
+ if (mapViewRef) {
135
+ mapViewRef.layersManager = new layers_manager_1.default(mapViewRef, (_a = props.legends) === null || _a === void 0 ? void 0 : _a.mapLegendsExtractor, function () {
136
+ var _a;
137
+ setLegendsList((_a = mapViewRef === null || mapViewRef === void 0 ? void 0 : mapViewRef.layersManager) === null || _a === void 0 ? void 0 : _a.legendsList);
138
+ });
139
+ }
140
+ }, [mapViewRef]);
129
141
  react_1.useEffect(function () {
130
142
  var _a;
131
143
  setSceneModes((_a = props.sceneModes) !== null && _a !== void 0 ? _a : [
@@ -243,25 +255,43 @@ var CesiumMap = function (props) {
243
255
  });
244
256
  }
245
257
  }, [props.zoom, props.center, mapViewRef]);
246
- return (react_1.default.createElement(resium_1.Viewer, __assign({ full: true, ref: ref }, viewerProps),
258
+ var bindCustomToolsToViewer = react_1.useCallback(function () {
259
+ return (mapViewRef &&
260
+ react_dom_1.createPortal(react_1.default.createElement(react_1.default.Fragment, null,
261
+ react_1.default.createElement(box_1.Box, { className: "sideToolsContainer" },
262
+ react_1.default.createElement(settings_1.CesiumSettings, { sceneModes: sceneModes, baseMaps: baseMaps, locale: locale }),
263
+ react_1.default.createElement(map_legend_1.MapLegendToggle, { onClick: function () { return setIsLegendsSidebarOpen(!isLegendsSidebarOpen); } })),
264
+ react_1.default.createElement(box_1.Box, { className: "toolsContainer" },
265
+ showMousePosition === true ? (react_1.default.createElement(coordinates_tracker_tool_1.CoordinatesTrackerTool, { projection: projection })) : (react_1.default.createElement(react_1.default.Fragment, null)),
266
+ showScale === true ? react_1.default.createElement(scale_tracker_tool_1.ScaleTrackerTool, { locale: locale }) : react_1.default.createElement(react_1.default.Fragment, null))), document.querySelector('.cesium-viewer')));
267
+ }, [
268
+ baseMaps,
269
+ locale,
270
+ mapViewRef,
271
+ projection,
272
+ sceneModes,
273
+ showMousePosition,
274
+ showScale,
275
+ isLegendsSidebarOpen,
276
+ ]);
277
+ return (react_1.default.createElement(resium_1.Viewer, __assign({ className: "viewer", full: true, ref: ref }, viewerProps),
247
278
  react_1.default.createElement(MapViewProvider, { value: mapViewRef },
279
+ react_1.default.createElement(map_legend_1.MapLegendSidebar, { title: (_a = props.legends) === null || _a === void 0 ? void 0 : _a.title, isOpen: isLegendsSidebarOpen, toggleSidebar: function () {
280
+ return setIsLegendsSidebarOpen(!isLegendsSidebarOpen);
281
+ }, noLegendsText: (_b = props.legends) === null || _b === void 0 ? void 0 : _b.emptyText, legends: (_d = (_c = props.legends) === null || _c === void 0 ? void 0 : _c.legendsList) !== null && _d !== void 0 ? _d : legendsList, actionsTexts: (_e = props.legends) === null || _e === void 0 ? void 0 : _e.actionsTexts }),
248
282
  props.children,
249
- react_1.default.createElement(box_1.Box, { className: "sideToolsContainer" },
250
- react_1.default.createElement(settings_1.CesiumSettings, { sceneModes: sceneModes, baseMaps: baseMaps, locale: locale })),
251
- react_1.default.createElement(box_1.Box, { className: "toolsContainer" },
252
- showMousePosition === true ? (react_1.default.createElement(coordinates_tracker_tool_1.CoordinatesTrackerTool, { projection: projection })) : (react_1.default.createElement(react_1.default.Fragment, null)),
253
- showScale === true ? react_1.default.createElement(scale_tracker_tool_1.ScaleTrackerTool, { locale: locale }) : react_1.default.createElement(react_1.default.Fragment, null)),
283
+ bindCustomToolsToViewer(),
254
284
  props.imageryContextMenu &&
255
285
  showImageryMenu &&
256
286
  imageryMenuPosition &&
257
287
  react_1.default.cloneElement(props.imageryContextMenu, {
258
- data: (_a = mapViewRef === null || mapViewRef === void 0 ? void 0 : mapViewRef.layersManager) === null || _a === void 0 ? void 0 : _a.findLayerByPOI(imageryMenuPosition.x, imageryMenuPosition.y),
288
+ data: (_f = mapViewRef === null || mapViewRef === void 0 ? void 0 : mapViewRef.layersManager) === null || _f === void 0 ? void 0 : _f.findLayerByPOI(imageryMenuPosition.x, imageryMenuPosition.y),
259
289
  position: {
260
290
  x: imageryMenuPosition.x,
261
291
  y: imageryMenuPosition.y,
262
292
  },
263
- style: getImageryMenuStyle(imageryMenuPosition.x, imageryMenuPosition.y, (_c = (_b = props.imageryContextMenuSize) === null || _b === void 0 ? void 0 : _b.width) !== null && _c !== void 0 ? _c : DEFAULT_WIDTH, (_e = (_d = props.imageryContextMenuSize) === null || _d === void 0 ? void 0 : _d.height) !== null && _e !== void 0 ? _e : DEFAULT_HEIGHT, (_g = (_f = props.imageryContextMenuSize) === null || _f === void 0 ? void 0 : _f.dynamicHeightIncrement) !== null && _g !== void 0 ? _g : DEFAULT_DYNAMIC_HEIGHT_INCREMENT),
264
- size: (_h = props.imageryContextMenuSize) !== null && _h !== void 0 ? _h : {
293
+ style: getImageryMenuStyle(imageryMenuPosition.x, imageryMenuPosition.y, (_h = (_g = props.imageryContextMenuSize) === null || _g === void 0 ? void 0 : _g.width) !== null && _h !== void 0 ? _h : DEFAULT_WIDTH, (_k = (_j = props.imageryContextMenuSize) === null || _j === void 0 ? void 0 : _j.height) !== null && _k !== void 0 ? _k : DEFAULT_HEIGHT, (_m = (_l = props.imageryContextMenuSize) === null || _l === void 0 ? void 0 : _l.dynamicHeightIncrement) !== null && _m !== void 0 ? _m : DEFAULT_DYNAMIC_HEIGHT_INCREMENT),
294
+ size: (_o = props.imageryContextMenuSize) !== null && _o !== void 0 ? _o : {
265
295
  height: DEFAULT_HEIGHT,
266
296
  width: DEFAULT_WIDTH,
267
297
  },
@@ -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
  }
@@ -44,6 +44,7 @@ var TerrainianHeightTool = function (props) {
44
44
  console.log('Loaded CSV content:\n', text);
45
45
  void cesium_1.sampleTerrainMostDetailed(mapViewer.terrainProvider, parsed.map(function (item) { return item.cartographic; })).then(function (updatedPositions) {
46
46
  console.log(updatedPositions);
47
+ updatedPositions = updatedPositions.slice(0, updatedPositions.length - 1); // UNIX brake line
47
48
  mapViewer.scene.globe.depthTestAgainstTerrain = true;
48
49
  mapViewer.entities.suspendEvents();
49
50
  mapViewer.entities.removeAll();
@@ -4,7 +4,8 @@ body[dir='rtl'] .chonky-fileListWrapper [class^='listContainer-'] {
4
4
 
5
5
  body[dir='rtl']
6
6
  .chonky-fileEntryClickableWrapper
7
- [class^='listFileEntryProperty-'] {
7
+ [class^='listFileEntryProperty-'],
8
+ body[dir='rtl'] .chonky-navbarContainer {
8
9
  direction: ltr !important;
9
10
  }
10
11
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@map-colonies/react-components",
3
- "version": "3.10.4",
3
+ "version": "3.12.0",
4
4
  "module": "dist/index.js",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -18,7 +18,7 @@
18
18
  "dependencies": {
19
19
  "@date-io/date-fns": "^1.3.13",
20
20
  "@here/quantized-mesh-decoder": "^1.2.8",
21
- "@map-colonies/react-core": "^3.3.2",
21
+ "@map-colonies/react-core": "^3.3.3",
22
22
  "@material-ui/core": "^4.11.0",
23
23
  "@material-ui/icons": "^4.9.1",
24
24
  "@material-ui/pickers": "^3.2.10",
@@ -93,7 +93,7 @@
93
93
  "jest-enzyme": "^7.1.2",
94
94
  "react-test-renderer": "^16.13.1"
95
95
  },
96
- "gitHead": "77edacc668fbc4fbdae5e5fb68630f79fb5250fd",
96
+ "gitHead": "fc727564af113a9fbfc599f1c7720dce840e8e83",
97
97
  "jest": {
98
98
  "coverageReporters": [
99
99
  "text",
@@ -1,7 +1,9 @@
1
1
  import React from 'react';
2
+ import { ArcGISTiledElevationTerrainProvider } from 'cesium';
2
3
  import { Story, Meta } from '@storybook/react/types-6-0';
3
4
  import { action } from '@storybook/addon-actions';
4
5
  import { CesiumMap } from '../map';
6
+ import { LayerType } from '../layers-manager';
5
7
  import { Cesium3DTileset } from './3d.tileset';
6
8
 
7
9
  export default {
@@ -18,12 +20,43 @@ const mapDivStyle = {
18
20
  position: 'absolute' as const,
19
21
  };
20
22
 
23
+ const BASE_MAPS = {
24
+ maps: [
25
+ {
26
+ id: '1st',
27
+ title: '1st Map Title',
28
+ isCurrent: true,
29
+ thumbnail:
30
+ 'https://nsw.digitaltwin.terria.io/build/efa2f6c408eb790753a9b5fb2f3dc678.png',
31
+ baseRasteLayers: [
32
+ {
33
+ id: 'GOOGLE_TERRAIN',
34
+ type: 'XYZ_LAYER' as LayerType,
35
+ opacity: 1,
36
+ zIndex: 0,
37
+ options: {
38
+ url: 'https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}',
39
+ layers: '',
40
+ credit: 'GOOGLE',
41
+ },
42
+ },
43
+ ],
44
+ baseVectorLayers: [],
45
+ },
46
+ ],
47
+ };
48
+
49
+ const ArcGisProvider = new ArcGISTiledElevationTerrainProvider({
50
+ url:
51
+ 'https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer',
52
+ });
53
+
21
54
  export const Cesium3DTilesetLayer: Story = (args: unknown) => (
22
55
  <div style={mapDivStyle}>
23
56
  <CesiumMap {...args}>
24
57
  <Cesium3DTileset
25
58
  isZoomTo={true}
26
- url="/mock/tileset/tileset.json"
59
+ url="/mock/tileset_1/tileset.json"
27
60
  onAllTilesLoad={action('onAllTilesLoad')}
28
61
  onInitialTilesLoad={action('onInitialTilesLoad')}
29
62
  onTileFailed={action('onTileFailed')}
@@ -39,6 +72,9 @@ export const Cesium3DTilesetLayer: Story = (args: unknown) => (
39
72
  );
40
73
 
41
74
  Cesium3DTilesetLayer.argTypes = {
75
+ baseMaps: {
76
+ defaultValue: BASE_MAPS,
77
+ },
42
78
  zoom: {
43
79
  defaultValue: 3,
44
80
  control: {
@@ -49,13 +85,17 @@ Cesium3DTilesetLayer.argTypes = {
49
85
  },
50
86
  };
51
87
 
52
- export const Cesium3DTilesetOnHeightLayer: Story = (args: unknown) => (
88
+ Cesium3DTilesetLayer.storyName = '3D Layer';
89
+
90
+ export const Cesium3DTilesetWithHeightCorrectionLayer: Story = (
91
+ args: unknown
92
+ ) => (
53
93
  <div style={mapDivStyle}>
54
94
  <CesiumMap {...args}>
55
95
  <Cesium3DTileset
56
96
  isZoomTo={false}
57
- heightFromGround={-170}
58
- url="/mock/tileset/tileset.json"
97
+ heightFromGround={-10}
98
+ url="/mock/tileset_1/tileset.json"
59
99
  onAllTilesLoad={action('onAllTilesLoad')}
60
100
  onInitialTilesLoad={action('onInitialTilesLoad')}
61
101
  onTileFailed={action('onTileFailed')}
@@ -70,9 +110,12 @@ export const Cesium3DTilesetOnHeightLayer: Story = (args: unknown) => (
70
110
  </div>
71
111
  );
72
112
 
73
- Cesium3DTilesetOnHeightLayer.argTypes = {
113
+ Cesium3DTilesetWithHeightCorrectionLayer.argTypes = {
114
+ baseMaps: {
115
+ defaultValue: BASE_MAPS,
116
+ },
74
117
  zoom: {
75
- defaultValue: 18,
118
+ defaultValue: 17,
76
119
  control: {
77
120
  type: 'range',
78
121
  min: 0,
@@ -84,6 +127,9 @@ Cesium3DTilesetOnHeightLayer.argTypes = {
84
127
  },
85
128
  };
86
129
 
130
+ Cesium3DTilesetWithHeightCorrectionLayer.storyName =
131
+ '3D with Height Correction Layer';
132
+
87
133
  export const CesiumSolar3DTilesetLayer: Story = (args: unknown) => (
88
134
  <div style={mapDivStyle}>
89
135
  <CesiumMap {...args}>
@@ -96,6 +142,12 @@ export const CesiumSolar3DTilesetLayer: Story = (args: unknown) => (
96
142
  );
97
143
 
98
144
  CesiumSolar3DTilesetLayer.argTypes = {
145
+ baseMaps: {
146
+ defaultValue: BASE_MAPS,
147
+ },
148
+ terrainProvider: {
149
+ defaultValue: ArcGisProvider,
150
+ },
99
151
  center: {
100
152
  defaultValue: [34.811, 31.908],
101
153
  },
@@ -108,3 +160,5 @@ CesiumSolar3DTilesetLayer.argTypes = {
108
160
  },
109
161
  },
110
162
  };
163
+
164
+ CesiumSolar3DTilesetLayer.storyName = 'Solar 3D Layer with Terrain Provider';
@@ -1,10 +1,11 @@
1
- import { Cartesian3, Cartographic, Matrix4 } from 'cesium';
2
1
  import React from 'react';
3
-
2
+ import { Cartesian3, Cartographic, Matrix4 } from 'cesium';
4
3
  import { Cesium3DTileset as Resium3DTileset } from 'resium';
5
4
  import { Cesium3DTilesetProps } from 'resium/dist/types/src/Cesium3DTileset/Cesium3DTileset';
6
5
  import { CesiumViewer, useCesiumMap } from '../map';
7
6
 
7
+ const GROUND_LEVEL = 0.0;
8
+
8
9
  export interface RCesium3DTilesetProps extends Cesium3DTilesetProps {
9
10
  isZoomTo?: boolean;
10
11
  heightFromGround?: number;
@@ -17,22 +18,25 @@ export const Cesium3DTileset: React.FC<RCesium3DTilesetProps> = (props) => {
17
18
  {...props}
18
19
  onReady={(tileset): void => {
19
20
  props.onReady?.(tileset);
20
- if (props.isZoomTo) {
21
+ if (props.isZoomTo === true) {
21
22
  void mapViewer.zoomTo(tileset);
22
23
  }
23
- if (props.heightFromGround) {
24
- const cartographic = Cartographic.fromCartesian(
25
- tileset.boundingSphere.center
26
- );
24
+ const scene = mapViewer.scene;
25
+ scene.globe.depthTestAgainstTerrain = true;
26
+ const cartographic = Cartographic.fromCartesian(
27
+ tileset.boundingSphere.center
28
+ );
29
+ const heightFromGround = props.heightFromGround ?? GROUND_LEVEL;
30
+ if (heightFromGround) {
27
31
  const surface = Cartesian3.fromRadians(
28
32
  cartographic.longitude,
29
33
  cartographic.latitude,
30
- 0.0
34
+ cartographic.height
31
35
  );
32
36
  const offset = Cartesian3.fromRadians(
33
37
  cartographic.longitude,
34
38
  cartographic.latitude,
35
- props.heightFromGround
39
+ cartographic.height + heightFromGround
36
40
  );
37
41
  const translation = Cartesian3.subtract(
38
42
  offset,
@@ -0,0 +1,120 @@
1
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
2
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
3
+ /* eslint-disable @typescript-eslint/no-unsafe-member-access */
4
+ /* eslint-disable @typescript-eslint/no-unnecessary-condition */
5
+ /*
6
+ https://sandcastle.cesium.com/index.html?#c=fVZtTxs5EP4re3xho0YOkOv1jgC6ElIuiAQKKaWQqnJ2nayL187Z3qCk4r/f+GXf8nKWot3YzzOeGT8z6wWWQRdLTRTFvB2cBl14y1JUznXGfMxbreBSYq798tV9gKOIKBVoESxFJgMqeICVIlqNuTfRFxzFZIozpj9a8Ei8EA5b7JPlVTK5jOgNvep/WfUPh7Sv+vzufdTt/9F/mT8+dK/+QgD6N758MSA6GJ3/HB712gN60H66fHq5Ht0l39K+vvnaWw27h/RmFP+8ueitBqvB+8FqRq+7V/MnMDa8+Kz6KUtieB+MPv8+/Am/i8HBoH2AztvdD0NBlu2n28do+uHHp8fz3rdXKiN91J6qLyS64/eHR5+YHv65b3OwgFRFNrQRkRJTfivFgsZEllmLJMGafBWSxR4TNjqOSRijcyVovEnm5DU30NuBsmacoQUlr+u0BzsX7jv3uoJr4BK53wx+jXkAY4IVucZLIm9p9ALs42CKmSJNt6rXXDreHueYv+XRqIhwAj44Z5D9az20b2jGxITA4c91MiJKf5yBFaW9OaBpmZEiIE0ZAeHAtCPPJU2ppguiEI7j0LlYCdY92hcjxwt9iGZkkh0HpfzuiAJtRgRNpUg/GnX247D9oX3UcJQ3ePrEujhWQqQjEXqPPAoJnRD5ShUJpxmPtJF6CKEI2Qgqe0eCK8EIYmLmVzv5LnaLgpvNYxCJ8T6wOxVWTDImIuMx5bMHwbLUZNggUH3W26XTIPSxQpnBecfWHAJHNOH6vMZp1HzdvstWYh5E6aKHrbE6JSAVMWGw7FfQDztRASSEzhJjoO4HSimnaZb+Y5creJCFtpK3htAPqaOunapguJApZoWInAKLokMzAlRNo/tMTnFEhhYdOsNNp66i44WNRsWwmE6dOksASqGn0Tlbni/vI8ywDN3uTR/Z/xuMYF7UO62YSTxPaGSFWvC8e1XuHNZBiCX7NSG2y/oWkevCJWG9rk9PT3f2oZo+zFaSKIjSHKNxsFMuugVUHOJBZc37hwAj2IKEDltUAuwOzv/awJfxKJzOGfG+DYTSFwR6GQNtbw2pGTxb9743EBQpLwrUb6xqUW1E5kHPB987dZRJ4W9rteVD2bDoUqIzyTcyVSmcNaQzVoG+NcpCcy95KrfFVXOiCGeboLQo5VQ/jEJSQlHbl2oKV9lESxxpT2r6MtitbDPWy7NuMmKCkzDfrrmBrvXLtx0t0zR8KUSZAXNUZiLvQ3cEx8tafkqyY+4Uo8kGowqsWNf9VwCZ57XAsfka9RawxbXHlKdSa+NVEZkFW3Y1n6uj4p210tmE5D6Fjd3a2tSPbTUJZbG0ly6XI/+/0lEY4TOdmDL3a8jNeMhUyCA0OGorHR4nntIJ3r2jOxJtTim390y/V3yz7t1jHkdYafh6QE5HYjZj5DzTGjK5n18SehxPoOzhCmMuC82gyHWUELjCxDUBrM+ZsaMFbr/a7NTELiu72uj6KdRzkksq16E9tb3m3onSS0bOHOVvms6F1OYyEyLU0gQ6IthQrUkGQcIhKmVoJ62cdBLTRUDj0/He2v1vvBdEDG7lsDLNGLunKzLeOztpAb5GY6Bu+ArfLIhkeGkgyeHZtZtECJ204O8mSwvBJlhWLP4H
7
+ */
8
+
9
+ import React, { useEffect, useState } from 'react';
10
+ import {
11
+ Cesium3DTileset,
12
+ Cesium3DTile,
13
+ Cartographic,
14
+ Cartesian3,
15
+ defined,
16
+ sampleTerrainMostDetailed,
17
+ Cesium3DTileContent,
18
+ } from 'cesium';
19
+ import { CesiumViewer, useCesiumMap } from '../map';
20
+
21
+ export interface Cesium3DTilesetWithUpdateProps {
22
+ url: string;
23
+ withUpdate?: boolean;
24
+ }
25
+
26
+ export const Cesium3DTilesetWithUpdate: React.FC<Cesium3DTilesetWithUpdateProps> = ({
27
+ url,
28
+ withUpdate,
29
+ }) => {
30
+ const mapViewer: CesiumViewer = useCesiumMap();
31
+ const scene = mapViewer.scene;
32
+ const [cesium3DTileset] = useState<Cesium3DTileset>(
33
+ new Cesium3DTileset({
34
+ url: url,
35
+ })
36
+ );
37
+ const [tileset] = useState<Cesium3DTileset>(
38
+ scene.primitives.add(cesium3DTileset)
39
+ );
40
+
41
+ useEffect(() => {
42
+ scene.globe.depthTestAgainstTerrain = true;
43
+ void mapViewer.zoomTo(tileset);
44
+ if (withUpdate === true) {
45
+ updateTileset(tileset);
46
+ }
47
+ // eslint-disable-next-line react-hooks/exhaustive-deps
48
+ }, []);
49
+
50
+ const updateContent = (
51
+ model: Cesium3DTileContent,
52
+ boundingVolume: any
53
+ ): void => {
54
+ const height = boundingVolume.minimumHeight
55
+ ? boundingVolume.minimumHeight
56
+ : boundingVolume.center.z - boundingVolume.radius;
57
+ // @ts-ignore
58
+ const center = model._rtcCenter ?? boundingVolume.center;
59
+ const normal = scene.globe.ellipsoid.geodeticSurfaceNormal(
60
+ center,
61
+ new Cartesian3()
62
+ );
63
+ const offset = Cartesian3.multiplyByScalar(
64
+ normal,
65
+ height,
66
+ new Cartesian3()
67
+ );
68
+ const carto = Cartographic.fromCartesian(center);
69
+ void new Promise((resolve, reject) => {
70
+ // @ts-ignore
71
+ if (scene.terrainProvider._ready !== true) {
72
+ const result = { ...carto };
73
+ result.height = 0;
74
+ resolve(result);
75
+ } else {
76
+ void sampleTerrainMostDetailed(scene.terrainProvider, [carto]).then(
77
+ (results) => {
78
+ const result = results[0];
79
+ if (!defined(result)) {
80
+ resolve(carto);
81
+ }
82
+ resolve(result);
83
+ }
84
+ );
85
+ }
86
+ }).then((result) => {
87
+ const resultCartesian = Cartographic.toCartesian(result as Cartographic);
88
+ const position = Cartesian3.subtract(
89
+ resultCartesian,
90
+ offset,
91
+ new Cartesian3()
92
+ );
93
+ // @ts-ignore
94
+ model._rtcCenter = Cartesian3.clone(position, model._rtcCenter);
95
+ });
96
+ };
97
+
98
+ const updateTile = (tile: Cesium3DTile): void => {
99
+ if (tile.content !== undefined) {
100
+ // @ts-ignore
101
+ updateContent(tile.content, tile.boundingVolume.boundingVolume);
102
+ } else {
103
+ const listener = tileset.tileLoad.addEventListener((t) => {
104
+ if (t === tile) {
105
+ updateContent(t.content, t.boundingVolume.boundingVolume);
106
+ listener();
107
+ }
108
+ });
109
+ }
110
+ tile.children.forEach((child) => updateTile(child));
111
+ };
112
+
113
+ const updateTileset = (tileset: Cesium3DTileset): void => {
114
+ void tileset.readyPromise.then(() => {
115
+ updateTile(tileset.root);
116
+ });
117
+ };
118
+
119
+ return <></>;
120
+ };
@@ -18,13 +18,18 @@ export const CesiumImageryLayer: React.FC<RCesiumImageryLayerProps> = (
18
18
  useLayoutEffect(() => {
19
19
  mapViewer.layersManager?.addMetaToLayer(
20
20
  meta,
21
- (layer: ImageryLayer, idx: number): boolean => {
22
- if (meta !== undefined) {
23
- // eslint-disable-next-line
24
- return (layer as any)._imageryProvider._resource._url === meta.url;
25
- }
26
- return false;
27
- }
21
+ /* eslint-disable */
22
+ meta.searchLayerPredicate ??
23
+ ((layer: ImageryLayer, idx: number): boolean => {
24
+ if (meta !== undefined) {
25
+ return (
26
+ (layer as any)._imageryProvider._resource._url ===
27
+ meta.options.url
28
+ );
29
+ }
30
+ return false;
31
+ })
32
+ /* eslint-enable */
28
33
  );
29
34
  }, [meta, mapViewer]);
30
35