Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Leaflet.js Essentials
Leaflet.js Essentials

Leaflet.js Essentials: Create interactive, mobile-friendly mapping applications using the incredibly light yet powerful Leaflet.js platform.

eBook
$9.99 $19.99
Paperback
$32.99
Subscription
Free Trial
Renews at $19.99p/m

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Table of content icon View table of contents Preview book icon Preview Book

Leaflet.js Essentials

Chapter 1. Creating Maps with Leaflet

Web-based mapping has evolved rapidly over the last two decades, from MapQuest and Google to real-time location information on our phones' mapping apps. There have been open source projects to develop web-based maps in the past, such as MapServer, GeoServer, and OpenLayers. However, Environmental Systems Research Institute (ESRI) includes the Flex and Silverlight APIs; these create web-based maps from their ArcServer services.

Over the last few years, JavaScript has taken the online mapping world by storm. In 2013, there was a JS.geo conference. The library at the center of attention was Leaflet. This is a JavaScript library used to create interactive, web-based maps. With it, you can create a simple map in as little as three lines of JavaScript, or you can create complex, interactive, editable maps with hundreds of lines of code.

Note

You can find more information on Leaflet at http://leafletjs.com.

This book assumes that you have a basic understanding of HTML and CSS, primarily of how to link external .js and .css files and how to name and size a <div> element. It also assumes that you have a working knowledge of JavaScript.

In this chapter, we will cover the following topics:

  • Tile layers
  • Vector layers
  • Pop ups
  • Custom functions / Responding to events
  • Mobile mapping

Creating a simple basemap

To create a map with Leaflet, you need to do the following four things:

  • Reference the JavaScript and Cascading Style Sheet (CSS) files
  • Create a <div> element to hold the map
  • Create a map object
  • Add a tile layer (base layer)

Before we get into the details of building the map, let's set up an HTML file that we can use throughout the book. Open a text editor and enter the following HTML:

<!DOCTYPE html><html>
<head><title>Leaflet Essentials</title>
</head>
<body>
</body>
</html>

Save the file as LeafletEssentials.html. We will add to this file throughout the rest of the book.

Tip

Downloading the example code

You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

Referencing the JavaScript and CSS files

There are two ways to load Leaflet into your code: you can either reference a hosted file or download a copy to your local machine and reference that copy. The next two sections will cover how you can set up your environment for a hosted copy or for a local copy.

Using a hosted copy

We will not be making any changes to the original CSS or JS files, so we will link to the hosted version.

In a text editor, open LeafletEssentials.html. In the <head> element, and after the </title> element, add the following code:

<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css"0.7.3 />

After the <body> tag, add the following code:

<script src="http://cdn.leafletjs.com/leaflet-0.7.3/Leaflet"></script>

The links are standard HTML for <link> and <script>. Open either link in your browser and you will see the contents of the files.

Using a local copy

Using a local copy is the same as a hosted copy, except the path to the files is different. Download Leaflet.js from http://leafletjs.com/download.html and extract it to your desktop. If you downloaded Leaflet-0.7.3.zip, you should have a folder with the same name. In the folder, you will find a subfolder named images and the following three files:

  • Leaflet.css: This is the cascading style sheet
  • Leaflet: This is a compressed version of Leaflet
  • Leaflet-src.js: This is the full version of Leaflet for developers

Add the following code in the <head> tag of LeafletEssentials.html:

<link rel="stylesheet"href="\PATH TO DESKTOP\leaflet-0.7.3\leaflet.css" />

Add the following code in the <body> tag of LeafletEssentials.html:

<script src="\leaflet-0.7.3\Leaflet"></script>0.7.3Leaflet

You now have local references to the Leaflet library and CSS. We are using the Leaflet file because it is smaller and will load faster. As long as you do not need to add any code to the file, you can delete the Leaflet-src.js file.

Creating a <div> tag to hold the map

You need a place to put the map. You can accomplished this by creating a <div> tag with an ID that will be referenced by a map object. The <div> tag that is holding the map needs a defined height. The easiest way to give the tag a height is to use CSS in the <div> tag that you created. Add the following code to the <body> tag of LeafletEssentials.html after the <script> reference to the Leaflet file:

<div id="map" style="width: 600px; height: 400px"></div>

Tip

Style the <div> tag in the HTML file and not the Leaflet.css file. If you do this, the map <div> size will be global for every page that uses it.

Creating a map object

Now that you have the references and a place to put the map, it is time to start coding the map using JavaScript. The first step is to create a map object. The map class takes a <div> tag (which you created in the previous step) and options: L.map(div id, options). To create a map object named map, add the following code after the <script> element in LeafletEssentials.html:

var map = L.map('map',{center: [35.10418, -106.62987],
zoom: 10
});

Alternatively, you can shorten the code using the setView() method, which takes the center and zoom options as parameters:

var map = L.map('map').setView([35.10418, -106.62987],10);

In the preceding code, you created a new instance of the map class and named it map. You may be used to creating new instances of a class using the keyword new; this is shown in the following code:

var map = new L.Map();

