simplegeo / polymaps

Polymaps is a free JavaScript library for making dynamic, interactive maps in modern web browsers.
http://polymaps.org/
Other
1.6k stars 213 forks source link

Constrain panning within boundaries #112

Closed matteomenapace closed 12 years ago

matteomenapace commented 12 years ago

Hi,

we're working on a project with offline maps, where tiles are loaded from a local folder. We therefore need to constrain the area that people can pan the map so that it's limited to what's covered by the tiles. Ideally we'd set the SouthWest and NorthEast corners of such area as lat/lon points, and the map would stop being dragged when reaching those corners, at any zoom level.

Reading the docs, the only constraint that can be applied to the viewable region of a map is centerRange. In my understanding, centerRange sets the limits of the map's center in the four directions. So if I pass the lat/lon of my area's SouthWest and NorthEast corners, I'd expect the map to stop being draggable when its center reaches one of these lat/lon. Yet, logging the map's center on "move" shows that the map can be dragged a little further than the SouthWest and NorthEast boundaries. That "little further" depends on the zoom level. So, I imagine I would set up a listener for the "move" event and when there's a change in the zoom level, reset the centerRange accordingly.

Could you shed some light on this issue, and point me in the right direction?

Thanks, M

mbostock commented 12 years ago

The reason a center constraint, rather than a visible-area constraint, is used is because the center constraint is zoom-independent.

Consider the simple case where you constrain the center to the "world tile" ⟨0,0⟩ at zoom level zero. This allows you to set the center of the map to any point in the tile, i.e., the center can be between ⟨0,0⟩ and ⟨1,1⟩ in coordinate space, or [-180,-85.5…] and [+180,+85.5…] in longitude and latitude. This also means that you can pan such that the tile is just off-screen; however, you cannot push the tile farther away, so if you pan back, the tile immediately becomes visible again.

If you implement a visible-area constraint instead, then the constraint changes as you zoom in and out. Consider the case where you zoomed in very far to some point in Antarctica: if you then zoom out, the center of map necessarily changes to prevent the undefined region below -85.5…º longitude from entering the view port. If you zoom back and forth around this point, the map swims weirdly as it cannot maintain a fixed center.

The center-constraint, thus, guarantees the the current center of the map is valid at any zoom level. The trade-off is that sometimes the viewport will be empty. You could implement a visible-area constraint by changing the center-constraint dynamically on move, but this has the unpleasant side-effect of making the map swim as you zoom in and out near the edge of the defined area. You might consider having default tiles that appear when tiles are unavailable (for example, with some blurred default land cover appearance).

Related: https://github.com/mbostock/d3/pull/504 https://github.com/mbostock/d3/pull/505