sampleTerrainMostDetailed.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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 = await Cesium.createWorldTerrainAsync();
  19. * const positions = [
  20. * Cesium.Cartographic.fromDegrees(86.925145, 27.988257),
  21. * Cesium.Cartographic.fromDegrees(87.0, 28.0)
  22. * ];
  23. * const updatedPositions = await Cesium.sampleTerrainMostDetailed(terrainProvider, positions);
  24. * // positions[0].height and positions[1].height have been updated.
  25. * // updatedPositions is just a reference to positions.
  26. */
  27. async function sampleTerrainMostDetailed(terrainProvider, positions) {
  28. //>>includeStart('debug', pragmas.debug);
  29. if (!defined(terrainProvider)) {
  30. throw new DeveloperError("terrainProvider is required.");
  31. }
  32. if (!defined(positions)) {
  33. throw new DeveloperError("positions is required.");
  34. }
  35. //>>includeEnd('debug');
  36. const byLevel = [];
  37. const maxLevels = [];
  38. // readyPromise has been deprecated; This is here for backwards compatibility
  39. await terrainProvider._readyPromise;
  40. const availability = terrainProvider.availability;
  41. //>>includeStart('debug', pragmas.debug);
  42. if (!defined(availability)) {
  43. throw new DeveloperError(
  44. "sampleTerrainMostDetailed requires a terrain provider that has tile availability."
  45. );
  46. }
  47. //>>includeEnd('debug');
  48. const promises = [];
  49. for (let i = 0; i < positions.length; ++i) {
  50. const position = positions[i];
  51. const maxLevel = availability.computeMaximumLevelAtPosition(position);
  52. maxLevels[i] = maxLevel;
  53. if (maxLevel === 0) {
  54. // This is a special case where we have a parent terrain and we are requesting
  55. // heights from an area that isn't covered by the top level terrain at all.
  56. // This will essentially trigger the loading of the parent terrains root tile
  57. terrainProvider.tilingScheme.positionToTileXY(
  58. position,
  59. 1,
  60. scratchCartesian2
  61. );
  62. const promise = terrainProvider.loadTileDataAvailability(
  63. scratchCartesian2.x,
  64. scratchCartesian2.y,
  65. 1
  66. );
  67. if (defined(promise)) {
  68. promises.push(promise);
  69. }
  70. }
  71. let atLevel = byLevel[maxLevel];
  72. if (!defined(atLevel)) {
  73. byLevel[maxLevel] = atLevel = [];
  74. }
  75. atLevel.push(position);
  76. }
  77. await Promise.all(promises);
  78. await Promise.all(
  79. byLevel.map(function (positionsAtLevel, index) {
  80. if (defined(positionsAtLevel)) {
  81. return sampleTerrain(terrainProvider, index, positionsAtLevel);
  82. }
  83. })
  84. );
  85. const changedPositions = [];
  86. for (let i = 0; i < positions.length; ++i) {
  87. const position = positions[i];
  88. const maxLevel = availability.computeMaximumLevelAtPosition(position);
  89. if (maxLevel !== maxLevels[i]) {
  90. // Now that we loaded the max availability, a higher level has become available
  91. changedPositions.push(position);
  92. }
  93. }
  94. if (changedPositions.length > 0) {
  95. await sampleTerrainMostDetailed(terrainProvider, changedPositions);
  96. }
  97. return positions;
  98. }
  99. export default sampleTerrainMostDetailed;