vue中使用antv L7 实现标点,画线,多边形绘制,计算距离,计算多边形区域面积,切换卫星图层

849 阅读1分钟

实际案例

//初始化地图
setMap() {
  this.scene = new Scene({
    id: 'map',
    logoVisible: false,
    map: new GaodeMap({
      style: 'light',
      center: [109, 39],
      mapStyle: 'amap://styles/darkblue',
      zoom: 7.5
    })
  });

  // 初始化边界
  this.drawBorder()

  this.markerLayer = new MarkerLayer({})
  //地图监听鼠标点击
  this.scene.on('click', (e) => {
    this.mapClickEmitter(e)
  })
},

绑定点击事件

开始标点 image.png

// 地图点击事件handler
mapClickEmitter(e) {
  //未开启标点模式
  if (!this.canMark) {
    return
  }

  //获取鼠标当前点的坐标
  const {lng, lat} = e.lnglat
  console.log([lng, lat]);

  //创建自定义marker
  const el = document.createElement('label')

  el.style.width = '30px'
  el.style.height = '35px'
  el.style.background = 'url(/marker-icon.png) no-repeat'
  el.style.backgroundSize = '100%'

  const marker = new Marker({
    color: 'blue',
    element: el,
    offsets: [0, -10]
  })
  //设置marker的坐标
  marker.setLnglat([lng, lat])
  //将marker添加的地图中
  this.scene.addMarker(marker);
  //将当前坐标存放到坐标数组,用于后续渲染lineLayer和pointLayer
  this.lnglatList.push([lng, lat])
  //将当前marker存放到marker数组,后续用于遍历移除
  this.markerList.push(marker)
  this.markerLayer.addMarker(marker)

  // 标两个点渲染线图层并且计算两点之间距离
  if (this.lnglatList.length === 2) {
    // 渲染线图层
    this.drawLineLayer()
    // 计算距离
    this.distance = calculateDistance(this.lnglatList)
  }

  // 标三个或以上点渲染几何图层并且封闭区域面积
  if (this.lnglatList.length > 2) {
    // 移除线图层
    this.scene.removeLayer(this.lineLayer)
    // 渲染几何图层
    this.drawPolygonLayer()
    // 计算面积
    this.area = calculateArea(this.lnglatList)
    console.log('面积', this.area);
  }
},

渲染线图层,并计算当前线的实际距离 image.png

//渲染线图层
drawLineLayer() {
  const lineData = getLineData(this.lnglatList)

  this.lineLayer = new LineLayer({
    autoFit: false
  })
    .source(lineData)
    .size(2)
    .shape('line')
    .color('#00D7E9')

  this.scene.addLayer(this.lineLayer);
},

渲染多边形,并计算所围成区域面积

image.png

//渲染几何图层
drawPolygonLayer() {
  //根据坐标点组合图层geojson数据
  const polygonData = getPolygonData(this.lnglatList)
  
  //如果几何图层实例存在,更换数据,否则 new 一个PolygonLayer
  if (this.polygonLayer) {
    this.polygonLayer.setData(polygonData)
    return
  }

  this.polygonLayer = new PolygonLayer({
    autoFit: false
  }).source(polygonData)
    .color('#0049C1')
    .shape('fill')
    .style({
      opacity: 0.5
    })

  //添加图层
  this.scene.addLayer(this.polygonLayer)
},

渲染点边界 image.png

//渲染边界
drawBorder() {
  const {organizationName} = this.$store.state.user.info.user
  const borderGeoJson = this.orgGeojson[organizationName]
  const borderLayer = new LineLayer({
    autoFit: true
  })
    .source(borderGeoJson)
    .color('#5B8FF9')
    .size(2)
    .style({
      opacity: 1
    })

  this.scene.addLayer(borderLayer)
},

切换卫星图层,L7官方没有提供切换图层的api,所以这里通过sense获取mapService来拿到高德的map实例,然后便可以使用高德地图相关的api,进行图层切换。

image.png

//切换卫星地图
triggerMap(showSatellite) {
  this.showSatellite = showSatellite
  if (!showSatellite) {
    this.satellite.hide()
    return
  }

  if (!this.satellite) {
    this.satellite = new AMap.TileLayer.Satellite()
    const {map} = this.scene.mapService
    this.satellite.setMap(map)
  } else {
    this.satellite.show()
  }
},
//重置并移除标记图层
resetLayer() {
  this.canMark = false
  this.lnglatList = []

  //移除线图层
  if (this.lineLayer) {
    this.scene.removeLayer(this.lineLayer)
  }

  //移除几何图层
  if (this.polygonLayer) {
    this.scene.removeLayer(this.polygonLayer)
    this.polygonLayer = null
  }

  //移除标点
  if (this.markerList.length > 0) {
    this.markerLayer.clear()
  }
  this.markerList = []
},
// 创建几何图层数据
export const getPolygonData = lnglatList => {
  return {
    type: "FeatureCollection",
    features: [
      {
        type: "Feature",
        id: 1043,
        properties: {"_draw_type": "fill"},
        geometry: {
          type: "Polygon",
          coordinates: [
            lnglatList
          ]
        },
      }
    ]
  }
}

// 创建线图层数据
export const getLineData = (lnglatList, type = 'Polygon') => {
  return {
    type: "FeatureCollection",
    features: [
      {
        type: "Feature",
        id: 1044,
        properties: {"_draw_type": "fill"},
        geometry: {
          type,
          coordinates: [
            lnglatList
          ]
        },
      }
    ]
  }
}

//传入坐标数组计算两点之间距离
export const calculateDistance = lnglatList => {
  const pointStart = new AMap.LngLat(lnglatList[0][0], lnglatList[0][1])
  const pointEnd = new AMap.LngLat(lnglatList[1][0], lnglatList[1][1])

  const distance = pointStart.distance(pointEnd).toFixed(2) || 0
  return `标点距离:${distance} m`
}

//传入坐标数组计算封闭区域面积
export const calculateArea = lnglatList => {
  const area = AMap.GeometryUtil.ringArea(lnglatList).toFixed(2) || 0
  return `标点区域面积:${area} ㎡`
}

export default {
  getPolygonData,
  getLineData,
  calculateDistance,
  calculateArea
}