Leaflet implements factories that remove the need for the new keyword. In this example, L.map() has been given the <div> map and two options: center and zoom. These two options position the map on the screen with the latitude and longitude in the center of the <div> element and zoomed in or out at the desired level. The center option takes the [latitude, longitude] parameters, and zoom takes an integer; the larger the number, the tighter the zoom.

Tip

It is good practice to always assign the center and zoom options. There is nothing worse than seeing a map of the world when all of the data is located Albuquerque, NM.

Adding a tile layer

The last step to create your first map in Leaflet is to add a tile layer. A tile layer can be thought of as your basemap. It is the imagery that you will add points, lines, and polygons on top of later in the book. Tile layers are a service provided by a tile server. A tile server usually breaks up the layer into 256 x 256 pixel images. You retrieve the images needed based on your location and zoom through a URL that requests /z/x/y.png. Only these tiles are loaded. As you pan and zoom, new tiles are added to your map.

The tile layer, at a minimum, requires the URL to a tile server. In this book, we will use OpenStreetMap for our tile layer.

Note

You need to abide by the terms of service to use OpenStreetMap tiles. The TOS is available at http://wiki.openstreetmap.org/wiki/Tile_usage_policy.

The URL to the OpenStreetMap tile server is shown in the following code:

L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png').addTo(map);

In the code, we provide the URL template to OpenStreetMaps. We also call the addTo() method so that the layer is drawn. We need to pass L.map() as a parameter to the addTo() function. We named our L.map() instance map in the previous section (var map = L.map()).

Note

Leaflet allows method chaining: the calling of multiple methods on an object at the same time. This is what we did when we put .addTo(map) at the end of the line, creating the instance of L.tileLayer(). The longer way of adding the layer to the map without chaining is to assign the instance to a variable and then call addTo() from the variable, as shown in the following code:

var x = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png');
x.addTo(map);

You now have a complete map that allows you to pan and zoom around the world. Your LeafletEssentials.html file should look like the following code:

<html>
<head><title>Leaflet Essentials</title>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
</head>
<body>
<script src="http://cdn.leafletjs.com/leaflet-0.7.3/Leaflet"></script>
<div id="map" style="width: 600px; height: 400px"></div>
<script>
var map = L.map('map', 
{
center: [35.10418, -106.62987],
zoom: 10
});
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png').addTo(map);
</script>
</body>
</html>

Even with liberal spacing, you were able to build a fully functional map of the world with pan and zoom capabilities in six lines of JavaScript. The following screenshot shows the finished map:

Adding a tile layer

Tile layer providers

Now that you have created your first map, you are probably wondering how to change the tile layer to something else. There are several tile layer providers, some of which require registration. This section will present you with two more options: Thunderforest and Stamen. Thunderforest provides tiles that extend OpenStreetMap, while Stamen provides more artistic map tiles. Both of these services can be used to add a different style of basemap to your Leaflet map.

Thunderforest provides five tile services:

  • OpenCycleMap
  • Transport
  • Landscape
  • Outdoors
  • Atlas (still in development)

To use Thunderforest, you need to point your tile layer to the URL of the tile server. The following code shows how you can add a Thunderforest tile layer:

var layer = new L.TileLayer('http://{s}.tile.thunderforest.com/landscape/{z}/{x}/{y}.png');
map.addLayer(layer);

The preceding code loads the landscape tile layer. To use another layer, just replace landscape in the URL with cycle, transport, or outdoors. The following screenshot shows the Thunderforest landscape layer loaded in Leaflet:

Tile layer providers

Stamen provides six tile layers; however, we will only discuss the following three layers:

  • Terrain (available in the United States only)
  • Watercolor
  • Toner

The other three are Burning Map, Mars and Trees, and Cabs & Crime. The Burning Map and Mars layers require WebGL, and Trees and Cabs & Crime are only available in San Francisco. While these maps have a definite wow factor, they are not practical for our purposes here.

Note

Learn about the Stamen tile layers, including Burning Map, Mars and Trees, and Cabs & Crime, at http://maps.stamen.com.

Stamen requires you to follow the same steps as Thunderforest, but it includes an additional step of adding a reference to the JavaScript file. After the reference to your Leaflet file, add the following reference:

<script type="text/javascript" src="http://maps.stamen.com/js/tile.stamen.js?v1.2.4"></script>

Instead of L.TileLayer(), Stamen uses L.StamenTileLayer(tile set name). Replace the tile set name with terrain, watercolor, or toner. Lastly, add addLayer() to the map as shown in the following code:

var layer = new L.StamenTileLayer("watercolor");
map.addLayer(layer);

Stamen's tile layers are not your typical basemap layers; they are works of cartographic art.

Tip

Stamen has an online tool to edit map layers and save the output as an image. To create your own artistic map images, go to http://mapstack.stamen.com.

The following screenshot shows the Stamen watercolor layer loaded in Leaflet. As you zoom in, you will see more detail:

Tile layer providers

Adding a Web Mapping Service tile layer

Another type of tile layer that can be added to a Leaflet map is a Web Mapping Service (WMS) tile layer. WMS is a way to request and transfer map images over the Web through HTTP. It is an Open Geospatial Consortium (OGC) specification.

