vue 引入 esri-loader 并加载地图

记录一下:

npm i esri-loader

引入css

在app.vue中

<style>
@import url('https://js.arcgis.com/4.6/esri/css/main.css');
</style>

新建js文件

在js文件中引入esri-loader

并加载其init.js文件

加载init.js 需要其中的loadScript

部分如下:

import * as esriLoader from 'esri-loader';

async loadScript() {
  await esriLoader.loadScript({
    url: 'https://js.arcgis.com/4.14/init.js',
  });
}

async loadInit () {
    this.loadScript()
    let that = this;
    await esriLoader.loadModules(this.gisModules, gisOptions).then(this.loading).then(obj => {
      that.mapEsri = obj;
    }).catch(err => {
      console.error(err.message);
    });
}

map.js文件放置在文章最后

加载地图vue页面文件:

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

import mapApi from "@/utils/map";



mapApi.mapInit("mapContainer", () => {
        mapApi.createTileLayer('baselayer_arcgis', 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer', { visible: false });
        mapApi.showBaseMap(["vec_w", "cva_w"], true);
});

map.js文件如下:

import * as esriLoader from 'esri-loader';
import mapConfig from './mapConfig';
class MapApi {
  constructor() {
    this.map = null;
    this.view = null;
    this.views = [];
    this.curBaseMap = null;
    this.popup = {};
    this.mapEsri = null;
    // this.geometryService = mapConfig.geometryService;
    this.measurementWidget = null;
    this.sketchView = null;
    this.gisModules = [
      "esri/Map",
      // views
      "esri/views/MapView",
      // layers
      "esri/layers/TileLayer",
      "esri/layers/WebTileLayer",
      "esri/layers/MapImageLayer",
      "esri/layers/GraphicsLayer",
      // graphic
      "esri/Graphic",
      // geometry
      "esri/geometry/Point",
      "esri/geometry/Polyline",
      // tasks
      "esri/tasks/GeometryService",
      "esri/tasks/IdentifyTask",
      "esri/tasks/support/IdentifyParameters",
      "esri/tasks/support/LengthsParameters",
      "esri/tasks/support/AreasAndLengthsParameters",
      // widgets
      "esri/widgets/Fullscreen",
      "esri/widgets/Fullscreen/FullscreenViewModel",
      "esri/widgets/Sketch",
      "esri/widgets/Sketch/SketchViewModel",
      "esri/widgets/DistanceMeasurement2D",
      "esri/widgets/AreaMeasurement2D",
    ];
  }
  async loadScript() {
    await esriLoader.loadScript({
      url: 'https://js.arcgis.com/4.14/init.js',
    });
  }

  async loadInit () {
    this.loadScript()
    let that = this;
    const gisOptions = {
      // url: mapConfig.esriJsUrl,
      // css: mapConfig.esriCssUrl
    };
    await esriLoader.loadModules(this.gisModules, gisOptions).then(this.loading).then(obj => {
      that.mapEsri = obj;
    }).catch(err => {
      console.error(err.message);
    });
  }

  loading (args) {
    let modules = {};
    for (let n in args) {
      let name = mapApi.gisModules[n].split('/').pop();
      modules[name] = args[n];
    }
    return modules;
  }

  /**
   * 初始化地图
   * @param {string} mapId 地图容器id
   * @param {function} onLoadComplete 地图加载完毕后回调
   */
  mapInit (mapId, onLoadComplete) {
    let that = this;
    console.log('nihao')
    console.log('setInterval',that.mapEsri)
    let mapEsriTimer = setInterval(() => {
      
      if (that.mapEsri && Object.keys(that.mapEsri).length == this.gisModules.length) {
        clearInterval(mapEsriTimer);
        that.map = new that.mapEsri.Map();
        // 创建二维地图
        that.view = new that.mapEsri.MapView({
          container: mapId,
          map: that.map,
          center: mapConfig.mapCenter,
          zoom: mapConfig.mapZoom,
          padding: {
            top: 0
          },
        });
        // 地图缩放及旋转约束
        that.view.constraints = {
          minZoom: mapConfig.mapMinZoom,
          maxZoom: mapConfig.mapMaxZoom,
          rotationEnabled: false // 地图旋转
        };
        // 清除地图底部内容(powered by ESRI)
        that.view.ui.remove('attribution');
        // 移除默认的zoom部件
        that.view.ui.remove('zoom');
        that.views.push(that.view);
        // 加载完毕回调
        if (onLoadComplete) onLoadComplete();
      }
    }, 10);
  }

  // 获取所有图层
  getLayers () {
    return this.map.layers.items;
  }

  /**
   * 根据图层id获取图层
   * @param {string} layerId 图层id
   * @return {object} 图层
   */
  getLayerById (layerId) {
    if (!layerId) return;
    const layer = this.map.findLayerById(layerId);
    if (layer) {
      return layer;
    }
  }

  /**
   * 创建瓦片图层
   * @param {string} layerId 图层id
   * @param {string} layerUrl 图层地址
   * @return {object} option 配置项
   */
  createTileLayer (layerId, layerUrl, option) {
    if (!option) option = {};
    let tileLayer = new this.mapEsri.TileLayer({
      id: layerId,
      url: layerUrl,
      title: option.title || "",
      maxScale: Array.isArray(option.scale) && option.scale.length > 0 ? option.scale[0] : 0,
      minScale: Array.isArray(option.scale) && option.scale.length > 0 ? option.scale[1] : 0,
      visible: option.visible == undefined ? true : option.visible,
      listMode: option.listMode == undefined ? "show" : option.listMode
    });
    this.map.add(tileLayer)
  }


  /**
   * 底图展示
   * @param {(string | array)} layerTypes 底图类型  
   * @param {boolean} layerSwitch 图层切换,默认为false 
   * google(m:矢量 s:影像 t:地形 h:影像标注)  
   * tianditu(墨卡托投影[vec_w:矢量底图 cva_w:矢量注记 img_w:影像底图 cia_w:影像注记 ter_w:地形底图 cta_w:地形注记 ibo_w:境界(省级以上) eva_w:矢量英文注记 eia_w:影像英文注记])  
   * tianditu(经纬度投影[vec_c:矢量底图 cva_c:矢量注记 img_c:影像底图 cia_c:影像注记 ter_c:地形底图 cta_c:地形注记 ibo_c:境界(省级以上) eva_c:矢量英文注记 eia_c:影像英文注记])
   */
  showBaseMap (layerTypes, layerSwitch) {
    const that = this;
    const google = ["m", "s", "t", "h"];
    const tianditu = ["vec_w", "cva_w", "img_w", "cia_w", "ter_w", "cta_w", "ibo_w", "eva_w", "eia_w", "vec_c", "cva_c", "img_c", "cia_c", "ter_c", "cta_c", "ibo_c", "eva_c", "eia_c"];
    hideLayer();
    if (typeof layerTypes === "string") {
      showLayer(layerTypes);
    } else if (typeof layerTypes === "object" && Array.isArray(layerTypes)) {
      layerTypes.forEach(item => {
        showLayer(item);
      });
    }
    // 获取底图id
    function getLayerId (sType) {
      if (google.indexOf(sType) != -1) {
        that.curBaseMap = "google";
      } else if (tianditu.indexOf(sType) != -1) {
        that.curBaseMap = "tianditu";
      }
      let layerId = "basemap_" + that.curBaseMap + "_" + sType;
      return layerId;
    }
    // 隐藏其他底图
    function hideLayer () {
      if (layerSwitch) {
        let layers = that.getLayers();
        let keepLayers = [];
        layers.forEach(item => {
          if (item.id.indexOf("basemap") != -1) {
            if (typeof layerTypes === "string") {
              item.id == getLayerId(layerTypes) ? item.visible = true : item.visible = false;
            } else if (typeof layerTypes === "object" && Array.isArray(layerTypes)) {
              item.visible = false;
              layerTypes.forEach(i => {
                if (item.id == getLayerId(i)) keepLayers.push(item);
              });
            }
          }
        });
        keepLayers.forEach(item => {
          item.visible = true;
        })
      }
    }
    // 展示底图
    function showLayer (sType) {
      const layerId = getLayerId(sType);
      let baseMap = that.getLayerById(layerId);
      if (!baseMap) {
        let gMap;
        switch (that.curBaseMap) {
          case "google":
            if (sType == "t") {
              gMap = new that.mapEsri.WebTileLayer({
                "urlTemplate": "http://mt{subDomain}.google.cn/maps/vt?lyrs=" + sType + "@132,r&hl=zh-CN&gl=CN&x={col}&y={row}&z={level}",
                "id": layerId,
                "listMode": 'hide',
                "subDomains": ["0", "1", "2"]
              });
            } else {
              gMap = new that.mapEsri.WebTileLayer({
                "urlTemplate": "http://mt{subDomain}.google.cn/maps/vt?lyrs=" + sType + "&hl=zh-CN&gl=CN&x={col}&y={row}&z={level}",
                "id": layerId,
                "listMode": 'hide',
                "subDomains": ["0", "1", "2"]
              });
            }
            break;
          case "tianditu":
            gMap = new that.mapEsri.WebTileLayer({
              "urlTemplate": "http://{subDomain}.tianditu.com/DataServer?T=" + sType + "&x={col}&y={row}&l={level}&tk=a8ceffa313eb053d916f4ae995493f5a",
              "id": layerId,
              "listMode": 'hide',
              "subDomains": ["t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"]
            });
            break;
        }
        that.map.add(gMap);
      }
    }
  }

  /**
   * 创建专题图层【MapImageLayer】
   * @param {string} layerId 图层id
   * @param {string} layerUrl 图层地址 
   * @param {object} option 图层可选参数
   * @return {object} 专题图层对象
   */
  createImageLayer (layerId, layerUrl, option) {
    if (!option) option = {};
    let imageLayer = new this.mapEsri.MapImageLayer({
      id: layerId,
      url: layerUrl,
      title: option.title || "",
      spatialReference: option.spatialReference || { wkid: 4326 },
      dpi: 96,
      opacity: typeof option.opacity == "number" ? option.opacity === 0 ? 0 : option.opacity : 1,
      maxScale: Array.isArray(option.scale) && option.scale.length > 0 ? option.scale[0] : 0,
      minScale: Array.isArray(option.scale) && option.scale.length > 0 ? option.scale[1] : 0,
      visible: option.visible == undefined ? true : option.visible,
      listMode: option.listMode == undefined ? "show" : option.listMode
    });
    if (option.sublayers) imageLayer.sublayers = option.sublayers;
    return imageLayer;
  }
}

const mapApi = new MapApi();

setInterval(() => {
  mapApi.loadInit();
}, 1);

export default mapApi;

window['mapApi'] = mapApi;
相关推荐
清灵xmf39 分钟前
在 Vue 3 中实现“折叠”与“展开”文本内容
前端·javascript·css·vue.js
我的椰子啊42 分钟前
el-input仅限输入数字 (输入框仅支持输入数字)
前端·javascript·vue.js
简单点了44 分钟前
el-table+el-form实现表单校验和解决不垂直居中导致的问题
javascript·vue.js·elementui
用户75390019234811 小时前
在vercel部署项目时除首页外刷新报404
前端·vue.js
小纯洁w2 小时前
el-tree 中:lazy=“true“ 模式下使用双击展开节点而不是单击
javascript·vue.js·elementui
深情废杨杨3 小时前
前端vue-ref与document.querySelector的对比
前端·javascript·vue.js
且行且知3 小时前
前端Vue 基础学习1
前端·vue.js·学习
dawn1912284 小时前
Vue入门之生命周期
前端·javascript·vue.js·前端框架·vue
sunywz4 小时前
封装提示词翻译组件
vue.js·人工智能·python·stable diffusion