|
1 | 1 | import defined from "../Core/defined.js"; |
2 | 2 | import DeveloperError from "../Core/DeveloperError.js"; |
3 | 3 | import Rectangle from "../Core/Rectangle.js"; |
| 4 | +import Cartographic from "../Core/Cartographic.js"; |
4 | 5 | import QuadtreeTileLoadState from "./QuadtreeTileLoadState.js"; |
5 | 6 | import TileSelectionResult from "./TileSelectionResult.js"; |
6 | 7 |
|
@@ -108,7 +109,8 @@ function QuadtreeTile(options) { |
108 | 109 | this._loadPriority = 0.0; |
109 | 110 |
|
110 | 111 | this._customData = []; |
111 | | - this._frameUpdated = undefined; |
| 112 | + this._addedCustomData = []; |
| 113 | + this._removedCustomData = []; |
112 | 114 | this._lastSelectionResult = TileSelectionResult.NONE; |
113 | 115 | this._lastSelectionResultFrame = undefined; |
114 | 116 | this._loadedCallbacks = {}; |
@@ -311,52 +313,67 @@ QuadtreeTile.prototype.clearPositionCache = function () { |
311 | 313 | } |
312 | 314 | }; |
313 | 315 |
|
314 | | -QuadtreeTile.prototype._updateCustomData = function ( |
315 | | - frameNumber, |
316 | | - added, |
317 | | - removed, |
318 | | -) { |
319 | | - let customData = this.customData; |
320 | | - |
321 | | - let i; |
322 | | - let data; |
323 | | - let rectangle; |
324 | | - |
325 | | - if (defined(added) && defined(removed)) { |
326 | | - customData = customData.filter(function (value) { |
327 | | - return removed.indexOf(value) === -1; |
328 | | - }); |
329 | | - this._customData = customData; |
330 | | - |
331 | | - rectangle = this._rectangle; |
332 | | - for (i = 0; i < added.length; ++i) { |
333 | | - data = added[i]; |
334 | | - if (Rectangle.contains(rectangle, data.positionCartographic)) { |
335 | | - customData.push(data); |
336 | | - } |
| 316 | +QuadtreeTile.prototype._updateCustomData = function () { |
| 317 | + const added = this._addedCustomData; |
| 318 | + const removed = this._removedCustomData; |
| 319 | + if (added.length === 0 && removed.length === 0) { |
| 320 | + return; |
| 321 | + } |
| 322 | + |
| 323 | + const customData = this.customData; |
| 324 | + for (let i = 0; i < added.length; ++i) { |
| 325 | + const data = added[i]; |
| 326 | + if (!Rectangle.contains(this._rectangle, data.positionCartographic)) { |
| 327 | + continue; |
337 | 328 | } |
338 | 329 |
|
339 | | - this._frameUpdated = frameNumber; |
340 | | - } else { |
341 | | - // interior or leaf tile, update from parent |
342 | | - const parent = this._parent; |
343 | | - if (defined(parent) && this._frameUpdated !== parent._frameUpdated) { |
344 | | - customData.length = 0; |
345 | | - |
346 | | - rectangle = this._rectangle; |
347 | | - const parentCustomData = parent.customData; |
348 | | - for (i = 0; i < parentCustomData.length; ++i) { |
349 | | - data = parentCustomData[i]; |
350 | | - if (Rectangle.contains(rectangle, data.positionCartographic)) { |
351 | | - customData.push(data); |
352 | | - } |
353 | | - } |
| 330 | + customData.push(data); |
| 331 | + |
| 332 | + const child = childTileAtPosition(this, data.positionCartographic); |
| 333 | + child._addedCustomData.push(data); |
| 334 | + } |
| 335 | + this._addedCustomData.length = 0; |
354 | 336 |
|
355 | | - this._frameUpdated = parent._frameUpdated; |
| 337 | + for (let i = 0; i < removed.length; ++i) { |
| 338 | + const data = removed[i]; |
| 339 | + const index = customData.indexOf(data); |
| 340 | + if (index !== -1) { |
| 341 | + customData.splice(index, 1); |
356 | 342 | } |
| 343 | + |
| 344 | + const child = childTileAtPosition(this, data.positionCartographic); |
| 345 | + child._removedCustomData.push(data); |
357 | 346 | } |
| 347 | + this._removedCustomData.length = 0; |
358 | 348 | }; |
359 | 349 |
|
| 350 | +const centerScratch = new Cartographic(); |
| 351 | + |
| 352 | +/** |
| 353 | + * Determines which child tile that contains the specified position. Assumes the position is within |
| 354 | + * the bounds of the parent tile. |
| 355 | + * @private |
| 356 | + * @param {QuadtreeTile} tile - The parent tile. |
| 357 | + * @param {Cartographic} positionCartographic - The cartographic position. |
| 358 | + * @returns {QuadtreeTile} The child tile that contains the position. |
| 359 | + */ |
| 360 | +function childTileAtPosition(tile, positionCartographic) { |
| 361 | + const center = Rectangle.center(tile.rectangle, centerScratch); |
| 362 | + const x = positionCartographic.longitude >= center.longitude ? 1 : 0; |
| 363 | + const y = positionCartographic.latitude < center.latitude ? 1 : 0; |
| 364 | + |
| 365 | + switch (y * 2 + x) { |
| 366 | + case 0: |
| 367 | + return tile.northwestChild; |
| 368 | + case 1: |
| 369 | + return tile.northeastChild; |
| 370 | + case 2: |
| 371 | + return tile.southwestChild; |
| 372 | + default: |
| 373 | + return tile.southeastChild; |
| 374 | + } |
| 375 | +} |
| 376 | + |
360 | 377 | Object.defineProperties(QuadtreeTile.prototype, { |
361 | 378 | /** |
362 | 379 | * Gets the tiling scheme used to tile the surface. |
|
0 commit comments