Improves method for getting child quad tile at position

This commit is contained in:
Matt Schwartz 2025-10-13 14:04:58 -04:00
parent 6febd2ba52
commit e8f082344c
3 changed files with 63 additions and 7 deletions

View File

@ -564,7 +564,7 @@ function selectTilesForRendering(primitive, frameState) {
}
});
levelZeroTiles.forEach((tile) => tile._updateCustomData());
levelZeroTiles.forEach((tile) => tile.updateCustomData());
customDataAdded.length = 0;
customDataRemoved.length = 0;
@ -721,7 +721,7 @@ function visitTile(
++debug.tilesVisited;
primitive._tileReplacementQueue.markTileRendered(tile);
tile._updateCustomData();
tile.updateCustomData();
if (tile.level > debug.maxDepthVisited) {
debug.maxDepthVisited = tile.level;

View File

@ -313,7 +313,7 @@ QuadtreeTile.prototype.clearPositionCache = function () {
}
};
QuadtreeTile.prototype._updateCustomData = function () {
QuadtreeTile.prototype.updateCustomData = function () {
const added = this._addedCustomData;
const removed = this._removedCustomData;
if (added.length === 0 && removed.length === 0) {
@ -342,7 +342,7 @@ QuadtreeTile.prototype._updateCustomData = function () {
this._removedCustomData.length = 0;
};
const centerScratch = new Cartographic();
const splitPointScratch = new Cartographic();
/**
* Determines which child tile that contains the specified position. Assumes the position is within
@ -353,9 +353,16 @@ const centerScratch = new Cartographic();
* @returns {QuadtreeTile} The child tile that contains the position.
*/
function childTileAtPosition(tile, positionCartographic) {
const center = Rectangle.center(tile.rectangle, centerScratch);
const x = positionCartographic.longitude >= center.longitude ? 1 : 0;
const y = positionCartographic.latitude < center.latitude ? 1 : 0;
// Can't assume that a given tiling scheme divides a parent into four tiles at its rectangle's center.
// But we can safely take any child tile's rectangle and take its center-facing corner as the parent's split point.
const nwChildRectangle = tile.northwestChild.rectangle;
const tileSplitPoint = Rectangle.southeast(
nwChildRectangle,
splitPointScratch,
);
const x = positionCartographic.longitude >= tileSplitPoint.longitude ? 1 : 0;
const y = positionCartographic.latitude < tileSplitPoint.latitude ? 1 : 0;
switch (y * 2 + x) {
case 0:

View File

@ -458,4 +458,53 @@ describe("Scene/QuadtreeTile", function () {
expect(cachedData).toEqual(dummyPosition);
});
});
describe("updateCustomData", function () {
function addAndRemoveCustomData(tilingScheme) {
const tile = new QuadtreeTile({
level: 0,
x: 0,
y: 0,
tilingScheme: tilingScheme,
});
const child = tile.northwestChild;
const centerCartographic = Rectangle.center(child.rectangle);
const data = {
positionCartographic: centerCartographic,
};
tile._addedCustomData.push(data);
tile.updateCustomData();
expect(tile.customData.has(data)).toBe(true);
expect(tile._addedCustomData.length).toBe(0);
expect(child._addedCustomData.length).toBe(1);
expect(child._addedCustomData[0]).toBe(data);
child.updateCustomData();
expect(child.customData.has(data)).toBe(true);
// Now remove the data from the parent tile.
tile._removedCustomData.push(data);
tile.updateCustomData();
expect(tile.customData.has(data)).toBe(false);
expect(tile._removedCustomData.length).toBe(0);
expect(child._removedCustomData.length).toBe(1);
expect(child._removedCustomData[0]).toBe(data);
child.updateCustomData();
expect(child.customData.has(data)).toBe(false);
}
it("can add and remove custom data when tiling scheme is GeographicTilingScheme", function () {
addAndRemoveCustomData(new GeographicTilingScheme());
});
it("can add and remove custom data when tiling scheme is WebMercatorTilingScheme", function () {
addAndRemoveCustomData(new WebMercatorTilingScheme());
});
});
});