diff --git a/src/scripts/components/globe/globe.tsx b/src/scripts/components/globe/globe.tsx index ddba09842..765d4a636 100644 --- a/src/scripts/components/globe/globe.tsx +++ b/src/scripts/components/globe/globe.tsx @@ -1,6 +1,6 @@ import React, {FunctionComponent, useRef, useEffect, useState} from 'react'; -import getGlobeView, {plainViewToCesiumView} from '../../libs/get-globe-view'; +import {getGlobeView, setGlobeView} from '../../libs/get-globe-view'; import {GlobeView} from '../../types/globe-view'; import {GlobeProjection} from '../../types/globe-projection'; @@ -66,17 +66,24 @@ const Globe: FunctionComponent = ({ return () => {}; } + // set correct scene mode + const sceneMode = + projection === GlobeProjection.Sphere + ? Cesium.SceneMode.SCENE3D + : Cesium.SceneMode.SCENE2D; + const options = {...cesiumOptions, sceneMode}; + // create cesium viewer - const scopedViewer = new Cesium.Viewer(ref.current, cesiumOptions); + const scopedViewer = new Cesium.Viewer(ref.current, options); // save viewer reference setViewer(scopedViewer); // set initial camera view - scopedViewer.scene.camera.setView(plainViewToCesiumView(view)); + setGlobeView(scopedViewer, view); // make camera change listener more sensitiv - scopedViewer.camera.percentageChanged = 0.01; + scopedViewer.camera.percentageChanged = 0.001; // add camera change listener scopedViewer.camera.changed.addEventListener(() => { @@ -117,7 +124,7 @@ const Globe: FunctionComponent = ({ return; } - viewer.scene.camera.setView(plainViewToCesiumView(view)); + setGlobeView(viewer, view); }, [viewer, view]); return ( diff --git a/src/scripts/components/url-sync/url-sync.tsx b/src/scripts/components/url-sync/url-sync.tsx index d03881a3c..c44485d89 100644 --- a/src/scripts/components/url-sync/url-sync.tsx +++ b/src/scripts/components/url-sync/url-sync.tsx @@ -13,8 +13,13 @@ const UrlSync: FunctionComponent<{}> = () => { // set globe query params in url when globe state changes useEffect(() => { - const params = new URLSearchParams(location.search); const globeValue = getParamString(globeState); + + if (!globeValue) { + return; + } + + const params = new URLSearchParams(location.search); params.set('globe', globeValue); history.replace({search: params.toString()}); }, [globeState]); diff --git a/src/scripts/config/main.ts b/src/scripts/config/main.ts index 896cbfe18..809962f13 100644 --- a/src/scripts/config/main.ts +++ b/src/scripts/config/main.ts @@ -4,10 +4,14 @@ import {GlobeProjection} from '../types/globe-projection'; const globeState: GlobeState = { projection: GlobeProjection.Sphere, view: { - destination: [18888448, 279066, 15407835], + position: { + height: 14484862, + latitude: 0.659017, + longitude: 0.002816 + }, orientation: { - heading: 6.2, - pitch: -1.59, + heading: Math.PI * 2, + pitch: Math.PI / -2, roll: 0 } } diff --git a/src/scripts/libs/get-globe-view.ts b/src/scripts/libs/get-globe-view.ts index 0433d623d..7a7f74919 100644 --- a/src/scripts/libs/get-globe-view.ts +++ b/src/scripts/libs/get-globe-view.ts @@ -1,39 +1,39 @@ import 'cesium/Build/Cesium/Cesium'; -import {CesiumView} from '../types/cesium-view'; import {GlobeView} from '../types/globe-view'; -export function cesiumViewToPlainView(cesiumView: CesiumView): GlobeView { - const {destination} = cesiumView; +const Cesium = window.Cesium; - return { - ...cesiumView, - destination: [destination.x, destination.y, destination.z] +// set the camera according to the given globe view +export function setGlobeView(viewer: Cesium.Viewer, view: GlobeView): void { + const {position, orientation} = view; + const cesiumView = { + destination: Cesium.Cartesian3.fromRadians( + position.longitude, + position.latitude, + position.height + ), + orientation }; -} -export function plainViewToCesiumView(plainView: GlobeView): CesiumView { - const {destination} = plainView; - - return { - ...plainView, - destination: window.Cesium.Cartesian3.fromArray(destination) - }; + viewer.scene.camera.setView(cesiumView); } -// get the position and camera distance from a cesium viewer -export default function getGlobeView(viewer: Cesium.Viewer): GlobeView { +// get the globe view from the current cesium camera +export function getGlobeView(viewer: Cesium.Viewer): GlobeView { const camera = viewer.scene.camera; - const destination = camera.positionWC; + const position = camera.positionCartographic; - const cesiumView = { - destination, + return { + position: { + longitude: position.longitude, + latitude: position.latitude, + height: position.height + }, orientation: { heading: camera.heading, pitch: camera.pitch, roll: camera.roll } }; - - return cesiumViewToPlainView(cesiumView); } diff --git a/src/scripts/libs/globe-url-parameter.ts b/src/scripts/libs/globe-url-parameter.ts index 50ae1d7ed..04bf8c792 100644 --- a/src/scripts/libs/globe-url-parameter.ts +++ b/src/scripts/libs/globe-url-parameter.ts @@ -41,28 +41,43 @@ export function parseUrl(): GlobeState | null { return null; } + // convert degree to radians + values[0] = values[0] * (Math.PI / 180); + values[1] = values[1] * (Math.PI / 180); + return { view: { - orientation: { - heading: values[0], - pitch: values[1], - roll: values[2] + position: { + longitude: values[0], + latitude: values[1], + height: values[2] }, - destination: [values[3], values[4], values[5]] + orientation: { + heading: values[3], + pitch: values[4], + roll: values[5] + } }, projection }; } -export function getParamString(globeState: GlobeState): string { +export function getParamString(globeState: GlobeState): string | null { const {view, projection} = globeState; - const {orientation, destination} = view; + const {position, orientation} = view; + const {longitude, latitude, height} = position; const {heading, pitch, roll} = orientation; + const values = [longitude, latitude, height, heading, pitch, roll]; + + if (values.some(num => isNaN(num))) { + return null; + } + + // convert radians to degree + values[0] = values[0] * (180 / Math.PI); + values[1] = values[1] * (180 / Math.PI); - const orientationString = [heading, pitch, roll] - .map(num => num.toFixed(2)) - .join(char); - const destinationString = destination.map(num => Math.round(num)).join(char); + const compactValues = values.map(num => num.toFixed(2)); - return [projection[0], orientationString, destinationString].join(char); + return [projection[0], ...compactValues].join(char); } diff --git a/src/scripts/types/cesium-view.d.ts b/src/scripts/types/cesium-view.d.ts deleted file mode 100644 index c5eb70df0..000000000 --- a/src/scripts/types/cesium-view.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -export interface CesiumView { - destination: Cesium.Cartesian3; - orientation: { - heading: number; - pitch: number; - roll: number; - }; -} diff --git a/src/scripts/types/globe-view.d.ts b/src/scripts/types/globe-view.d.ts index ccc944d57..e0f0a8f1d 100644 --- a/src/scripts/types/globe-view.d.ts +++ b/src/scripts/types/globe-view.d.ts @@ -1,5 +1,9 @@ export interface GlobeView { - destination: [number, number, number]; + position: { + longitude: number; + latitude: number; + height: number; + }; orientation: { heading: number; pitch: number;