MapLibre GL JS第49课:用表达式创建渐变线

📌 学习目标

  • 掌握用表达式创建渐变线的实现方法
  • 理解相关API的使用
  • 能够独立完成类似功能开发

🎯 核心概念

使用表达式创建渐变线条。

💻 完 整 代 码

代码示例

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Create a gradient line using an expression</title>
    <meta property="og:description" content="使用线渐变 paint 属性和表达式来可视化从线条起点开始距离。" />
    <meta property="og:created" content="2025-06-25" />
    <meta charset='utf-8'>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel='stylesheet' href='https://unpkg.com/maplibre-gl@5.24.0/dist/maplibre-gl.css' />
    <script src='https://unpkg.com/maplibre-gl@5.24.0/dist/maplibre-gl.js'></script>
    <style>
        body { margin: 0; padding: 0; }
        html, body, #map { height: 100%; }
    </style>
</head>
<body>
<div id="map"></div>

<script>
    const map = new maplibregl.Map({
        container: 'map',
        style: 'https://tiles.openfreemap.org/styles/bright',
        center: [-77.035, 38.875],
        zoom: 12
    });

    const geojson = {
        'type': 'FeatureCollection',
        'features': [
            {
                'type': 'Feature',
                'properties': {},
                'geometry': {
                    'coordinates': [
                        [-77.044211, 38.852924],
                        [-77.045659, 38.860158],
                        [-77.044232, 38.862326],
                        [-77.040879, 38.865454],
                        [-77.039936, 38.867698],
                        [-77.040338, 38.86943],
                        [-77.04264, 38.872528],
                        [-77.03696, 38.878424],
                        [-77.032309, 38.87937],
                        [-77.030056, 38.880945],
                        [-77.027645, 38.881779],
                        [-77.026946, 38.882645],
                        [-77.026942, 38.885502],
                        [-77.028054, 38.887449],
                        [-77.02806, 38.892088],
                        [-77.03364, 38.892108],
                        [-77.033643, 38.899926]
                    ],
                    'type': 'LineString'
                }
            }
        ]
    };

    map.on('load', () => {
        // 'line-gradient' 只能与GeoJSON源一起使用
        // 并且源必须将'lineMetrics'选项设置为true
        map.addSource('line', {
            type: 'geojson',
            lineMetrics: true,
            data: geojson
        });

        // 图层必须是'line'类型
        map.addLayer({
            type: 'line',
            source: 'line',
            id: 'line',
            paint: {
                'line-color': 'red',
                'line-width': 14,
                // 'line-gradient' 必须使用表达式指定
                // 使用特殊的'line-progress'属性
                'line-gradient': [
                    'interpolate',
                    ['linear'],
                    ['line-progress'],
                    0,
                    'blue',
                    0.1,
                    'royalblue',
                    0.3,
                    'cyan',
                    0.5,
                    'lime',
                    0.7,
                    'yellow',
                    1,
                    'red'
                ]
            },
            layout: {
                'line-cap': 'round',
                'line-join': 'round'
            }
        });
    });
</script>
</body>
</html>

🔍 代码解析

初始化地图

使用 new maplibregl.Map() 创建地图实例,配置基本参数。本示例的核心特色是展示如何使用 line-gradient 属性和表达式创建渐变线条。

关键配置项

  • container: 地图容器的 DOM 元素 ID
  • style : 使用 OpenStreetMap 亮色样式 https://tiles.openfreemap.org/styles/bright
  • center : 地图初始中心点 [-77.035, 38.875](美国华盛顿特区)
  • zoom: 初始缩放级别为 12,显示城市级别视图

GeoJSON 数据源配置

javascript 复制代码
map.addSource('line', {
    type: 'geojson',
    lineMetrics: true,  // 必须启用此选项才能使用 line-gradient
    data: geojson
});

line-gradient 表达式配置

javascript 复制代码
map.addLayer({
    type: 'line',
    source: 'line',
    id: 'line',
    paint: {
        'line-color': 'red',
        'line-width': 14,
        'line-gradient': [
            'interpolate',
            ['linear'],
            ['line-progress'],  // 特殊属性,表示线条进度(0-1)
            0, 'blue',          // 起点:蓝色
            0.1, 'royalblue',   // 10%:皇家蓝
            0.3, 'cyan',        // 30%:青色
            0.5, 'lime',        // 中点:石灰绿
            0.7, 'yellow',      // 70%:黄色
            1, 'red'            // 终点:红色
        ]
    },
    layout: {
        'line-cap': 'round',
        'line-join': 'round'
    }
});

