sampleTerrainMostDetailed.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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. * @exports 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
  40. .then(function() {
  41. var byLevel = [];
  42. var maxLevels = [];
  43. var availability = terrainProvider.availability;
  44. //>>includeStart('debug', pragmas.debug);
  45. if (!defined(availability)) {
  46. throw new DeveloperError('sampleTerrainMostDetailed requires a terrain provider that has tile availability.');
  47. }
  48. //>>includeEnd('debug');
  49. var promises = [];
  50. for (var i = 0; i < positions.length; ++i) {
  51. var position = positions[i];
  52. var 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(position, 1, scratchCartesian2);
  59. var promise = terrainProvider.loadTileDataAvailability(scratchCartesian2.x, scratchCartesian2.y, 1);
  60. if (defined(promise)) {
  61. promises.push(promise);
  62. }
  63. }
  64. var atLevel = byLevel[maxLevel];
  65. if (!defined(atLevel)) {
  66. byLevel[maxLevel] = atLevel = [];
  67. }
  68. atLevel.push(position);
  69. }
  70. return when.all(promises)
  71. .then(function() {
  72. return when.all(byLevel.map(function(positionsAtLevel, index) {
  73. if (defined(positionsAtLevel)) {
  74. return sampleTerrain(terrainProvider, index, positionsAtLevel);
  75. }
  76. }));
  77. })
  78. .then(function() {
  79. var changedPositions = [];
  80. for (var i = 0; i < positions.length; ++i) {
  81. var position = positions[i];
  82. var maxLevel = availability.computeMaximumLevelAtPosition(position);
  83. if (maxLevel !== maxLevels[i]) {
  84. // Now that we loaded the max availability, a higher level has become available
  85. changedPositions.push(position);
  86. }
  87. }
  88. if (changedPositions.length > 0) {
  89. return sampleTerrainMostDetailed(terrainProvider, changedPositions);
  90. }
  91. })
  92. .then(function() {
  93. return positions;
  94. });
  95. });
  96. }
  97. export default sampleTerrainMostDetailed;