一、添加数据源

添加数据源

  1. // addSource.js
  2. import { geoUrl } from '@/fetch/env'
  3. // 添加mapbox source
  4. export default function addSource(map, source = []) {
  5. for (const name of source) {
  6. if (name) {
  7. map.addSource(name, {
  8. type: 'vector',
  9. scheme: 'tms',
  10. tiles: [`${geoUrl}/geoserver/gwc/service/tms/1.0.0/linanAI%3A${name}@EPSG%3A900913@pbf/{z}/{x}/{y}.pbf`],
  11. })
  12. }
  13. }
  14. }
  15. // 页面引入后使用方法
  16. this.fileUrlArr = [leizhuShpUrl, riceShpUrl] // 此处为数据源地址数组
  17. // 添加对应的数据源和突出
  18. await addSource(this.mapboxInstance, [...this.fileUrlArr])

二、增

默认添加 symbol(符号),line(线),fill(填充),background(背景),raster(栅格)

点图层—> icon图标、文字

export default async function addBaseLayer(map) { 
  const imageList = [ 
    { 
      url: require('@/assets/images/common/base_icon.png'), 
      usedName: 'base-marker', 
    }, 
  ] 
  for (const item of imageList) { 
    await new Promise((resolve, reject) => { 
      const existImage = map.hasImage(item.usedName) 
      if (existImage) resolve() 
      else { 
        map.loadImage(item.url, function (error, image) { 
          if (error) { 
            reject() 
          } 
          map.addImage(item.usedName, image) 
          resolve() 
        }) 
      } 
    }) 
  } 

  await map.addLayer({ 
    id: `base-layer`, 
    source: `base`, // 数据源的名称 
    'source-layer': `base`, // 数据源的图层 
    type: 'symbol', 
    filter: true, 
    layout: { 
        // 图标类属性 
      'icon-image': `base-marker`, // 图标的图片名称 
      'icon-size': 0.8, //  
      'icon-allow-overlap': true, // 是否允许图标重叠 
      "icon-offset": [0, 0], // 图标的偏移量(可选,默认值为 [0, 0]) 

      // 文本类属性 
      "text-field": "", // 文本所对应的字段 
      "text-size": 16, // 文本的大小(默认值为 16,单位:像素) 
      "text-max-width": 10, // 文本的最大宽度,超过则折行(可选,默认值为 10,单位:ems)  
      "text-line-height": 1.2, // 文本的行高(默认值为 1.2,单位:ems) 
      "text-letter-spacing": 0, // 文本的字符间距(默认值为 0,单位:ems) 
      "text-justify": "center", // 文本的水平对齐方式(可选值为 auto、left、center、right。默认值为 center) 
      "text-rotate": 0, // 文本的顺时针旋转角度 
      "text-padding": 2, // 文本的外边距 
      "text-offset": [0, 0], // 文本的偏移量 
    }, 
    paint: { 
        // 图标类属性(需要设置 icon-image) 
        "icon-opacity": 1, // 图标的不透明度 
        "icon-halo-color": "rgba(0,0,0,0)", // 图标的光晕颜色 
        "icon-halo-width": 0, // 图标的光晕宽度 
        "icon-halo-blur": 0, // 图标的光晕模糊宽度 
        "icon-translate": [0, 0], // 图标的平移 
        "icon-translate-anchor": "map", // 图标的平移锚点,即相对的参考物(可选值为 map、viewport,默认为 map) 

        // 文本类属性(需要设置 text-field) 
        "text-opacity": 1, // 文本的不透明度 
        "text-color": "#000000", // 文本的颜色 
        "text-halo-color": "rgba(0,0,0,0)", // 文本的光晕颜色 
        "text-halo-width": 0, // 文本的光晕宽度 
        "text-halo-blur": 0, // 文本的光晕模糊宽度 
        "text-translate": [0, 0], // 文本的平移 
        "text-translate-anchor": "map", // 文本的平移锚点,即相对的参考物(可选值为 map、viewport,默认为 map) 
    }, 
  }) 
}

线图层

// 添加线 addLinanLayer.js 
// 添加临安图层 
export default function addLinanLayer(map) { 
  return new Promise(async (resolve, reject) => { 
    try { 
      // 添加临安边界 
      await map.addLayer({ 
        id: 'linan_boundary-layer', // 唯一 图层id  
        source: 'region_linan',  // 数据源的名称 
        'source-layer': 'region_linan',  // 数据源的图层 
        type: 'line', // 类型  
        layout: { // // 布局类属性 
          'line-cap': 'round', 
          'line-join': 'round', 
        }, 
        paint: { // 绘制类属性 
          'line-color': borderColor, 
          'line-width': 2, 
        }, 
      }) 
      resolve() 
    } catch (err) { 
      reject(err) 
    } 
  }) 
}

面:shp图层 (矢量图)

mapbox日常操作 - 图1

