Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mapbox 入门及基础知识 #8

Open
zhouzhili opened this issue Apr 15, 2019 · 0 comments
Open

Mapbox 入门及基础知识 #8

zhouzhili opened this issue Apr 15, 2019 · 0 comments

Comments

@zhouzhili
Copy link
Owner

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
})

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

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

2.mapbox 中的 paint

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

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
            }
          }
        })
      })
    })
})

在线示例

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant