Vue.js2+ArcGIS3三、添加自定义图形标注

Github

添加点、线、面、图片等图形标注,鼠标移入图形有高亮效果。

添加标注功能方法封装


<template>
  <div id="map-container"
    style="width:100%;height:100%;">
    <div
      style="position:absolute;right:50px;top:50px;z-index:999;">
      <button
        @click="addCustomSymbols()">自定义标注</button>
      <button
        @click="clearCustomSymbols()">清除标注</button>
    </div>
  </div>
</template>
<script>
import { loadCss, loadModules } from 'esri-loader'
export default {
  name: 'CustomSymbols',
  data() {
    return {
      positionLayer: '', // 定位图层
      customSymbolsLayer: '', // 自定义标注图层
      gisConstructor: {}, // gis 构造函数
      gisModules: [
        'esri/SpatialReference',
        'esri/Color',
        'esri/symbols/TextSymbol',
        'esri/symbols/SimpleMarkerSymbol',
        'esri/symbols/SimpleLineSymbol',
        'esri/symbols/SimpleFillSymbol',
        'esri/symbols/PictureMarkerSymbol', // 图片标注
        'esri/symbols/TextSymbol', // 文字标注
        'esri/symbols/Font',
        'esri/geometry/Extent',
        'esri/geometry/Point',
        'esri/geometry/Polyline',
        'esri/geometry/Polygon',
        'esri/geometry/geometryEngine',
        'esri/layers/GraphicsLayer', // 图形图层
        'esri/graphic', // 图形
        'esri/map',
      ],
      map: '',
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    /**
     * @name: 地图点击事件
     */
    mapClickFun() {
      this.map.on('click', e => {
        console.log(e)
      })
    },

    /**
     * @name: 设置中心点和缩放
     * @param {point} Array
     * @param {zoom} Number
     */
    setCenterAndZoom(point, zoom) {
      let _point = new this.gisConstructor.Point(
        point[0],
        point[1],
        new this.gisConstructor.SpatialReference(this.map.spatialReference)
      )
      if (zoom) {
        this.map.centerAt(_point)
        this.map.centerAndZoom(_point, zoom)
      } else {
        this.map.centerAt(_point)
      }
      this.clearCustomSymbols('定位图层')
      let icon = require('@/assets/images/positioning.gif')

      let symbol = new this.gisConstructor.PictureMarkerSymbol(icon, 50, 50)
      let graphic = new this.gisConstructor.graphic(_point, symbol)
      this.positionLayer.add(graphic)
    },

    /**
     * @name: 根据图层 ID 清除图层上的图形标注
     * @param {ID} 图层 id
     */
    clearCustomSymbols(ID) {
      if (ID) {
        // 传入图层 id,清除指定图层上的标注
        let layer = this.map.getLayer(ID)
        if (layer) {
          layer.clear()
        }
      } else {
        // 没有传入 id,先获取所有显示的图层,根据 className 过滤出标注图层,然后清除标注
        let scale = this.map.getScale()
        let layers = this.map.getLayersVisibleAtScale(scale)
        let _layers = layers.filter(item => {
          return item.className === 'custom-layer'
        })
        _layers.forEach(element => {
          element.clear()
        })
      }
    },

    /**
     * @name: 添加自定义标注
     * @param {data} Array 坐标集合
     */
    addCustomSymbols() {
      this.clearCustomSymbols('自定义标注图层')

      // 添加点
      let pointList = [
        {
          x: -13045958.820458127,
          y: 3857040.953346878
        },
        {
          x: - 13046302.78708541,
          y: 3855244.6831821785
        },
        {
          x: -13043281.135811023,
          y: 3855505.0468097497
        }
      ]
      pointList.forEach(item => {
        let pointGeometry = new this.gisConstructor.Point(
          item.x,
          item.y,
          new this.gisConstructor.SpatialReference(this.map.spatialReference)
        )
        let pointSymbol = new this.gisConstructor.SimpleMarkerSymbol({
          color: new this.gisConstructor.Color([255, 0, 0]),
          width: 10,
          height: 10,
        })
        let pointSymbolGraphic = new this.gisConstructor.graphic(
          pointGeometry,
          pointSymbol,
        )
        this.customSymbolsLayer.add(pointSymbolGraphic)
      })

      // 添加线
      let pathsList = [
        {
          paths: [
            [
              [-13039796.085052641, 3858789.450368899],
              [-13039862.96745239, 3855101.3637541444]
            ]
          ]
        },
        {
          paths: [
            [
              [-13043465.062410325, 3857375.365345625],
              [-13043035.104126222, 3855120.4730112157],
              [-13041492.031617718, 3857031.398718342]
            ]
          ]
        },
        {
          paths: [
            [
              [-13045423.761260131, 3854050.3546152245],
              [-13043388.62538204, 3853801.934273298]
            ]
          ]
        }
      ]
      pathsList.forEach(item => {
        let polylineSymbol = new this.gisConstructor.SimpleLineSymbol(
          this.gisConstructor.SimpleLineSymbol.STYLE_SOLID,
          new this.gisConstructor.Color([255, 0, 0, 1]),
          3
        )
        let polylineGeometry = new this.gisConstructor.Polyline({
          paths: item.paths,
          spatialReference: this.map.spatialReference
        })
        let polylineGraphic = new this.gisConstructor.graphic(
          polylineGeometry,
          polylineSymbol
        )
        this.customSymbolsLayer.add(polylineGraphic)
      })

      // 添加面
      let ringsList = [
        {
          rings: [
            [
              [-13042519.154185297, 3858502.8115128297],
              [-13040761.102534741, 3858053.743971655],
              [-13040780.211791812, 3857432.693116839],
              [-13040722.884020599, 3856209.7006642777],
              [-13041057.296019346, 3856219.2552928133],
              [-13041859.88481634, 3856544.112663025],
              [-13042519.154185297, 3858502.8115128297]
            ]
          ]
        },
        {
          rings: [
            [
              [-13040608.228478171, 3855225.5739251073],
              [-13040254.707222352, 3855588.6498094616],
              [-13039251.471226111, 3854824.279526611],
              [-13039194.143454896, 3854308.329585687],
              [-13039824.748938248, 3854499.422156399],
              [-13040608.228478171, 3855225.5739251073]
            ]
          ]
        },
        {
          rings: [
            [
              [-13045309.105717704, 3858646.1309408643],
              [-13043904.575322965, 3858197.0633996897],
              [-13045223.114060882, 3857270.264431733],
              [-13045309.105717704, 3858646.1309408643]
            ]
          ]
        }
      ]
      ringsList.forEach(item => {
        let polygonSymbol = new this.gisConstructor.SimpleFillSymbol(
          this.gisConstructor.SimpleFillSymbol.STYLE_SOLID,
          new this.gisConstructor.SimpleLineSymbol(
            {
              color: new this.gisConstructor.Color([0, 48, 166, 0.8]),
              width: 2,
            }
          ),
          new this.gisConstructor.Color([0, 48, 166, 0.25])
        )
        let polygonGeometry = new this.gisConstructor.Polygon({
          rings: item.rings,
          spatialReference: this.map.spatialReference
        })
        let polygonGraphic = new this.gisConstructor.graphic(
          polygonGeometry,
          polygonSymbol
        )
        this.customSymbolsLayer.add(polygonGraphic)
      })

      // 添加多个文字图标标注
      let symbolData = [
        {
          text: 'marker1',
          x: -13043465.062410325,
          y: 3857375.365345625,
          type: 1,
        },
        {
          text: 'marker2',
          x: -13041492.031617718,
          y: 3857031.398718342,
          type: 2,
        },
        {
          text: 'marker3',
          x: -13041042.964076541,
          y: 3855808.4062657813,
          type: 2,
        },
        {
          text: 'marker4',
          x: -13044606.840520333,
          y: 3854317.8842142224,
          type: 3,
        },
        {
          text: 'marker5',
          x: -13043035.104126222,
          y: 3855120.4730112157,
          type: 3,
        },
      ]
      let icon = ''
      symbolData.forEach(item => {
        if (item.type === 1) {
          icon = require('@/assets/images/ico01.png')
        } else if (item.type === 2) {
          icon = require('@/assets/images/ico02.png')
        } else {
          icon = require('@/assets/images/ico03.png')
        }
        let point = new this.gisConstructor.Point(
          item.x,
          item.y,
          new this.gisConstructor.SpatialReference(this.map.spatialReference)
        )
        let symbol = new this.gisConstructor.PictureMarkerSymbol({
          url: icon,
          height: 20,
          width: 20,
        })
        let iconGraphic = new this.gisConstructor.graphic(
          point,
          symbol,
          item
        )
        this.customSymbolsLayer.add(iconGraphic)
        let textSymbol = new this.gisConstructor.TextSymbol(
          item.text,
          new this.gisConstructor.Font('16px'),
          new this.gisConstructor.Color([0, 0, 0])
        )
        let holoColor = this.gisConstructor.Color('#fff')
        textSymbol.setOffset(0, 15).setHaloColor(holoColor).setHaloSize(2)
        let textGraphic = new this.gisConstructor.graphic(
          new this.gisConstructor.Point(
            item.x,
            item.y,
            new this.gisConstructor.SpatialReference(this.map.spatialReference)
          ),
          textSymbol
        )
        this.customSymbolsLayer.add(textGraphic)
      })
    },

    /**
     * @name: 初始化地图
     */
    init() {
      // 加载 css
      loadCss('https://js.arcgis.com/3.32/esri/css/esri.css')
      // loadCss('http://localhost:8081/static/arcgis/3.34/esri/css/esri.css')
      // 加载模块
      loadModules(this.gisModules, {
        // url: 'http://localhost:8081/static/arcgis/3.34/init.js',
        url: 'https://js.arcgis.com/3.32/',
      })
        .then(this.initMap)
        .then(this.addCustomLayer)
        .then(this.mapClickFun)
    },

    /**
     * @name: 添加自定义图层
     * @msg: 地图初始化完成之后添加自定义图层或服务
     */
    addCustomLayer() {
      this.positionLayer = new this.gisConstructor.GraphicsLayer({
        id: '定位图层',
        className: 'custom-layer', // 筛选出 className 相同的图层去清除这些图层上的标注
      })
      this.map.addLayer(this.positionLayer)

      // 高亮图层
      let highlightLayer = new this.gisConstructor.GraphicsLayer({
        id: '高亮图层',
        className: 'highlight-layer',
      })
      this.map.addLayer(highlightLayer)

      this.customSymbolsLayer = new this.gisConstructor.GraphicsLayer({
        id: '自定义标注图层',
        className: 'custom-layer',
      })
      this.map.addLayer(this.customSymbolsLayer)
      // 针对某个 GraphicsLayer 做点击等事件事件
      this.customSymbolsLayer.on('click', event => {
        if (event.graphic.attributes) {
          console.log(event.graphic.attributes)
          let point = [event.graphic.attributes.x, event.graphic.attributes.y]
          this.setCenterAndZoom(point)
        }
      })
      // 做图形高亮效果
      this.customSymbolsLayer.on("mouse-over", (evt) => {
        if (evt.graphic.geometry) {
          let geometry = evt.graphic.geometry
          if (geometry.x && geometry.y) {
            // 面
          }
          if (geometry.paths) {
            // 线
          }
          if (geometry.rings) {
            // 面
            let fillSymbol = new this.gisConstructor.SimpleFillSymbol().setColor(new this.gisConstructor.Color([0, 48, 166, 0.5]))
            fillSymbol.setOutline(new this.gisConstructor.SimpleLineSymbol(this.gisConstructor.SimpleLineSymbol.STYLE_SOLID, new this.gisConstructor.Color([0, 255, 255]), 3))
            let fillGraphic = new this.gisConstructor.graphic(evt.graphic.geometry, fillSymbol)
            highlightLayer.add(fillGraphic)
          }
        }
      })
      this.customSymbolsLayer.on("mouse-out", () => {
        highlightLayer.clear()
      })
    },
    initMap(args) {
      // 将 ArcGIS 的每个功能模块都存放到 gisConstructor 中
      for (let k in args) {
        let name = this.gisModules[k].split('/').pop()
        this.gisConstructor[name] = args[k]
      }
      this.map = new this.gisConstructor.map('map-container', {
        basemap: 'osm',
        logo: false,
        slider: true,
        wkid: '4490',
      })
      // 设置初始化范围
      let extent = {
        xmin: -117.1839455,
        ymin: 32.68087830000002,
        xmax: -117.15035189999998,
        ymax: 32.732100979999984,
      }
      /*
        如果坐标系是 4490,初始化范围需要设置空间参考坐标系
        // 'esri/SpatialReference',
        new this.gisConstructor.SpatialReference({
          wkid: 4490
        })
      */
      this.map.setExtent(
        new this.gisConstructor.Extent(
          extent.xmin,
          extent.ymin,
          extent.xmax,
          extent.ymax
        )
      )
    },
  },
}
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值