UNPKG

terriajs

Version:

Geospatial data visualization platform.

221 lines (198 loc) 7.41 kB
import { action } from "mobx"; import Cartesian3 from "terriajs-cesium/Source/Core/Cartesian3"; import Cartographic from "terriajs-cesium/Source/Core/Cartographic"; import CesiumMath from "terriajs-cesium/Source/Core/Math"; import Camera from "terriajs-cesium/Source/Scene/Camera"; import Scene from "terriajs-cesium/Source/Scene/Scene"; import LatLonHeight from "../../../../lib/Core/LatLonHeight"; import Cesium from "../../../../lib/Models/Cesium"; import Terria from "../../../../lib/Models/Terria"; import MovementsController from "../../../../lib/ReactViews/Tools/PedestrianMode/MovementsController"; import { MAX_VERTICAL_LOOK_ANGLE, PEDESTRIAN_HEIGHT } from "../../../../lib/ReactViews/Tools/PedestrianMode/PedestrianMode"; import { setViewerMode } from "../../../../lib/Models/ViewerMode"; describe("MovementsController", function () { let cesium: Cesium; let scene: Scene; let camera: Camera; let controller: MovementsController; beforeEach(async function () { const terria = new Terria(); setViewerMode("3dsmooth", terria.mainViewer); const container = document.createElement("div"); terria.mainViewer.attach(container); await terria.mainViewer.viewerLoadPromise; cesium = terria.cesium!; controller = new MovementsController( cesium, () => {}, PEDESTRIAN_HEIGHT, MAX_VERTICAL_LOOK_ANGLE ); scene = cesium.scene; camera = scene.camera; }); describe("when activated", function () { it( "disables all default map interactions", action(function () { controller.activate(); expect(scene.screenSpaceCameraController.enableTranslate).toBe(false); expect(scene.screenSpaceCameraController.enableRotate).toBe(false); expect(scene.screenSpaceCameraController.enableLook).toBe(false); expect(scene.screenSpaceCameraController.enableTilt).toBe(false); expect(scene.screenSpaceCameraController.enableZoom).toBe(false); expect(cesium.isFeaturePickingPaused).toBe(true); }) ); it("sets up the key map", function () { const setupKeyMap = spyOn(controller, "setupKeyMap"); controller.activate(); expect(setupKeyMap).toHaveBeenCalled(); }); it("sets up the mouse map", function () { const setupMouseMap = spyOn(controller, "setupMouseMap"); controller.activate(); expect(setupMouseMap).toHaveBeenCalled(); }); it("starts animating", function () { const startAnimating = spyOn(controller, "startAnimating"); controller.activate(); expect(startAnimating).toHaveBeenCalled(); }); }); describe("when deactivated", function () { it( "re-enables all default map interactions", action(function () { const deactivate = controller.activate(); deactivate(); expect(scene.screenSpaceCameraController.enableTranslate).toBe(true); expect(scene.screenSpaceCameraController.enableRotate).toBe(true); expect(scene.screenSpaceCameraController.enableLook).toBe(true); expect(scene.screenSpaceCameraController.enableTilt).toBe(true); expect(scene.screenSpaceCameraController.enableZoom).toBe(true); expect(cesium.isFeaturePickingPaused).toBe(false); }) ); it("destroys the key map", function () { const destroyKeyMap = jasmine.createSpy("destroyKeyMap"); spyOn(controller, "setupKeyMap").and.returnValue(destroyKeyMap); const deactivate = controller.activate(); deactivate(); expect(destroyKeyMap).toHaveBeenCalled(); }); it("destroys the mouse map", function () { const destroyMouseMap = jasmine.createSpy("destroyMouseMap"); spyOn(controller, "setupMouseMap").and.returnValue(destroyMouseMap); const deactivate = controller.activate(); deactivate(); expect(destroyMouseMap).toHaveBeenCalled(); }); it("stops animating", function () { const stopAnimating = jasmine.createSpy("stopAnimating"); spyOn(controller, "startAnimating").and.returnValue(stopAnimating); const deactivate = controller.activate(); deactivate(); expect(stopAnimating).toHaveBeenCalled(); }); }); describe("moveAmount", function () { describe("in walk mode", function () { it("is a constant", function () { expect(controller.moveAmount).toBe(0.2); }); }); describe("in fly mode", function () { it("is proportional to the height", function () { controller.mode = "fly"; spyOnProperty( controller, "currentPedestrianHeightFromSurface" ).and.returnValue(100); expect(controller.moveAmount).toBe(1); }); it("is never below baseAmount", function () { controller.mode = "fly"; spyOnProperty( controller, "currentPedestrianHeightFromSurface" ).and.returnValue(0.5); expect(controller.moveAmount).toBe(0.2); }); }); }); describe("when animating", function () { beforeEach(function () { camera.position = Cartographic.toCartesian( Cartographic.fromDegrees(76.93, 8.52, 1) ); }); it("automatically switches to fly mode when moving up", function () { controller.mode = "walk"; controller.activeMovements.add("up"); controller.animate(); expect(controller.mode).toEqual("fly"); }); it("automatically switches to walk mode when moving down and hitting ground", function () { controller.mode = "fly"; controller.activeMovements.add("down"); controller.animate(); expect(controller.mode).toEqual("walk"); }); }); describe("movements", function () { beforeEach(function () { camera.position = Cartographic.toCartesian( Cartographic.fromDegrees(76.93, 8.52, 100) ); }); it("can move forward", function () { spyOnProperty(controller, "moveAmount").and.returnValue(100000); controller.move("forward"); expect(toLatLonHeight(camera.position)).toEqual({ latitude: 8.55, longitude: 77.81, height: 844.61 }); }); it("can move backward", function () { spyOnProperty(controller, "moveAmount").and.returnValue(100000); controller.move("backward"); expect(toLatLonHeight(camera.position)).toEqual({ latitude: 8.49, longitude: 76.05, height: 844.61 }); }); it("can move up", function () { spyOnProperty(controller, "moveAmount").and.returnValue(100); controller.move("up"); expect(toLatLonHeight(camera.position)).toEqual({ latitude: 8.52, longitude: 76.93, height: 200 }); }); it("can move down", function () { spyOnProperty(controller, "moveAmount").and.returnValue(100); controller.move("down"); expect(toLatLonHeight(camera.position)).toEqual({ latitude: 8.52, longitude: 76.93, height: 0 }); }); }); }); function toLatLonHeight(position: Cartesian3): LatLonHeight { const cartographic = Cartographic.fromCartesian(position); const round2 = (float: number) => Math.round(float * 100) / 100; return { latitude: round2(CesiumMath.toDegrees(cartographic.latitude)), longitude: round2(CesiumMath.toDegrees(cartographic.longitude)), height: round2(cartographic.height) }; }