Skip to content

Commit

Permalink
fix(globe): fix position sync (#158)
Browse files Browse the repository at this point in the history
  • Loading branch information
pwambach committed Oct 16, 2019
1 parent 03da065 commit 98fb75c
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 51 deletions.
17 changes: 12 additions & 5 deletions src/scripts/components/globe/globe.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -66,17 +66,24 @@ const Globe: FunctionComponent<Props> = ({
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(() => {
Expand Down Expand Up @@ -117,7 +124,7 @@ const Globe: FunctionComponent<Props> = ({
return;
}

viewer.scene.camera.setView(plainViewToCesiumView(view));
setGlobeView(viewer, view);
}, [viewer, view]);

return (
Expand Down
7 changes: 6 additions & 1 deletion src/scripts/components/url-sync/url-sync.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Expand Down
10 changes: 7 additions & 3 deletions src/scripts/config/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
Expand Down
42 changes: 21 additions & 21 deletions src/scripts/libs/get-globe-view.ts
Original file line number Diff line number Diff line change
@@ -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);
}
39 changes: 27 additions & 12 deletions src/scripts/libs/globe-url-parameter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
8 changes: 0 additions & 8 deletions src/scripts/types/cesium-view.d.ts

This file was deleted.

6 changes: 5 additions & 1 deletion src/scripts/types/globe-view.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
export interface GlobeView {
destination: [number, number, number];
position: {
longitude: number;
latitude: number;
height: number;
};
orientation: {
heading: number;
pitch: number;
Expand Down

0 comments on commit 98fb75c

Please sign in to comment.