Mapbox GL JS fundamentals

Welcome to a quick tour of Mapbox GL JS. This guide walks through essential functions and common patterns in this web mapping API, highlighting some of the core concepts that distinguish Mapbox GL JS from other map libraries. For those with experience using Leaflet, Mapbox.js, or OpenLayers, the next few sections will introduce some of the differences in Mapbox GL JS as well as features that should look familiar.

Core differences in Mapbox GL JS

Client-side rendering

At the heart of Mapbox GL JS is client-side rendering. For creating web apps in Mapbox GL JS, maps render as vector tiles using JavaScript and WebGL. Rather than composing a series of image files on a server, the ability to change styles on the fly expands the possibilities for how a map can be displayed.

The camera

The camera represents the map’s field of view. The viewpoint of the camera in a system like Leaflet or Mapbox.js is determined by the map’s centerpoint and zoom level, an integer usually between 0 and 22. Mapbox GL JS also includes parameters for adjusting the map’s perspective.

  • Centerpoint: in longitude, latitude order
  • Zoom level: any number within the zoom range. This can be a fractional number like 1.5 or 6.2 and the map will render correctly.
  • Bearing: a map rotation value in degrees. The map will be rotated and details like text labels will react by rotating right-side-up
  • Tilt: also in degrees, a value by which the map will be tilted in perspective.

Here’s an example of combining bearing and zoom.

Layers

Traditional JavaScript map libraries often have two distinct categories of what are called “layers”:

  • baselayers: image tiles that provide the foundation of the map. These tend to have a lot of data — a street map contains labels, buildings, and icons, details that wouldn’t work very well if they were rendered by browsers. Think L.mapbox.tileLayer in Mapbox.js and L.TileLayer in Leaflet.
  • overlays: these are often vector data like GeoJSON, encapsulated in layers like L.mapbox.featureLayer in Mapbox.js and L.geoJson in Leaflet. Relative to baselayers, they contain less information but are far more interactive: overlays can be changed in JavaScript and clicks on them can be detected and can trigger popups.

With Mapbox GL JS, a layer is a styled representation of vector or raster data. Each layer provides rules about how certain data should be drawn in the browser, and the renderer uses these layers to actually draw the map on the screen.

Here, the level of map detail varies with zoom. The terrain, buildings, public transportation stops, and location information is rendered as its own layer.

Because everything on the map is loaded as vectors in the browser, Mapbox GL JS has no distinction between baselayers and overlay layers. This means that map details like labels and icons and elements like streets and buildings can be modified with JavaScript, just like overlays in earlier mapping libraries. This also means that the functions and methods for changing and accessing styles of layers are a bit more detailed, as you will see in the sections below.

Adding a map

The basis of every Mapbox GL JS project is the mapboxgl.Map class.

var map = new mapboxgl.Map({
  // container id
  container: 'map',
  // style location
  style: 'mapbox://styles/mapbox/streets-9',
  // starting position
  center: [-74.50, 40],
  zoom: 9
});

This will look similar to Leaflet’s L.Map class or Mapbox.js’s L.mapbox.map, with a few core differences:

Coordinates

Where Mapbox GL JS handles coordinates as arrays (here [-74.50, 40]), it assumes that the coordinates are in longitude, latitude order (vs latitude, longitude in Leaflet and Mapbox.js). This order corresponds to the order of coordinates in GeoJSON and every other geospatial format, as well as math’s X, Y ordering.

Map style

The map loads a style via the URL mapbox://styles/mapbox/streets-v9. This is a URL to a remote file that the map will download in order to determine the tilesets it includes and how they are styled for the end-user. Mapbox GL JS permits URLs instead of literal data in several places, including data sources.

Since these resources are remote, they are asynchronous, like other remote resources in JavaScript libraries. Therefore, code that connects to Mapbox GL JS will tend to use event binding in order to change the map at the right time. For instance:

map.on('load', function() {
  map.addLayer({
    id: 'terrain-data',
    type: 'line',
    source: {
      type: 'vector',
      url: 'mapbox://mapbox.mapbox-terrain-v2'
    },
    'source-layer': 'contour'
  });
});

The above code uses the map.on('load', function() { code to run map.addLayer only once the map’s resources, including the style, have been loaded. If it were to run the map.addLayer method immediately, it would trigger an error because addLayer adds a layer to a style and the style would not yet exist.

There are also two separate methods for changing the map’s position: jumpTo and easeTo. jumpTo is similar to old-fashioned map navigation: the map will instantly show a different place in the world. easeTo is fancy: instead of moving immediately, it intelligently animates between places in the world, zoom, bearing, or tilt values, making it easier to keep track of where and how much the map is moving.

Adding data to the map

Data can be added to the map as a layer using the addLayer() method. addLayer takes an object as a parameter that also includes id (created by the user) and type properties. When adding a layer, you are required to provide a source, which makes the data available to the renderer to be drawn, and you have the option to also specify layout and paint properties that tells the renderer how to draw it.

Specifying a source

You will need to add a source when you add a new layer. A source requires a type and a url meaning that all data types can be accessed as remote resources (just like style in Map above). There are five types of sources, each with its own properties:

Vector sources also need to include a source-layer with the name of the layer used from the vector file source (often the name of the original file). See this example using a vector source:

map.on('load', function() {
  map.addLayer({
    id: 'rpd_parks',
    type: 'fill',
    source: {
      type: 'vector',
      url: 'mapbox://mapbox.3o7ubwm8'
    },
    'source-layer': 'RPD_Parks'
  });
});

For more information on each source type, check out the Sources section of the Mapbox Style Specification.

Specifying layout and paint properties

Layers feature two special sub-properties that enable data styling: paint and layout. These are used to define how data will be rendered on the map. layout properties refer to placement and visibility, among other high-level preferences, and are applied early in the rendering process. paint properties are more fine-grained style attributes like opacity, color, and translation. They are less processing-intensive and rendered later.

The following code adds a layer to the map to style the parks data with a green fill.

map.on('load', function() {
  map.addLayer({
    id: 'rpd_parks',
    type: 'fill',
    source: {
      type: 'vector',
      url: 'mapbox://mapbox.3o7ubwm8'
    },
    'source-layer': 'RPD_Parks',
    layout: {
      visibility: 'visible'
    },
    paint: {
      'fill-color': 'rgba(61,153,80,0.55)'
    }
  });
});

The final product: a map zoomed to San Francisco with a layer that fills land used for parks in green. The layer is based on a vector source of the city’s park lands data.

Next steps

You’ve got the basics down, now go forth and make something!

  • Check out the current examples to see Mapbox GL JS’s full range of interactivity.
  • Need inspiration? View the newest additions to the gallery.

For more tips and updates, be sure to keep up with our blog. Happy mapping!

Additional questions? Ask our support team or learn more about How Mapbox Works.