DSDSWeb/static/js/Cesium-1.53/Specs/Scene/ImageryLayerCollectionSpec.js

570 lines
21 KiB
JavaScript
Raw Normal View History

2024-07-11 18:02:47 +08:00
defineSuite([
'Scene/ImageryLayerCollection',
'Core/Cartesian3',
'Core/Ellipsoid',
'Core/Event',
'Core/GeographicTilingScheme',
'Core/Matrix4',
'Core/Ray',
'Core/Rectangle',
'Core/WebMercatorProjection',
'Core/WebMercatorTilingScheme',
'Scene/Globe',
'Scene/ImageryLayer',
'Scene/ImageryLayerFeatureInfo',
'Scene/ImageryProvider',
'Specs/createScene',
'Specs/pollToPromise',
'ThirdParty/when'
], function(
ImageryLayerCollection,
Cartesian3,
Ellipsoid,
Event,
GeographicTilingScheme,
Matrix4,
Ray,
Rectangle,
WebMercatorProjection,
WebMercatorTilingScheme,
Globe,
ImageryLayer,
ImageryLayerFeatureInfo,
ImageryProvider,
createScene,
pollToPromise,
when) {
'use strict';
var fakeProvider = {
isReady : function() { return false; }
};
it('tracks the base layer on add', function() {
var layer1 = new ImageryLayer(fakeProvider);
var layer2 = new ImageryLayer(fakeProvider);
var layer3 = new ImageryLayer(fakeProvider);
var collection = new ImageryLayerCollection();
expect(layer1.isBaseLayer()).toEqual(false);
collection.add(layer1);
expect(layer1.isBaseLayer()).toEqual(true);
collection.add(layer2);
expect(layer1.isBaseLayer()).toEqual(true);
expect(layer2.isBaseLayer()).toEqual(false);
collection.add(layer3, 0);
expect(layer1.isBaseLayer()).toEqual(false);
expect(layer2.isBaseLayer()).toEqual(false);
expect(layer3.isBaseLayer()).toEqual(true);
});
it('tracks the base layer on remove', function() {
var layer1 = new ImageryLayer(fakeProvider);
var layer2 = new ImageryLayer(fakeProvider);
var layer3 = new ImageryLayer(fakeProvider);
var collection = new ImageryLayerCollection();
collection.add(layer1);
collection.add(layer2);
collection.add(layer3);
expect(layer1.isBaseLayer()).toEqual(true);
expect(layer2.isBaseLayer()).toEqual(false);
expect(layer3.isBaseLayer()).toEqual(false);
collection.remove(layer1);
expect(layer2.isBaseLayer()).toEqual(true);
expect(layer3.isBaseLayer()).toEqual(false);
collection.remove(layer3);
expect(layer2.isBaseLayer()).toEqual(true);
});
it('updates isBaseLayer on re-add', function() {
var layer1 = new ImageryLayer(fakeProvider);
var layer2 = new ImageryLayer(fakeProvider);
var collection = new ImageryLayerCollection();
layer1._isBaseLayer = true;
layer2._isBaseLayer = true;
collection.add(layer1);
collection.add(layer2);
expect(layer1.isBaseLayer()).toEqual(true);
expect(layer2.isBaseLayer()).toEqual(false);
});
it('does not crash when raising and lowering a single layer.', function() {
var layer1 = new ImageryLayer(fakeProvider);
var collection = new ImageryLayerCollection();
collection.add(layer1);
collection.raise(layer1);
collection.lower(layer1);
collection.raiseToTop(layer1);
collection.lowerToBottom(layer1);
});
it('tracks the base layer on raise and lower', function() {
var layer1 = new ImageryLayer(fakeProvider);
var layer2 = new ImageryLayer(fakeProvider);
var layer3 = new ImageryLayer(fakeProvider);
var collection = new ImageryLayerCollection();
collection.add(layer1);
collection.add(layer2);
collection.add(layer3);
expect(layer1.isBaseLayer()).toEqual(true);
expect(layer2.isBaseLayer()).toEqual(false);
expect(layer3.isBaseLayer()).toEqual(false);
collection.lower(layer1);
expect(layer1.isBaseLayer()).toEqual(true);
expect(layer2.isBaseLayer()).toEqual(false);
expect(layer3.isBaseLayer()).toEqual(false);
collection.raise(layer1);
expect(layer1.isBaseLayer()).toEqual(false);
expect(layer2.isBaseLayer()).toEqual(true);
expect(layer3.isBaseLayer()).toEqual(false);
collection.lower(layer1);
expect(layer1.isBaseLayer()).toEqual(true);
expect(layer2.isBaseLayer()).toEqual(false);
expect(layer3.isBaseLayer()).toEqual(false);
});
it('tracks the base layer on raiseToTop to lowerToBottom', function() {
var layer1 = new ImageryLayer(fakeProvider);
var layer2 = new ImageryLayer(fakeProvider);
var layer3 = new ImageryLayer(fakeProvider);
var collection = new ImageryLayerCollection();
collection.add(layer1);
collection.add(layer2);
collection.add(layer3);
expect(layer1.isBaseLayer()).toEqual(true);
expect(layer2.isBaseLayer()).toEqual(false);
expect(layer3.isBaseLayer()).toEqual(false);
collection.raiseToTop(layer1);
expect(layer1.isBaseLayer()).toEqual(false);
expect(layer2.isBaseLayer()).toEqual(true);
expect(layer3.isBaseLayer()).toEqual(false);
collection.lowerToBottom(layer1);
expect(layer1.isBaseLayer()).toEqual(true);
expect(layer2.isBaseLayer()).toEqual(false);
expect(layer3.isBaseLayer()).toEqual(false);
});
it('add throws when layer is undefined', function() {
var collection = new ImageryLayerCollection();
expect(function() {
collection.add(undefined);
}).toThrowDeveloperError();
});
it('addImageryProvider throws when imageryProvider is undefined', function() {
var collection = new ImageryLayerCollection();
expect(function() {
collection.addImageryProvider(undefined);
}).toThrowDeveloperError();
});
it('add throws when index is outside valid range', function() {
var collection = new ImageryLayerCollection();
var layer1 = new ImageryLayer(fakeProvider);
var layer2 = new ImageryLayer(fakeProvider);
expect(function() {
collection.add(layer1, 1);
}).toThrowDeveloperError();
expect(function() {
collection.add(layer1, -1);
}).toThrowDeveloperError();
collection.add(layer1, 0);
expect(function() {
collection.add(layer2, -1);
}).toThrowDeveloperError();
expect(function() {
collection.add(layer2, 2);
}).toThrowDeveloperError();
collection.add(layer2, 0);
});
it('remove ignores request to remove a layer that does not exist in the collection', function() {
var collection = new ImageryLayerCollection();
var layer1 = new ImageryLayer(fakeProvider);
expect(collection.remove(layer1)).toBe(false);
});
it('contains works as expected', function() {
var collection = new ImageryLayerCollection();
var layer1 = new ImageryLayer(fakeProvider);
var layer2 = new ImageryLayer(fakeProvider);
expect(collection.contains(layer1)).toEqual(false);
expect(collection.contains(layer2)).toEqual(false);
collection.add(layer1);
expect(collection.contains(layer1)).toEqual(true);
expect(collection.contains(layer2)).toEqual(false);
collection.add(layer2);
expect(collection.contains(layer1)).toEqual(true);
expect(collection.contains(layer2)).toEqual(true);
collection.remove(layer1);
expect(collection.contains(layer1)).toEqual(false);
expect(collection.contains(layer2)).toEqual(true);
collection.remove(layer2);
expect(collection.contains(layer1)).toEqual(false);
expect(collection.contains(layer2)).toEqual(false);
});
it('get throws if index is not provided', function() {
var collection = new ImageryLayerCollection();
expect(function() {
collection.get();
}).toThrowDeveloperError();
});
it('throws when raising an undefined layer', function() {
var collection = new ImageryLayerCollection();
expect(function() {
collection.raise(undefined);
}).toThrowDeveloperError();
});
it('throws when raising a layer not in the collection', function() {
var collection = new ImageryLayerCollection();
var layer1 = new ImageryLayer(fakeProvider);
expect(function() {
collection.raise(layer1);
}).toThrowDeveloperError();
});
it('reports whether or not it is destroyed', function() {
var collection = new ImageryLayerCollection();
expect(collection.isDestroyed()).toEqual(false);
collection.destroy();
expect(collection.isDestroyed()).toEqual(true);
});
describe('pickImageryLayerFeatures', function() {
var scene;
var globe;
var camera;
beforeAll(function() {
scene = createScene();
globe = scene.globe = new Globe();
camera = scene.camera;
scene.frameState.passes.render = true;
});
afterAll(function() {
scene.destroyForSpecs();
});
beforeEach(function() {
globe.imageryLayers.removeAll();
});
/**
* Repeatedly calls update until the load queue is empty. Returns a promise that resolves
* once the load queue is empty.
*/
function updateUntilDone(globe) {
// update until the load queue is empty.
return pollToPromise(function() {
globe._surface._debug.enableDebugOutput = true;
scene.render();
return globe._surface.tileProvider.ready && globe._surface._tileLoadQueueHigh.length === 0 && globe._surface._tileLoadQueueMedium.length === 0 && globe._surface._tileLoadQueueLow.length === 0 && globe._surface._debug.tilesWaitingForChildren === 0;
});
}
it('returns undefined when pick ray does not intersect surface', function() {
var ellipsoid = Ellipsoid.WGS84;
camera.lookAt(new Cartesian3(ellipsoid.maximumRadius, 0.0, 0.0), new Cartesian3(0.0, 0.0, 100.0));
var ray = new Ray(camera.position, Cartesian3.negate(camera.direction, new Cartesian3()));
var featuresPromise = scene.imageryLayers.pickImageryLayerFeatures(ray, scene);
expect(featuresPromise).toBeUndefined();
});
it('returns undefined when globe has no pickable layers', function() {
var ellipsoid = Ellipsoid.WGS84;
camera.lookAt(new Cartesian3(ellipsoid.maximumRadius, 0.0, 0.0), new Cartesian3(0.0, 0.0, 100.0));
var ray = new Ray(camera.position, camera.direction);
var featuresPromise = scene.imageryLayers.pickImageryLayerFeatures(ray, scene);
expect(featuresPromise).toBeUndefined();
});
it('returns undefined when ImageryProvider does not implement pickFeatures', function() {
var provider = {
ready : true,
rectangle : Rectangle.MAX_VALUE,
tileWidth : 256,
tileHeight : 256,
maximumLevel : 0,
minimumLevel : 0,
tilingScheme : new GeographicTilingScheme(),
errorEvent : new Event(),
hasAlphaChannel : true,
requestImage : function(x, y, level) {
return ImageryProvider.loadImage(this, 'Data/Images/Blue.png');
}
};
globe.imageryLayers.addImageryProvider(provider);
return updateUntilDone(globe).then(function() {
var ellipsoid = Ellipsoid.WGS84;
camera.lookAt(new Cartesian3(ellipsoid.maximumRadius, 0.0, 0.0), new Cartesian3(0.0, 0.0, 100.0));
var ray = new Ray(camera.position, camera.direction);
var featuresPromise = scene.imageryLayers.pickImageryLayerFeatures(ray, scene);
expect(featuresPromise).toBeUndefined();
});
});
it('returns undefined when ImageryProvider.pickFeatures returns undefined', function() {
var provider = {
ready : true,
rectangle : Rectangle.MAX_VALUE,
tileWidth : 256,
tileHeight : 256,
maximumLevel : 0,
minimumLevel : 0,
tilingScheme : new GeographicTilingScheme(),
errorEvent : new Event(),
hasAlphaChannel : true,
pickFeatures : function(x, y, level, longitude, latitude) {
return undefined;
},
requestImage : function(x, y, level) {
return ImageryProvider.loadImage(this, 'Data/Images/Blue.png');
}
};
globe.imageryLayers.addImageryProvider(provider);
return updateUntilDone(globe).then(function() {
var ellipsoid = Ellipsoid.WGS84;
camera.lookAt(new Cartesian3(ellipsoid.maximumRadius, 0.0, 0.0), new Cartesian3(0.0, 0.0, 100.0));
var ray = new Ray(camera.position, camera.direction);
var featuresPromise = scene.imageryLayers.pickImageryLayerFeatures(ray, scene);
expect(featuresPromise).toBeUndefined();
});
});
it('returns features from one layer', function() {
var provider = {
ready : true,
rectangle : Rectangle.MAX_VALUE,
tileWidth : 256,
tileHeight : 256,
maximumLevel : 0,
minimumLevel : 0,
tilingScheme : new GeographicTilingScheme(),
errorEvent : new Event(),
hasAlphaChannel : true,
pickFeatures : function(x, y, level, longitude, latitude) {
var deferred = when.defer();
setTimeout(function() {
var featureInfo = new ImageryLayerFeatureInfo();
featureInfo.name = 'Foo';
featureInfo.description = '<strong>Foo!</strong>';
deferred.resolve([featureInfo]);
}, 1);
return deferred.promise;
},
requestImage : function(x, y, level) {
return ImageryProvider.loadImage(this, 'Data/Images/Blue.png');
}
};
var currentLayer = globe.imageryLayers.addImageryProvider(provider);
return updateUntilDone(globe).then(function() {
var ellipsoid = Ellipsoid.WGS84;
camera.lookAt(new Cartesian3(ellipsoid.maximumRadius, 0.0, 0.0), new Cartesian3(0.0, 0.0, 100.0));
camera.lookAtTransform(Matrix4.IDENTITY);
var ray = new Ray(camera.position, camera.direction);
var featuresPromise = scene.imageryLayers.pickImageryLayerFeatures(ray, scene);
expect(featuresPromise).toBeDefined();
return featuresPromise.then(function(features) {
expect(features.length).toBe(1);
expect(features[0].name).toEqual('Foo');
expect(features[0].description).toContain('Foo!');
expect(features[0].imageryLayer).toBe(currentLayer);
});
});
});
it('returns features from two layers', function() {
var provider1 = {
ready : true,
rectangle : Rectangle.MAX_VALUE,
tileWidth : 256,
tileHeight : 256,
maximumLevel : 0,
minimumLevel : 0,
tilingScheme : new GeographicTilingScheme(),
errorEvent : new Event(),
hasAlphaChannel : true,
pickFeatures : function(x, y, level, longitude, latitude) {
var deferred = when.defer();
setTimeout(function() {
var featureInfo = new ImageryLayerFeatureInfo();
featureInfo.name = 'Foo';
featureInfo.description = '<strong>Foo!</strong>';
deferred.resolve([featureInfo]);
}, 1);
return deferred.promise;
},
requestImage : function(x, y, level) {
return ImageryProvider.loadImage(this, 'Data/Images/Blue.png');
}
};
var currentLayer1 = globe.imageryLayers.addImageryProvider(provider1);
var provider2 = {
ready : true,
rectangle : Rectangle.MAX_VALUE,
tileWidth : 256,
tileHeight : 256,
maximumLevel : 0,
minimumLevel : 0,
tilingScheme : new GeographicTilingScheme(),
errorEvent : new Event(),
hasAlphaChannel : true,
pickFeatures : function(x, y, level, longitude, latitude) {
var deferred = when.defer();
setTimeout(function() {
var featureInfo = new ImageryLayerFeatureInfo();
featureInfo.name = 'Bar';
featureInfo.description = '<strong>Bar!</strong>';
deferred.resolve([featureInfo]);
}, 1);
return deferred.promise;
},
requestImage : function(x, y, level) {
return ImageryProvider.loadImage(this, 'Data/Images/Green.png');
}
};
var currentLayer2 = globe.imageryLayers.addImageryProvider(provider2);
return updateUntilDone(globe).then(function() {
var ellipsoid = Ellipsoid.WGS84;
camera.lookAt(new Cartesian3(ellipsoid.maximumRadius, 0.0, 0.0), new Cartesian3(0.0, 0.0, 100.0));
camera.lookAtTransform(Matrix4.IDENTITY);
var ray = new Ray(camera.position, camera.direction);
var featuresPromise = scene.imageryLayers.pickImageryLayerFeatures(ray, scene);
expect(featuresPromise).toBeDefined();
return featuresPromise.then(function(features) {
expect(features.length).toBe(2);
expect(features[0].name).toEqual('Bar');
expect(features[0].description).toContain('Bar!');
expect(features[0].imageryLayer).toBe(currentLayer2);
expect(features[1].name).toEqual('Foo');
expect(features[1].description).toContain('Foo!');
expect(features[1].imageryLayer).toBe(currentLayer1);
});
});
});
it('correctly picks from a terrain tile that is partially covered by correct-level imagery and partially covered by imagery from an ancestor level', function() {
var provider = {
ready : true,
rectangle : new Rectangle(-Math.PI, -WebMercatorProjection.MaximumLatitude, Math.PI, WebMercatorProjection.MaximumLatitude),
tileWidth : 256,
tileHeight : 256,
maximumLevel : 1,
minimumLevel : 1,
tilingScheme : new WebMercatorTilingScheme(),
errorEvent : new Event(),
hasAlphaChannel : true,
pickFeatures : function(x, y, level, longitude, latitude) {
var deferred = when.defer();
setTimeout(function() {
var featureInfo = new ImageryLayerFeatureInfo();
featureInfo.name = 'L' + level + 'X' + x + 'Y' + y;
deferred.resolve([featureInfo]);
}, 1);
return deferred.promise;
},
requestImage : function(x, y, level) {
// At level 1, only the northwest quadrant has a valid tile.
if (level !== 1 || (x === 0 && y === 0)) {
return ImageryProvider.loadImage(this, 'Data/Images/Blue.png');
}
return when.reject();
}
};
globe.imageryLayers.addImageryProvider(provider);
camera.setView({ destination : Rectangle.fromDegrees(-180.0, 0, 0, 90) });
return updateUntilDone(globe).then(function() {
var ray = new Ray(camera.position, camera.direction);
var featuresPromise = scene.imageryLayers.pickImageryLayerFeatures(ray, scene);
expect(featuresPromise).toBeDefined();
return featuresPromise.then(function(features) {
// Verify that we don't end up picking from imagery level 0.
expect(features.length).toBe(1);
expect(features[0].name).toEqual('L1X0Y0');
});
});
});
});
}, 'WebGL');