UNPKG

maplibre-gl

Version:

BSD licensed community fork of mapbox-gl, a WebGL interactive maps library

115 lines (87 loc) 4.96 kB
import {describe, beforeEach, test, expect, vi} from 'vitest'; import {createMap, beforeMapTest} from '../../util/test/util'; import {LngLat} from '../../geo/lng_lat'; import {type OverscaledTileID} from '../../source/tile_id'; import {type CameraOptions} from '../camera'; import {type Terrain} from '../../render/terrain'; import {mercatorZfromAltitude} from '../../geo/mercator_coordinate'; beforeEach(() => { beforeMapTest(); global.fetch = null; }); describe('calculateCameraOptionsFromTo', () => { // Choose initial zoom to avoid center being constrained by mercator latitude limits. test('pitch 90 with terrain', () => { const map = createMap(); const mockedGetElevation = vi.fn((_lngLat: LngLat, _zoom: number) => 111200); const terrainStub = {} as Terrain; terrainStub.getElevationForLngLatZoom = mockedGetElevation; map.terrain = terrainStub; // distance between lng x and lng x+1 is 111.2km at same lat // altitude same as center elevation => 90° pitch const cameraOptions: CameraOptions = map.calculateCameraOptionsFromTo(new LngLat(1, 0), 111200, new LngLat(0, 0)); expect(cameraOptions).toBeDefined(); expect(cameraOptions.pitch).toBeCloseTo(90); expect(mockedGetElevation.mock.calls).toHaveLength(1); }); test('pitch 153.435 with terrain', () => { const map = createMap(); const mockedGetElevation = vi.fn((_lngLat: LngLat, _zoom: number) => 111200 * 3); const terrainStub = {} as Terrain; terrainStub.getElevationForLngLatZoom = mockedGetElevation; map.terrain = terrainStub; // distance between lng x and lng x+1 is 111.2km at same lat // (elevation difference of cam and center) / 2 = grounddistance => // acos(111.2 / sqrt(111.2² + (111.2 * 2)²)) = acos(1/sqrt(5)) => 63.435 + 90 = 153.435 const cameraOptions: CameraOptions = map.calculateCameraOptionsFromTo(new LngLat(1, 0), 111200, new LngLat(0, 0)); expect(cameraOptions).toBeDefined(); expect(cameraOptions.pitch).toBeCloseTo(153.435); expect(mockedGetElevation.mock.calls).toHaveLength(1); }); test('pitch 63 with terrain', () => { const map = createMap(); const mockedGetElevation = vi.fn((_lngLat: LngLat, _zoom: number) => 111200 / 2); const terrainStub = {} as Terrain; terrainStub.getElevationForLngLatZoom = mockedGetElevation; map.terrain = terrainStub; // distance between lng x and lng x+1 is 111.2km at same lat // (elevation difference of cam and center) * 2 = grounddistance => // acos(111.2 / sqrt(111.2² + (111.2 * 0.5)²)) = acos(1/sqrt(1.25)) => 90 (looking down) - 26.565 = 63.435 const cameraOptions: CameraOptions = map.calculateCameraOptionsFromTo(new LngLat(0, 0), 111200, new LngLat(1, 0)); expect(cameraOptions).toBeDefined(); expect(cameraOptions.pitch).toBeCloseTo(63.435); expect(mockedGetElevation.mock.calls).toHaveLength(1); }); test('zoom distance 1000', () => { const map = createMap(); const mockedGetElevation = vi.fn((_lngLat: LngLat, _zoom: number) => 1000); const terrainStub = {} as Terrain; terrainStub.getElevationForLngLatZoom = mockedGetElevation; map.terrain = terrainStub; const expectedZoom = Math.log2(map.transform.cameraToCenterDistance / mercatorZfromAltitude(1000, 0) / map.transform.tileSize); const cameraOptions = map.calculateCameraOptionsFromTo(new LngLat(0, 0), 0, new LngLat(0, 0)); expect(cameraOptions).toBeDefined(); expect(cameraOptions.zoom).toBeCloseTo(expectedZoom); expect(mockedGetElevation.mock.calls).toHaveLength(1); }); test('don\'t call getElevation when altitude supplied', () => { const map = createMap(); const mockedGetElevation = vi.fn((_tileID: OverscaledTileID, _x: number, _y: number, _extent?: number) => 0); const terrainStub = {} as Terrain; terrainStub.getElevation = mockedGetElevation; map.terrain = terrainStub; const cameraOptions = map.calculateCameraOptionsFromTo(new LngLat(0, 0), 0, new LngLat(0, 0), 1000); expect(cameraOptions).toBeDefined(); expect(mockedGetElevation.mock.calls).toHaveLength(0); }); test('don\'t call getElevation when altitude 0 supplied', () => { const map = createMap(); const mockedGetElevation = vi.fn((_tileID: OverscaledTileID, _x: number, _y: number, _extent?: number) => 0); const terrainStub = {} as Terrain; terrainStub.getElevation = mockedGetElevation; map.terrain = terrainStub; const cameraOptions = map.calculateCameraOptionsFromTo(new LngLat(0, 0), 0, new LngLat(1, 0), 0); expect(cameraOptions).toBeDefined(); expect(mockedGetElevation.mock.calls).toHaveLength(0); }); });