Skip to content

Commit

Permalink
feat(carto): Support .tileSize prop in H3Tileset2D (#8687)
Browse files Browse the repository at this point in the history
* feat(carto): Support .tileSize prop in H3Tileset2D
* chore(carto): Add tests for QuadbinTileset2D getTileZoom @ tileSize
  • Loading branch information
donmccurdy authored Mar 28, 2024
1 parent 75dedf1 commit c5f4b96
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 6 deletions.
4 changes: 2 additions & 2 deletions modules/carto/src/layers/h3-tile-layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,13 @@ export default class H3TileLayer<DataT = any, ExtraPropsT extends {} = {}> exten
if (this.props.minZoom) {
minresolution = Math.max(
minresolution,
getHexagonResolution({zoom: this.props.minZoom, latitude: 0})
getHexagonResolution({zoom: this.props.minZoom, latitude: 0}, this.props.tileSize)
);
}
if (this.props.maxZoom) {
maxresolution = Math.min(
maxresolution,
getHexagonResolution({zoom: this.props.maxZoom, latitude: 0})
getHexagonResolution({zoom: this.props.maxZoom, latitude: 0}, this.props.tileSize)
);
}

Expand Down
13 changes: 10 additions & 3 deletions modules/carto/src/layers/h3-tileset-2d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,14 @@ function tileToBoundingBox(index: string): GeoBoundingBox {
// similar
// Relative scale factor (0 = no biasing, 2 = a few hexagons cover view)
const BIAS = 2;
export function getHexagonResolution(viewport): number {
const hexagonScaleFactor = (2 / 3) * viewport.zoom;
export function getHexagonResolution(
viewport: {zoom: number; latitude: number},
tileSize: number
): number {
// Difference in given tile size compared to deck's internal 512px tile size,
// expressed as an offset to the viewport zoom.
const zoomOffset = Math.log2(tileSize / 512);
const hexagonScaleFactor = (2 / 3) * (viewport.zoom - zoomOffset);
const latitudeScaleFactor = Math.log(1 / Math.cos((Math.PI * viewport.latitude) / 180));

// Clip and bias
Expand All @@ -84,8 +90,9 @@ export default class H3Tileset2D extends Tileset2D {
getTileIndices({viewport, minZoom, maxZoom}): H3TileIndex[] {
if (viewport.latitude === undefined) return [];
const [east, south, west, north] = viewport.getBounds();
const {tileSize} = this.opts;

let z = getHexagonResolution(viewport);
let z = getHexagonResolution(viewport, tileSize);
let indices: string[];
if (typeof minZoom === 'number' && Number.isFinite(minZoom) && z < minZoom) {
// TODO support `extent` prop
Expand Down
2 changes: 1 addition & 1 deletion modules/geo-layers/src/tileset-2d/tileset-2d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export const DEFAULT_TILESET2D_PROPS: Omit<Required<Tileset2DProps>, 'getTileDat
* and only creates new tiles if they are present.
*/
export class Tileset2D {
private opts: Required<Tileset2DProps>;
protected opts: Required<Tileset2DProps>;
private _requestScheduler: RequestScheduler;
private _cache: Map<string, Tile2DHeader>;
private _dirty: boolean;
Expand Down
33 changes: 33 additions & 0 deletions test/modules/carto/layers/h3-tileset-2d.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,39 @@ test('H3Tileset2D', async t => {
t.end();
});

test('H3Tileset2D#tileSize', async t => {
const tileset512 = new H3Tileset2D({tileSize: 512});
const tileset1024 = new H3Tileset2D({tileSize: 1024});
const tileset2048 = new H3Tileset2D({tileSize: 2048});

const viewport = new WebMercatorViewport({
latitude: 0,
longitude: 0,
zoom: 9,
width: 1440,
height: 900
});

const indicesSort = (a, b) => parseInt(a.i, 16) - parseInt(b.i, 16);
const indices512 = tileset512.getTileIndices({viewport}).sort(indicesSort);
const indices1024 = tileset1024.getTileIndices({viewport}).sort(indicesSort);
const indices2048 = tileset2048.getTileIndices({viewport}).sort(indicesSort);

t.equal(indices512.length, 34, 'indices.length @ 512px');
t.equal(indices1024.length, 6, 'indices.length @ 1024px');
t.equal(indices2048.length, 2, 'indices.length @ 2048px');

t.deepEqual(indices512[0], {i: '8475481ffffffff'}, 'indices[0] @ 512px');
t.deepEqual(indices1024[0], {i: '837548fffffffff'}, 'indices[0] @ 1024px');
t.deepEqual(indices2048[0], {i: '82754ffffffffff'}, 'indices[0] @ 2048px');

t.equal(tileset512.getTileZoom(indices512[0]), 4, 'zoom @ 512px');
t.equal(tileset1024.getTileZoom(indices1024[0]), 3, 'zoom @ 1024px');
t.equal(tileset2048.getTileZoom(indices2048[0]), 2, 'zoom @ 2048px');

t.end();
});

test('H3Tileset2D res0', async t => {
const tileset = new H3Tileset2D({});
const viewport = new WebMercatorViewport({
Expand Down
69 changes: 69 additions & 0 deletions test/modules/carto/layers/quadbin-tileset-2d.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,72 @@ test('QuadbinTileset2D', async t => {
);
t.end();
});

test('QuadbinTileset2D#tileSize', async t => {
const tileset512 = new QuadbinTileset2D({tileSize: 512});
const tileset1024 = new QuadbinTileset2D({tileSize: 1024});
const tileset2048 = new QuadbinTileset2D({tileSize: 2048});
const viewport = new WebMercatorViewport({
latitude: 0,
longitude: 0,
zoom: 6,
width: 1440,
height: 900
});

// Required for getTileMetadata to function
tileset512._viewport = viewport;
tileset1024._viewport = viewport;
tileset2048._viewport = viewport;

const indices512 = tileset512.getTileIndices({viewport});
const indices1024 = tileset1024.getTileIndices({viewport});
const indices2048 = tileset2048.getTileIndices({viewport});

t.equal(indices512.length, 8, 'indices.length @ 512px');
t.equal(indices1024.length, 4, 'indices.length @ 1024px');
t.equal(indices2048.length, 4, 'indices.length @ 2048px');

t.deepEqual(
indices512,
[
{q: 5216293168890249215n, i: '4863feffffffffff'},
{q: 5216294268401876991n, i: '4863ffffffffffff'},
{q: 5217795101773791231n, i: '486954ffffffffff'},
{q: 5217796201285419007n, i: '486955ffffffffff'},
{q: 5217045234843647999n, i: '4866aaffffffffff'},
{q: 5217046334355275775n, i: '4866abffffffffff'},
{q: 5218547167727190015n, i: '486c00ffffffffff'},
{q: 5218548267238817791n, i: '486c01ffffffffff'}
],
'indices @ 512px'
);

t.deepEqual(
indices1024,
[
{q: 5211790668774506495n, i: '4853ffffffffffff'},
{q: 5213294800681304063n, i: '485957ffffffffff'},
{q: 5212542734727905279n, i: '4856abffffffffff'},
{q: 5214046866634702847n, i: '485c03ffffffffff'}
],
'indices @ 1024px'
);

t.deepEqual(
indices2048,
[
{q: 5207287069147135999n, i: '4843ffffffffffff'},
{q: 5208799997146955775n, i: '48495fffffffffff'},
{q: 5208043533147045887n, i: '4846afffffffffff'},
{q: 5209556461146865663n, i: '484c0fffffffffff'}
],
'indices @ 2048px'
);

t.equal(tileset512.getTileZoom(indices512[0]), 6, 'zoom @ 512px');
t.equal(tileset1024.getTileZoom(indices1024[0]), 5, 'zoom @ 1024px');
t.equal(tileset2048.getTileZoom(indices2048[0]), 4, 'zoom @ 2048px');

t.end();
});

0 comments on commit c5f4b96

Please sign in to comment.