Tip

For detailed technical information on the WMS specification, see the OGC website: http://www.opengeospatial.org/standards/wms.

With an understanding of how to add tile layers, and having seen several examples, you may have noticed that none of the examples were of satellite imagery. The first WMS layer you will add to your map is the United States Geological Survey (USGS) Imagery Topo.

Like the L.tileLayer() function that we used previously, the L.tileLayer.wms() function takes a URL and a set of options as parameters. The following code adds the WMS layer to your map:

varusgs = L.tileLayer.wms("http://basemap.nationalmap.gov/ArcGIS/services/USGSImageryTopo/MapServer/WMSServer", {
layers:'0',
format: 'image/png',
transparent: true,
attribution: "USGS"
}).addTo(map);

The URL for the WMS was taken from the USGS website. You can find other WMS layers at http://basemap.nationalmap.gov/arcgis/rest/services. The options specified are the layer name, the format, the transparency, and the attribution. The layer name will be provided on the information page of the service you are connecting to. The format is an image, and the transparency is set to true. Since this layer covers the globe, and we are not putting any other layers underneath it, the transparency could be set to false. In the next example, you will see how setting the transparency to true allows another layer to become visible. Lastly, there is an attribution set to USGS. When you assign an attribution to a layer, Leaflet adds the text value in the lower-right corner of the map. It is important to use an attribution as it is similar to citing a source in text. If it is not your data, it is accepted practice to give credit where credit is due. Many times, it is also required by copyright. Since this layer is from the USGS, it is accredited in the attribution property of the layer.

Note

The attribution value can contain hyperlinks, as shown in the following code:

attribution: "<a href='http://basemap.nationalmap.gov/arcgis/rest/services'>USGS</a>"

Insert the WMS layer code into LeafletEssentials.html, and you should now have a map with satellite imagery. The following screenshot shows the satellite imagery loaded into Leaflet:

Adding a Web Mapping Service tile layer

Multiple tile layers

In the previous example, you added a WMS layer and set the transparency to true. The reason you need to do this is because you can add multiple tile layers on top of each other, and with the transparency set to true, you will be able to see them all at the same time. In this example, you need to add the National Weather Service (NWS) radar mosaic WMS on top of the USGS satellite imagery.

Note

The National Oceanic and Atmospheric Administration (NOAA) provides a list of several WMS layers; they are available at the following link:

http://nowcoast.noaa.gov/help/mapservices.shtml?name=mapservices

The adding of extra WMS layers follows the same format as the previous example, but with a different URL, layer name, and attribution. Add the following code after the code for the satellite imagery in LeafletEssentials.html:

Varnexrad = L.tileLayer.wms("http://nowcoast.noaa.gov/wms/com.esri.wms.Esrimap/obs", {
layers: 'RAS_RIDGE_NEXRAD',
format: 'image/png',
transparent: true,
attribution: "NOAA/NWS"
}).addTo(map);

This code adds the NOAA WMS layer for the NWS radar mosaic. Note that the URL and layer have changed and the attribution is set to NOAA/NWS. The RAS_RIDGE_NEXRAD layer is a grid that displays values when they begin to exist. The name of the layer can be found on the NOAA website; you are not expected to remember that RAS_RIDGE_NEXRAD is the weather radar layer. There are large portions of the map with no data, and since we set the transparency to true, these blank spaces allow the satellite imagery to become visible. Your map should now show the satellite imagery with the radar mosaic overlaid, as in the following screenshot:

Multiple tile layers

If you set the transparency to false, you allow the layer to draw on the entire map. Areas with no data are displayed as white squares and cover the satellite imagery underneath, as shown in the following screenshot:

Multiple tile layers

WMS layers do not need to serve as base layers only; they can be used as additional data. This was shown in the previous example where you overlaid the radar on the satellite imagery. In this example, you used a satellite image. You can also use the OpenStreetMap tile layer from the first map. Again, just set the transparency to true. WMS layers can be added just like points, lines, and polygons, which is discussed in the following sections.

Adding data to your map

So far, you have learned how to add tile layers to a map. In the previous example, you added a WMS layer on top of a base tile layer. Now, you will learn how to draw your own layers that need to be added on top of a tile layer. The three geometric primitives of vector data that you can add to a map are often referred to as points, lines, and polygons.

In this section, you will learn how to add markers, polylines, and polygons to your map.

Points

So far, your map is not that interesting. You often draw a map to highlight a specific place or point. Leaflet has a Point class; however, it is not used to simply add a point on the map with an icon to specify the place. In Leaflet, points are added to the map using the Marker class. At minimum, the Marker class requires a latitude and longitude, as shown in the following code:

Var myMarker = L.marker([35.10418, -106.62987]).addTo(map);

Note

You can create a marker by simply calling L.marker([lat,long]).addTo(map);, but assigning the marker to a variable will allow you to interact with it by name. How do you delete a specific marker if it does not have a name?

In the preceding code, you created a marker at point [35.10418, -106.62987], and then, as with the tile layer, you used the addTo(map) function. This created a marker icon at the specified latitude and longitude. The following screenshot shows the marker on the map:

Points