⚙️ 参数说明

参数 类型 必填 默认值 说明
container string 是 - 地图容器元素的 ID
style string/object 是 - 地图样式 URL 或内联样式对象
center number, number 否 [0, 0] 初始中心点坐标
zoom number 否 0 初始缩放级别

GeoJSON 数据源配置

参数 类型 必填 默认值 说明
lineMetrics boolean 否 false 是否计算线条度量(启用后支持 line-progress)

line-gradient 表达式

参数 类型 说明
line-progress expression 特殊属性,返回当前点在线条上的进度(0 到 1)
interpolate expression 插值表达式,用于创建平滑过渡
linear keyword 线性插值方式

🎨 效果说明

运行代码后,地图上会显示一条彩虹渐变的路径:

  • 起点 : 坐标 [-77.0442, 38.8529],颜色为蓝色
  • 终点 : 坐标 [-77.0336, 38.8999],颜色为红色
  • 渐变过渡: 蓝 → 皇家蓝 → 青 → 石灰绿 → 黄 → 红

渐变原理:

  1. line-progress 返回 0(起点)到 1(终点)的值
  2. interpolate 表达式根据 line-progress 值进行线性插值
  3. 在指定的进度点之间平滑过渡颜色

💡 常 见 问 题

Q1: line-gradient 为什么不生效?

A: 需要满足两个条件:

  1. 数据源必须是 GeoJSON 类型
  2. 数据源必须设置 lineMetrics: true

Q2: line-progress 是什么?

A: line-progress 是一个特殊的表达式属性,返回当前点在线条路径上的进度,值从 0(起点)到 1(终点)。

Q3: 可以使用其他插值方式吗?

A: 可以。除了 linear,还可以使用 exponential 或 cubic-bezier 插值方式。

Q4: 可以基于其他属性创建渐变吗?

A: line-gradient 只能使用 line-progress 作为输入,无法直接使用其他属性。

📝 练习任务

  1. 基础练习:修改渐变颜色和颜色节点位置
  2. 进阶挑战:创建双向渐变(从两端向中间渐变)
  3. 拓展思考:如何实现动态渐变动画?

🌟 最佳实践

  1. 性能优化 : lineMetrics 会增加内存使用,只在需要时启用
  2. 颜色数量: 适当控制颜色节点数量,过多会影响性能
  3. 线条宽度: 较宽的线条更能展示渐变效果
  4. 端点处理 : 使用 line-cap: round 使端点更平滑
  5. 兼容性检查: 确保目标浏览器支持此功能
  6. 备用方案 : 为不支持 line-gradient 的环境提供纯色备用

🔗 延伸阅读


本文是MapLibre GL JS实践课程系列的一部分,欢迎关注收藏

相关推荐
vjmap3 小时前
AI 智能体调用绘图工具画矢量地图:唯杰 AI 地图绘制上线,支持 MCP 接入 Cursor、Claude Code
gis·agent·mcp
我喜欢就喜欢13 小时前
点云 LAS/LAZ 按 shp 范围裁剪:PDAL pipeline、坐标系对齐与空洞检查
gis·点云·测绘·las·pdal
阿琳a_2 天前
b-map-viewer:面向 Vue 3 的地图可视化 SDK,从接入到展示再到交互分析
前端·javascript·vue.js·gis·数据可视化·地图
总要学点什么4 天前
第92篇:三维特效-圆(逐渐消逝)——从圆心开始,让一个洞把整片光啃到只剩外圈
gis·webgl·cesium·空间分析·1024程序员节
vjmap4 天前
AI 地图动画-以真实地图为画布的 AI 视频编辑器-唯杰 AI 地图动画正式上线
人工智能·编辑器·音视频·gis·cad
vjmap4 天前
Cesium + MCP:在 Cursor、Claude Code 里一句话生成地图视频,唯杰 AI 地图动画上线
gis·cesium·mcp
supermapsupport4 天前
SuperMap GIS 基础产品 FAQ 集锦(20261030)
gis·supermap·iserver·idesktopx
god_cvz6 天前
实践:Linux环境构建CTB工具(cesium-terrain-builder)
linux·gis·ctb
梅如你7 天前
ISPRS | 1990-2020年间中国人工林与天然林的空间分布数据
arcgis·gis·遥感
数据库小学妹7 天前
空间数据库 PostGIS 兼容性怎么验?函数、类型、坐标系逐条核(附 SQL)
gis·信创·空间分析·空间数据库·地图渲染