Data Driven Line
Runnable MapLibre GL JS example: Data Driven Line. Open the live demo, read the complete source, and copy the file into your project. No build step or API key.
single HTML file · CDN dependencies onlyinterface may contain Chinese labels
Source
<!--
示例:属性驱动的线样式
核心逻辑:line-width 用 interpolate 读 lanes,line-color 用 match 读等级
数据:页面内构造的 18 段道路,带车道数与道路等级
依赖:MapLibre GL JS 4 · jsDelivr CDN · demotiles 样式
-->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta name="robots" content="noindex,follow">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>属性驱动的线样式</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/maplibre-gl@4/dist/maplibre-gl.css">
<style>
html,body{height:100%;margin:0}
body{display:flex;flex-direction:column;overflow:hidden;
font:13px/1.6 -apple-system,"Segoe UI","PingFang SC",sans-serif;color:#16181d}
.bar{flex:0 0 auto;display:flex;gap:14px;align-items:center;padding:8px 12px;
background:#f6f7f9;border-bottom:1px solid #e3e6ea;font-size:12px;color:#58606e;flex-wrap:wrap}
.bar b{color:#16181d;font-weight:600}
.bar input[type=range]{width:120px}
#map{flex:1 1 auto;min-height:0}
.legend{position:absolute;left:12px;bottom:28px;z-index:2;background:rgba(255,255,255,0.92);
border:1px solid #e3e6ea;border-radius:6px;padding:8px 10px;font-size:12px;color:#3a4250}
.legend i{display:inline-block;width:18px;height:4px;border-radius:2px;margin-right:6px;vertical-align:middle}
</style>
</head>
<body>
<div class="bar">
<span>路段 <b>18</b></span>
<label>宽度缩放 <input id="s" type="range" min="0.5" max="2.5" step="0.1" value="1"> <b id="sv">1.0</b></label>
<span>宽度和颜色都来自要素属性</span>
</div>
<div id="map"></div>
<div class="legend">
<div><i style="background:#f03e3e"></i>快速路</div>
<div><i style="background:#f59f00"></i>主干路</div>
<div><i style="background:#4dabf7"></i>次干路</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/maplibre-gl@4/dist/maplibre-gl.js"></script>
<script>
(function () {
'use strict';
if (typeof maplibregl === 'undefined') {
document.body.innerHTML =
'<div style="padding:24px;color:#b42318">MapLibre 加载失败,请检查能否访问 cdn.jsdelivr.net</div>';
return;
}
var TYPES = ['快速路', '主干路', '次干路'];
var features = [];
var base = [112, 33];
/* 生成一张区域路网,每条路随机给等级与车道数 */
for (var i = 0; i < 18; i++) {
var horizontal = i % 2 === 0;
var k = Math.floor(i / 2);
var coords = horizontal
? [[base[0] - 4.5, base[1] - 3.6 + k * 0.55], [base[0] + 4.5, base[1] - 3.6 + k * 0.55 + 0.15]]
: [[base[0] - 3.6 + k * 1.0, base[1] - 3.5], [base[0] - 3.6 + k * 1.0 - 0.15, base[1] + 3.8]];
features.push({
type: 'Feature',
properties: {
name: '路段 ' + (i + 1),
type: TYPES[i % 3],
lanes: 2 + (i % 5)
},
geometry: { type: 'LineString', coordinates: coords }
});
}
var map = new maplibregl.Map({
container: 'map',
style: 'https://demotiles.maplibre.org/style.json',
center: [112.2, 33.2],
zoom: 5.4,
attributionControl: { compact: true, customAttribution: 'MapLibre demo tiles' }
});
map.addControl(new maplibregl.NavigationControl(), 'top-right');
var scale = 1;
map.on('load', function () {
map.addSource('roads', {
type: 'geojson',
data: { type: 'FeatureCollection', features: features }
});
map.addLayer({
id: 'roads',
type: 'line',
source: 'roads',
layout: { 'line-cap': 'round', 'line-join': 'round' },
paint: {
'line-width': [
'interpolate', ['linear'], ['get', 'lanes'],
2, 2,
6, 9
],
'line-color': [
'match', ['get', 'type'],
'快速路', '#f03e3e',
'主干路', '#f59f00',
'#4dabf7'
],
'line-opacity': 0.9
}
});
});
document.getElementById('s').addEventListener('input', function () {
scale = parseFloat(this.value);
document.getElementById('sv').textContent = scale.toFixed(1);
if (!map.getLayer('roads')) return;
/* 把缩放系数乘进表达式里,避免逐条改属性 */
map.setPaintProperty('roads', 'line-width', [
'interpolate', ['linear'], ['get', 'lanes'],
2, 2 * scale,
6, 9 * scale
]);
});
map.on('mousemove', 'roads', function (e) {
var p = e.features[0].properties;
map.getCanvas().style.cursor = 'pointer';
map.getCanvas().title = p.name + ' · ' + p.type + ' · ' + p.lanes + ' 车道';
});
map.on('mouseleave', 'roads', function () {
map.getCanvas().style.cursor = '';
map.getCanvas().title = '';
});
map.on('error', function (e) {
if (e.error) console.warn('地图错误:' + e.error.message);
});
})();
</script>
</body>
</html>
Language: the code and this page are in English; the full tutorial and API notes for this example are in Chinese. The demo itself is the authoritative version — it runs exactly as shown.