// 添加竹图斑图层 
export default function addLinanLayer(map) { 
  return new Promise(async (resolve, reject) => { 
    try { 
      // 添加竹图斑 
      await map.addLayer({ 
        id: 'plant1_spot-layer', // 唯一 图层id  
        source: 'bamboo_maozhu_plant_spot',  // 数据源的名称 
        'source-layer': 'bamboo_maozhu_plant_spot',  // 数据源的图层 
        type: 'fill', // 类型  
        "minzoom": 0, // 最小层级(可选,取值范围为 0 ~ 24。当 style 的 zoom 小于此 minzoom 时,layer 将被隐藏) 
        "maxzoom": 24, // 最大层级(可选,取值范围为 0 ~ 24。当 style 的 zoom 大于此 maxzoom 时,layer 将被隐藏) 
        layout: { // // 布局类属性 
          "visibility": "visible", // 可见性(可选,可选值为 none、visible,默认值为 visible) 
        }, 
        paint: { // 绘制类属性 
          "fill-opacity": 1, // 填充的不透明度(可选,取值范围为 0 ~ 1,默认值为 1) 
          "fill-color": "#000000", // 填充的颜色 
          "fill-outline-color": "#000000", // 描边的颜色 
          "fill-translate": [0, 0], // 填充的平移 
        }, 
      }) 
      resolve() 
    } catch (err) { 
      reject(err) 
    } 
  }) 
}

面:tif图层(png图片)

mapbox日常操作 - 图2

import { geoUrl } from '@/fetch/env' 
// 加载tif图 
export default function addTifLayer(map, sourceTifList, isHide = false) { 
  return new Promise(async (resolve, reject) => { 
    try { 
      for (const tifName of sourceTifList) { 
        if (tifName) { 
          map.addLayer({ 
            id: tifName, 
            type: 'raster', //这里要用raster ,因为切片得到的是图片 
            source: { 
              type: 'raster', //切片地图使用png 所以这里设置为raster 
              tiles: [ 
                `${geoUrl}/geoserver/gwc/service/wmts?SERVICE=WMTS&REQUEST=GetTile&LAYER=linanAI:${tifName}&TILEMATRIX=EPSG:900913:{z}&TILEMATRIXSET=EPSG:900913&format=image%2Fpng&TileCol={x}&TileRow={y}`, 
              ], 
            }, 
            "source-layer":'source-layer-name', 
            tileSize: 256, 
            // minzoom: 15.5, 
            "paint": { // 绘制类属性 
                "raster-opacity": 1, // 图片的不透明度 
            } 
          }) 
        } 
      } 
      resolve() 
    } catch (err) { 
      reject(err) 
    } 
  }) 
}

三、删

// 删除图层+删除数据源 
this.mapboxInstance.removeLayer(`图层id`) 
this.mapboxInstance.removeSource(`图层id`) 

// 不删除图层 仅隐藏 
this.mapboxInstance.setFilter(`图层id`, false) 
// 显示图层 
this.mapboxInstance.setFilter(`图层id`, true)

四、改

// 移动图层位置 
this.mapboxInstance.moveLayer(`图层id`, `beforeId`) 
// beforeId(string?)用来插入新图层的现有图层 ID。  
// 如果该参数(argument)被省略,该图层将会被添加到图层最上层。

五、查/过滤

// A & B & C 
filter: [ 
      'all', 
      ['match', ['get', 'code'], A, ['match', ['get', 'taski_id'], B, ['match', ['get', 'id'], C, true, false], false], false], 
    ], 
// A || B || C 
filter: [ 
      'all', 
      ['any', [ 
          ['match', ['get', 'type'], A, true, false], 
          ['match', ['get', 'type'], B, true, false], 
          ['match', ['get', 'type'], C, true, false] 
        ] 
      ], 
    ],

六、事件

// 初始化绑定对应事件 
async initMapbox(map) { 
    // 存储 mapbox 地图实例 
    this.mapboxInstance = map 
    // 添加数据源 
    // 添加图层 
    this.bindClickEvent(this.mapboxInstance) 
}, 

// 地图绑定点击事件 
bindClickEvent(map) { 
  map.on('click', '图层id', async (e) => { 
    e.preventDefault() 
    let properties = e.features[0].properties 
   // 此处可拿到点击后的图层信息 
    console.log('properties: ', properties) 
    const lonAndLat = [Number(properties.longitude), Number(properties.latitude)] 
    let popup = new mapboxgl.Popup({ 
      className: 'popup', 
      closeOnClick: true, 
    }) 
    popup.setLngLat(lonAndLat).setHTML('<div id="dialog-moadl"></div>').addTo(this.mapboxInstance) 
    // PointDetailModal 为自定义的弹窗组件 
    const MapInsectWarnModal = Vue.extend(PointDetailModal) 
    new MapInsectWarnModal({ 
      propsData: { 
        detail: properties, 
      }, 
    }).$mount('#dialog-moadl') 
    let closeBtn = document.getElementsByClassName('close-icon')[0] 
    closeBtn.addEventListener('click', () => { 
      popup.remove() 
    }) 
  }) 
}, 

// 清除默认弹窗样式 
::v-deep .mapboxgl-popup { 
  z-index: 99; 
  .mapboxgl-popup-tip { 
    display: none; 
  } 

  .mapboxgl-popup-content { 
    background: none; 
    padding: 0; 
  } 

  .mapboxgl-popup-close-button { 
    display: none; 
  } 
} 

// PointDetailModal 组件 
<template> 
  <div class="point-detail-modal"> 
    <div class="close-icon"></div> 
    <div class="box"> 
     <!-- 弹窗基本内容 --> 
    </div> 
  </div> 
</template> 
<script> 
export default { 
  props: { 
    detail: { 
      required: true, 
    }, 
  }, 
} 
</script>