Skip to content

Commit

Permalink
Merge pull request #646 from mapbox/maxbounds
Browse files Browse the repository at this point in the history
Map navigation constraints & max bounds
  • Loading branch information
mourner committed Aug 6, 2014
2 parents 09325eb + 53e8fd4 commit 93858be
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 0 deletions.
57 changes: 57 additions & 0 deletions js/geo/transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ function Transform(minZoom, maxZoom) {
this._minZoom = minZoom || 0;
this._maxZoom = maxZoom || 22;

this.latRange = [-85, 85];

this.width = 0;
this.height = 0;
this.zoom = 0;
Expand Down Expand Up @@ -61,6 +63,7 @@ Transform.prototype = {
this.scale = this.zoomScale(zoom);
this.tileZoom = Math.floor(zoom);
this.zoomFraction = zoom - this.tileZoom;
this._constrain();
},

zoomScale: function(zoom) { return Math.pow(2, zoom); },
Expand Down Expand Up @@ -104,6 +107,7 @@ Transform.prototype = {
panBy: function(offset) {
var point = this.centerPoint._add(offset);
this.center = this.pointLocation(point);
this._constrain();
},

zoomAroundTo: function(zoom, p) {
Expand Down Expand Up @@ -148,5 +152,58 @@ Transform.prototype = {
row: tileCenter.row * kt - p2.y,
zoom: this.tileZoom
};
},

_constrain: function() {
if (!this.center) return;

var minY, maxY, minX, maxX, sy, sx, x2, y2,
size = this.size;

if (this.latRange) {
minY = this.latY(this.latRange[1]);
maxY = this.latY(this.latRange[0]);
sy = maxY - minY < size.y ? size.y / (maxY - minY) : 0;
}

if (this.lngRange) {
minX = this.lngX(this.lngRange[0]);
maxX = this.lngX(this.lngRange[1]);
sx = maxX - minX < size.x ? size.x / (maxX - minX) : 0;
}

// how much the map should scale to fit the screen into given latitude/longitude ranges
var s = Math.max(sx || 0, sy || 0);

if (s) {
this.center = this.unproject(new Point(
sx ? (maxX + minX) / 2 : this.x,
sy ? (maxY + minY) / 2 : this.y));
this.zoom += this.scaleZoom(s);
return;
}

if (this.latRange) {
var y = this.y,
h2 = size.y / 2;

if (y - h2 < minY) y2 = minY + h2;
if (y + h2 > maxY) y2 = maxY - h2;
}

if (this.lngRange) {
var x = this.x,
w2 = size.x / 2;

if (x - w2 < minX) x2 = minX + w2;
if (x + w2 > maxX) x2 = maxX - w2;
}

// pan the map if the screen goes off the range
if (x2 !== undefined || y2 !== undefined) {
this.center = this.unproject(new Point(
x2 !== undefined ? x2 : this.x,
y2 !== undefined ? y2 : this.y));
}
}
};
7 changes: 7 additions & 0 deletions js/ui/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ var Map = module.exports = function(options) {
this.transform = new Transform(options.minZoom, options.maxZoom);
this.hash = options.hash && new Hash(this);

if (options.maxBounds) {
var b = LatLngBounds.convert(options.maxBounds);
this.transform.latRange = [b.getSouth(), b.getNorth()];
this.transform.lngRange = [b.getWest(), b.getEast()];
}

this._onStyleChange = this._onStyleChange.bind(this);
this._updateBuckets = this._updateBuckets.bind(this);
this.render = this.render.bind(this);
Expand Down Expand Up @@ -162,6 +168,7 @@ util.extend(Map.prototype, {

this.transform.width = width;
this.transform.height = height;
this.transform._constrain();

if (this.style && this.style.sprite) {
this.style.sprite.resize(this.painter.gl);
Expand Down
1 change: 1 addition & 0 deletions test/js/geo/transform.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ test('transform', function(t) {
var transform = new Transform();
transform.width = 500;
transform.height = 500;
transform.latRange = undefined;
t.deepEqual(transform.center, { lat: 0, lng: 0 });
t.equal(transform.panBy(new Point(10, 10)), undefined);
t.deepEqual(transform.center, { lat: -7.01366792756663, lng: 7.03125 });
Expand Down

0 comments on commit 93858be

Please sign in to comment.