Home

Area of Interests

  • Digital Photogrammetry
  • Computer Visiion
  • Geoinformatics

Articles

Education

  • Ph.D. (RS&GIS) AIT
  • M.Sc. (RS&GIS) AIT
  • B.Sc. (Computer Science) RBRI

Classes

How to use MapLibre GL JS


Kumpee Teeravech
Geoinformatics Program (GI)
Faculty of Computer Science and Information Technology (CSIT)
Rambhai Barni Rajabhat University (RBRU)
2025-03-01
Many of my projects require interactive web mapping applications, which play a crucial role in visualizing spatial data and enhancing user engagement. There are several JavaScript libraries available for rendering maps in web browsers, each with its own strengths and use cases. Some of the most widely used options include: Among these, I have been using OpenLayers for nearly a decade and have grown to appreciate its flexibility and powerful features. It has been my go-to library for handling various mapping needs. However, for some of my recent projects, I need to transition to MapLibre GL JS, which provides enhanced support for vector tiles and improved performance with WebGL rendering.

To familiarize myself with this shift, I decided to write this article as a quick review of the setup process and basic configuration of MapLibre GL JS. This guide aims to help others who, like me, are making the transition and need a straightforward starting point.

About the library

MapLibre GL JS is an open-source JavaScript library for rendering interactive maps using WebGL. It is a community-driven fork of Mapbox GL JS (v1) that allows developers to create high-performance, customizable, and vector-tile-based maps without requiring a Mapbox subscription. The library supports various map styles, dynamic data visualization, and user interactions such as zooming, panning, and rotating.

At its core, MapLibre GL JS is built on WebGL, a low-level JavaScript API that enables direct access to the GPU for rendering both 2D and 3D graphics efficiently. Unlike traditional raster-based mapping libraries such as Google Maps or Leaflet, which rely on pre-rendered image tiles, MapLibre GL JS dynamically renders vector tiles in real time. This hardware-accelerated approach enables smooth transitions, rapid updates, and interactive features that enhance the overall user experience.

How MapLibre GL JS Renders Maps

The rendering process in MapLibre GL JS follows several key steps to ensure efficient and accurate visualization of geographic data. The first step is tile loading and parsing. Vector tiles are fetched from a tile server and then parsed into different geometries, including points, lines, polygons, and labels. The raw geographic data is converted into GPU-friendly formats such as vertex buffers, index buffers, and attribute buffers, which WebGL can efficiently process.

Once the data is prepared, MapLibre GL JS utilizes GLSL (OpenGL Shading Language) to define vertex shaders and fragment shaders that execute rendering tasks on the GPU. Different shader programs handle various map elements. Fill layers are used for polygons, such as landmasses and water bodies. Line layers render roads and boundaries, while symbol layers are responsible for text labels and icons. Since WebGL operates in Normalized Device Coordinates (NDC) ranging from -1 to 1, while map coordinates are defined in longitude and latitude, a projection matrix is required to convert geographic coordinates into screen-space coordinates. MapLibre GL JS typically uses the Web Mercator projection, ensuring consistency across different zoom levels and devices.

Once the geometries and textures are ready, WebGL draw calls, such as gl.drawArrays or gl.drawElements, execute the rendering. Map features are drawn back to front, following a layer hierarchy based on z-index. The depth buffer and stencil buffer in WebGL help maintain proper layering and occlusion of features, ensuring that overlapping elements are displayed correctly.

How to install

There are several ways to install MapLibre GL JS, including using NPM, configuring Content Security Policy (CSP) directives, or linking to a Content Delivery Network (CDN). For simplicity and ease of use, I will use the CDN method, specifically the distribution from unpkg.com. This approach allows you to quickly integrate MapLibre GL JS into your web application without additional dependencies or build configurations. To add the library to your web page, include the following lines in the <head> section of your HTML document. This will load both the JavaScript library and the required CSS for proper styling and functionality of the interactive map.
<script src="https://unpkg.com/maplibre-gl@^5.1.1/dist/maplibre-gl.js"></script>
<link href="https://unpkg.com/maplibre-gl@^5.1.1/dist/maplibre-gl.css" rel="stylesheet" />
Next, create a new map object to display the map. This involves initializing MapLibre GL JS and specifying the necessary configuration parameters. The following code will use an HTML element with the ID "map" as the target canvas for rendering the map. It will also apply a map style from https://demotiles.maplibre.org/style.json, which provides a basic tile layer for visualization. The map's initial view will be centered at the origin of the geographic coordinate system (0, 0) and the zoom level will be set to 2, providing a global overview.
var map = new maplibregl.Map({
  container: 'map', 
  style: 'https://demotiles.maplibre.org/style.json',
  center: [0, 0],
  zoom: 2
});

Adding markers

A marker can be added to the map using the Marker object in MapLibre GL JS. The default coordinates of the marker are specified using the setLngLat method, which takes a longitude-latitude pair as input. After defining the marker’s position, the addTo method is called on the Marker object to attach it to the parent map object,
var marker = new maplibregl.Marker()
.setLngLat([100.523186, 13.736717]) // Longitude, Latitude
.addTo(map); // Add to map

Adding popup label

The following methods can be added to the Marker object to adds a popup label that appears when the user clicks on the marker. This is achieved by creating a Popup object and setting its content using the setHTML method. The popup is then associated with the marker using the setPopup method, allowing it to display when the marker is clicked. The offset parameter is used to specify the desired distance between the marker and the popup label, ensuring that the label appears at an appropriate position relative to the marker.
.setPopup(new maplibregl.Popup({ offset: 25 }) // Add a popup with some text
.setText("Hello from Bangkok!"))

Setting map center and zoom level

The center of the map can be adjusted dynamically using the setCenter method, which takes a longitude-latitude coordinate pair as input. Similarly, the zoom level can be configured using the setZoom method, which determines how close or far the view appears. A higher zoom value provides a more detailed, close-up view, while a lower zoom value offers a broader, global perspective
map.setCenter([101.0, 14.0]); // Moves the map to a new location
map.setZoom(3); // Zoom into the city

Set background map style

The default map style provided by MapLibre GL JS uses the style URL from https://demotiles.maplibre.org/style.json. However, there are several alternative map styles available from different providers, each offering unique visual designs and features suited for various applications. Some alternative map style URLs are listed below, but it's important to note that certain map styles require an API key for access. The below code changes map style by using the setStyle method.
map.setStyle('https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json');

Result

After executing the above code, the map is successfully displayed with its center set to Chanthaburi, a province located in the eastern part of Thailand. The map uses the default map style, providing a clear and interactive view of the area. A marker is placed at the Chanthaburi, and when clicked, a popup label appears, displaying the text "Chanthaburi!".

Conclusion

This article provides a quick review and covers the basic usage of MapLibre GL JS. I found the setup process to be straightforward and easy, making it a great choice for developers who need to quickly integrate interactive maps into their web applications.

However, I have not yet explored some of its additional features, such as adding polygons and working with raster tile maps. Another aspect I have yet to test is its support for interactive modifications, particularly real-time updates to polyline vertex coordinates based on keyboard and mouse inputs. Many of my applications rely on these interactive features, and I have already developed a custom implementation on top of OpenLayers to handle such requirements. It would be interesting to evaluate whether MapLibre GL JS can offer similar flexibility or if additional workarounds would be needed for these advanced interactions.

The English in this article has been revised using ChatGPS-4o.