Skip to content

Instantly share code, notes, and snippets.

@RandomEtc
Created September 28, 2011 19:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RandomEtc/1248897 to your computer and use it in GitHub Desktop.
Save RandomEtc/1248897 to your computer and use it in GitHub Desktop.
How to enforce provider limits on interaction and tile loading in Modest Maps JS

See issue 57 for discussion and planned improvements.

<!DOCTYPE html>
<html>
<head>
<title>Modest Maps JS</title>
<script type="text/javascript" src="https://raw.github.com/stamen/modestmaps-js/v0.18.4/modestmaps.min.js"></script>
<script type="text/javascript">
window.onload = function() {
// "import" the namespace
var MM = com.modestmaps;
var provider = new MM.TemplatedMapProvider("http://otile1.mqcdn.com/tiles/1.0.0/osm/{Z}/{X}/{Y}.png");
// override provider limits so that tiles are not loaded unless they are inside these bounds:
var minZoom = 2;
var maxZoom = 10;
var topLeft = new MM.Location(51.4, -131.8);
var bottomRight = new MM.Location(21.5, -50.5);
provider.bottomRightInnerLimit = provider.locationCoordinate(bottomRight).zoomTo(maxZoom);
provider.topLeftOuterLimit = provider.locationCoordinate(topLeft).zoomTo(minZoom);
// override sourceCoordinate so that it doesn't use coord limits to wrap tiles
// but so that it rejects any tile coordinates that lie outside the limits
provider.sourceCoordinate = function(coord) {
// don't need .container() stuff here but it means *something* will get loaded at low zoom levels
// e.g. at level 0 the base tile could contain the entire extent
// skip the .container() stuff if you don't want to load/render tiles outside the extent *at all*
var TL = this.topLeftOuterLimit.zoomTo(coord.zoom).container();
var BR = this.bottomRightInnerLimit.zoomTo(coord.zoom).container().right().down();
if (coord.row < TL.row || coord.row >= BR.row || coord.column < TL.column || coord.column >= BR.column) {
// it's too high or too low or too lefty or too righty:
return null;
}
// otherwise it's cool, let it through
return coord;
}
var map = new MM.Map(document.body, provider);
// override enforceLimits so that you can't pan outside the given limits
// Prevent the user from navigating the map outside the `outerLimits`
// of the map's provider.
map.enforceLimits = function(coord) {
coord = coord.copy();
var limits = this.provider.outerLimits();
if (limits) {
var minZoom = limits[0].zoom;
var maxZoom = limits[1].zoom;
if (coord.zoom < minZoom) {
coord = coord.zoomTo(minZoom);
}
else if (coord.zoom > maxZoom) {
coord = coord.zoomTo(maxZoom);
}
// this generally does the *intended* thing,
// but it's not always desired behavior so it's disabled for now
var topLeftLimit = limits[0].zoomTo(coord.zoom);
var bottomRightLimit = limits[1].zoomTo(coord.zoom);
var currentTopLeft = this.pointCoordinate(new MM.Point(0,0));
var currentBottomRight = this.pointCoordinate(this.dimensions);
if (bottomRightLimit.row - topLeftLimit.row < currentBottomRight.row - currentTopLeft.row) {
// if the limit is smaller than the current view center it
coord.row = (bottomRightLimit.row + topLeftLimit.row) / 2;
}
else {
if (currentTopLeft.row < topLeftLimit.row) {
coord.row += topLeftLimit.row - currentTopLeft.row;
}
else if (currentBottomRight.row > bottomRightLimit.row) {
coord.row -= currentBottomRight.row - bottomRightLimit.row;
}
}
if (bottomRightLimit.column - topLeftLimit.column < currentBottomRight.column - currentTopLeft.column) {
// if the limit is smaller than the current view, center it
coord.column = (bottomRightLimit.column + topLeftLimit.column) / 2;
}
else {
if (currentTopLeft.column < topLeftLimit.column) {
coord.column += topLeftLimit.column - currentTopLeft.column;
}
else if (currentBottomRight.column > bottomRightLimit.column) {
coord.column -= currentBottomRight.column - bottomRightLimit.column;
}
}
}
return coord;
}
map.setCenterZoom(new MM.Location(37.811530, -122.2666097), 5);
}
</script>
<style>
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
border: 0;
}
</style>
</head>
<body>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment