See issue 57 for discussion and planned improvements.
Created
September 28, 2011 19:06
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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