The preceding example is a simplified, and almost useless, marker. The Marker class has options, events, and methods that you can call to make them more interactive and useful. You will learn about methods—specifically the bindPopup() method— and events later in this chapter.

There are 10 options you can specify when creating a marker, as follows:

  • icon
  • clickable
  • draggable
  • keyboard
  • title
  • alt
  • zIndexOffset
  • opacity
  • riseOnHover
  • riseOffset

The options clickable, draggable, keyboard, zIndexOffset, opacity, riseOnHover, and riseOffset are all set to a default value. In Chapter 4, Creating Custom Markers, you will learn about the icon option in detail. Two options that you should set are title and alt. The title option is the tooltip text that will be displayed when you hover over the point with the cursor, and the alt option is the alternative text that is read using screen readers for accessibility. These options are used in the following code:

varmyMarker = L.marker([35.10418, -106.62987],
{title:"MyPoint",alt:"The Big I",draggable:true}).addTo(map);

The code extends the original marker example by adding a title and alt text and making the marker draggable. You will use the draggable options with an event in the last section of this chapter. The options are set the same as when we created our map instance; use curly braces to group the options, and separate each option with a comma. This is how options will be set for all objects.

Polylines

The first vector layer you will learn to create is aLine. In Leaflet, you will use the Polyline class. A polyline can represent a single line segment or a line with multiple segments. Polylines and polygons extend the path class. You do not call path directly, but you have access to its methods, properties, and events. To draw a polyline, you need to provide at least a single longitude and latitude pair. The option for a polyline is set as default, so you need not specify any values unless you want to override the default. This is shown in the following code:

var polyline = L.polyline([[35.10418, -106.62987],[35.19738, -106.875]], {color: 'red',weight:8}).addTo(map);

In this example, the polyline is red and has a weight of 8. The weight option defaults to 5. If you want a thicker line, increase the number. For a thinner line, decrease the number. To add more segments to the line, just add additional latitude and longitude values as shown in the following code:

var polyline = L.polyline([[35.10418, -106.62987],[35.19738, -106.875],[35.07946, -106.80634]], {color: 'red',weight:8}).addTo(map);

Note

You need to first provide a latitude and longitude pair because a line consists of at least two points. Afterwards, you can declare additional latitudes and longitudes to extend your line.

The following screenshot shows the polyline added to the map:

Polylines

Polygons

A polygon is a polyline that is closed. Polygons tend to be classified by the number of sides, as follows:

  • Triangle (3)
  • Hexagon (6)
  • Octagon (8)

Leaflet has a class for drawing two common polygons: a circle and a rectangle. When drawing a polygon, you will specify a minimum of three coordinates. A triangle is the simplest polygon that you can draw. That is why you need to provide at least three points. You do not need to specify the starting point at the end of the list. Leaflet will automatically close the polygon for you. To draw a polygon, simply copy the code for the polyline with three points and change the class to L.polygon(), as shown in the following code:

var polygon = L.polygon([[35.10418, -106.62987],[35.19738, -106.875],[35.07946, -106.80634]], {color: 'red',weight:8}).addTo(map);

Since Leaflet automatically closes the polygon, our three-point polyline can become a polygon. Since polyline and polygon inherit from path, the options color and weight apply to both. You will notice that color and weight refer to the outline of the polygon. Two options that you will find useful when drawing polygons are fillColor and fillOpacity:

var polygon = L.polygon([[35.10418, -106.62987],[35.19738, -106.875],[35.07946, -106.80634]], {color: 'red',weight:8,fillColor:'blue',fillOpacity:1}).addTo(map);

The preceding code draws a red triangle with a weight of 8. The additional options of fillColor and fillOpacity are set to blue and 1. The fill color of a polygon will be set to the default if no fillColor option is selected. You only need to use fillColor if you want a different fill color than the outline.

Note

Opacity is a value between 0 and 1, where 0 is 100 percent opacity and 1 is no opacity (solid).

The following screenshot shows the red triangle with a blue fill added to the map:

Polygons

Rectangles and circles

Circles and rectangles are common polygons that have built-in classes in Leaflet. You can also draw them manually using polygon and by specifying all of the line segments, but that would be a difficult route to take.

Rectangles

To create a rectangle, you need an instance of the class L.rectangle() with the latitude and longitude pair for the upper-left corner and lower-right corner as a parameter. The class extends L.polygon(), so you have access to the same options, methods, and events:

var myRectangle = L.rectangle([[35.19738, -106.875],[35.10418, -106.62987]], {color: "red", weight: 8,fillColor:"blue"}).addTo(map);

The preceding code uses the first two points in the polyline and triangle, but in reverse order (upper left and lower right). The options are the same as the polygon, but with opacity removed. The following screenshot shows the rectangle added to the map:

Rectangles

Circles

To create a circle, you need an instance of L.circle() with the center point and a radius (in meters) as parameters. You can specify the same options as you used in your rectangle because the circle class extends the path class. This is shown in the following code:

L.circle([35.10418, -106.62987], 8046.72,{color: "red", weight: 8,fillColor:"blue"}).addTo(map);

