Zhili's blog Zhili's blog
首页
关于
GitHub (opens new window)

Zhili

转型中的前端老兵
首页
关于
GitHub (opens new window)
  • webpack 区分环境使用CDN以及HtmlWebpackPlugin插件的编写
  • 使用 Mpvue 开发小程序总结
  • 前端知识汇总-持续更新
  • webGL知识汇总-持续更新
  • React思想要点
  • Mapbox 入门初试
  • 构建自己的 GLSL 绘图器 - 2d 版
  • webGL二维有向距离场(SDF)及布尔运算
  • webGL入门:绘制一个三角形
  • 使用 GLSL 绘图尝试:绘制正弦曲线
  • 简单解析虚拟 DOM
  • 自己动手开发一个 markdown 转微信文章工具
  • Vue组件扩展及权限管理的实现技巧
  • 使用 CSS 绘制三角形
  • Nginx 前端配置和使用
  • webpack按需加载配置和babel编译
  • 面试总结39题
  • 使用node反向代理接口改造旧项目
  • 可视化表单搭建系统的开发与思考
  • 前端
zhili
2019-04-15

Mapbox 入门初试

Mapbox入坑初试,建筑物拉起以及点击高亮

mapbox 是一个优秀的 2D、3D 地图库,它提供精美的地图服务以及高效的地图渲染方式。map 使用 webGL 渲染地图,可以动态修改地图样式,满足不同的需求

# 1. Mapbox 中 layer 和 source 的关系

mapbox 使用数据来驱动图层的,和其他的如 leaflet,openlayer 这类地图库不一样,除了底图之外,其他的图层都需要提供 source 图层,layer 根据 source 作为数据进行渲染。每一个 layer 和 source 都需要有一个 id,通过 id 名称来进行区分。一个 layer 对应一个 source,但是通一个 source 可以对应多个 layer。这样就方便对数据进行分层管理,可以将 source 中不同类别的数据展示在不同的 layer 中。 mapbox 支持的 source 有这些:vector, raster, raster-dem, geojson, image, video. 例如:加载 geojson 数据:

map.addSource('geoData', {
  type: 'geojson',
  data: data
})
1
2
3
4

mapbox 没有提供加载文件的功能,所以如果是从文件中加载的话,需要自己写 XHR 请求,然后再设置 source,例如,从文件中加载 geojson 可以这么写:

fetch('./data/data.geojson')
  .then(resp => resp.json())
  .then(data => {
    //调用addSource方法
  })
1
2
3
4
5

# 2.mapbox 中的 paint

paint 属性用来设置 mapbox 图层的绘制规则,这是 mapbox 的精华所在,mapbox 文档有专门一栏讲解样式设置 (opens new window)的,这里面可以设置绘制面的颜色,填充色,透明度等等,而且还可以通过一些逻辑判断来设置不同的属性,十分灵活和复杂。建议通过官网来学习

# 3.mapbox 拉起建筑物以及点击建筑物高亮示例

map.on('load', function() {
  // 请求geojson数据
  fetch('./data/data.geojson')
    .then(resp => resp.json())
    .then(data => {
      // 加载图片作为建筑物纹理,异步方法
      map.loadImage('./data/texture.jpg', (err, image) => {
        // 纹理加载
        map.addImage('texture', image)

        // 设置数据源,由于原数据中没有id属性,由 mapbox生成唯一ID值
        map.addSource('geoData', {
          type: 'geojson',
          data,
          generateId: true
        })

        // 建筑物贴图
        map.addLayer({
          id: '3d-build',
          // 设置数据源
          source: 'geoData',
          type: 'fill-extrusion',
          // 只显示属性值building==yes的数据
          filter: ['==', 'building', 'yes'],
          // 缩放级别大于15级显示
          minzoom: 15,
          paint: {
            // 拉升高度通过属性值height获取
            'fill-extrusion-height': ['to-number', ['get', 'height']],
            'fill-extrusion-base': 0,
            'fill-extrusion-opacity': 1,
            // 设置纹理
            'fill-extrusion-pattern': 'texture'
          }
        })

        // 建筑物顶部
        map.addLayer({
          id: 'buildTop',
          // 数据源
          source: 'geoData',
          type: 'fill-extrusion',
          // 针对建筑物
          filter: ['==', 'building', 'yes'],
          minzoom: 15,
          paint: {
            // 填充颜色根据状态切换
            'fill-extrusion-color': [
              'case',
              ['boolean', ['feature-state', 'hover'], true],
              '#aaa',
              'red'
            ],
            // 起始高度和拉升高度相同,则只是顶部的面被处理
            'fill-extrusion-height': ['to-number', ['get', 'height']],
            'fill-extrusion-base': ['to-number', ['get', 'height']],
            'fill-extrusion-opacity': 1
          }
        })

        // 点击事件
        let hoverId = null
        map.on('click', '3d-build', e => {
          if (e.features.length > 0) {
            // hoverId为空,表示是初次点击
            if (!hoverId) {
              // 获取要素ID,根据数据值和id设置状态
              hoverId = e.features[0].id
              map.setFeatureState({ source: 'geoData', id: hoverId }, { hover: false })
            } else {
              map.setFeatureState({ source: 'geoData', id: hoverId }, { hover: true })
              hoverId = null
            }
          }
        })
      })
    })
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

代码效果如下:

在线示例可前往 http://zhouzhili.github.io/demo/mapbox-3d-build/ (opens new window) 查看

编辑 (opens new window)
#Mapbox
上次更新: 2022/03/14, 06:54:51
React思想要点
构建自己的 GLSL 绘图器 - 2d 版

← React思想要点 构建自己的 GLSL 绘图器 - 2d 版→

最近更新
01
可视化表单搭建系统的开发与思考
03-09
02
使用node反向代理接口改造旧项目
11-17
03
面试总结39题
10-11
更多文章>
Theme by Vdoing | Copyright © 2022-2023 zhili | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式