基于百度地图 WebGL 技术实现带纹理的线图层

应用场景介绍

在一些场景中,需要在百度地图上展示带有纹理的线段,例如交通线路、管道线路等。传统的线段绘制方法无法满足此需求,需要使用 WebGL 技术来实现。

代码基本功能介绍

本代码基于百度地图 WebGL 技术,实现了带有纹理的线图层功能。用户可以通过点击按钮添加或移除图层,并通过点击线段来拾取和高亮显示。

功能实现步骤及关键代码分析说明

1. 加载必要的脚本和样式

async mounted() {
  await Promise.all([
    this.loadScripts([
      'https://api.map.baidu.com/api?type=subway&v=1.0&ak=cxtWZ9zGiLlLdQwBSuGGwpanwqfaLvEc&services=&t=20240319170303',
      'http://api.map.baidu.com/getscript?type=webgl&v=1.0&ak=cxtWZ9zGiLlLdQwBSuGGwpanwqfaLvEc&services=&t=20240319170303',
      'https://mapopen.bj.bcebos.com/github/BMapGLLib/InfoBox/src/InfoBox.js',
      'https://mapopen.bj.bcebos.com/github/BMapGLLib/RichMarker/src/RichMarker.min.js',
      'https://mapopen.bj.bcebos.com/github/BMapGLLib/DrawingManager/src/DrawingManager.min.js',
      'https://mapopen.cdn.bcebos.com/github/BMapGLLib/DistanceTool/src/DistanceTool.min.js',
    ]),
    this.loadStyles([
      'http://api.map.baidu.com/res/webgl/10/bmap.css',
      'http://mapopen.cdn.bcebos.com/github/BMapGLLib/DrawingManager/src/DrawingManager.min.css',
    ]),
  ])
}

首先,加载必要的脚本和样式,包括百度地图 WebGL API、纹理图片和一些辅助库。

2. 初始化地图

var map = new BMapGL.Map('allmap', {
  displayOptions: {
    poi: false,
    poiText: false,
  },
})

初始化百度地图 WebGL 地图,并隐藏兴趣点和兴趣点文字。

3. 设置线段样式

var lineLayer = new BMapGL.LineLayer({
  enablePicked: true,
  autoSelect: true,
  pickWidth: 30,
  pickHeight: 30,
  opacity: 1,
  selectedColor: 'blue', // 选中项颜色
  style: {
    sequence: true, // 是否采用间隔填充纹理,默认false
    marginLength: 8, // 间隔距离,默认16,单位像素
    borderColor: 'rgba(0,125,125,1)',
    borderMask: true, // 是否受内部填充区域掩膜,默认true,如果存在borderWeight小于0,则自动切换false
    borderWeight: 2, // 描边宽度,可以设置负值
    strokeWeight: 6, // 描边线宽度,默认0
    strokeLineJoin: 'miter', //描边线连接处类型, 可选'miter', 'round', 'bevel'
    strokeLineCap: 'square', // 描边线端头类型,可选'round', 'butt', 'square',默认round
    // 填充纹理图片地址,默认是空。图片需要是竖向表达,在填充时会自动横向处理。
    strokeTextureUrl: [
      'match',
      ['get', 'name'],
      'demo1',
      upTwo,
      'demo2',
      icon1,
      'demo3',
      icon2,
      icon3,
    ],
    strokeTextureWidth: ['match', ['get', 'name'], 'demo1', 32, 16],
    strokeTextureHeight: [
      'match',
      ['get', 'name'],
      'demo1',
      64,
      64,
    ],
    strokeColor: [
      'case',
      ['boolean', ['feature-state', 'picked'], false],
      '#6704ff',
      [
        'match',
        ['get', 'name'],
        'demo1',
        '#ce4848',
        'demo2',
        'red',
        'demo3',
        '#666',
        '#6704ff',
      ],
    ],
    strokeOpacity: 0.5,
  },
})

创建线段图层,并设置其样式。其中,style属性指定了线段的纹理、颜色、宽度等属性。

4. 添加线段数据

fetch(
  'https://mapopen-pub-jsapigl.bj.bcebos.com/svgmodel/lineLayerData.json',
)
  .then((res) => {
    return res.json()
  })
  .then((testLineData) => {
    lineLayer.setData(testLineData)
  })

从远程服务器获取线段数据,并将其添加到图层中。

5. 添加事件监听

lineLayer.addEventListener('click', function (e) {
  if (e.value.dataIndex !== -1 && e.value.dataItem) {
    this.updateState(e.value.dataIndex, { picked: true })
  }
})

为线段图层添加点击事件监听,当用户点击线段时,拾取并高亮显示该线段。

6. 添加按钮控制

<ul class="btn-wrap" style="z-index: 99">
  <li class="light btn" onclick="addLineLayer()">添加图层</li>
  <li class="night btn" onclick="removeLineLayer()">清除图层</li>
</ul>
function addLineLayer() {
  if (!lineLayer) {
    // ...
  }
  lineLayer.setData(testLineData)
}

function removeLineLayer() {
  map.removeNormalLayer(lineLayer)
  lineLayer = null
}

添加两个按钮,用于控制图层的添加和移除。

总结与展望

通过这段代码,我们实现了基于百度地图 WebGL 技术的带有纹理的线图层功能。该功能可以用于展示带有纹理的交通线路、管道线路等数据。

未来,可以考虑以下优化和拓展方向:

  • 支持更多类型的纹理和样式
  • 优化性能,提高渲染速度
  • 提供更多事件和交互功能,例如线段编辑、拖拽等
Login
ECHO recommendation
ScriptEcho.ai

User Annotations

间隔图标填充