The preceding code specifies the center point, a radius of 5 miles (8046.72 meters), and the same options as the rectangle in the previous example. The following screenshot shows the circle added to the map:

Circles

MultiPolylines and MultiPolygons

In the previous examples, you created each polyline and polygon as its own layer. When you start creating real data, you will find that you want multiple polylines or polygons on a single layer. For starters, it is more realistic, and it also makes it possible to deal with similar features as a single entity. If you want to map parks and bike trails on a single map, it makes sense to add the parks as MultiPolygon and the bike trails as MultiPolyline. Then, you can provide the user with the option of turning either layer on or off.

Tip

Bracketing for MultiPolylines and MultiPolygons can get confusing. You need brackets to hold the MultiPolyline or MultiPolygon, brackets for each polyline or polygon, and brackets for each latitude and longitude.

MultiPolylines

Creating a MultiPolyline is functionally the same as a single polyline, except that you pass multiple longitudes and latitudes; a set for each polygon. This is shown in the following code:

var multipolyline = L.multiPolyline([[[35.10418, -106.62987],[35.19738, -106.875],[35.07946, -106.80634]],[[35.11654, -106.58318],[35.13142, -106.48876],[35.07384, -106.52412]]],{color: 'red',weight:8}).addTo(map);

In the preceding code, the first polyline is the same as the polyline example. A second polyline is added, and the options are also the same as the first polyline example. The following screenshot shows the MultiPolyline added to the map:

MultiPolylines

MultiPolygons

Creating a MultiPolygon is the same as creating a MultiPolyline. Since Leaflet will automatically close the polyline, as long as our polylines have three or more points, we can use them. This is shown in the following code:

var multipolygon = L.multiPolygon([[[35.10418, -106.62987],[35.19738, -106.875],[35.07946, -106.80634]],[[35.11654, -106.58318],[35.13142, -106.48876],[35.07384, -106.52412]]],{color: 'red',weight:8}).addTo(map).bindPopup("We are the same layer");

In the preceding code, you can see that the parameters used are identical to those used in the MultiPolyline example earlier. When we create a MultiPolygon or MultiPolyline, the options will apply to every polygon or polyline in the collection. This means that they all have to be the same color, weight, opacity, and so on. There is a new method in the preceding code: .bindPopup("We are the same layer"). MultiPolygons and MultiPolylines also share the same pop up. Pop ups will be discussed later in this chapter. Also, note the use of method chaining in the line L.multiPolygon().addTo().bindPopup(). The following screenshot shows the MultiPolygon added to the map:

MultiPolygons

Groups of layers

MultiPolyline and MultiPolygon layers allow you to combine multiple polylines and polygons. If you want to create group layers of different types, such as a marker layer with a circle, you can use a layer group or a feature group.

The layer group

A layer group allows you to add multiple layers of different types to the map and manage them as a single layer. To use a layer group, you will need to define several layers:

var marker=L.marker([35.10418, -106.62987]).bindPopup("I am a Marker");
var marker2=L.marker([35.02381, -106.63811]).bindPopup("I am Marker 2");
var polyline=L.polyline([[35.10418, -106.62987],[35.19738, -106.875],[35.07946, -106.80634]], {color: 'red',weight:8}).bindPopup("I am a Polyline");

The preceding code creates two markers and a polyline. Note that you will not use the addTo(map) function after creating the layers, like you did in the previous examples. You will let the layer group handle adding the layer to the map. A layer group requires a set of layers as a parameter:

var myLayerGroup=L.layerGroup([marker, polyline]).addTo(map); 

In the previous code, an instance of L.layerGroup() was created as myLayerGroup. The layers passed as a parameter were marker and polyline. Finally, the layer group was added to the map. The earlier code shows three layers, but only two were added to the layer group. To add layers to a layer group without passing them as a parameter during creation, you can use the layer group addLayer() method. This method takes a layer as a parameter, as shown in the following code:

myLayerGroup.addLayer(marker2);

Now, all three layers have been added to the layer group and are displayed on the map. The following screenshot shows the layer group added to the map:

The layer group

If you want to remove a layer from the layer group, you can use the removeLayer() method and pass the layer name as a parameter:

myLayerGroup.removeLayer(marker);

If you remove a layer from the group, it will no longer be displayed on the map because the addTo() function was called for the layer group and not the individual layer. If you want to display the layer but no longer want it to be part of the layer group, use the removeLayer() function, as shown in the preceding code, and then add the layer to the map as shown in the earlier examples. This is shown in the following code:

marker.addTo(map);

All style options and pop ups need to be assigned to the layer when it is created. You cannot assign a style or pop ups to a layer group as a whole. This is where feature groups can be used.

Feature groups

A feature group is similar to a layer group, but extends it to allow mouse events and includes the bindPopup() method. The constructor for a feature group is the same as the layer group: just pass a set of layers as a parameter. The following code displays an example of a feature group:

VarmyfeatureGroup=L.featureGroup([marker, marker2, polyline])
     .addTo(map).setStyle({color:'purple',opacity:.5})
     .bindPopup("We have the same popup because we are a group");

