ArcGis for javascript map component packaging, super simple! ! !

Effect picture

Insert picture description here
Online preview If it is inconsistent with the above picture, please press Ctrl+ F5or give feedback in the comment area.

Preface

Those who have read the first three children's shoes in this column should know that the amount of code to integrate all the functions together is very large, and there may be many lines and points drawn on the map, and there may be dozens of points in the project that need to be applied to the ArcGis map. Further Benpian is to combine three functions implemented together into a package assembly Vue, strive to achieve using minimalist Api drawing lines, drawing a custom icon, acquired Graphic data base map switching, add a widget function, so that the code Get sufficient reuse.

ArcGisMap component

<template>
  <div id="map" class="map-container"></div>
</template>

<script>
import {
     
      loadModules } from 'esri-loader'
import {
     
      manyGraphics } from '@/utils/arcgisUtils'

export default {
     
     
  name: 'ArcGisMap',
  props: {
     
     
    // 选择加载地图自定义部件 ['switch-map', 'full-screen']
    tools: {
     
     
      type: Array,
      default: () => []
    },
    // 图形数据
    graphicsData: {
     
     
      type: Array,
      default: () => []
    },
    // 地图初始中心点
    centerPoint: {
     
     
      type: Array,
      default: () => [0, 0]
    },
    // 初始底图
    defaultBaseMap: {
     
     
      type: String,
      default: 'osm'
    },
    // 初始缩放级别
    zoom: {
     
     
      type: Number,
      default: 12
    }
  },
  data () {
     
     
    return {
     
     
      view: null,
      // 用于切换底图ID的数组
      baseMaps: ['osm', 'satellite', 'terrain']
    }
  },
  mounted () {
     
     
    const {
     
      defaultBaseMap, centerPoint, zoom, graphicsData } = this
    loadModules(
      ['esri/Map', 'esri/views/MapView', 'esri/Graphic'],
      {
     
      css: true }
    )
      .then(
        ([ArcGISMap, MapView, Graphic]) => {
     
     
          const map = new ArcGISMap({
     
     
            basemap: defaultBaseMap
          })

          this.view = new MapView({
     
     
            container: document.getElementById('map'),
            map: map,
            center: centerPoint,
            zoom: zoom
          })

          // 将图形添加到视图的图形层
          graphicsData.length && this.view.graphics.addMany(manyGraphics(Graphic, graphicsData))

          // 绑定点击事件
          this.view.on('click', e => {
     
     
            this.view.hitTest(e)
              .then(res => {
     
     
                // 获取每个图形上的ID
                res.results.length && this.$emit('clickGraphic', res.results[0].graphic.attributes)
              })
          })

          // 添加自定义控件
          this.tools.includes('switch-map') && this.view.ui.add(this.switchMapBtn(map), 'top-left')
          this.tools.includes('full-screen') && this.view.ui.add(this.fullScreenBtn(), 'top-left')
        }
      )
  },
  methods: {
     
     
    // 地图切换按钮
    switchMapBtn (map) {
     
     
      const btn = document.createElement('img')
      btn.src = require('./icons/switch-map.jpg')
      btn.style.width = '32px'
      btn.style.height = '32px'
      btn.style.cursor = 'pointer'
      btn.onclick = () => {
     
     
        let index = this.baseMaps.indexOf(map.basemap.id)
        map.basemap = index < this.baseMaps.length - 1 ? this.baseMaps[++index] : this.baseMaps[0]
      }
      return btn
    },
    // 地图全屏按钮
    fullScreenBtn () {
     
     
      const btn = document.createElement('div')
      btn.id = 'full-screen-btn'
      btn.style.width = '32px'
      btn.style.height = '32px'
      btn.style.cursor = 'pointer'
      btn.onclick = function () {
     
     
        const mapContainer = document.getElementById('map')
        const _body = document.body
        this.classList.toggle('full-screen')
        mapContainer.classList.toggle('full-screen')
        mapContainer.classList.contains('full-screen') ? (_body.style.overflow = 'hidden') : (_body.style.overflow = '')
      }
      return btn
    }
  },
  beforeDestroy () {
     
     
    this.view && (this.view.container = null)
  }
}
</script>

<style scoped lang="less">
.map-container {
     
     
  width: 100%;
  height: 100%;
  background: #f5f5f5;

  &.full-screen {
     
     
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    z-index: 1;
  }

  /deep/ #full-screen-btn {
     
     
    background: #fff url('./icons/full-screen.svg') no-repeat center center / 100% 100%;

    &.full-screen {
     
     
      background-image: url('./icons/normal-screen.svg');
    }
  }
}

