sampleTerrainMostDetailed.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import when from "../ThirdParty/when.js";
  2. import Cartesian2 from "./Cartesian2.js";
  3. import defined from "./defined.js";
  4. import DeveloperError from "./DeveloperError.js";
  5. import sampleTerrain from "./sampleTerrain.js";
  6. var scratchCartesian2 = new Cartesian2();
  7. /**
  8. * Initiates a sampleTerrain() request at the maximum available tile level for a terrain dataset.
  9. *
  10. * @function sampleTerrainMostDetailed
  11. *
  12. * @param {TerrainProvider} terrainProvider The terrain provider from which to query heights.
  13. * @param {Cartographic[]} positions The positions to update with terrain heights.
  14. * @returns {Promise.<Cartographic[]>} A promise that resolves to the provided list of positions when terrain the query has completed. This
  15. * promise will reject if the terrain provider's `availability` property is undefined.
  16. *
  17. * @example
  18. * // Query the terrain height of two Cartographic positions
  19. * var terrainProvider = Cesium.createWorldTerrain();
  20. * var positions = [
  21. * Cesium.Cartographic.fromDegrees(86.925145, 27.988257),
  22. * Cesium.Cartographic.fromDegrees(87.0, 28.0)
  23. * ];
  24. * var promise = Cesium.sampleTerrainMostDetailed(terrainProvider, positions);
  25. * Cesium.when(promise, function(updatedPositions) {
  26. * // positions[0].height and positions[1].height have been updated.
  27. * // updatedPositions is just a reference to positions.
  28. * });
  29. */
  30. function sampleTerrainMostDetailed(terrainProvider, positions) {
  31. //>>includeStart('debug', pragmas.debug);
  32. if (!defined(terrainProvider)) {
  33. throw new DeveloperError("terrainProvider is required.");
  34. }
  35. if (!defined(positions)) {
  36. throw new DeveloperError("positions is required.");
  37. }
  38. //>>includeEnd('debug');
  39. return terrainProvider.readyPromise.then(function () {
  40. var byLevel = [];
  41. var maxLevels = [];
  42. var availability = terrainProvider.availability;
  43. //>>includeStart('debug', pragmas.debug);
  44. if (!defined(availability)) {
  45. throw new DeveloperError(
  46. "sampleTerrainMostDetailed requires a terrain provider that has tile availability."
  47. );
  48. }
  49. //>>includeEnd('debug');
  50. var promises = [];
  51. for (var i = 0; i < positions.length; ++i) {
  52. var position = positions[i];
  53. var maxLevel = availability.computeMaximumLevelAtPosition(position);
  54. maxLevels[i] = maxLevel;
  55. if (maxLevel === 0) {
  56. // This is a special case where we have a parent terrain and we are requesting
  57. // heights from an area that isn't covered by the top level terrain at all.
  58. // This will essentially trigger the loading of the parent terrains root tile
  59. terrainProvider.tilingScheme.positionToTileXY(
  60. position,
  61. 1,
  62. scratchCartesian2
  63. );
  64. var promise = terrainProvider.loadTileDataAvailability(
  65. scratchCartesian2.x,
  66. scratchCartesian2.y,
  67. 1
  68. );
  69. if (defined(promise)) {
  70. promises.push(promise);
  71. }
  72. }
  73. var atLevel = byLevel[maxLevel];
  74. if (!defined(atLevel)) {
  75. byLevel[maxLevel] = atLevel = [];
  76. }
  77. atLevel.push(position);
  78. }
  79. return when
  80. .all(promises)
  81. .then(function () {
  82. return when.all(
  83. byLevel.map(function (positionsAtLevel, index) {
  84. if (defined(positionsAtLevel)) {
  85. return sampleTerrain(terrainProvider, index, positionsAtLevel);
  86. }
  87. })
  88. );
  89. })
  90. .then(function () {
  91. var changedPositions = [];
  92. for (var i = 0; i < positions.length; ++i) {
  93. var position = positions[i];
  94. var maxLevel = availability.computeMaximumLevelAtPosition(position);
  95. if (maxLevel !== maxLevels[i]) {
  96. // Now that we loaded the max availability, a higher level has become available
  97. changedPositions.push(position);
  98. }
  99. }
  100. if (changedPositions.length > 0) {
  101. return sampleTerrainMostDetailed(terrainProvider, changedPositions);
  102. }
  103. })
  104. .then(function () {
  105. return positions;
  106. });
  107. });
  108. }
  109. export default sampleTerrainMostDetailed;