Skip to content

Commit 3b55a73

Browse files
authored
TilingScheme: Fix incorrect reporting of empty tile ranges (#1328)
* Correctly report empty tile range if requested range is outside the given bounds. * Add bounds for geojson
1 parent 8ecd0bd commit 3b55a73

File tree

3 files changed

+73
-11
lines changed

3 files changed

+73
-11
lines changed

src/three/plugins/images/sources/GeoJSONImageSource.js

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,8 @@ export class GeoJSONImageSource extends TiledImageSource {
6464

6565
// seems that this approach to optimize rendering by defining bounds
6666
// doesn't work if not using a very large offset for the bounds, maybe an error?
67-
// const geoBounds = this._geoJSONBounds( 50 );
68-
// if ( geoBounds ) {
69-
// this.tiling.setContentBounds( ...geoBounds );
70-
// console.log( `GeoJSONImageSource: set content bounds from geojson: ${geoBounds}` );
71-
// } else {
72-
// this.tiling.setContentBounds( ...this.tiling.projection.getBounds() );
73-
// }
67+
const geoBounds = this._geoJSONBounds( 50 ).map( v => v * MathUtils.DEG2RAD );
68+
this.tiling.setContentBounds( ...geoBounds );
7469

7570
}
7671

src/three/plugins/images/utils/TilingScheme.js

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
import { MathUtils } from 'three';
22

3+
function doBoundsIntersect( a, b ) {
4+
5+
const [ aMinX, aMinY, aMaxX, aMaxY ] = a;
6+
const [ bMinX, bMinY, bMaxX, bMaxY ] = b;
7+
8+
return ! ( aMinX >= bMaxX || aMaxX <= bMinX || aMinY >= bMaxY || aMaxY <= bMinY );
9+
10+
}
11+
312
// Class for storing and querying a tiling scheme including a bounds, origin, and negative tile indices.
413
// Assumes that tiles are split into four child tiles at each level.
514

@@ -199,10 +208,36 @@ export class TilingScheme {
199208

200209
getTilesInRange( minX, minY, maxX, maxY, level, normalized = false ) {
201210

202-
[ minX, minY, maxX, maxY ] = this.clampToContentBounds( [ minX, minY, maxX, maxY ], normalized );
211+
// check if the range is outside the content bounds
212+
const range = [ minX, minY, maxX, maxY ];
213+
const contentBounds = this.getContentBounds( normalized );
214+
let tileBounds = this.getLevel( level ).tileBounds;
215+
if ( ! doBoundsIntersect( range, contentBounds ) ) {
216+
217+
return [ 0, 0, - 1, - 1 ];
218+
219+
}
220+
221+
// check if the range is outside the tile bounds
222+
if ( tileBounds ) {
223+
224+
if ( normalized ) {
225+
226+
tileBounds = this.toNormalizedRange( tileBounds );
227+
228+
}
229+
230+
if ( ! doBoundsIntersect( range, contentBounds ) ) {
231+
232+
return [ 0, 0, - 1, - 1 ];
233+
234+
}
235+
236+
}
203237

204-
const minTile = this.getTileAtPoint( minX, minY, level, normalized );
205-
const maxTile = this.getTileAtPoint( maxX, maxY, level, normalized );
238+
const [ clampedMinX, clampedMinY, clampedMaxX, clampedMaxY ] = this.clampToContentBounds( range, normalized );
239+
const minTile = this.getTileAtPoint( clampedMinX, clampedMinY, level, normalized );
240+
const maxTile = this.getTileAtPoint( clampedMaxX, clampedMaxY, level, normalized );
206241

207242
if ( this.flipY ) {
208243

test/TilingScheme.test.js

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { TilingScheme } from '../src/three/plugins/images/utils/TilingScheme.js';
22
import { ProjectionScheme } from '../src/three/plugins/images/utils/ProjectionScheme.js';
33

4-
describe( 'TiltingScheme', () => {
4+
describe( 'TilingScheme', () => {
55

66
it( 'should allow for automatically building levels.', () => {
77

@@ -123,6 +123,38 @@ describe( 'TiltingScheme', () => {
123123

124124
} );
125125

126+
if ( 'should report an empty set of tiles if the requested range is outside the level tile bounds.', () => {
127+
128+
const scheme = new TilingScheme();
129+
scheme.setLevel( 0, {
130+
tileCountX: 4,
131+
tileCountY: 4,
132+
tileBounds: [ 0.5, 0.5, 1.5, 1.5 ],
133+
} );
134+
135+
expect( scheme.getTilesInRange( 0, 0, 0.25, 0.25, 0 ) ).toEqual( [ 0, 0, - 1, - 1 ] );
136+
expect( scheme.getTilesInRange( 1.75, 1.75, 2, 2, 0 ) ).toEqual( [ 0, 0, - 1, - 1 ] );
137+
expect( scheme.getTilesInRange( 0, 1.75, 2, 2, 0 ) ).toEqual( [ 0, 0, - 1, - 1 ] );
138+
expect( scheme.getTilesInRange( 1.75, 0, 2, 2, 0 ) ).toEqual( [ 0, 0, - 1, - 1 ] );
139+
140+
} );
141+
142+
if ( 'should report an empty set of tiles if the requested range is outside the tiling scheme content bounds.', () => {
143+
144+
const scheme = new TilingScheme();
145+
scheme.setContentBounds( 0.5, 0.5, 1.5, 1.5 );
146+
scheme.setLevel( 0, {
147+
tileCountX: 4,
148+
tileCountY: 4,
149+
} );
150+
151+
expect( scheme.getTilesInRange( 0, 0, 0.25, 0.25, 0 ) ).toEqual( [ 0, 0, - 1, - 1 ] );
152+
expect( scheme.getTilesInRange( 1.75, 1.75, 2, 2, 0 ) ).toEqual( [ 0, 0, - 1, - 1 ] );
153+
expect( scheme.getTilesInRange( 0, 1.75, 2, 2, 0 ) ).toEqual( [ 0, 0, - 1, - 1 ] );
154+
expect( scheme.getTilesInRange( 1.75, 0, 2, 2, 0 ) ).toEqual( [ 0, 0, - 1, - 1 ] );
155+
156+
} );
157+
126158
it( 'should correctly report the set of tiles in a range relative to level tile bounds.', () => {
127159

128160
const scheme = new TilingScheme();

0 commit comments

Comments
 (0)