Skip to main content

How to control your Leaflet map with URL parameters

I needed a way to control the appearance for my Leaflet map of New Zealand, especially when embedding a map with an iframe. Leaflet have no native support for URL parameters for, like the Permalink control for OpenLayers (there is a plugin + Leaflet-hash). This blog post will show you how you can add support for URL parameters for map position (latitude/longitude), zoom level and active layers.

First, I'm defining my layers in an JavaScript object:

var layers = {
  'Seafloor': L.tileLayer('tiles/nz-seafloor/{z}/{x}/{y}.png'),
  'Topographic': L.tileLayer('tiles/nz-topo/{z}/{x}/{y}.png'),
  'Tour': L.cartoDB('http://thematicmapping.cartodb.com/api/v2/sql?q=SELECT * FROM new_zealand_tour')
};

You can use the same object to populate the Leaflet layers control. Next, I'm extracting the URL parameters with a regular expression (from Papermashup):

var params = {};
window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m, key, value) {
  params[key] = value;
});

All URL parameters are now stored as key/value pairs in the params object. We need to create an array of active map layers:

if (params.layers) {
  var activeLayers = params.layers.split(',').map(function(item) {    
    return layers[item];
  });
}

The array map function will create a new array with a reference to the visible layers on the map. Please note that the map function is not supported in Internet Explorer < 9 (you can easily rewrite the function with a for loop to support this browser).

We can now create a map with our URL parameters:

var map = new L.Map('map', {
  center: [params.lat || -41.2728, params.lng || 173.2996],
  minZoom: 4,
  maxZoom: 12,  
  zoom: params.zoom || 6,
  layers: activeLayers || [layers.Seafloor, layers.Topographic]
});


I'm using the Logical OR (||) operator to add default values. Lastly, I'm adding my map layers to the layers control, allowing users to toggle the visibility:

L.control.layers({}, layers).addTo(map);

This is the full example:

We can now control the map med URL parameters like (the code in this example is changed to support base layers and overlays):

http://earthatlas.info/nz/?lat=-42.4&lng=168&zoom=8



http://earthatlas.info/nz/?lat=-39.296&lng=174.065&zoom=11&layers=Springs


Easy peasy!

Comments

Anonymous said…
Thanks so much. That was the missing link.. for me, getting the overlays in a url hash. happy travels..
Bryan McBride said…
There is an OL style Permalink plugin for Leaflet at https://github.com/shramov/leaflet-plugins.
Anonymous said…
it would be quite useful if

https://github.com/mlevans/leaflet-hash

handled baselayers & overlays
Alexander Rutz said…
Is there still no native leaflet-support for this? I felt all the solutions that are around seemed very fragile …

Popular posts from this blog

Creating a WebGL Earth with three.js

This blog post will show you how to create a WebGL Earth with three.js , a great JavaScript library which helps you to go 3D in the browser. I was surprised how easy it seemed when reading a blog post  by Jerome Etienne . So I decided to give it a try using earth textures  from one of my favourite cartographers, Tom Patterson . WebGL is a JavaScript API for rendering interactive 3D graphics in modern web browsers without the use of plug-ins. Three.js is built on top of WebGL, and allows you to create complex 3D scenes with a few lines of JavaScript. If your browser supports WebGL you should see a rotating Earth below: [ Fullscreen ] To be able to display something with three.js, you need three things: a scene, a camera and a renderer. var width  = window.innerWidth,     height = window.innerHeight; var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera(45, width / height, 0.01, 1000); camera.position.z = 1.5; var rende...

Terrain building with three.js

In my last blog post , we converted a digital elevation model (DEM) to a WebGL-friendly format ( i.e. easy to transfer and parse by JavaScript in the browser). In this blog post, we'll use the elevation data to build a terrain mesh with three.js .  First we need to transfer the terrain data to the browser. The elevation values are stored in a binary file as 16-bit unsigned integers. This page explains how you can send and receive binary data using JavaScript typed arrays. I've created a TerrainLoader by adapting the  XHRLoader . You can also use this function: function loadTerrain(file, callback) {   var xhr = new XMLHttpRequest();   xhr.responseType = 'arraybuffer';   xhr.open('GET', file, true);   xhr.onload = function(evt) {         if (xhr.response) {       callback(new Uint16Array(xhr.response));     }   };     xhr.send(null); } Loading elevation data with the Terrai...

Creating 3D terrains with Cesium

Previously, I’ve used three.js to create 3D terrain maps in the browser ( 1 , 2 , 3 , 4 , 5 , 6 ). It worked great for smaller areas, but three.js doesn’t have built-in support for tiling and advanced LOD algorithms needed to render large terrains. So I decided to take Cesium for a spin. Cesium is a JavaScript library for creating 3D globes and 2D maps in the browser without a plugin. Like three.js, it uses WebGL for hardware-accelerated graphics. Cesium allows you to add your own terrain data, and this blog post will show you how. Impressed by the terrain rendering in @CesiumJS - with a 10m elevation model for Norway! Farewell Google Earth. pic.twitter.com/RQKvfu2hBb — Bjørn Sandvik (@thematicmapping) October 4, 2014 Compared to  the dying Google Earth plugin , it's quite complicated to get started with Cesium. The source code is well documented and the live coding Sandcastle is great, but there is a lack of tutorials  and my development slows down when ...