computeFlyToLocationForRectangle.js 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import defined from '../Core/defined.js';
  2. import Rectangle from '../Core/Rectangle.js';
  3. import sampleTerrainMostDetailed from '../Core/sampleTerrainMostDetailed.js';
  4. import when from '../ThirdParty/when.js';
  5. import SceneMode from './SceneMode.js';
  6. /**
  7. * Computes the final camera location to view a rectangle adjusted for the current terrain.
  8. * If the terrain does not support availability, the height above the ellipsoid is used.
  9. *
  10. * @param {Rectangle} rectangle The rectangle being zoomed to.
  11. * @param {Scene} scene The scene being used.
  12. *
  13. * @returns {Cartographic} The optimal location to place the camera so that the entire rectangle is in view.
  14. *
  15. * @private
  16. */
  17. function computeFlyToLocationForRectangle(rectangle, scene) {
  18. var terrainProvider = scene.terrainProvider;
  19. var mapProjection = scene.mapProjection;
  20. var ellipsoid = mapProjection.ellipsoid;
  21. var positionWithoutTerrain;
  22. var tmp = scene.camera.getRectangleCameraCoordinates(rectangle);
  23. if (scene.mode === SceneMode.SCENE3D) {
  24. positionWithoutTerrain = ellipsoid.cartesianToCartographic(tmp);
  25. } else {
  26. positionWithoutTerrain = mapProjection.unproject(tmp);
  27. }
  28. if (!defined(terrainProvider)) {
  29. return when.resolve(positionWithoutTerrain);
  30. }
  31. return terrainProvider.readyPromise.then(function() {
  32. var availability = terrainProvider.availability;
  33. if (!defined(availability) || scene.mode === SceneMode.SCENE2D) {
  34. return positionWithoutTerrain;
  35. }
  36. var cartographics = [
  37. Rectangle.center(rectangle),
  38. Rectangle.southeast(rectangle),
  39. Rectangle.southwest(rectangle),
  40. Rectangle.northeast(rectangle),
  41. Rectangle.northwest(rectangle)
  42. ];
  43. return computeFlyToLocationForRectangle._sampleTerrainMostDetailed(terrainProvider, cartographics)
  44. .then(function(positionsOnTerrain) {
  45. var maxHeight = positionsOnTerrain.reduce(function(currentMax, item) {
  46. return Math.max(item.height, currentMax);
  47. }, -Number.MAX_VALUE);
  48. var finalPosition = positionWithoutTerrain;
  49. finalPosition.height += maxHeight;
  50. return finalPosition;
  51. });
  52. });
  53. }
  54. //Exposed for testing.
  55. computeFlyToLocationForRectangle._sampleTerrainMostDetailed = sampleTerrainMostDetailed;
  56. export default computeFlyToLocationForRectangle;