Skip to content

Commit

Permalink
computeFlyToLocationForRectangle needs to wait for terrain to become …
Browse files Browse the repository at this point in the history
…ready

If you performed a geocode before the terrain became ready, it would
throw an exception.

Fixes #6908.
  • Loading branch information
mramato committed Aug 10, 2018
1 parent f982edf commit bd08572
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 27 deletions.
61 changes: 34 additions & 27 deletions Source/Scene/computeFlyToLocationForRectangle.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,41 +24,48 @@ define([
*/
function computeFlyToLocationForRectangle(rectangle, scene) {
var terrainProvider = scene.terrainProvider;
var availability = defined(terrainProvider) ? terrainProvider.availability : undefined;

if (!defined(availability) || scene.mode === SceneMode.SCENE2D) {
if (!defined(terrainProvider)) {
return when.resolve(rectangle);
}

var cartographics = [
Rectangle.center(rectangle),
Rectangle.southeast(rectangle),
Rectangle.southwest(rectangle),
Rectangle.northeast(rectangle),
Rectangle.northwest(rectangle)
];
return terrainProvider.readyPromise.then(function() {
var availability = terrainProvider.availability;

return computeFlyToLocationForRectangle._sampleTerrainMostDetailed(terrainProvider, cartographics)
.then(function(positionsOnTerrain) {
var maxHeight = positionsOnTerrain.reduce(function(currentMax, item) {
return Math.max(item.height, currentMax);
}, -Number.MAX_VALUE);
if (!defined(availability) || scene.mode === SceneMode.SCENE2D) {
return rectangle;
}

var finalPosition;
var cartographics = [
Rectangle.center(rectangle),
Rectangle.southeast(rectangle),
Rectangle.southwest(rectangle),
Rectangle.northeast(rectangle),
Rectangle.northwest(rectangle)
];

var camera = scene.camera;
var mapProjection = scene.mapProjection;
var ellipsoid = mapProjection.ellipsoid;
var tmp = camera.getRectangleCameraCoordinates(rectangle);
if (scene.mode === SceneMode.SCENE3D) {
finalPosition = ellipsoid.cartesianToCartographic(tmp);
} else {
finalPosition = mapProjection.unproject(tmp);
}
return computeFlyToLocationForRectangle._sampleTerrainMostDetailed(terrainProvider, cartographics)
.then(function(positionsOnTerrain) {
var maxHeight = positionsOnTerrain.reduce(function(currentMax, item) {
return Math.max(item.height, currentMax);
}, -Number.MAX_VALUE);

finalPosition.height += maxHeight;
return finalPosition;
});
var finalPosition;

var camera = scene.camera;
var mapProjection = scene.mapProjection;
var ellipsoid = mapProjection.ellipsoid;
var tmp = camera.getRectangleCameraCoordinates(rectangle);
if (scene.mode === SceneMode.SCENE3D) {
finalPosition = ellipsoid.cartesianToCartographic(tmp);
} else {
finalPosition = mapProjection.unproject(tmp);
}

finalPosition.height += maxHeight;
return finalPosition;
});
});
}

//Exposed for testing.
Expand Down
15 changes: 15 additions & 0 deletions Specs/Scene/computeFlyToLocationForRectangleSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,21 @@ defineSuite([
});
});

it('waits for terrain to become ready', function() {
var terrainProvider = new EllipsoidTerrainProvider();
spyOn(terrainProvider.readyPromise, 'then').and.callThrough();

scene.globe = new Globe();
scene.terrainProvider = terrainProvider;

var rectangle = new Rectangle(0.2, 0.4, 0.6, 0.8);
return computeFlyToLocationForRectangle(rectangle, scene)
.then(function(result) {
expect(result).toBe(rectangle);
expect(terrainProvider.readyPromise.then).toHaveBeenCalled();
});
});

it('returns original rectangle when terrain undefined', function() {
scene.terrainProvider = undefined;
var rectangle = new Rectangle(0.2, 0.4, 0.6, 0.8);
Expand Down

0 comments on commit bd08572

Please sign in to comment.