computeFlyToLocationForRectangle.js 2.3 KB

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