In the preceding code, the layers added are the same three that you added in the layer group. Since the feature group extends the layer group, you can assign a style and pop up to all of the layers at once. The following screenshot shows the feature group added to the map:

Feature groups

When you created the polyline in the previous example, you set the color to red. Note now that since you passed style information to the feature group by setting the color to purple, the polyline took the information from the feature group and discarded its original settings. If you removed the polyline from the feature group, it will be removed from the map as well. If you try to add the polyline to the map using addTo(), as in the previous examples, it will still be purple and have the new pop up. The markers are still blue even though you passed style information to the feature group. The setStyle() method only applies to layers in the feature group that have a setStyle() method. Since a polyline extends the path class, it has a setStyle() method. The markers do not have a setStyle() method, so their color did not change.

Pop ups

The last few examples introduced pop ups. A pop up provides a way to make your layers interactive or provides information to the user. The simplest way to add a pop up to a marker, polyline, or polygon is to use the bindPopup() method. This method takes the contents of the pop up as a parameter. Using the marker variable we created earlier, we bind the pop up to it with the following code:

marker.bindPopup("I am a marker");

The bindPopup() method allows you to enter HTML as the content. This is shown in the following code:

marker.bindPopup("<h1>My Marker</h1><p>This is information about the marker</p><ul><li>Info 1</li><li>Info 2</li><li>Info 3</li></ul>")

The ability to use HTML in a pop up comes in handy when you have a lot of details to add. It allows the use of images and links in pop ups. The following screenshot shows the HTML-formatted pop up added to a marker on the map:

Pop ups

You can also create an instance of the popup class and then assign it to multiple objects:

var mypopup = L.popup({keepInView:true,closeButton:false})
.setContent("<h1>My Marker</h1><p>This is information about the marker</p><ul><li>Info 1</li><li>Info 2</li><li>Info 3</li></ul>");
marker.bindPopup(mypopup);
marker2.bindPopup(mypopup);

In the preceding code, you create an instance of the L.popup() class and assign it to the variable mypopup. Then, you can call the bindPopup() method on marker and marker2 with mypopup as the parameter. Both markers will have the same pop up content and options.

In the last section of this chapter, you will learn how to create a function that allows you to create a pop up with options and pass the content as a parameter.

Mobile mapping

The maps you have made so far have been tested on the desktop. One of the benefits of mapping in JavaScript is that mobile devices can run the code in a standard web browser without any external applications or plugins. Leaflet runs on mobile devices, such as iPhone, iPad, and Android devices. Any web page with a Leaflet map will work on a mobile device without any changes; however, you probably want to customize the map for mobile devices so that it works and looks like it was built specifically for mobile.

Lastly, the L.map() class has a locate() method, which uses the W3C Geolocation API. The Geolocation API allows you to find and track a user's location using the IP address, the wireless network information, or the GPS on a device. You do not need to know how to use the API; Leaflet handles all of this when you call locate().

HTML and CSS

The first step in converting your Leaflet map to a mobile version is to have it display properly on mobile devices. You can always tell when you open a website on your phone whether the developer took the time to make it mobile-accessible. How many times have you been on a website where the page loads and all you can see is the top-left corner, and you have to zoom around to read the page. It is not a good user experience. In LeafletEssentials.html in the <head> tag after the <link> tag for the CSS file, add the following code:

<style>

body{
padding: 0;
margin: 0;
    }
html, body, #map {
height: 100%;
        }
</style>

In the preceding CSS code, you set the padding and margin values to 0. Think of a web page as a box model, where each element exists in its own box. Each box has a margin, which is the space between it and other boxes, and also padding, which is the space between the content inside the box and the box border (even if a border is not physically drawn). Setting the padding and margin values to 0 makes the <body> content fit to the size of the page. Lastly, you set the height value of the <html>, <body>, and <div id = 'map'> elements to 100%.

Note

In CSS, # is the ID selector. In the code, #map is telling us to select the element with the id = 'map' line. In this case, it is our <div> element that holds the map.

The following diagram shows an overview of the settings for the web page:

HTML and CSS

The last step is to add the following code in the <head> section and after the </title> element:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

The preceding code modifies the viewport that the site is seen through. This code sets the viewport to the width of the device and renders it by a ratio of 1:1. Lastly, it disables the ability to resize the web page. This, however, does not affect your ability to zoom on the map.

Creating a mobile map with JavaScript

Now that you have configured the web page to render properly on mobile devices, it is time to add the JavaScript code that will grab the user's current location. For this, perform the following steps:

  1. Create the map instance, but do not use setView:
    var map = L.map('map');
  2. Add a tile layer:
    L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png').addTo(map);
  3. Define a function to successfully find the location:
    Function foundLocation(e){}
  4. Define a function to unsuccessfully find the location:
    functionnotFoundLocation(e){}
    
  5. Add an event listener for foundLocation() and notFoundLocation():
    map.on('locationfound', foundLocation);
    map.on('locationerror', notFoundLocation);
  6. Use locate() to set the map view:
    map.locate({setView: true, maxZoom:10});

