QuadtreeTile.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. /*global define*/
  2. define([
  3. '../Core/defined',
  4. '../Core/defineProperties',
  5. '../Core/DeveloperError',
  6. './QuadtreeTileLoadState'
  7. ], function(
  8. defined,
  9. defineProperties,
  10. DeveloperError,
  11. QuadtreeTileLoadState) {
  12. "use strict";
  13. /**
  14. * A single tile in a {@link QuadtreePrimitive}.
  15. *
  16. * @alias QuadtreeTile
  17. * @constructor
  18. * @private
  19. *
  20. * @param {Number} options.level The level of the tile in the quadtree.
  21. * @param {Number} options.x The X coordinate of the tile in the quadtree. 0 is the westernmost tile.
  22. * @param {Number} options.y The Y coordinate of the tile in the quadtree. 0 is the northernmost tile.
  23. * @param {TilingScheme} options.tilingScheme The tiling scheme in which this tile exists.
  24. * @param {QuadtreeTile} [options.parent] This tile's parent, or undefined if this is a root tile.
  25. */
  26. var QuadtreeTile = function QuadtreeTile(options) {
  27. //>>includeStart('debug', pragmas.debug);
  28. if (!defined(options)) {
  29. throw new DeveloperError('options is required.');
  30. }
  31. if (!defined(options.x)) {
  32. throw new DeveloperError('options.x is required.');
  33. } else if (!defined(options.y)) {
  34. throw new DeveloperError('options.y is required.');
  35. } else if (options.x < 0 || options.y < 0) {
  36. throw new DeveloperError('options.x and options.y must be greater than or equal to zero.');
  37. }
  38. if (!defined(options.level)) {
  39. throw new DeveloperError('options.level is required and must be greater than or equal to zero.');
  40. }
  41. if (!defined(options.tilingScheme)) {
  42. throw new DeveloperError('options.tilingScheme is required.');
  43. }
  44. //>>includeEnd('debug');
  45. this._tilingScheme = options.tilingScheme;
  46. this._x = options.x;
  47. this._y = options.y;
  48. this._level = options.level;
  49. this._parent = options.parent;
  50. this._rectangle = this._tilingScheme.tileXYToRectangle(this._x, this._y, this._level);
  51. this._children = undefined;
  52. // QuadtreeTileReplacementQueue gets/sets these private properties.
  53. this._replacementPrevious = undefined;
  54. this._replacementNext = undefined;
  55. // The distance from the camera to this tile, updated when the tile is selected
  56. // for rendering. We can get rid of this if we have a better way to sort by
  57. // distance - for example, by using the natural ordering of a quadtree.
  58. // QuadtreePrimitive gets/sets this private property.
  59. this._distance = 0.0;
  60. /**
  61. * Gets or sets the current state of the tile in the tile load pipeline.
  62. * @type {QuadtreeTileLoadState}
  63. * @default {@link QuadtreeTileLoadState.START}
  64. */
  65. this.state = QuadtreeTileLoadState.START;
  66. /**
  67. * Gets or sets a value indicating whether or not the tile is currently renderable.
  68. * @type {Boolean}
  69. * @default false
  70. */
  71. this.renderable = false;
  72. /**
  73. * Gets or set a value indicating whether or not the tile was entire upsampled from its
  74. * parent tile. If all four children of a parent tile were upsampled from the parent,
  75. * we will render the parent instead of the children even if the LOD indicates that
  76. * the children would be preferable.
  77. * @type {Boolean}
  78. * @default false
  79. */
  80. this.upsampledFromParent = false;
  81. /**
  82. * Gets or sets the additional data associated with this tile. The exact content is specific to the
  83. * {@link QuadtreeTileProvider}.
  84. * @type {Object}
  85. * @default undefined
  86. */
  87. this.data = undefined;
  88. };
  89. /**
  90. * Creates a rectangular set of tiles for level of detail zero, the coarsest, least detailed level.
  91. *
  92. * @memberof QuadtreeTile
  93. *
  94. * @param {TilingScheme} tilingScheme The tiling scheme for which the tiles are to be created.
  95. * @returns {QuadtreeTile[]} An array containing the tiles at level of detail zero, starting with the
  96. * tile in the northwest corner and followed by the tile (if any) to its east.
  97. */
  98. QuadtreeTile.createLevelZeroTiles = function(tilingScheme) {
  99. if (!defined(tilingScheme)) {
  100. throw new DeveloperError('tilingScheme is required.');
  101. }
  102. var numberOfLevelZeroTilesX = tilingScheme.getNumberOfXTilesAtLevel(0);
  103. var numberOfLevelZeroTilesY = tilingScheme.getNumberOfYTilesAtLevel(0);
  104. var result = new Array(numberOfLevelZeroTilesX * numberOfLevelZeroTilesY);
  105. var index = 0;
  106. for (var y = 0; y < numberOfLevelZeroTilesY; ++y) {
  107. for (var x = 0; x < numberOfLevelZeroTilesX; ++x) {
  108. result[index++] = new QuadtreeTile({
  109. tilingScheme : tilingScheme,
  110. x : x,
  111. y : y,
  112. level : 0
  113. });
  114. }
  115. }
  116. return result;
  117. };
  118. defineProperties(QuadtreeTile.prototype, {
  119. /**
  120. * Gets the tiling scheme used to tile the surface.
  121. * @memberof QuadtreeTile.prototype
  122. * @type {TilingScheme}
  123. */
  124. tilingScheme : {
  125. get : function() {
  126. return this._tilingScheme;
  127. }
  128. },
  129. /**
  130. * Gets the tile X coordinate.
  131. * @memberof QuadtreeTile.prototype
  132. * @type {Number}
  133. */
  134. x : {
  135. get : function() {
  136. return this._x;
  137. }
  138. },
  139. /**
  140. * Gets the tile Y coordinate.
  141. * @memberof QuadtreeTile.prototype
  142. * @type {Number}
  143. */
  144. y : {
  145. get : function() {
  146. return this._y;
  147. }
  148. },
  149. /**
  150. * Gets the level-of-detail, where zero is the coarsest, least-detailed.
  151. * @memberof QuadtreeTile.prototype
  152. * @type {Number}
  153. */
  154. level : {
  155. get : function() {
  156. return this._level;
  157. }
  158. },
  159. /**
  160. * Gets the parent tile of this tile.
  161. * @memberof QuadtreeTile.prototype
  162. * @type {QuadtreeTile}
  163. */
  164. parent : {
  165. get : function() {
  166. return this._parent;
  167. }
  168. },
  169. /**
  170. * Gets the cartographic rectangle of the tile, with north, south, east and
  171. * west properties in radians.
  172. * @memberof QuadtreeTile.prototype
  173. * @type {Rectangle}
  174. */
  175. rectangle : {
  176. get : function() {
  177. return this._rectangle;
  178. }
  179. },
  180. /**
  181. * An array of tiles that is at the next level of the tile tree.
  182. * @memberof QuadtreeTile.prototype
  183. * @type {QuadtreeTile[]}
  184. */
  185. children : {
  186. get : function() {
  187. if (!defined(this._children)) {
  188. var tilingScheme = this.tilingScheme;
  189. var level = this.level + 1;
  190. var x = this.x * 2;
  191. var y = this.y * 2;
  192. this._children = [new QuadtreeTile({
  193. tilingScheme : tilingScheme,
  194. x : x,
  195. y : y,
  196. level : level,
  197. parent : this
  198. }), new QuadtreeTile({
  199. tilingScheme : tilingScheme,
  200. x : x + 1,
  201. y : y,
  202. level : level,
  203. parent : this
  204. }), new QuadtreeTile({
  205. tilingScheme : tilingScheme,
  206. x : x,
  207. y : y + 1,
  208. level : level,
  209. parent : this
  210. }), new QuadtreeTile({
  211. tilingScheme : tilingScheme,
  212. x : x + 1,
  213. y : y + 1,
  214. level : level,
  215. parent : this
  216. })];
  217. }
  218. return this._children;
  219. }
  220. },
  221. /**
  222. * Gets a value indicating whether or not this tile needs further loading.
  223. * This property will return true if the {@link QuadtreeTile#state} is
  224. * <code>START</code> or <code>LOADING</code>.
  225. * @memberof QuadtreeTile.prototype
  226. * @type {Boolean}
  227. */
  228. needsLoading : {
  229. get : function() {
  230. return this.state < QuadtreeTileLoadState.DONE;
  231. }
  232. },
  233. /**
  234. * Gets a value indicating whether or not this tile is eligible to be unloaded.
  235. * Typically, a tile is ineligible to be unloaded while an asynchronous operation,
  236. * such as a request for data, is in progress on it. A tile will never be
  237. * unloaded while it is needed for rendering, regardless of the value of this
  238. * property. If {@link QuadtreeTile#data} is defined and has an
  239. * <code>eligibleForUnloading</code> property, the value of that property is returned.
  240. * Otherwise, this property returns true.
  241. * @memberof QuadtreeTile.prototype
  242. * @type {Boolean}
  243. */
  244. eligibleForUnloading : {
  245. get : function() {
  246. var result = true;
  247. if (defined(this.data)) {
  248. result = this.data.eligibleForUnloading;
  249. if (!defined(result)) {
  250. result = true;
  251. }
  252. }
  253. return result;
  254. }
  255. }
  256. });
  257. /**
  258. * Frees the resources assocated with this tile and returns it to the <code>START</code>
  259. * {@link QuadtreeTileLoadState}. If the {@link QuadtreeTile#data} property is defined and it
  260. * has a <code>freeResources</code> method, the method will be invoked.
  261. *
  262. * @memberof QuadtreeTile
  263. */
  264. QuadtreeTile.prototype.freeResources = function() {
  265. this.state = QuadtreeTileLoadState.START;
  266. this.renderable = false;
  267. this.upsampledFromParent = false;
  268. if (defined(this.data) && defined(this.data.freeResources)) {
  269. this.data.freeResources();
  270. }
  271. if (defined(this._children)) {
  272. for (var i = 0, len = this._children.length; i < len; ++i) {
  273. this._children[i].freeResources();
  274. }
  275. this._children = undefined;
  276. }
  277. };
  278. return QuadtreeTile;
  279. });