MapboxGL part 3 - NieneB/webmapping_for_developers GitHub Wiki
Making our own style json
Instead of manipulating a style object we can also make our own style json.
:arrow_forward: Create a style object in your JavaScript main.js
file. Or create a separate style.json
file.
:arrow_forward: Change the map style to your style object:d
var map = new mapboxgl.Map({
container: 'map',
style: mystyle,
hash: true,
zoom: 11,
pitch: 60,
bearing: 62.4,
center: [ 4.8, 52.4]
});
Add a source
For now we start with 1 source, namely our vector tiles that are hosted on Maptiler.
:arrow_forward: Go to your Maptiler account and get the Cartiqo tile source url.
You can use a tile.json
source or the xyz
tile source. It looks something like this:
https://api.maptiler.com/tiles/a8d5fe6e-07e0-4e0a-b4f9-d54742c99a84/tiles.json?key=
https://api.maptiler.com/tiles/a8d5fe6e-07e0-4e0a-b4f9-d54742c99a84/{z}/{x}/{y}.pbf?key=
:arrow_forward: Define the source in your style object:
"sources": {
"cartiqo":{
"type": "vector",
"tiles": ["https://api.maptiler.com/tiles/a8d5fe6e-07e0-4e0a-b4f9-d54742c99a84/{z}/{x}/{y}.pbf?key="]
}
},
:information_source: The source name we give to it is cartiqo
but you can give it any name you like.
:information_source: The type of source is vector
and the url to the tiles is given.
Tile json
A tile json is a JSON format to describe a vector tile source. Check the specs https://github.com/mapbox/tilejson-spec. It is not obliged to use, but when using MapboxGL.js it gives some extra functionality. For example, overzooming is enabled when using a tilejson source.
Layers
Next we can create layers, accordingly on what layers are available in the vector data. The first layer we add is a background layer with the background fill color white.
:arrow_forward: Create a background layer.
"layers":[
{
"id": "background",
"type": "background",
"paint": {
"background-color":"#FFFFFF"
}
}
]
:information_source: The "id"
is a custom name you give to the layer. You can give it any name you like.
:information_source: "type"
is the rendering type of the layer. It can be one of fill
, line
, symbol
, circle
, fill-extrusion
, raster
or background
.
:arrow_forward: Have a look at the style specification for all the different layer types: https://docs.mapbox.com/mapbox-gl-js/style-spec/#layers
We can go on and on with adding layers. Try to add for all the types one layer!
"layers":[
{
"id": "background",
"type": "background",
"paint": {
"background-color":"#FFFFFF"
}
},
{
"id": "water",
"source": "cartiqo",
"source-layer": "water",
"type": "fill",
"paint":{
"fill-color": "blue"
}
}
]
:information_source: The "source"
is the name of the source provided in the beginning of the style object. We called it "cartiqo"
.
:information_source: The "source-layer"
is the name of the data layer in the vector tiles. This information is fixed. We provided all the names of the layers for you already. A bit further on we will explain how you can request the vector tile information.
:information_source: "paint"
Default paint properties for this layer.
There are more options you can give to a layer. For example:
- layout
- filter
- minzoom
- maxzoom
Fill-Extrusion
Do you want this cool 3D effect? This is called fill-extrusion
.
A fill-extrusion is only possible on polygons!
The type of layer is fill-extrusion
:
{
"id": "building_extrusion",
"type": "fill-extrusion",
"source": "cartiqo",
"source-layer":"urban",
"maxzoom": 22,
"minzoom": 11,
"paint": {
"fill-extrusion-height": 20,
"fill-extrusion-color": "#f37788",
"fill-extrusion-opacity": 0.9
}
}
:arrow_forward: Try to get one or more layers in fill-extrusion. (extrusion == 2,5D )
Make a beautiful map visualization.
:arrow_forward: Try adding more layers, like roads and buildings. Change the colors and make your own map!
Change your map settings so you get a nice view. Change colors, add extrusions and layers. Also see if you can use filters.
:link: Make use of the Mapbox style spec: https://www.mapbox.com/mapbox-gl-js/style-spec/
:link: Mapbox also provides a lot of examples: https://www.mapbox.com/mapbox-gl-js/example/simple-map/
Some styling tips.
- The order of the layers in your
style
is the order of drawing. So first defined layer, "background", is drawn first, the next layer is drawn on top, etc. - The labels placing priority is also dependend on the layer order. Layers at the top have less drawing priority, layers at the bottom of the file have more drawing priority!
- Is your map slow? Check out :link: Improve the performance of your MapboxGL map
- Using a lot a fill-extrusions will also make your map slow.
Glyphs & Fonts
In order to add labels we need a font. Fonts have also to be converted to pbf
, in order to render them with WebGL, these are called Glyphs. Mapbox provides some fonts glyphs but then there are also some open source alternatives and of course we can host them ourselves. (see Advanced Glyps, Fonts)
We add the glyphs
reference at the top of our style specification.
{
"version": 8,
"name": "Mijn eigen Stijl",
"sprite": "url",
"glyphs": "url/{fontstack}/{range}.pbf",
"sources": {...},
"layers": [...]
}
Using Mapbox fonts is possible by adding the glyphs to the style.json:
"glyphs": "mapbox://fonts/openmaptiles/{fontstack}/{range}.pbf",
But you do need your mapbox access token.
If you do not want to depend on the Mapbox token we can use free providers or make our own. For example using fonts from openmaptiles:
"glyphs": "http://fonts.openmaptiles.org/{fontstack}/{range}.pbf",
Or the ones form Webmapper:
"glyphs": "https://ta.webmapper.nl/wm/glyphs/{fontstack}/{range}.pbf",
In the advanced tutorial Glyphs you can learn how to transform you own font to pbf range.
Now we can add a label layer of type symbol
:
{
"id": "high_prior_labels",
"type": "symbol",
"source": "cartiqo",
"source-layer": "labels",
"maxzoom": 20,
"minzoom": 5,
"layout": {
"visibility": "visible",
"symbol-placement": "point",
"symbol-avoid-edges" : false,
"text-field":"{name}",
"text-font": ["Open Sans Regular"],
"text-size": 20,
"text-max-width": 5,
"text-anchor": "center",
"text-line-height": 1,
"text-justify": "center",
"text-padding": 20,
"text-allow-overlap": false
},
"paint":{
"text-opacity": 1,
"text-color": "#535353"
}
}
There are a lot of options to style your labels. Have a look at :https://www.mapbox.com/mapbox-gl-js/style-spec#layers-symbol
The most important is "text-field" : "{name}"
. This takes the name
attribute to assign the label text.
Then "text-font":"["Open Sans Regular"]
gets the Open Sans font which is available at our glyphs link.
"text-size"
and "text-color"
are also very important!
:arrow_forward: Add labels to your map!
Alternative Glyph sources:
"glyphs": "mapbox://fonts/openmaptiles/{fontstack}/{range}.pbf",
"glyphs": "http://fonts.openmaptiles.org/{fontstack}/{range}.pbf",
"glyphs" : "https://free.tilehosting.com/fonts/{fontstack}/{range}.pbf?key={key}"
"glyphs" : "https://maps.tilehosting.com/fonts/{fontstack}/{range}.pbf.pict?key=ownkey"
Sprites & Icons
A sprite is a single image containing all icons included in a style. Sprites are often used in web development and even video games to improve performance. By combining lots of small images into a single image (sprite), you can reduce the number of requests needed to fetch all the images, improving performance and making your map faster.
:link: https://www.mapbox.com/help/define-sprite/ :link: https://www.mapbox.com/mapbox-gl-js/style-spec/#sprite
Your style requires the image sprites used for patterns and icons.
"sprite": "http://openmaptiles.org/sprites/"
The link contains 2 files:
- a png file with the images
- a json file with the x and y location and reference name to the images.
The 2 files have the same file name.
Example of an icon in the json
file:
"airport-15": {
"width": 42,
"height": 42,
"x": 76,
"y": 300,
"pixelRatio": 2,
"visible": true
}
This means that you can reference an icon by name, such as "airport-15", and our map renderer will reference the JSON file to get data about the icon and then only show the sprite at that specific icon.
In order to create your own sprites and self-host them via HTTP, you need to use the spritezero-cli. See the advanced Sprite tutorial to make them yourself.
For now we can use the OpenMaptile sprites. If you have a look at the
Openmaptiles Github you can find the available icons and their reference name.
Use this sprite source in your style.json
:
"sprite": "https://openmaptiles.github.io/klokantech-basic-gl-style/sprite"
To make a icon in your map we need a layer with type symbol
:
{
"id": "poi-park",
"type": "symbol",
"source": "cartiqo",
"source-layer": "pois",
"minzoom": 15,
"filter": [
"all",
[
"in",
"type",
"public_space"
]
],
"layout": {
"icon-image": "playground_11",
"text-padding": 2,
"text-font": [
"Lato"
],
"text-anchor": "center",
"text-field":"{name}",
"text-offset": [
0,
0.6
],
"text-size": 12,
"text-max-width": 9
},
"paint": {
"text-halo-blur": 0.5,
"text-color": "#79906c",
"text-halo-width": 1,
"text-halo-color": "#ffffff"
}
},
:information_source: In the layout
we specify the "icon-image"
to use. This is the reference name that is defined in the sprite.json file.
Alternative Sprite sources:
"sprite": "https://openmaptiles.github.io/klokantech-basic-gl-style/sprite"
"sprite": "https://maps.tilehosting.com/styles/basic/sprite"
Webmapper
"sprite": "https://ta.webmapper.nl/wm/sprites/wm_sprite"