MapboxGL part 1 - NieneB/webmapping_for_developers GitHub Wiki
Mapbox GL JS is a JavaScript library that uses WebGL to render interactive maps from vector tiles and Mapbox styles. Different from Leaflet, we now need Vector Tiles AND a map style. The vector tiles come without styling so we need to solve this on the client side.
Vector tiles are a way to deliver geographic data in small chunks to a browser or other client app. Vector tiles are similar to raster tiles but instead of raster images the data returned is a vector representation of the features in the tile.
Vector tiles make huge maps fast while offering full design flexibility. They are the vector data equivalent of image tiles for web mapping, applying the strengths of tiling – developed for caching, scaling and serving map imagery rapidly – to vector data.
Vector tiles have two important advantages over fully rendered image tiles:
- Styling - as vectors, tiles can be styled when requested, allowing for many map styles on global data
- Size - vector tiles are really small, enabling global high resolution maps, fast map loads, and efficient caching
As the name suggests, vector tiles contain vector data instead of the rendered image. They contain geometries and metadata – like road names, place names, house numbers – in a compact, structured format. Vector tiles are rendered only when requested by a client, like a web browser or a mobile app. Rendering happens in the client.
Mapbox have defined an open standard for vector map tiles called "vector-tile-spec" which uses Google protocol buffers for space-efficient data serialisation. Web Mercator is the projection of reference, but vector tiles may be used to represent data with any projection and tile extent scheme. It is also tied to the Mapnik rendering engine, using a "serialized version of the internal data that Mapnik uses".
More about mapbox vector tile: https://www.mapbox.com/vector-tiles/specification/
Mapbox provides some basic styles and tiles. You can start using Mapbox services for free. But when hosting a lot of your data on their services or using their service for commercial goals Mapbox has a pricing plan.
Mapbox also offers the Mapbox Studio's style editor. A user interface where you can define your map style. Behind the scenes, Studio creates the style.json and hosts it on the Mapbox Styles API when published. This style is then accessible via endpoint to add to your map. If you are interested have a look at Mapbox
In the next step we will learn how to use the Mapbox GL.js library without the Mapbox token! We will use alternative tile providers and learn how to manipulate the style with JavaScript at the client side.
Alternative Tile providers:
- Mapbox Studio
- Open Maptiles
- Maptiler
- ESRI
- PDOK Kadaster beta
- Gemeente Amsterdam beta
- Webmapper Cartiqo beta
Making your own tiles is possible. You can find a list of all tile generators here.
From experience we tried the following command line tools. In the table of contents you can see a small overview of some of these things to get you started.
- Tippecanoe from Mapbox
- T-rex from Pirmin Kalberer
- Tegola from Go-spatial
Online hosting:
Hosting
- Geoserver
- OpenMapTile Server from MapTiler
For this workshop we use the Vector Tiles of Cartiqo.
Cartiqo is a vector tile map developed by Webmapper. Cartiqo is a Vector Tile product based on open source geo data of the Netherlands. It provides a full and detailed map of the Netherlands customizable to your own likes. It is recently moved to Maptiler for hosting.
Have a look at the documentation
The vector tiles come with 3 basic styles provided.
- Dark
- Light
- Topography
We will start with the most basic form of using MapboxGL.js using already provided styles and tiles from Cartiqo. In order to use the MapTiler maps we need a MapTiler account.
During the workshop we will work with a simple HTML page example. The examples can also be found in the git repository. Feel free to set up a folder and structure for yourself or work in any framework you'd like.
For this workshop, we assume you already know HTML,CSS and some JavaScript. If not see this Workshop Vector Tiles workshop. This is almost the same workshop but includes more explanation about the basic concepts of HTML, CSS and JavaScript.
<!DOCTYPE html>
<html>
<head>
<title> My title </title>
</head>
<body>
<H1>Example</H1>
</body>
</html>
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v1.4.1/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v1.4.1/mapbox-gl.css' rel='stylesheet' />
We will need a <div>
were our map will be placed.
<div>
with an id="map"
in the <body>
<div id="map"></div>
The map needs a height and width in order to be seen. Add a bit of CSS to the HTML document. The following is sufficient:
#map {
height: 500px;
width:100%;
}
Initialize a map creating a mapboxgl.Map
instance. Also use the Mapbox-gl-js API documentation.
https://api.maptiler.com/maps/96f41b36-a033-4b38-9f22-e2f64fb3868e/style.json?key=
let map = new mapboxgl.Map({
container: 'map',
style: 'https://api.maptiler.com/maps/96f41b36-a033-4b38-9f22-e2f64fb3868e/style.json?key=<>',
hash: true,
zoom: 11,
pitch: 60,
bearing: 62.4,
center: [4.8, 52.4],
attributionControl: false
});
ℹ️ new mapboxgl.Map({...});
creates a mapbox GL map!
ℹ️ container: "map"
places the map in our <div id="map">
object from the HTML.
ℹ️ hash: true
puts the #location in the URL of our map. With /zoom/lat/long/bearing/pitch
. See what happens to the URL of your map when you pan around.
ℹ️ The options zoom
,pitch
, bearing
and center
set the starting position of our map when opening it the first time. Now pointing to Amsterdam.
ℹ️ style: 'https://api.maptiler.com/maps/96f41b36-a033-4b38-9f22-e2f64fb3868e/style.json?key=<>'
is the mapbox url for the tiles, style, fonts and Glyphs! .
A Mapbox style contains all the elements we need for a map:
- The source like the Vector Tiles
- Styling information per style layer
- Fonts, Sprites and Glyphs
MapboxGL.js offers us a whole range of map options. Have a look at the documentation Mapbox has some specific webGL options. Like rotating and tilting the map.
The same as for our Leaflet map:
ℹ️ Looking for a specific place to centre on? Find your coordinates here: mapcoordinates.net
ℹ️ The minZoom
and maxZoom
restrict the map from zooming in or out further then those zoom levels. If you want to know how far "zoomed" in you are, have a look at this description of scales and examples about zoom levels.
ℹ️ The maxBounds
are the coordinates of a bounding box to which the user is restricted. Check the latlngbounds documentation. 🔗 Finding easy creation of bounding boxes at: https://boundingbox.klokantech.com/
Using these kind of map options, limits the use of the map to a great extent! When using a paid subscription plan on a tile provider this can be very useful. But also the IX design can be improved with these settings. People are directed to what you want to show them on the map and cannot "get lost" or use the map for different purposes. So do not forget about what you want the user to see and use these map options! :)
While with Leaflet the hash was a separate plug-in, Mapbox provides these already. On the other hand, a basic map in Mapbox does not contain the controls by default as Leaflet does. So let's add these. Mapbox offers some User Interface options. Look at https://docs.mapbox.com/mapbox-gl-js/api/#user%20interface
map.addControl(new mapboxgl.NavigationControl(), "top-left");
The AttributionControl
gives options for showing and defining the small source reference at the bottom of the map. If no attribution is given in the map's style we can provide one ourselves. Also we can overrule the attribution control provided by the style.
In the map options we set {attributionControl: false}
and then we add a new attribution control:
map.addControl(new mapboxgl.AttributionControl({
compact:true,
customAttribution: "hello there"
})
There is also a button for displaying a full screen map:
map.addControl(new mapboxgl.FullscreenControl({container: document.querySelector('body')}));
Do you want a pop-up when someone opens you application and does not have WebGL support? Add the following code to your JavaSript file:
// Check for Mapbox gl support:
if (!mapboxgl.supported()) {
alert('Your browser does not support Mapbox GL');
};
➡️ Continue to MapboxGL part 2 start manipulation the map with JavaScript!