From cd114391d53413d517f50dc65d379a5ff7ee679e Mon Sep 17 00:00:00 2001 From: glughi Date: Wed, 10 Jul 2024 16:19:37 +0200 Subject: [PATCH 1/3] Allow to use Cesium in `SCENE2D` mode as map viewer --- CHANGES.md | 1 + lib/Models/Cesium.ts | 33 ++++++++++++++++------ lib/Models/ViewerMode.ts | 10 +++++++ lib/ReactViews/Map/Panels/SettingPanel.tsx | 12 ++++---- lib/ViewModels/TerriaViewer.ts | 8 ++++++ 5 files changed, 51 insertions(+), 13 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 0f7d555feb7..e13e6264b68 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,7 @@ #### next release (8.7.6) - Set default value for date and datetime WPS fields only when the field is marked as required. +- Allow to use Cesium in `SCENE2D` mode (and WebMercator projection) as map viewer. - [The next improvement] #### 8.7.5 - 2024-06-26 diff --git a/lib/Models/Cesium.ts b/lib/Models/Cesium.ts index d795f65c296..2ddc12e936a 100644 --- a/lib/Models/Cesium.ts +++ b/lib/Models/Cesium.ts @@ -90,8 +90,11 @@ import TerriaFeature from "./Feature/Feature"; import GlobeOrMap from "./GlobeOrMap"; import Terria from "./Terria"; import UserDrawing from "./UserDrawing"; -import { setViewerMode } from "./ViewerMode"; +import ViewerMode, { setViewerMode } from "./ViewerMode"; import ScreenSpaceEventHandler from "terriajs-cesium/Source/Core/ScreenSpaceEventHandler"; +import SceneMode from "terriajs-cesium/Source/Scene/SceneMode"; +import GeographicProjection from "terriajs-cesium/Source/Core/GeographicProjection"; +import WebMercatorProjection from "terriajs-cesium/Source/Core/WebMercatorProjection"; //import Cesium3DTilesInspector from "terriajs-cesium/Source/Widgets/Cesium3DTilesInspector/Cesium3DTilesInspector"; @@ -189,7 +192,14 @@ export default class Cesium extends GlobeOrMap { SingleTileImageryProvider.fromUrl(img), {} ), - scene3DOnly: true, + scene3DOnly: false, + sceneMode: terriaViewer.viewerMode && terriaViewer.viewerMode === ViewerMode.Cesium + ? SceneMode.SCENE3D + : SceneMode.SCENE2D, + mapProjection: + terriaViewer.viewerMode && terriaViewer.viewerMode === ViewerMode.Cesium + ? new GeographicProjection() + : new WebMercatorProjection(), shadows: true, useBrowserRecommendedResolution: !this.terria.useNativeResolution }; @@ -867,6 +877,12 @@ export default class Cesium extends GlobeOrMap { duration: flightDurationSeconds, destination: finalDestination }); + } else if (defined(target.rectangle)) { + // target has a rectangle + return flyToPromise(camera, { + duration: flightDurationSeconds, + destination: target.rectangle + }); } else if (defined(target.entities)) { // target is some DataSource return waitForDataSourceToLoad(target).then(() => { @@ -922,12 +938,6 @@ export default class Cesium extends GlobeOrMap { } else { return Promise.resolve(); } - } else if (defined(target.rectangle)) { - // target has a rectangle - return flyToPromise(camera, { - duration: flightDurationSeconds, - destination: target.rectangle - }); } else { return Promise.resolve(); } @@ -1001,6 +1011,13 @@ export default class Cesium extends GlobeOrMap { const scene = this.scene; const camera = scene.camera; + if (scene.mode === SceneMode.SCENE2D) { + const rect = camera.computeViewRectangle(); + if (rect) { + return new CameraView(rect); + } + } + const width = scene.canvas.clientWidth; const height = scene.canvas.clientHeight; diff --git a/lib/Models/ViewerMode.ts b/lib/Models/ViewerMode.ts index 52533c9af34..958593eaef0 100644 --- a/lib/Models/ViewerMode.ts +++ b/lib/Models/ViewerMode.ts @@ -3,6 +3,7 @@ import TerriaViewer from "../ViewModels/TerriaViewer"; enum ViewerMode { Cesium = "cesium", + Cesium2D = "cesium2d", Leaflet = "leaflet" } @@ -24,6 +25,12 @@ export const MapViewers = Object.seal({ terrain: false, label: "settingPanel.viewerModeLabels.Leaflet", available: true + }, + "cesium2d": { + viewerMode: ViewerMode.Cesium2D, + terrain: false, + label: "settingPanel.viewerModeLabels.Leaflet", + available: true } }); @@ -38,6 +45,9 @@ export function setViewerMode( if (viewerMode === "3d" || viewerMode === "3dsmooth") { viewer.viewerMode = ViewerMode.Cesium; viewer.viewerOptions.useTerrain = viewerMode === "3d"; + } else if (viewerMode === "cesium2d") { + viewer.viewerMode = ViewerMode.Cesium2D; + viewer.viewerOptions.useTerrain = false; } else if (viewerMode === "2d") { viewer.viewerMode = ViewerMode.Leaflet; } else { diff --git a/lib/ReactViews/Map/Panels/SettingPanel.tsx b/lib/ReactViews/Map/Panels/SettingPanel.tsx index 48c9cd436a1..39f038774df 100644 --- a/lib/ReactViews/Map/Panels/SettingPanel.tsx +++ b/lib/ReactViews/Map/Panels/SettingPanel.tsx @@ -168,11 +168,13 @@ class SettingPanel extends React.Component { 2: t("settingPanel.qualityLabels.lowerPerformance") }; const currentViewer = - this.props.terria.mainViewer.viewerMode === ViewerMode.Cesium - ? this.props.terria.mainViewer.viewerOptions.useTerrain - ? "3d" - : "3dsmooth" - : "2d"; + this.props.terria.mainViewer.viewerMode === ViewerMode.Cesium2D + ? ViewerMode.Cesium2D + : this.props.terria.mainViewer.viewerMode === ViewerMode.Cesium + ? this.props.terria.mainViewer.viewerOptions.useTerrain + ? "3d" + : "3dsmooth" + : "2d"; const useNativeResolution = this.props.terria.useNativeResolution; const nativeResolutionLabel = t("settingPanel.nativeResolutionLabel", { diff --git a/lib/ViewModels/TerriaViewer.ts b/lib/ViewModels/TerriaViewer.ts index f2ddec0e238..e5ca64abdfc 100644 --- a/lib/ViewModels/TerriaViewer.ts +++ b/lib/ViewModels/TerriaViewer.ts @@ -36,6 +36,12 @@ const cesiumFromPromise = computed( { keepAlive: true } ); +const cesium2dFromPromise = computed( + () => + fromPromise(import("../Models/Cesium").then((Cesium) => Cesium.default)), + { keepAlive: true } +); + // Viewer options. Designed to be easily serialisable interface ViewerOptions { useTerrain: boolean; @@ -173,6 +179,8 @@ export default class TerriaViewer { viewerFromPromise = leafletFromPromise.get(); } else if (this.attached && this.viewerMode === ViewerMode.Cesium) { viewerFromPromise = cesiumFromPromise.get(); + } else if (this.attached && this.viewerMode === ViewerMode.Cesium2D) { + viewerFromPromise = cesium2dFromPromise.get(); } return viewerFromPromise; } From 6b967b9f739483953a703f996cd467cf6e64dc08 Mon Sep 17 00:00:00 2001 From: glughi Date: Wed, 10 Jul 2024 16:20:17 +0200 Subject: [PATCH 2/3] Add a new configuration parameter `mapViewers` to specify which map viewers to show in `SettingPanel` --- CHANGES.md | 1 + lib/Models/Terria.ts | 8 +++++++- lib/ReactViews/Map/Panels/SettingPanel.tsx | 6 +++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index e13e6264b68..3db57cdd4ab 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,7 @@ - Set default value for date and datetime WPS fields only when the field is marked as required. - Allow to use Cesium in `SCENE2D` mode (and WebMercator projection) as map viewer. +- Add a new configuration parameter `mapViewers` to specify which map viewers to show in `SettingPanel`. - [The next improvement] #### 8.7.5 - 2024-06-26 diff --git a/lib/Models/Terria.ts b/lib/Models/Terria.ts index ea1e1b2fdb5..08f1a89ef32 100644 --- a/lib/Models/Terria.ts +++ b/lib/Models/Terria.ts @@ -351,6 +351,11 @@ export interface ConfigParameters { */ searchBarConfig?: ModelPropertiesFromTraits; searchProviders: ModelPropertiesFromTraits[]; + + /** + * List of the enabled MapViewers: 3d, 3dsmooth, 2d, cesium2d + */ + mapViewers: string[]; } interface StartOptions { @@ -568,7 +573,8 @@ export default class Terria { aboutButtonHrefUrl: "about.html", plugins: undefined, searchBarConfig: undefined, - searchProviders: [] + searchProviders: [], + mapViewers: ["3d", "3dsmooth", "2d"] }; @observable diff --git a/lib/ReactViews/Map/Panels/SettingPanel.tsx b/lib/ReactViews/Map/Panels/SettingPanel.tsx index 39f038774df..ada0c13dbdd 100644 --- a/lib/ReactViews/Map/Panels/SettingPanel.tsx +++ b/lib/ReactViews/Map/Panels/SettingPanel.tsx @@ -53,6 +53,10 @@ class SettingPanel extends React.Component { constructor(props: PropTypes) { super(props); makeObservable(this); + + Object.entries(MapViewers).forEach(([key, elem]) => { + elem.available = props.terria.configParameters.mapViewers.includes(key); + }); } @observable _hoverBaseMap = null; @@ -249,7 +253,7 @@ class SettingPanel extends React.Component { {t("settingPanel.mapView")} - {Object.entries(MapViewers).map(([key, viewerMode]) => ( + {Object.entries(MapViewers).filter(([_, viewerMode]) => viewerMode.available).map(([key, viewerMode]) => ( Date: Mon, 28 Oct 2024 18:47:34 +0100 Subject: [PATCH 3/3] Fix lint problems --- CHANGES.md | 1 + lib/Models/Cesium.ts | 7 +++--- lib/Models/ViewerMode.ts | 2 +- lib/ReactViews/Map/Panels/SettingPanel.tsx | 28 ++++++++++++---------- 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 51a3eb35c44..069121f5e5e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,7 @@ - Remove RollbarErrorServiceProvder - Error services now instantiated externally to terriajs + - Allow to use Cesium in `SCENE2D` mode (and WebMercator projection) as map viewer. - Add a new configuration parameter `mapViewers` to specify which map viewers to show in `SettingPanel`. - [The next improvement] diff --git a/lib/Models/Cesium.ts b/lib/Models/Cesium.ts index 9724dd62745..edd6bed79bf 100644 --- a/lib/Models/Cesium.ts +++ b/lib/Models/Cesium.ts @@ -194,9 +194,10 @@ export default class Cesium extends GlobeOrMap { {} ), scene3DOnly: false, - sceneMode: terriaViewer.viewerMode && terriaViewer.viewerMode === ViewerMode.Cesium - ? SceneMode.SCENE3D - : SceneMode.SCENE2D, + sceneMode: + terriaViewer.viewerMode && terriaViewer.viewerMode === ViewerMode.Cesium + ? SceneMode.SCENE3D + : SceneMode.SCENE2D, mapProjection: terriaViewer.viewerMode && terriaViewer.viewerMode === ViewerMode.Cesium ? new GeographicProjection() diff --git a/lib/Models/ViewerMode.ts b/lib/Models/ViewerMode.ts index 958593eaef0..5bd97bce821 100644 --- a/lib/Models/ViewerMode.ts +++ b/lib/Models/ViewerMode.ts @@ -26,7 +26,7 @@ export const MapViewers = Object.seal({ label: "settingPanel.viewerModeLabels.Leaflet", available: true }, - "cesium2d": { + cesium2d: { viewerMode: ViewerMode.Cesium2D, terrain: false, label: "settingPanel.viewerModeLabels.Leaflet", diff --git a/lib/ReactViews/Map/Panels/SettingPanel.tsx b/lib/ReactViews/Map/Panels/SettingPanel.tsx index ada0c13dbdd..59e4cde72bb 100644 --- a/lib/ReactViews/Map/Panels/SettingPanel.tsx +++ b/lib/ReactViews/Map/Panels/SettingPanel.tsx @@ -175,10 +175,10 @@ class SettingPanel extends React.Component { this.props.terria.mainViewer.viewerMode === ViewerMode.Cesium2D ? ViewerMode.Cesium2D : this.props.terria.mainViewer.viewerMode === ViewerMode.Cesium - ? this.props.terria.mainViewer.viewerOptions.useTerrain - ? "3d" - : "3dsmooth" - : "2d"; + ? this.props.terria.mainViewer.viewerOptions.useTerrain + ? "3d" + : "3dsmooth" + : "2d"; const useNativeResolution = this.props.terria.useNativeResolution; const nativeResolutionLabel = t("settingPanel.nativeResolutionLabel", { @@ -253,15 +253,17 @@ class SettingPanel extends React.Component { {t("settingPanel.mapView")} - {Object.entries(MapViewers).filter(([_, viewerMode]) => viewerMode.available).map(([key, viewerMode]) => ( - this.selectViewer(key as any, event)} - > - {t(viewerMode.label)} - - ))} + {Object.entries(MapViewers) + .filter(([_, viewerMode]) => viewerMode.available) + .map(([key, viewerMode]) => ( + this.selectViewer(key as any, event)} + > + {t(viewerMode.label)} + + ))} {!!supportsSide && ( <>