Skip to content

Commit

Permalink
finish TileJSON.bounds implementation + testing
Browse files Browse the repository at this point in the history
  • Loading branch information
Molly Lloyd committed Apr 7, 2017
1 parent 364a410 commit e49d03e
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 46 deletions.
40 changes: 0 additions & 40 deletions js/source/tile_bounds.js

This file was deleted.

12 changes: 6 additions & 6 deletions src/source/raster_tile_source.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ class RasterTileSource extends Evented {
this._loaded = false;
this.options = options;
util.extend(this, util.pick(options, ['url', 'scheme', 'tileSize']));

this.setBounds(options.bounds);

}

load() {
Expand All @@ -35,6 +34,7 @@ class RasterTileSource extends Evented {
return this.fire('error', err);
}
util.extend(this, tileJSON);
this.setBounds(tileJSON.bounds);

// `content` is included here to prevent a race condition where `Style#_updateSources` is called
// before the TileJSON arrives. this makes sure the tiles needed are loaded once TileJSON arrives
Expand All @@ -51,10 +51,10 @@ class RasterTileSource extends Evented {
}

setBounds(bounds) {
this.bounds = bounds;
if (bounds) {
this.tileBounds = new TileBounds(bounds, this.minzoom, this.maxzoom);
}
this.bounds = bounds;
if (bounds) {
this.tileBounds = new TileBounds(bounds, this.minzoom, this.maxzoom);
}
}

serialize() {
Expand Down
33 changes: 33 additions & 0 deletions src/source/tile_bounds.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
'use strict';

const LngLatBounds = require('../geo/lng_lat_bounds');
const clamp = require('../util/util').clamp;

class TileBounds {
constructor(bounds, minzoom, maxzoom) {
this.bounds = LngLatBounds.convert(bounds);
this.minzoom = minzoom || 0;
this.maxzoom = maxzoom || 24;
}

contains(coord) {
const level = [
[Math.floor(this.lngX(this.bounds.getWest(), coord.z)), Math.floor(this.latY(this.bounds.getNorth(), coord.z))],
[Math.ceil(this.lngX(this.bounds.getEast(), coord.z)), Math.ceil(this.latY(this.bounds.getSouth(), coord.z))]
];
const hit = coord.x >= level[0][0] && coord.x < level[1][0] && coord.y >= level[0][1] && coord.y < level[1][1];
return hit;
}

lngX(lng, zoom) {
return (lng + 180) * (Math.pow(2, zoom) / 360);
}

latY(lat, zoom) {
const f = clamp(Math.sin(Math.PI / 180 * lat), -0.9999, 0.9999);
const scale = Math.pow(2, zoom) / (2 * Math.PI);
return Math.pow(2, zoom - 1) + 0.5 * Math.log((1 + f) / (1 - f)) * -scale;
}
}

module.exports = TileBounds;
15 changes: 15 additions & 0 deletions src/source/vector_tile_source.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const Evented = require('../util/evented');
const util = require('../util/util');
const loadTileJSON = require('./load_tilejson');
const normalizeURL = require('../util/mapbox').normalizeTileURL;
const TileBounds = require('./tile_bounds');

class VectorTileSource extends Evented {

Expand Down Expand Up @@ -39,6 +40,8 @@ class VectorTileSource extends Evented {
return;
}
util.extend(this, tileJSON);
this.setBounds(tileJSON.bounds);

// `content` is included here to prevent a race condition where `Style#_updateSources` is called
// before the TileJSON arrives. this makes sure the tiles needed are loaded once TileJSON arrives
// ref: https://github.com/mapbox/mapbox-gl-js/pull/4347#discussion_r104418088
Expand All @@ -48,6 +51,18 @@ class VectorTileSource extends Evented {
});
}

setBounds(bounds) {
this.bounds = bounds;
if (bounds) {
this.tileBounds = new TileBounds(bounds, this.minzoom, this.maxzoom);
}
}

hasTile(coord) {
console.log('has tile');
return !this.tileBounds || this.tileBounds.contains(coord);
}

onAdd(map) {
this.load();
this.map = map;
Expand Down
13 changes: 13 additions & 0 deletions test/unit/source/vector_tile_source.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,5 +178,18 @@ test('VectorTileSource', (t) => {
});
});

t.test('respects TileJSON.bounds', (t)=>{
const source = createSource({
minzoom: 0,
maxzoom: 22,
attribution: "Mapbox",
tiles: ["http://example.com/{z}/{x}/{y}.png"],
});
source.setBounds([[-47, -7], [-45, -5]]);
t.false(source.hasTile({z: 8, x:96, y: 132}), 'returns false for tiles outside bounds');
t.true(source.hasTile({z: 8, x:95, y: 132}), 'returns true for tiles inside bounds');
t.end();
});

t.end();
});

0 comments on commit e49d03e

Please sign in to comment.