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