import { defaultValue } from "../../Source/Cesium.js"; import { Ellipsoid } from "../../Source/Cesium.js"; import { GeographicTilingScheme } from "../../Source/Cesium.js"; import { GoogleEarthEnterpriseMetadata } from "../../Source/Cesium.js"; import { GoogleEarthEnterpriseTerrainData } from "../../Source/Cesium.js"; import { GoogleEarthEnterpriseTerrainProvider } from "../../Source/Cesium.js"; import { GoogleEarthEnterpriseTileInformation } from "../../Source/Cesium.js"; import { Math as CesiumMath } from "../../Source/Cesium.js"; import { Request } from "../../Source/Cesium.js"; import { RequestScheduler } from "../../Source/Cesium.js"; import { Resource } from "../../Source/Cesium.js"; import { TerrainProvider } from "../../Source/Cesium.js"; import pollToPromise from "../pollToPromise.js"; import { when } from "../../Source/Cesium.js"; describe("Core/GoogleEarthEnterpriseTerrainProvider", function () { function installMockGetQuadTreePacket() { spyOn( GoogleEarthEnterpriseMetadata.prototype, "getQuadTreePacket" ).and.callFake(function (quadKey, version) { quadKey = defaultValue(quadKey, ""); var t = new GoogleEarthEnterpriseTileInformation(0xff, 1, 1, 1); t.ancestorHasTerrain = true; this._tileInfo[quadKey + "0"] = t; t = new GoogleEarthEnterpriseTileInformation(0xff, 1, 1, 1); t.ancestorHasTerrain = true; this._tileInfo[quadKey + "1"] = t; t = new GoogleEarthEnterpriseTileInformation(0xff, 1, 1, 1); t.ancestorHasTerrain = true; this._tileInfo[quadKey + "2"] = t; t = new GoogleEarthEnterpriseTileInformation(0xff, 1, 1, 1); t.ancestorHasTerrain = true; this._tileInfo[quadKey + "3"] = t; return when(); }); } var terrainProvider; function waitForTile(level, x, y, f) { terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ url: "made/up/url", }); return pollToPromise(function () { return ( terrainProvider.ready && terrainProvider.getTileDataAvailable(x, y, level) ); }).then(function () { var promise = terrainProvider.requestTileGeometry(level, x, y); return when(promise, f, function (error) { expect("requestTileGeometry").toBe("returning a tile."); // test failure }); }); } function createRequest() { return new Request({ throttleByServer: true, }); } beforeEach(function () { RequestScheduler.clearForSpecs(); }); afterEach(function () { Resource._Implementations.loadWithXhr = Resource._DefaultImplementations.loadWithXhr; }); it("conforms to TerrainProvider interface", function () { expect(GoogleEarthEnterpriseTerrainProvider).toConformToInterface( TerrainProvider ); }); it("constructor throws if url is not provided", function () { expect(function () { return new GoogleEarthEnterpriseTerrainProvider(); }).toThrowDeveloperError(); expect(function () { return new GoogleEarthEnterpriseTerrainProvider({}); }).toThrowDeveloperError(); }); it("resolves readyPromise", function () { installMockGetQuadTreePacket(); terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ url: "made/up/url", }); return terrainProvider.readyPromise.then(function (result) { expect(result).toBe(true); expect(terrainProvider.ready).toBe(true); }); }); it("resolves readyPromise with Resource", function () { var resource = new Resource({ url: "made/up/url", }); installMockGetQuadTreePacket(); terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ url: resource, }); return terrainProvider.readyPromise.then(function (result) { expect(result).toBe(true); expect(terrainProvider.ready).toBe(true); }); }); it("uses geographic tiling scheme by default", function () { installMockGetQuadTreePacket(); terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ url: "made/up/url", }); return pollToPromise(function () { return terrainProvider.ready; }).then(function () { expect(terrainProvider.tilingScheme).toBeInstanceOf( GeographicTilingScheme ); }); }); it("can use a custom ellipsoid", function () { installMockGetQuadTreePacket(); var ellipsoid = new Ellipsoid(1, 2, 3); terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ url: "made/up/url", ellipsoid: ellipsoid, }); return pollToPromise(function () { return terrainProvider.ready; }).then(function () { expect(terrainProvider.tilingScheme.ellipsoid).toEqual(ellipsoid); }); }); it("has error event", function () { terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ url: "made/up/url", }); expect(terrainProvider.errorEvent).toBeDefined(); expect(terrainProvider.errorEvent).toBe(terrainProvider.errorEvent); }); it("returns reasonable geometric error for various levels", function () { terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ url: "made/up/url", }); expect(terrainProvider.getLevelMaximumGeometricError(0)).toBeGreaterThan( 0.0 ); expect(terrainProvider.getLevelMaximumGeometricError(0)).toEqualEpsilon( terrainProvider.getLevelMaximumGeometricError(1) * 2.0, CesiumMath.EPSILON10 ); expect(terrainProvider.getLevelMaximumGeometricError(1)).toEqualEpsilon( terrainProvider.getLevelMaximumGeometricError(2) * 2.0, CesiumMath.EPSILON10 ); }); it("readyPromise rejects if there isn't terrain", function () { installMockGetQuadTreePacket(); var metadata = new GoogleEarthEnterpriseMetadata({ url: "made/up/url", }); metadata.terrainPresent = false; terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ metadata: metadata, }); return terrainProvider.readyPromise .then(function () { fail("Server does not have terrain, so we shouldn't resolve."); }) .otherwise(function () { expect(terrainProvider.ready).toBe(false); }); }); it("logo is undefined if credit is not provided", function () { installMockGetQuadTreePacket(); terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ url: "made/up/url", }); return pollToPromise(function () { return terrainProvider.ready; }).then(function () { expect(terrainProvider.credit).toBeUndefined(); }); }); it("logo is defined if credit is provided", function () { installMockGetQuadTreePacket(); terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ url: "made/up/url", credit: "thanks to our awesome made up contributors!", }); return pollToPromise(function () { return terrainProvider.ready; }).then(function () { expect(terrainProvider.credit).toBeDefined(); }); }); it("has a water mask is false", function () { installMockGetQuadTreePacket(); terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ url: "made/up/url", }); return pollToPromise(function () { return terrainProvider.ready; }).then(function () { expect(terrainProvider.hasWaterMask).toBe(false); }); }); it("has vertex normals is false", function () { installMockGetQuadTreePacket(); terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ url: "made/up/url", }); return pollToPromise(function () { return terrainProvider.ready; }).then(function () { expect(terrainProvider.hasVertexNormals).toBe(false); }); }); describe("requestTileGeometry", function () { it("provides GoogleEarthEnterpriseTerrainData", function () { installMockGetQuadTreePacket(); Resource._Implementations.loadWithXhr = function ( url, responseType, method, data, headers, deferred, overrideMimeType ) { Resource._DefaultImplementations.loadWithXhr( "Data/GoogleEarthEnterprise/gee.terrain", responseType, method, data, headers, deferred ); }; return waitForTile(0, 0, 0, function (loadedData) { expect(loadedData).toBeInstanceOf(GoogleEarthEnterpriseTerrainData); }); }); it("returns undefined if too many requests are already in progress", function () { installMockGetQuadTreePacket(); var baseUrl = "made/up/url"; var deferreds = []; var loadRealTile = true; Resource._Implementations.loadWithXhr = function ( url, responseType, method, data, headers, deferred, overrideMimeType ) { if (url.indexOf("dbRoot.v5") !== -1) { return deferred.reject(); // Just reject dbRoot file and use defaults. } if (loadRealTile) { loadRealTile = false; return Resource._DefaultImplementations.loadWithXhr( "Data/GoogleEarthEnterprise/gee.terrain", responseType, method, data, headers, deferred ); } // Do nothing, so requests never complete deferreds.push(deferred); }; terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ url: baseUrl, }); var promises = []; return pollToPromise(function () { return terrainProvider.ready; }) .then(function () { return pollToPromise(function () { var b = true; for (var i = 0; i < 10; ++i) { b = b && terrainProvider.getTileDataAvailable(i, i, i); } return b && terrainProvider.getTileDataAvailable(1, 2, 3); }); }) .then(function () { var promise; for (var i = 0; i < RequestScheduler.maximumRequestsPerServer; ++i) { promise = terrainProvider.requestTileGeometry( i, i, i, createRequest() ); promises.push(promise); } RequestScheduler.update(); expect(promise).toBeDefined(); return terrainProvider.requestTileGeometry(1, 2, 3, createRequest()); }) .then(function (terrainData) { expect(terrainData).toBeUndefined(); for (var i = 0; i < deferreds.length; ++i) { deferreds[i].resolve(); } // Parsing terrain will fail, so just eat the errors and request the tile again return when.all(promises).otherwise(function () { loadRealTile = true; return terrainProvider.requestTileGeometry(1, 2, 3); }); }) .then(function (terrainData) { expect(terrainData).toBeDefined(); }); }); it("supports getTileDataAvailable()", function () { installMockGetQuadTreePacket(); var baseUrl = "made/up/url"; Resource._Implementations.loadWithXhr = function ( url, responseType, method, data, headers, deferred, overrideMimeType ) { Resource._DefaultImplementations.loadWithXhr( "Data/CesiumTerrainTileJson/tile.terrain", responseType, method, data, headers, deferred ); }; terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ url: baseUrl, }); return pollToPromise(function () { return terrainProvider.ready; }).then(function () { var tileInfo = terrainProvider._metadata._tileInfo; var info = tileInfo[GoogleEarthEnterpriseMetadata.tileXYToQuadKey(0, 1, 0)]; info._bits = 0x7f; // Remove terrain bit from 0,1,0 tile info.terrainState = 1; // NONE info.ancestorHasTerrain = true; expect(terrainProvider.getTileDataAvailable(0, 0, 0)).toBe(true); expect(terrainProvider.getTileDataAvailable(0, 1, 0)).toBe(false); expect(terrainProvider.getTileDataAvailable(1, 0, 0)).toBe(true); expect(terrainProvider.getTileDataAvailable(1, 1, 0)).toBe(true); expect(terrainProvider.getTileDataAvailable(0, 0, 2)).toBe(false); }); }); }); });