Building Tile‑Style Large‑Screen Maps with mapbox‑gl, maplibre‑gl, and Tianditu
This tutorial explains the differences between mapbox‑gl and maplibre‑gl, shows how to obtain and use Tianditu tile services, and provides step‑by‑step code for creating a tile‑style large‑screen map with 2.5D view, custom layers, and business data overlays.
What You Will Learn
Understand the strengths and limitations of mapbox-gl and maplibre-gl .
Learn how to use the official Tianditu map platform.
Implement a practical tile‑style map project.
Metaphor About the Hammer
Just as a person holding a hammer sees everything as a nail, the author treats mapbox-gl / maplibre-gl as a "multi‑function hammer" for large‑screen map development.
1. Choosing a Map Engine
The GIS world is dominated by Mapbox’s vector‑tile standard (MAPBOX VECTOR TILE SPECIFICATION). mapbox-gl is the official rendering engine, offering features such as projection support, layer stacking, GeoJSON, images, text, custom styles, 2.5D rotation, 3D models, DOM‑based HTML overlays, and WebGL rendering.
Key advantages are its 2.5D view and 3D model support, which surpass OpenLayers and Leaflet. However, it has drawbacks: no support for underground pipe‑network visualization, weaker 3D compared to Cesium, and limited openness.
Since version 2, mapbox-gl-js requires an access token tied to an international credit card, making it less accessible for many developers.
1.2 Why Switch to maplibre‑gl?
maplibre-gl is a fully open‑source fork of mapbox-gl that does not require an access token. It retains the powerful capabilities of mapbox-gl while being truly open.
1.3 Simple Selection Principle
If you need Mapbox’s official tile service, use mapbox-gl .
If you only need the engine’s capabilities without Mapbox tiles, choose the open maplibre-gl .
2. How Large‑Screen Maps Are Usually Built
Two common visual styles exist for big‑screen maps: a wireframe style and a tile style. The choice depends on business requirements—coarse‑grained data favors wireframe, while precise geographic detail requires tile style.
3. Using Tianditu as an Online Tile Service
Tianditu, provided by the National Basic Geographic Information Center, offers free, authoritative map tiles. After registering as an individual developer, you obtain a key used in tile URLs.
// Global variable to store the key (do NOT expose it in production)
window.MY_KEY = '88******************2030'Tile URLs are constructed like:
https://t0.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILECOL={x}&TILEROW={y}&TILEMATRIX={z}&tk=${MY_KEY}4. Rendering the Map with maplibre‑gl
4.1 Install the Engine
Via Yarn:
yarn add maplibre-gl@latestOr via CDN:
<script src='https://unpkg.com/maplibre-gl@latest/dist/maplibre-gl.js'></script>
<link href='https://unpkg.com/maplibre-gl@latest/dist/maplibre-gl.css' rel='stylesheet' />4.2 Initialize a Tianditu Tile Map
<template>
<div ref="mapEl" class="map"></div>
</template>
<script setup>
import mapboxgl from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';
import { onMounted, ref } from 'vue';
const mapEl = ref(null);
const initOption = {
style: {
version: 8,
id: '43f36e14-e3f5-43c1-84c0-50a9c80dc5c7',
sources: {
'tdt-vec': {
type: 'raster',
tiles: [`https://t0.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILECOL={x}&TILEROW={y}&TILEMATRIX={z}&tk=${MY_KEY}`],
tileSize: 256
}
},
layers: [{
id: 'tdt-tiles-layer',
type: 'raster',
source: 'tdt-vec'
}]
}
};
onMounted(() => {
const map = new mapboxgl.Map({
container: mapEl.value,
...initOption
});
});
</script>
<style scoped>
.map { width: 600px; height: 300px; }
</style>This creates a Mercator‑projected, tile‑style 2D map with 2.5D tilt support.
4.3 Adding Layers and Sources
In the Mapbox/Maplibre model, a map consists of sources (data) and layers (visual representation). Adding a feature follows two steps:
// step 1: add a source
map.addSource('my-source', { type: 'geojson', data: myGeoJSON });
// step 2: add a layer
map.addLayer({ id: 'my-layer', type: 'fill', source: 'my-source', paint: { 'fill-color': 'red', 'fill-opacity': 0.5 } });4.4 Adding Tianditu Annotation Tiles
"sources": {
"tdt-cva": {
"type": "raster",
"tiles": [
`https://t0.tianditu.gov.cn/cva_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILECOL={x}&TILEROW={y}&TILEMATRIX={z}&tk=${MY_KEY}`
],
"tileSize": 256
}
},
"layers": [{
"id": "tdt-cva-layer",
"type": "raster",
"source": "tdt-cva"
}]4.5 Fine‑Tuning Map Appearance
Adjust raster layer paint properties to match a dark UI theme:
{
"id": "tdt-tiles-layer",
"type": "raster",
"source": "tdt-vec",
"paint": {
"raster-brightness-max": 0.7,
"raster-brightness-min": 0.3,
"raster-hue-rotate": 20,
"raster-saturation": 0.7
}
}Alternatively, switch to Tianditu imagery tiles by changing the source URLs.
5. Loading Business Data
5.1 Rendering Polygon Areas
map.on('style.load', () => {
map.addSource('geojson-area-source', {
type: 'geojson',
data: geojsonArea
});
map.addLayer({
id: 'geojson-area-layer',
type: 'fill',
source: 'geojson-area-source',
paint: { 'fill-color': 'red', 'fill-opacity': 0.5 }
});
});5.2 Adding Icons and Labels
First load custom images:
const loadImages = async (imgs) => {
await Promise.all(Object.entries(imgs).map(([key, url]) =>
new Promise((resolve) => {
map.loadImage(url, (error, res) => {
if (error) throw error;
map.addImage(key, res);
resolve(res);
});
})
));
};Then add a GeoJSON source for the points and two layers – one for the icons and one for the text labels:
// add source
map.addSource('boys-source', { type: 'geojson', data: boys });
// icon layer
map.addLayer({
id: 'boys-icon-layer',
type: 'symbol',
source: 'boys-source',
layout: {
'icon-image': '{icon}',
'icon-size': 0.2,
'icon-anchor': 'center',
'icon-rotation-alignment': 'viewport',
'icon-allow-overlap': true
}
});
// label layer
map.addLayer({
id: 'boys-name-layer',
type: 'symbol',
source: 'boys-source',
layout: {
'text-field': '{name}',
'text-size': 14,
'text-offset': [0, 2.4],
'text-allow-overlap': true
},
paint: { 'text-color': 'white' }
});6. Conclusion
The article covered:
The usage scope of mapbox-gl and maplibre-gl .
How to obtain and apply Tianditu tile services.
Practical implementations of several business scenarios, including tile‑style maps, annotation layers, visual adjustments, and dynamic data overlays.
With this knowledge, developing tile‑style large‑screen maps should no longer be a hurdle. The next chapter will explore wireframe‑style map development.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.