Using maplibre-gl with Tianditu Tiles for Large‑Screen Map Development
This article explains how to choose between mapbox‑gl and its open‑source fork maplibre‑gl, obtain free Tianditu tile services, install the library, render 2.5D and vector tiles, customize styles, and overlay business data such as polygons, icons and labels for large‑screen web maps.
What You Will Learn
You will understand the differences between mapbox-gl and maplibre-gl , how to obtain free tiles from the authoritative "Tianditu" platform, and how to build a complete large‑screen map with 2.5D view, custom styling, and business data overlays.
Choosing a Map Engine
The article first compares the two engines. mapbox-gl is a widely used vector‑tile engine that supports 2.5D rotation, 3D models, raster and vector layers, but it requires an access token and a credit‑card‑bound account after version 2.0. maplibre-gl is a fork of mapbox-gl that removes the token requirement and remains fully open‑source.
When to Use Each
If you need Mapbox‑provided tile services, stick with mapbox-gl .
If you only need the rendering capabilities and prefer an open source solution, choose maplibre-gl .
Getting Tianditu Tiles
Register on the Tianditu website, create an API key, and use the WMTS URL pattern to request vector, annotation, or imagery tiles. The key is stored in a global variable MY_KEY to avoid accidental exposure.
window.MY_KEY = '88******************2030'Installing maplibre‑gl
Install via Yarn or include the CDN:
yarn add maplibre-gl@latest <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"/>Rendering a Tianditu Tile Map
Initialize the map with a raster source that points to the Tianditu vector tiles and a layer that displays them. The example also shows how to enable 2.5D perspective.
<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,
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(() => {
new mapboxgl.Map({ container: mapEl.value, ...initOption });
});
</script>
<style scoped>
.map { width: 600px; height: 300px; }
</style>Adding Annotation Tiles
Another raster source for annotation tiles can be added in the same style definition, then referenced by a new layer.
"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" }
]Customizing the Style
Adjust raster brightness, hue, and saturation to match a dark‑theme dashboard.
{
"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
}
}Loading Business Data
Business‑specific layers are added by creating a geojson source and then adding fill , symbol (icons), and symbol (labels) layers. The article provides helper functions to load custom icons and shows the two‑step pattern (add source → add layer).
// Load custom icons
const loadImages = async (imgs) => {
await Promise.all(Object.entries(imgs).map(([key, url]) =>
new Promise(resolve => {
map.loadImage(url, (err, res) => { if (err) throw err; map.addImage(key, res); resolve(res); });
})
));
};
await loadImages(images);
// Add GeoJSON 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
}
});
// Name 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' }
});Conclusion
The guide covered the full workflow: selecting a map engine, obtaining free Tianditu tiles, installing maplibre-gl , rendering 2.5D maps, customizing visual style, and overlaying business‑specific polygons, icons, and labels. The next article will explore the "wireframe" style for large‑screen maps.
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.