The code creates the map and adds a tile layer. It then skips over the functions and event listeners and tries to locate the user. If it is able to locate the user, it runs the code in foundLocation() and sets the view to the latitude and longitude of the user. If it does not locate the user, it executes the code in notFoundLocation() and displays a zoomed-out world map.

To make this example more usable, add the following code to notFoundLocation():

function notFoundLocation(e){
alert("Unable to find your location. You may need to enable Geolocation.");}

The alert() function creates a pop up in the browser with the message passed as a parameter. Anytime that the browser is unable to locate the user, they will see the following message. While some devices do not have location capabilities, at times, they need to be allowed in their security settings:

Creating a mobile map with JavaScript

Now, add the following code to foundLocation():

function foundLocation(e){
varmydate = new Date(e.timestamp);
L.marker(e.latlng).addTo(map).bindPopup(mydate.toString());
     }

The preceding code will run when the user's location is found. The e in foundLocation(e) is an event object. It is sent when an event is triggered to the function that is responsible for handling that specific event type. It contains information about the event that you will want to know. In the preceding code, the first event object we grab is the timestamp object. If you were to display the timestamp in a pop up, you would get a bunch of numbers: 1400094289048. The timestamp is the number of milliseconds that have passed since January 1, 1970 00:00:00 UTC. If you create an instance of the date class and pass it to the timestamp object, you receive a human-readable date. Next, the code creates a marker. The latitude and longitude are stored in e.latlng. You then add the marker to the map and bind a pop up. The pop up needs a string as a parameter, so you can use the toString() method of the date class or use String(mydate) to convert it. The following screenshot shows the pop up with the date and time when the user clicked on it:

Creating a mobile map with JavaScript

Events and event handlers

So far, you have created maps that display data and added a pop up that displayed when the user clicked on a marker. Now, you will learn how to handle other events and assign these events to event handler functions to process them and do something as a result.

You will first learn how to handle a map event. There are 34 events in the map class that can be subscribed to. This example will focus on the click event. To subscribe to an event, you use the event method .on(); so, for a map event, you use the map.on() method and pass the parameters as the event and function to handle the event. This is shown in the following code:

map.on('click', function(){alert("You clicked the map");});

The code tells Leaflet to send an alert pop-up box with the text You clicked the map when the user clicks on the map. In the mobile example, you created a listener that had a named function that executed foundLocation(). In the preceding code, the function was put in as a parameter. This is known as an anonymous function. The function has no name, and so, it can only be called when the user clicks on the map.

Remember e from the mobile example? If you pass e to the function, you can get the longlat value of the spot that the user clicked on, as shown in the following code:

map.on('click',function(e){
var coord=e.latlng.toString().split(',');
var lat=coord[0].split('(');
var long=coord[1].split(')');
alert("you clicked the map at LAT: "+ lat[1]+" and LONG:"+long[0])
});

The preceding code is spaced in a way that is more readable, but you can put it all on a single line. The code displays the longitude and latitude of the spot where the user clicked on the map. The second line assigns the variable coord, the value of e.latlng. The next two lines strip the latitude and longitude from the value so that you can display them clearly.

You can build on this example by adding a marker when the user clicks on the map by simply replacing the code with the following:

L.marker(e.latlng).addTo(map);

The preceding code is identical to the code in the mobile example. The difference is that in the mobile example, it was only executed when locate() was successful. In this example, it is executed every time the user clicks on the map.

In the section on markers, you created a marker that had the property draggable:true. Markers have three events that deal with dragging: dragstart, drag, and dragend. Perform the following steps to return the longitude and latitude of the marker in a pop up on dragend:

  1. Create the marker and set the draggable property to true:
    varmyMarker = L.marker([35.10418, -106.62987],{title:"MyPoint",alt:"The Big I",draggable:true}).addTo(map);
  2. Write a function to bind a pop up to the marker and call the method getLatLong():
    myMarker.bindPopup("I have been moved to: "+String(myMarker.getLatLng()));
  3. Subscribe to the event:
    myMarker.on('dragend',whereAmI);

Open the map and click on the marker. Hold down the left mouse button and drag the marker to a new location on the map. Release the left button and click on the marker again to trigger the pop up. The pop up will have the new latitude and longitude of the marker.

Custom functions

You subscribed to an event and handled it with a function. So far, you have only passed e as a parameter. In JavaScript, you can send anything you want to the function. Also, functions can be called anywhere in your code. You do not have to call them only in response to an event. In this short example, you will create a function that returns a pop up and is triggered on a call and not by an event.

First, create a marker and bind a pop up to it. For the content of the pop up, enter createPopup(Text as a parameter). Add the marker to the map as shown in the following code:

var marker1 = L.marker([35.10418, -106.62987]).addTo(map).bindPopup(createPopup("Text as a parameter"));

Create a second marker and set the content of the pop up to createPopup (Different text as a parameter):

var marker2 = L.marker([35, -106]).addTo(map).bindPopup(createPopup("Different text as a parameter"));

In the previous examples, you created a pop up by passing text or a pop-up instance. In this example, you call a function, createPopup(), with a string as a parameter, as shown in the following code:

