import { CesiumTerrainProvider } from "../../Source/Cesium.js"; import { Ellipsoid } from "../../Source/Cesium.js"; import { GeographicTilingScheme } from "../../Source/Cesium.js"; import { getAbsoluteUri } from "../../Source/Cesium.js"; import { HeightmapTerrainData } from "../../Source/Cesium.js"; import { IonResource } from "../../Source/Cesium.js"; import { Math as CesiumMath } from "../../Source/Cesium.js"; import { QuantizedMeshTerrainData } 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/CesiumTerrainProvider", function () { beforeEach(function () { RequestScheduler.clearForSpecs(); }); afterEach(function () { Resource._Implementations.loadWithXhr = Resource._DefaultImplementations.loadWithXhr; }); function returnTileJson(path) { var oldLoad = Resource._Implementations.loadWithXhr; Resource._Implementations.loadWithXhr = function ( url, responseType, method, data, headers, deferred, overrideMimeType ) { if (url.indexOf("layer.json") >= 0) { Resource._DefaultImplementations.loadWithXhr( path, responseType, method, data, headers, deferred ); } else { return oldLoad( url, responseType, method, data, headers, deferred, overrideMimeType ); } }; } function returnHeightmapTileJson() { return returnTileJson( "Data/CesiumTerrainTileJson/StandardHeightmap.tile.json" ); } function returnQuantizedMeshTileJson() { return returnTileJson("Data/CesiumTerrainTileJson/QuantizedMesh.tile.json"); } function returnVertexNormalTileJson() { return returnTileJson("Data/CesiumTerrainTileJson/VertexNormals.tile.json"); } function returnOctVertexNormalTileJson() { return returnTileJson( "Data/CesiumTerrainTileJson/OctVertexNormals.tile.json" ); } function returnWaterMaskTileJson() { return returnTileJson("Data/CesiumTerrainTileJson/WaterMask.tile.json"); } function returnPartialAvailabilityTileJson() { return returnTileJson( "Data/CesiumTerrainTileJson/PartialAvailability.tile.json" ); } function returnParentUrlTileJson() { var paths = [ "Data/CesiumTerrainTileJson/ParentUrl.tile.json", "Data/CesiumTerrainTileJson/Parent.tile.json", ]; var i = 0; var oldLoad = Resource._Implementations.loadWithXhr; Resource._Implementations.loadWithXhr = function ( url, responseType, method, data, headers, deferred, overrideMimeType ) { if (url.indexOf("layer.json") >= 0) { Resource._DefaultImplementations.loadWithXhr( paths[i++], responseType, method, data, headers, deferred ); } else { return oldLoad( url, responseType, method, data, headers, deferred, overrideMimeType ); } }; } function returnMetadataAvailabilityTileJson() { return returnTileJson( "Data/CesiumTerrainTileJson/MetadataAvailability.tile.json" ); } function waitForTile(level, x, y, requestNormals, requestWaterMask, f) { var terrainProvider = new CesiumTerrainProvider({ url: "made/up/url", requestVertexNormals: requestNormals, requestWaterMask: requestWaterMask, }); return pollToPromise(function () { return terrainProvider.ready; }).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, }); } it("conforms to TerrainProvider interface", function () { expect(CesiumTerrainProvider).toConformToInterface(TerrainProvider); }); it("constructor throws if url is not provided", function () { expect(function () { return new CesiumTerrainProvider(); }).toThrowDeveloperError(); expect(function () { return new CesiumTerrainProvider({}); }).toThrowDeveloperError(); }); it("resolves readyPromise", function () { var provider = new CesiumTerrainProvider({ url: "made/up/url", }); return provider.readyPromise.then(function (result) { expect(result).toBe(true); expect(provider.ready).toBe(true); }); }); it("resolves readyPromise when url promise is used", function () { var provider = new CesiumTerrainProvider({ url: when.resolve("made/up/url"), }); return provider.readyPromise.then(function (result) { expect(result).toBe(true); expect(provider.ready).toBe(true); }); }); it("resolves readyPromise with Resource", function () { var resource = new Resource({ url: "made/up/url", }); var provider = new CesiumTerrainProvider({ url: resource, }); return provider.readyPromise.then(function (result) { expect(result).toBe(true); expect(provider.ready).toBe(true); }); }); it("rejects readyPromise when url rejects", function () { var error = new Error(); var provider = new CesiumTerrainProvider({ url: when.reject(error), }); return provider.readyPromise .then(function () { fail("should not resolve"); }) .otherwise(function (result) { expect(result).toBe(error); expect(provider.ready).toBe(false); }); }); it("uses geographic tiling scheme by default", function () { returnHeightmapTileJson(); var provider = new CesiumTerrainProvider({ url: "made/up/url", }); return pollToPromise(function () { return provider.ready; }).then(function () { expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); }); }); it("can use a custom ellipsoid", function () { returnHeightmapTileJson(); var ellipsoid = new Ellipsoid(1, 2, 3); var provider = new CesiumTerrainProvider({ url: "made/up/url", ellipsoid: ellipsoid, }); return pollToPromise(function () { return provider.ready; }).then(function () { expect(provider.tilingScheme.ellipsoid).toEqual(ellipsoid); }); }); it("has error event", function () { var provider = new CesiumTerrainProvider({ url: "made/up/url", }); expect(provider.errorEvent).toBeDefined(); expect(provider.errorEvent).toBe(provider.errorEvent); }); it("returns reasonable geometric error for various levels", function () { returnQuantizedMeshTileJson(); var provider = new CesiumTerrainProvider({ url: "made/up/url", }); return pollToPromise(function () { return provider.ready; }).then(function () { expect(provider.getLevelMaximumGeometricError(0)).toBeGreaterThan(0.0); expect(provider.getLevelMaximumGeometricError(0)).toEqualEpsilon( provider.getLevelMaximumGeometricError(1) * 2.0, CesiumMath.EPSILON10 ); expect(provider.getLevelMaximumGeometricError(1)).toEqualEpsilon( provider.getLevelMaximumGeometricError(2) * 2.0, CesiumMath.EPSILON10 ); }); }); it("logo is undefined if credit is not provided", function () { returnHeightmapTileJson(); var provider = new CesiumTerrainProvider({ url: "made/up/url", }); return pollToPromise(function () { return provider.ready; }).then(function () { expect(provider.credit).toBeUndefined(); }); }); it("logo is defined if credit is provided", function () { returnHeightmapTileJson(); var provider = new CesiumTerrainProvider({ url: "made/up/url", credit: "thanks to our awesome made up contributors!", }); return pollToPromise(function () { return provider.ready; }).then(function () { expect(provider.credit).toBeDefined(); }); }); it("has a water mask", function () { returnHeightmapTileJson(); var provider = new CesiumTerrainProvider({ url: "made/up/url", }); return pollToPromise(function () { return provider.ready; }).then(function () { expect(provider.hasWaterMask).toBe(true); }); }); it("has vertex normals", function () { returnOctVertexNormalTileJson(); var provider = new CesiumTerrainProvider({ url: "made/up/url", requestVertexNormals: true, }); return pollToPromise(function () { return provider.ready; }).then(function () { expect(provider.requestVertexNormals).toBe(true); expect(provider.hasVertexNormals).toBe(true); }); }); it("does not request vertex normals", function () { returnOctVertexNormalTileJson(); var provider = new CesiumTerrainProvider({ url: "made/up/url", requestVertexNormals: false, }); return pollToPromise(function () { return provider.ready; }).then(function () { expect(provider.requestVertexNormals).toBe(false); expect(provider.hasVertexNormals).toBe(false); }); }); it("requests parent layer.json", function () { returnParentUrlTileJson(); var provider = new CesiumTerrainProvider({ url: "made/up/url", requestVertexNormals: true, requestWaterMask: true, }); return pollToPromise(function () { return provider.ready; }).then(function () { expect(provider._tileCredits[0].html).toBe( "This is a child tileset! This amazing data is courtesy The Amazing Data Source!" ); expect(provider.requestVertexNormals).toBe(true); expect(provider.requestWaterMask).toBe(true); expect(provider.hasVertexNormals).toBe(false); // Neither tileset has them expect(provider.hasWaterMask).toBe(true); // The child tileset has them expect(provider.availability.isTileAvailable(1, 2, 1)).toBe(true); // Both have this expect(provider.availability.isTileAvailable(1, 3, 1)).toBe(true); // Parent has this, but child doesn't expect(provider.availability.isTileAvailable(2, 0, 0)).toBe(false); // Neither has this var layers = provider._layers; expect(layers.length).toBe(2); expect(layers[0].hasVertexNormals).toBe(false); expect(layers[0].hasWaterMask).toBe(true); expect(layers[0].availability.isTileAvailable(1, 2, 1)).toBe(true); expect(layers[0].availability.isTileAvailable(1, 3, 1)).toBe(false); expect(layers[0].availability.isTileAvailable(2, 0, 0)).toBe(false); expect(layers[1].hasVertexNormals).toBe(false); expect(layers[1].hasWaterMask).toBe(false); expect(layers[1].availability.isTileAvailable(1, 2, 1)).toBe(true); expect(layers[1].availability.isTileAvailable(1, 3, 1)).toBe(true); expect(layers[1].availability.isTileAvailable(2, 0, 0)).toBe(false); }); }); it("raises an error if layer.json does not specify a format", function () { returnTileJson("Data/CesiumTerrainTileJson/NoFormat.tile.json"); var provider = new CesiumTerrainProvider({ url: "made/up/url", }); var deferred = when.defer(); provider.errorEvent.addEventListener(function (e) { deferred.resolve(e); }); return deferred.promise.then(function (error) { expect(error.message).toContain("format is not specified"); }); }); it("raises an error if layer.json specifies an unknown format", function () { returnTileJson("Data/CesiumTerrainTileJson/InvalidFormat.tile.json"); var provider = new CesiumTerrainProvider({ url: "made/up/url", }); var deferred = when.defer(); provider.errorEvent.addEventListener(function (e) { deferred.resolve(e); }); return deferred.promise.then(function (error) { expect(error.message).toContain("invalid or not supported"); }); }); it("raises an error if layer.json does not specify quantized-mesh 1.x format", function () { returnTileJson("Data/CesiumTerrainTileJson/QuantizedMesh2.0.tile.json"); var provider = new CesiumTerrainProvider({ url: "made/up/url", }); var deferred = when.defer(); provider.errorEvent.addEventListener(function (e) { deferred.resolve(e); }); return deferred.promise.then(function (error) { expect(error.message).toContain("invalid or not supported"); }); }); it("supports quantized-mesh1.x minor versions", function () { returnTileJson("Data/CesiumTerrainTileJson/QuantizedMesh1.1.tile.json"); var provider = new CesiumTerrainProvider({ url: "made/up/url", }); var errorListener = jasmine.createSpy("error"); provider.errorEvent.addEventListener(errorListener); return pollToPromise(function () { return provider.ready; }).then(function () { expect(errorListener).not.toHaveBeenCalled(); }); }); it("raises an error if layer.json does not specify a tiles property", function () { returnTileJson("Data/CesiumTerrainTileJson/NoTiles.tile.json"); var provider = new CesiumTerrainProvider({ url: "made/up/url", }); var deferred = when.defer(); provider.errorEvent.addEventListener(function (e) { deferred.resolve(e); }); return deferred.promise.then(function (error) { expect(error.message).toContain( "does not specify any tile URL templates" ); }); }); it("raises an error if layer.json tiles property is an empty array", function () { returnTileJson("Data/CesiumTerrainTileJson/EmptyTilesArray.tile.json"); var provider = new CesiumTerrainProvider({ url: "made/up/url", }); var deferred = when.defer(); provider.errorEvent.addEventListener(function (e) { deferred.resolve(e); }); return deferred.promise.then(function (error) { expect(error.message).toContain( "does not specify any tile URL templates" ); }); }); it("uses attribution specified in layer.json", function () { returnTileJson("Data/CesiumTerrainTileJson/WithAttribution.tile.json"); var provider = new CesiumTerrainProvider({ url: "made/up/url", }); return pollToPromise(function () { return provider.ready; }).then(function () { expect(provider._tileCredits[0].html).toBe( "This amazing data is courtesy The Amazing Data Source!" ); }); }); it("do not add blank attribution if layer.json does not have one", function () { returnTileJson("Data/CesiumTerrainTileJson/WaterMask.tile.json"); var provider = new CesiumTerrainProvider({ url: "made/up/url", }); return pollToPromise(function () { return provider.ready; }).then(function () { expect(provider._tileCredit).toBeUndefined(); }); }); it("The undefined availability tile is returned at level 0", function () { var layer = { availabilityLevels: 10, }; expect( CesiumTerrainProvider._getAvailabilityTile(layer, 0, 0, 0) ).toBeUndefined(); expect( CesiumTerrainProvider._getAvailabilityTile(layer, 1, 0, 0) ).toBeUndefined(); }); it("The correct availability tile is computed in first level", function () { var layer = { availabilityLevels: 10, }; expect(CesiumTerrainProvider._getAvailabilityTile(layer, 1, 1, 1)).toEqual({ level: 0, x: 0, y: 0, }); expect(CesiumTerrainProvider._getAvailabilityTile(layer, 4, 2, 2)).toEqual({ level: 0, x: 1, y: 0, }); expect( CesiumTerrainProvider._getAvailabilityTile(layer, 80, 50, 10) ).toEqual({ level: 0, x: 0, y: 0, }); }); it("The correct availability tile is computed in second level", function () { var layer = { availabilityLevels: 10, }; var expected = { level: 10, x: 80, y: 50, }; var xs = [expected.x, expected.x]; var ys = [expected.y, expected.y]; // Compute level 20 tiles by always taking SW or NE child for (var i = 0; i < 10; ++i) { xs[0] *= 2; ys[0] *= 2; xs[1] = xs[1] * 2 + 1; ys[1] = ys[1] * 2 + 1; } expect( CesiumTerrainProvider._getAvailabilityTile(layer, xs[0], ys[0], 20) ).toEqual(expected); expect( CesiumTerrainProvider._getAvailabilityTile(layer, xs[1], ys[1], 20) ).toEqual(expected); }); describe("requestTileGeometry", function () { it("uses multiple urls specified in layer.json", function () { returnTileJson("Data/CesiumTerrainTileJson/MultipleUrls.tile.json"); var provider = new CesiumTerrainProvider({ url: "made/up/url", }); return pollToPromise(function () { return provider.ready; }).then(function () { spyOn(Resource._Implementations, "loadWithXhr"); provider.requestTileGeometry(0, 0, 0); expect( Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] ).toContain("foo0.com"); provider.requestTileGeometry(1, 0, 0); expect( Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] ).toContain("foo1.com"); provider.requestTileGeometry(1, -1, 0); expect( Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] ).toContain("foo2.com"); provider.requestTileGeometry(1, 0, 1); expect( Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] ).toContain("foo3.com"); }); }); it("supports scheme-less template URLs in layer.json resolved with absolute URL", function () { returnTileJson("Data/CesiumTerrainTileJson/MultipleUrls.tile.json"); var url = getAbsoluteUri("Data/CesiumTerrainTileJson"); var provider = new CesiumTerrainProvider({ url: url, }); return pollToPromise(function () { return provider.ready; }).then(function () { spyOn(Resource._Implementations, "loadWithXhr"); provider.requestTileGeometry(0, 0, 0); expect( Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] ).toContain("foo0.com"); provider.requestTileGeometry(1, 0, 0); expect( Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] ).toContain("foo1.com"); provider.requestTileGeometry(1, -1, 0); expect( Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] ).toContain("foo2.com"); provider.requestTileGeometry(1, 0, 1); expect( Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] ).toContain("foo3.com"); }); }); it("provides HeightmapTerrainData", function () { Resource._Implementations.loadWithXhr = function ( url, responseType, method, data, headers, deferred, overrideMimeType ) { // Just return any old file, as long as its big enough Resource._DefaultImplementations.loadWithXhr( "Data/EarthOrientationParameters/IcrfToFixedStkComponentsRotationData.json", responseType, method, data, headers, deferred ); }; returnHeightmapTileJson(); return waitForTile(0, 0, 0, false, false, function (loadedData) { expect(loadedData).toBeInstanceOf(HeightmapTerrainData); }); }); it("provides QuantizedMeshTerrainData", function () { Resource._Implementations.loadWithXhr = function ( url, responseType, method, data, headers, deferred, overrideMimeType ) { Resource._DefaultImplementations.loadWithXhr( "Data/CesiumTerrainTileJson/tile.terrain", responseType, method, data, headers, deferred ); }; returnQuantizedMeshTileJson(); return waitForTile(0, 0, 0, false, false, function (loadedData) { expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); }); }); it("provides QuantizedMeshTerrainData with 32bit indices", function () { Resource._Implementations.loadWithXhr = function ( url, responseType, method, data, headers, deferred, overrideMimeType ) { Resource._DefaultImplementations.loadWithXhr( "Data/CesiumTerrainTileJson/tile.32bitIndices.terrain", responseType, method, data, headers, deferred ); }; returnQuantizedMeshTileJson(); return waitForTile(0, 0, 0, false, false, function (loadedData) { expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); expect(loadedData._indices.BYTES_PER_ELEMENT).toBe(4); }); }); it("provides QuantizedMeshTerrainData with VertexNormals", function () { Resource._Implementations.loadWithXhr = function ( url, responseType, method, data, headers, deferred, overrideMimeType ) { Resource._DefaultImplementations.loadWithXhr( "Data/CesiumTerrainTileJson/tile.vertexnormals.terrain", responseType, method, data, headers, deferred ); }; returnVertexNormalTileJson(); return waitForTile(0, 0, 0, true, false, function (loadedData) { expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); expect(loadedData._encodedNormals).toBeDefined(); }); }); it("provides QuantizedMeshTerrainData with WaterMask", function () { Resource._Implementations.loadWithXhr = function ( url, responseType, method, data, headers, deferred, overrideMimeType ) { Resource._DefaultImplementations.loadWithXhr( "Data/CesiumTerrainTileJson/tile.watermask.terrain", responseType, method, data, headers, deferred ); }; returnWaterMaskTileJson(); return waitForTile(0, 0, 0, false, true, function (loadedData) { expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); expect(loadedData._waterMask).toBeDefined(); }); }); it("provides QuantizedMeshTerrainData with VertexNormals and WaterMask", function () { Resource._Implementations.loadWithXhr = function ( url, responseType, method, data, headers, deferred, overrideMimeType ) { Resource._DefaultImplementations.loadWithXhr( "Data/CesiumTerrainTileJson/tile.octvertexnormals.watermask.terrain", responseType, method, data, headers, deferred ); }; returnWaterMaskTileJson(); return waitForTile(0, 0, 0, true, true, function (loadedData) { expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); expect(loadedData._encodedNormals).toBeDefined(); expect(loadedData._waterMask).toBeDefined(); }); }); it("provides QuantizedMeshTerrainData with OctVertexNormals", function () { Resource._Implementations.loadWithXhr = function ( url, responseType, method, data, headers, deferred, overrideMimeType ) { Resource._DefaultImplementations.loadWithXhr( "Data/CesiumTerrainTileJson/tile.octvertexnormals.terrain", responseType, method, data, headers, deferred ); }; returnOctVertexNormalTileJson(); return waitForTile(0, 0, 0, true, false, function (loadedData) { expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); expect(loadedData._encodedNormals).toBeDefined(); }); }); it("provides QuantizedMeshTerrainData with VertexNormals and unknown extensions", function () { Resource._Implementations.loadWithXhr = function ( url, responseType, method, data, headers, deferred, overrideMimeType ) { Resource._DefaultImplementations.loadWithXhr( "Data/CesiumTerrainTileJson/tile.vertexnormals.unknownext.terrain", responseType, method, data, headers, deferred ); }; returnVertexNormalTileJson(); return waitForTile(0, 0, 0, true, false, function (loadedData) { expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); expect(loadedData._encodedNormals).toBeDefined(); }); }); it("provides QuantizedMeshTerrainData with OctVertexNormals and unknown extensions", function () { Resource._Implementations.loadWithXhr = function ( url, responseType, method, data, headers, deferred, overrideMimeType ) { Resource._DefaultImplementations.loadWithXhr( "Data/CesiumTerrainTileJson/tile.octvertexnormals.unknownext.terrain", responseType, method, data, headers, deferred ); }; returnOctVertexNormalTileJson(); return waitForTile(0, 0, 0, true, false, function (loadedData) { expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); expect(loadedData._encodedNormals).toBeDefined(); }); }); it("provides QuantizedMeshTerrainData with unknown extension", function () { Resource._Implementations.loadWithXhr = function ( url, responseType, method, data, headers, deferred, overrideMimeType ) { Resource._DefaultImplementations.loadWithXhr( "Data/CesiumTerrainTileJson/tile.unknownext.terrain", responseType, method, data, headers, deferred ); }; returnOctVertexNormalTileJson(); return waitForTile(0, 0, 0, false, false, function (loadedData) { expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); }); }); it("provides QuantizedMeshTerrainData with Metadata availability", function () { Resource._Implementations.loadWithXhr = function ( url, responseType, method, data, headers, deferred, overrideMimeType ) { Resource._DefaultImplementations.loadWithXhr( "Data/CesiumTerrainTileJson/tile.metadataavailability.terrain", responseType, method, data, headers, deferred ); }; returnMetadataAvailabilityTileJson(); var terrainProvider = new CesiumTerrainProvider({ url: "made/up/url", }); return pollToPromise(function () { return terrainProvider.ready; }) .then(function () { expect(terrainProvider.hasMetadata).toBe(true); expect(terrainProvider._layers[0].availabilityLevels).toBe(10); expect(terrainProvider.availability.isTileAvailable(0, 0, 0)).toBe( true ); expect(terrainProvider.availability.isTileAvailable(0, 1, 0)).toBe( true ); expect(terrainProvider.availability.isTileAvailable(1, 0, 0)).toBe( false ); return terrainProvider.requestTileGeometry(0, 0, 0); }) .then(function (loadedData) { expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); expect(terrainProvider.availability.isTileAvailable(1, 0, 0)).toBe( true ); }); }); it("returns undefined if too many requests are already in progress", function () { var baseUrl = "made/up/url"; var deferreds = []; Resource._Implementations.loadWithXhr = function ( url, responseType, method, data, headers, deferred, overrideMimeType ) { // Do nothing, so requests never complete deferreds.push(deferred); }; returnHeightmapTileJson(); var terrainProvider = new CesiumTerrainProvider({ url: baseUrl, }); return pollToPromise(function () { return terrainProvider.ready; }).then(function () { var promise; var i; for (i = 0; i < RequestScheduler.maximumRequestsPerServer; ++i) { promise = terrainProvider.requestTileGeometry( 0, 0, 0, createRequest() ); } RequestScheduler.update(); expect(promise).toBeDefined(); promise = terrainProvider.requestTileGeometry(0, 0, 0, createRequest()); expect(promise).toBeUndefined(); for (i = 0; i < deferreds.length; ++i) { deferreds[i].resolve(); } }); }); it("supports getTileDataAvailable()", function () { 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 ); }; returnQuantizedMeshTileJson(); var terrainProvider = new CesiumTerrainProvider({ url: baseUrl, }); return pollToPromise(function () { return terrainProvider.ready; }).then(function () { expect(terrainProvider.getTileDataAvailable(0, 0, 0)).toBe(true); expect(terrainProvider.getTileDataAvailable(0, 0, 2)).toBe(false); }); }); it("getTileDataAvailable() converts xyz to tms", function () { var baseUrl = "made/up/url"; returnPartialAvailabilityTileJson(); var terrainProvider = new CesiumTerrainProvider({ url: baseUrl, }); return pollToPromise(function () { return terrainProvider.ready; }).then(function () { expect(terrainProvider.getTileDataAvailable(1, 3, 2)).toBe(true); expect(terrainProvider.getTileDataAvailable(1, 0, 2)).toBe(false); }); }); it("getTileDataAvailable() with Metadata availability", function () { Resource._Implementations.loadWithXhr = function ( url, responseType, method, data, headers, deferred, overrideMimeType ) { Resource._DefaultImplementations.loadWithXhr( "Data/CesiumTerrainTileJson/tile.metadataavailability.terrain", responseType, method, data, headers, deferred ); }; returnMetadataAvailabilityTileJson(); var terrainProvider = new CesiumTerrainProvider({ url: "made/up/url", }); return pollToPromise(function () { return terrainProvider.ready; }) .then(function () { expect(terrainProvider.getTileDataAvailable(0, 0, 0)).toBe(true); expect(terrainProvider.getTileDataAvailable(0, 0, 1)).toBeUndefined(); return terrainProvider.requestTileGeometry(0, 0, 0); }) .then(function () { expect(terrainProvider.getTileDataAvailable(0, 0, 1)).toBe(true); }); }); it("supports a query string in the base URL", function () { Resource._Implementations.loadWithXhr = function ( url, responseType, method, data, headers, deferred, overrideMimeType ) { // Just return any old file, as long as its big enough Resource._DefaultImplementations.loadWithXhr( "Data/EarthOrientationParameters/IcrfToFixedStkComponentsRotationData.json", responseType, method, data, headers, deferred ); }; returnHeightmapTileJson(); return waitForTile(0, 0, 0, false, false, function (loadedData) { expect(loadedData).toBeInstanceOf(HeightmapTerrainData); }); }); it("Uses query parameter extensions for ion resource", function () { var terrainProvider = new CesiumTerrainProvider({ url: IonResource.fromAssetId(1), requestVertexNormals: true, requestWaterMask: true, }); return pollToPromise(function () { return terrainProvider.ready; }).then(function () { var getDerivedResource = spyOn( IonResource.prototype, "getDerivedResource" ).and.callThrough(); terrainProvider.requestTileGeometry(0, 0, 0); var options = getDerivedResource.calls.argsFor(0)[0]; expect(options.queryParameters.extensions).toEqual( "octvertexnormals-watermask-metadata" ); }); }); }); });