Can I prevent panning Leaflet map out of the world's edge?

Is there a way to limit panning out of the world's edge? On this picture, brown is the world, grey is emptiness. I want to make it impossible to pan like this.

out of this world

Answers:

Answer

Leaflet allows you to control how much the map resists being dragged out of bounds with the maxBoundsViscosity option (value: 0 to 1). Setting it to maximum disables dragging out of bounds entirely.

var map = new L.Map('map', {
  center: bounds.getCenter(),
  zoom: 5,
  layers: [osm],
  maxBounds: bounds,
  maxBoundsViscosity: 1.0
});

This feature is available in 1.0.0. The relevant pull request includes a working example:

var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
  osmAttrib = '&copy; <a href="http://openstreetmap.org/copyright">OpenStreetMap</a> contributors',
  osm1 = L.tileLayer(osmUrl, {
    maxZoom: 18,
    attribution: osmAttrib
  }),
  osm2 = L.tileLayer(osmUrl, {
    maxZoom: 18,
    attribution: osmAttrib
  }),
  bounds = new L.LatLngBounds(new L.LatLng(49.5, -11.3), new L.LatLng(61.2, 2.5));

var map1 = new L.Map('map1', {
  center: bounds.getCenter(),
  zoom: 5,
  layers: [osm1],
  maxBounds: bounds,
  maxBoundsViscosity: 0.75
});

var map2 = new L.Map('map2', {
  center: bounds.getCenter(),
  zoom: 5,
  layers: [osm2],
  maxBounds: bounds,
  maxBoundsViscosity: 1.0
});

var latlngs = L.rectangle(bounds).getLatLngs();
L.polyline(latlngs[0].concat(latlngs[0][0])).addTo(map1);
L.polyline(latlngs[0].concat(latlngs[0][0])).addTo(map2);
html,
body,
#map {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
}
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>

<h1>Left: Bouncy maxBounds. Right: Not bouncy.</h1>

<div id="map1" style="float: left; width:45%; height: 80%;"></div>
<div id="map2" style="float: left; width:45%; height: 80%;"></div>

Answer

This is how I resolved it for the world map

var map = L.map('map').setView([51.505, -0.09], 3);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png').addTo(map);

var southWest = L.latLng(-89.98155760646617, -180),
northEast = L.latLng(89.99346179538875, 180);
var bounds = L.latLngBounds(southWest, northEast);

map.setMaxBounds(bounds);
map.on('drag', function() {
    map.panInsideBounds(bounds, { animate: false });
});

See working example both for version .7.0.7 http://jsfiddle.net/exqar2w4/18/ and for version 1.0.3 http://jsfiddle.net/exqar2w4/20/

Answer

I use react-leaflet so syntax slightly different to above, but thought it would be helpful to show some sensible bounds to use (none of the answers above do that).

import Leaflet from 'leaflet'
import { Map as LeafletMap} from 'react-leaflet'

// Set map bounds.
// Allow scroll over the international date line, so users can comfortably zoom into locations near the date line.
const corner1 = Leaflet.latLng(-90, -200)
const corner2 = Leaflet.latLng(90, 200)
const bounds = Leaflet.latLngBounds(corner1, corner2)

Which is then rendered as...

<LeafletMap
  maxBoundsViscosity={1.0}
  maxBounds={bounds}
  {...otherProps}
>

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.