</style>

arcgisUtils.js

/**
 * 创建线
 * @param Graphic 实例对象
 * @param paths 路径经纬度数组
 * @param color 路径的颜色
 * @param borderWidth 路径的宽度
 * @param id  该图形的 ID,用于判断点击的图形
 * @returns {*}
 */
export function createLineGraphic (Graphic, paths, color, borderWidth, id) {
    
    
  return new Graphic({
    
    
    geometry: {
    
    
      type: 'polyline',
      paths: paths
    },
    symbol: {
    
    
      type: 'simple-line',
      color: color, // 颜色 rgb or rgba [255, 0, 0, 0.5] or 16进制
      width: borderWidth
    },
    attributes: {
    
    
      id: id
    }
  })
}

/**
 * 创建点
 * @param Graphic
 * @param lng 点的位置
 * @param lat
 * @param markerUrl 图片的 url
 * @param width 点的大小
 * @param height
 * @param id
 * @returns {*}
 */
export function createPointGraphic (Graphic, lng, lat, markerUrl, width, height, id) {
    
    
  return new Graphic({
    
    
    geometry: {
    
    
      type: 'point',
      longitude: lng,
      latitude: lat
    },
    symbol: {
    
    
      type: 'picture-marker',
      url: markerUrl,
      width: width,
      height: height
    },
    attributes: {
    
    
      id: id
    }
  })
}

/**
 * 生成 'Graphic实例' 数组
 * @param Graphic Graphic类
 * @param graphicsData 生成 Graphic 实例的数据
 * @returns {[]}
 */
export function manyGraphics (Graphic, graphicsData) {
    
    
  const graphics = []
  graphicsData.forEach(item => {
    
    
    if (item.paths) {
    
    
      graphics.push(createLineGraphic(Graphic, ...Object.values(item)))
    } else if (item.lng) {
    
    
      graphics.push(createPointGraphic(Graphic, ...Object.values(item)))
    }
  })
  return graphics
}

Parent component

<template>
  <div class="arcgis-map-wrapper">
    <arc-gis-map
      :tools="['switch-map', 'full-screen']"
      :graphicsData="graphicsData"
      :centerPoint="[117.17144639449873, 31.83296921125205]"
      @clickGraphic="getParams"
    />
  </div>
</template>

<script>
import ArcGisMap from '@/components/ArcgisMap/ArcgisMap'

export default {
     
     
  components: {
     
      ArcGisMap },
  data () {
     
     
    return {
     
     
      // 图形数据
      graphicsData: [
        {
     
     
          paths: [
            [117.129359, 31.839979],
            [117.128810, 31.839979],
            [117.128810, 31.832240],
            [117.227610, 31.833600]
          ],
          color: '#1e80ff',
          width: 5,
          id: 'Hello world'
        },
        {
     
     
          lng: 117.129359,
          lat: 31.839979,
          markerUrl: require('@/assets/img/view-start.png'),
          width: '32px',
          height: '48px',
          id: 'Foo'
        },
        {
     
     
          lng: 117.227610,
          lat: 31.833600,
          markerUrl: require('@/assets/img/view-end.png'),
          width: '32px',
          height: '48px',
          id: 'Bar'
        }
      ]
    }
  },
  methods: {
     
     
    getParams (e) {
     
     
      this.$message.info(JSON.stringify(e))
    }
  }
}
</script>

<style lang="less" scoped>
.arcgis-map-wrapper {
     
     
  width: 100%;
  height: 100%;
}
</style>

Concluding remarks

Phew~~ I have posted so many smelly and long codes. In fact, I read the blog post first to see if there is a demo picture, and second to see if the code is highlighted, otherwise it is difficult to read it in depth. Of people can see what they want the first time.
Why open the ArcGisJS series of columns? The main thing is that after entering the pit of ArcGisJS, I feel like I need to record it. What if ArcGisJS is used in future projects? This thing will be forgotten for half a year. Although the articles in this column are all based on the superficial use of ArcGisJS, it will take a lot of time to toss after forgetting the sevens and eights. Recording it will not only deepen understanding, but also help people who are in contact for the first time avoid more detours.

Guess you like

Origin blog.csdn.net/dizuncainiao/article/details/108479865