sampleTerrainMostDetailed.js 4.0 KB

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