functioncreatePopup(x){
return L.popup({keepInView:true,closeButton:false}).setContent(x);function createPopup(x){
returnL.popup({keepInView:true,closeButton:false}).setContent(x);
}

The function takes a parameter called x. In the marker, when you call the function, you pass a string. This is sent to the function and stored as x. When the pop up is created, the setContent() method is given the value of x instead of a hardcoded string. This function is useful if you have a lot of options set on your pop ups and want them all to be the same. It limits the number of times that you need to repeat the same code. Just pass the text of the pop up to the function, and you get a new pop up with the standardized formatting options. The following screenshot shows both of the pop ups generated by the custom function:

Custom functions

Summary

This chapter covered almost every major topic required to create a Leaflet map. You learned how to add tile layers from multiple providers, including satellite imagery. You can now add points, lines, and polygons to the map, as well as collections of polylines and polygons. You can group layers of different types into layer or feature collections. This chapter covered the styling of objects and adding pop ups. You learned how to interact with the user by responding to events and created custom functions to allow you to code more by writing less.

In the next chapter, you will learn how to add GeoJSON data to your map.

Left arrow icon Right arrow icon

Description

If you are a web developer working with geospatial concepts and mapping APIs, and you want to learn Leaflet to create mapping solutions, this book is for you. You need to have a basic knowledge of working with JavaScript and performing web application development.

What you will learn

  • Incorporate Tile Layers and Web Mapping Services into your map
  • Write custom functions that use events to make interactive maps
  • Add GeoJSON data to a web map
  • Create your own images to use as markers on your map
  • Build desktop applications using C#
  • Make heatmaps and chloropleth maps
  • Take advantage of thirdparty plugins to enhance your map
Estimated delivery fee Deliver to United States

Economy delivery 10 - 13 business days

Free $6.95

Premium delivery 6 - 9 business days

$21.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Aug 18, 2014
Length: 180 pages
Edition : 1st
Language : English
ISBN-13 : 9781783554812
Languages :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Estimated delivery fee Deliver to United States

Economy delivery 10 - 13 business days

Free $6.95

Premium delivery 6 - 9 business days

$21.95
(Includes tracking information)

Product Details

Publication date : Aug 18, 2014
Length: 180 pages
Edition : 1st
Language : English
ISBN-13 : 9781783554812
Languages :

Packt Subscriptions

See our plans and pricing
Modal Close icon
$19.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
$199.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts
$279.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total $ 59.98
Leaflet.js Essentials
$32.99
Learning D3.js Mapping
$26.99
Total $ 59.98 Stars icon
Banner background image

Table of Contents

7 Chapters
1. Creating Maps with Leaflet Chevron down icon Chevron up icon
2. Mapping GeoJSON Data Chevron down icon Chevron up icon
3. Creating Heatmaps and Choropleth Maps Chevron down icon Chevron up icon
4. Creating Custom Markers Chevron down icon Chevron up icon
5. ESRI in Leaflet Chevron down icon Chevron up icon
6. Leaflet in Node.js, Python, and C# Chevron down icon Chevron up icon
Index Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
(7 Ratings)
5 star 28.6%
4 star 57.1%
3 star 0%
2 star 14.3%
1 star 0%
Filter icon Filter
Top Reviews

Filter reviews by




Sergiy Koshel Jul 30, 2015
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Excellent book and prompt delivery.
Amazon Verified review Amazon
MG Sep 25, 2016
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Great introduction
Amazon Verified review Amazon
たなかゆう Oct 19, 2015
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
Leaflet.jsの勉強のために購入しました。英語ですが、ある程度読めればすらすらと読める内容です。サンプルがあるので、動作についてはそれを動かせばわかります。サンプルコードに誤りが多いので注意が必要です。その分を1点引きましたが、Leafletを勉強するにはよい書籍と思います。
Amazon Verified review Amazon
Bud Suttree Mar 27, 2015
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
To echo the previous reviewer....I found the book to be generally an excellent guide but the code samples within the text made things very confusing at first. They are unformatted for starters, and as mentioned, there are no before/after snapshots of the code you are writing as you follow along within each chapter. I found that downloading the complete code file that comes with the purchase of the book (may need to go elsewhere to d-load it) and opening the relevant html file that matched the code example/chapter i was working on, as a means of comparison, made things much easier than trying to follow the supplied code in the book.
Amazon Verified review Amazon
J. R. Hall Aug 15, 2015
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
As someone who is OK-ish with Javascript and has no experience with GIS, this is a great intro to web-map development with Leaflet. As a beginner, you could probably learn what the book teaches by putting in a little more effort and reading the online docs, or by digging up Youtube tutorials, but I'm the type of person who appreciates a print-format collection of solid, simple, well-explained examples that library docs often lack. (If you have experience with Leaflet, though, definitely just read the docs.)That said, there were numerous blatant typing mistakes in the code examples (e.g., declaring a function without putting a space between the keyword "function" and the name of the function, or declaring a variable without putting a space between "var" and the variable name). If you have any experience with Javascript you can pretty easily spot these as typos and just work around them, but it's a shame that such an excellent introduction couldn't get that bit right.If you're looking to make maps on the web, and have enough presence of mind to not just type the example code verbatim, you can't go wrong by starting with this book.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela