vue2.x + ArcGIS API for JavaScript 3.3x

10 篇文章 0 订阅

1. 通过 npm 安装 esri-loader ; 

  思路:通过vuex 将ArcGIS模块保存,加上vue的watch监听达到全不同模块间的调用。

<template>
  <div class="mapBox">
    <!-- 地图 -->
    <div id="viewDiv" class="viewDiv" >
     
  </div>
</template>

<script>
import { loadModules } from "esri-loader";
import { mapGetters } from "vuex";

export default {
  data() {
    return {
      view: "",
      map: "",
    };
  },

  watch: {
    /**
     * 外部 选中面
     * 
     */
    sceneInformationParamVux(data) {
      let self = this;
      if (data) {
        self.sceneInformationParam = data.features[0].attributes;
        self.sceneDialogVisible = true;
        self.mapUtil.zoomMap(this, data);
        self.dynamicLayersFn(data);
      }
    }
  },
  computed: {
    /**
     * fullScreen   是否全屏
     * comExpression  选中的微格过滤条件
     */
    ...mapGetters(["fullScreen", "comExpression", "mapModular", "sceneInformationParamVux", "selectScene", "mapLoadingComplete"]),
  },
  methods: {
    loadModules() {
      let self = this;
    /**引入的gis模块*/
      let loadModulesArr = [
        "esri/map",
        "esri/layers/ArcGISTiledMapServiceLayer", // 瓦片图
        "esri/layers/ArcGISDynamicMapServiceLayer", // 动态地图服务
        "esri/symbols/SimpleMarkerSymbol", // 用来在graphics图层上画点和多点的
        "esri/symbols/TextSymbol", // 用来在graphics图层上写文字
        "esri/layers/GraphicsLayer", // 包含图形的图层
        "esri/Color", // 继承dojo/_base/Color中的所有属性,以提供设置颜色的函数
        "esri/graphic", // 用来创建几何图层的
        "esri/geometry/Point", // 几何图形中的点类
        "esri/SpatialReference", // 定义图层的空间参考
        "esri/layers/FeatureLayer",
        "esri/symbols/PictureMarkerSymbol",
        "esri/symbols/SimpleFillSymbol",
        "esri/symbols/SimpleLineSymbol",
        "esri/tasks/query", // 查询
        "esri/tasks/QueryTask",
        "esri/renderers/UniqueValueRenderer",
        "esri/renderers/ClassBreaksRenderer",
        "esri/graphicsUtils",
        "dojo/domReady!",
      ];

      this.gisModules = loadModulesArr;
      const options = {
        // 可以使用自定义资源加载,arcgis 官网加载太慢了,经常加载失败.后面会讲到自己本地如何配置资源
         url: "https://js.arcgis.com/3.34/",
         css: "https://js.arcgis.com/3.34/esri/css/esri.css",
      };

      loadModules(loadModulesArr, options)
        .then(this.TDTinstance)
        .then(this.gisInit);
    },
    TDTinstance(args) {
      let self = this;
      // 这里处理了一下传参,构造函数全部保存到 gisConstructor 对象中,对应的函数
      // key 值为加载模块的最后一个单词
      // 将引入的模块添加到vuex中
      for (let k in args) {
        let name = this.gisModules[k].split("/").pop();
        name = name.replace(/^\S/, (s) => s.toUpperCase());
        this.gisConstructor[name] = args[k];
        // 提交到vuex
        let param = {
          name: name,
          Fn: args[k],
        };
        self.$store.commit("mapModular", param);
      }
    },
    gisInit() {
      let self = this;
      let map;
      map = new self.mapModular.Map("viewDiv", {
        center: new self.mapModular.Point(
          109.02479399322853,
          32.69607182534896,
          new self.mapModular.SpatialReference({
            wkid: 4326,
          })
        ),
        zoom: 9,
        maxZoom: 12,
        showLabels: true,
        logo: false,
      });

      /**
       *  底图 (影像底图、矢量底图)
       */
      // 矢量底图
      self.vecLayer = new self.mapModular.ArcGISTiledMapServiceLayer(
           '地图服务URL',
        {
          id: "generalTile",
        }
      );

      // 网格
      self.gridLayer = new self.mapModular.FeatureLayer(
         '要素图层服务URL',
        {
          id: "layerShanxiGrid",
          outFields: ["*"], // 指定[“*”]来获取图层中所有字段的值,这在编辑要素时非常有用
          visible: false, // 隐藏
        }
      );

      // 过滤条件
      let expression = "RESNAME = '城区老城分局'";
      self.gridLayer.setDefinitionExpression(expression);

      /**
       * 17大类图层
       */
      self.sceneLayer = new self.mapModular.ArcGISDynamicMapServiceLayer(
        '动态服务URL',
        {
          id: "featureLayerId",
        }
      );

      // 添加图层(两种方式)

        //一次性添加多个
      map.addLayers([self.vecLayer, self.gridLayer]);
        // 一次性添加一个
      map.addLayer(self.sceneLayer);

      //   在地图上隐藏缩放模块
      map.on("load", function () {
        map.hideZoomSlider();
      });
      self.map = map;

      // 图层点击事件添加
      self.map.on("click", self.mapClick);
      // 添加到vuex
      // self.$store.commit("MAP", self.map);
      let param = {
        name: "Map",
        Fn: self.map,
      };
      self.$store.commit("mapModular", param);
      // 地图服务加载完成
      self.$store.commit("mapLoadingComplete", true);

    },
  
    // 底图切换
    mapVectorClick(type) {
      let self = this;
      /* 
       self.map.addLayer(地图,图层顺序)
      */
      // 切影像
      if (type === "realScene") {
        self.mapModular.Map.removeLayer(self.vecLayer);
        self.mapModular.Map.addLayer(self.imgLayer, 1);
        self.mapModular.Map.addLayer(self.imgLabel, 0);
      } else {
        // 切矢量地图
        self.mapModular.Map.removeLayer(self.imgLayer);
        self.mapModular.Map.removeLayer(self.imgLabel);
        self.mapModular.Map.addLayer(self.vecLayer, 0);
      }
    },
    /* 网格、微格、场景复选框点击 */
    checkboxChange(type, value) {
      let self = this;
      switch (type) {
        // 分局网格
        case "gridCheckbox":
          self.gridLayer.setVisibility(value);
          break;
        // 下辖微格
        case "microteaching":
          self.mGridLayer.setVisibility(value);
          break;
        // 场景
        case "scene":
          // 显示隐藏图层
          self.sceneLayer.setVisibility(value);
          // 场景图层恢复初始状态
          if (!value) {
            if (self.mapModular.Map.getLayer("dynamicLayersGraphicsLayerId")) {
              self.mapModular.Map.getLayer(
                "dynamicLayersGraphicsLayerId"
              ).clear();
            }

            let activeIdArr = [];
            self.majorDategoriesArr.forEach((data) => {
              data.active = false;
              activeIdArr.push(data.id);
            });
            self.sceneLayer.setVisibleLayers(activeIdArr);
          }
          break;
      }
      this.detailObj = "";
    },

    
    // 地图点击事件
    mapClick(e) {
      let self = this;
      //获得用户点击的地图坐标
      let point = e.mapPoint;
      // 筛选的服务URL
      let queryTaskUrl = "";
      // 筛选条件
      let where = {
        where: self.comExpression,
        geometry: point,
      };
      /**
       * 筛选地图服务URL
       */

      this.majorDategoriesArr.forEach((item) => {
        if (item.active) {
          queryTaskUrl = `${this.configUrl.MapServer.type}/${item.id}`;
        }
      });
      // 查询
      self.mapUtil.queryUtil(self, queryTaskUrl, where, self.dynamicLayersFn);
    },
    // 图层选中事件
    dynamicLayersFn(queryResult) {

      let self = this;
      // 点击的地方是否有绘制的图层
      if (queryResult.features == 0) {
        return;
      }
      if (queryResult.features[0].attributes.GWM_STATUS === 1) {
        return
      }

      // 绘制图层的id
      let graphicsLayerId = "dynamicLayersGraphicsLayerId";
      // 创建绘制(选中的图层样式添加)
      self.mapUtil.selectLayers(this, queryResult, graphicsLayerId, callBack);
      // 回调
      function callBack(attributes) {
        self.sceneInformationParam = attributes;
        //当前视图为预警视图时,只有在要素预警状态为1时才显示预警信息对话框
        if (
          self.isTypeActive === "2" &&
          attributes &&
          attributes.GWM_WARN_STATUS == 1
        ) {
          self.sceneWarnDialogVisible = true;
        }
      }
      // 场景弹层
      if (self.isTypeActive === "1") {
        self.sceneDialogVisible = true;
      }
    },

    // "目标市场视图" ==> 图例复选框事件
    legendCheckboxFn(data) {
      let self = this;
      let mGridLayerExpression = "";
      data.map((item) => {
        switch (item) {
          case "数据完整录入":
            if (mGridLayerExpression) {
              mGridLayerExpression += " or GWM_STATUS = 0";
            } else {
              mGridLayerExpression = "GWM_STATUS = 0";
            }
            break;
          case "数据未录入":
            if (mGridLayerExpression) {
              mGridLayerExpression += " or GWM_STATUS = 1";
            } else {
              mGridLayerExpression = "GWM_STATUS = 1";
            }
            break;
          case "数据部分录入":
            if (mGridLayerExpression) {
              mGridLayerExpression += " or GWM_STATUS = 2";
            } else {
              mGridLayerExpression = "GWM_STATUS = 2";
            }

            break;
        }
      });
      if (!mGridLayerExpression) {
        mGridLayerExpression = "GWM_STATUS = 404";
      }

      // 清除选中面图层
      if (self.mapModular.Map.getLayer("dynamicLayersGraphicsLayerId")) {
        self.mapModular.Map.getLayer("dynamicLayersGraphicsLayerId").clear();
      }
      // 根据微格筛选渲染部分
      mGridLayerExpression = self.comExpression
        ? `(${mGridLayerExpression})` + " and " + self.comExpression
        : `(${mGridLayerExpression})`;
      self.mapUtil.thematicLayerFiltering(self, ['legendStyleLayer'], mGridLayerExpression)

      /**
       * 筛选地图服务URL
       */
      let queryTaskUrl = '';
      this.majorDategoriesArr.forEach((item) => {
        if (item.active) {
          queryTaskUrl = `${this.configUrl.MapServer.type}/${item.id}`;
        }
      });
      // 查询范围并缩放图层
      self.mapUtil.queryUtil(self, queryTaskUrl, mGridLayerExpression, (queryResult) => {
        self.mapUtil.zoomMap(self, queryResult)
      })
    },
  
    // 子组件回调
    /**
     * data  用来区分子组件
     * param 子组件返回参数
     */
    childrenCallBack(data, param) {
      let self = this;
      switch (data) {
        case "SummaryList":
          // self.drawerSummary = false;
          if (param.name === "detail" && param.type === "target") {
            self.sceneDialogVisible = true;
            self.sceneInformationParam = param.features;
          } else if (param.name === "detail" && param.type === "marketing") {
            self.sceneWarnDialogVisible = true;
            self.sceneInformationParam = param.features;
          }
          break;
        case "microteaching":
          // 微格显示隐藏
          self.mGridLayer.setVisibility(param);
          break;
      }
      // console.log(data)
    },
  },
  beforeDestroy() {
    // 地图服务加载完成
    this.$store.commit("mapLoadingComplete", false);
  },
  created() {
    this.loadModules();
  },
};
</script>

<style  lang="scss" scoped>
.mapBox {
  .drawerBox {
    top: 100px;
    height: calc(100% - 110px);
    width: 30%;
    left: 40px;
  }
  
}
</style>

mapUtil.js

  说明: self.mapModular. 是在引入arcgis模块时添加到vuex的变量

在不同的模块中,只需要引入vuex中声明的mapModular,就可以使用gis模块功能;

/***
 *
 *   █████▒█    ██  ▄████▄   ██ ▄█▀       ██████╗ ██╗   ██╗ ██████╗
 * ▓██   ▒ ██  ▓██▒▒██▀ ▀█   ██▄█▒        ██╔══██╗██║   ██║██╔════╝
 * ▒████ ░▓██  ▒██░▒▓█    ▄ ▓███▄░        ██████╔╝██║   ██║██║  ███╗
 * ░▓█▒  ░▓▓█  ░██░▒▓▓▄ ▄██▒▓██ █▄        ██╔══██╗██║   ██║██║   ██║
 * ░▒█░   ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄       ██████╔╝╚██████╔╝╚██████╔╝
 *  ▒ ░   ░▒▓▒ ▒ ▒ ░ ░▒ ▒  ░▒ ▒▒ ▓▒       ╚═════╝  ╚═════╝  ╚═════╝
 *  ░     ░░▒░ ░ ░   ░  ▒   ░ ░▒ ▒░
 *  ░ ░    ░░░ ░ ░ ░        ░ ░░ ░
 *           ░     ░ ░      ░  ░
 */

/**
 * 
 * 图层 ==>(FeatureLayer)
 * 
 * 搜索关键 字定位到方法: 
 * 查询,打点、坐标定位,图层选中,图层过滤,图层显示隐藏,
 * 删除图层、清除图层,根据条件对服务进行查询并渲染图层,定位到选中面范围
 * 
 * 
 */

/**
 * 关键字:查询  支持(where,geometry)
 * @param {Object} self 
 * @param {String} queryTaskUrl 服务地址
 * @param {String} condition 筛选条件
 * @param {Function} callBack 回调函数
 * 
 *   通过condition类型 object、string 区分查询条件
 *   condition类型 object  {where:'xx',geometry:'xx'}
 *   condition类型 string  'xxxxx'
 */


export function queryUtil(self, queryTaskUrl, condition, callBack) {
  let query = new self.mapModular.Query();
  query.outFields = ["*"];
  query.outSpatialReference = self.mapModular.Map.spatialReference; // 空间参考
  query.returnGeometry = true; // 查询返回Geometry

  if (typeof (condition) == 'object') {
    query.where = condition.where; // 筛选条件
    query.geometry = condition.geometry;
  } else {
    query.where = condition; // 筛选条件
  }
  //实例化查询对象
  // var queryTask = new self.QueryTask("http://192.168.124.14:6080/arcgis/rest/services/shanxi/scene_type/MapServer/12");
  var queryTask = new self.mapModular.QueryTask(queryTaskUrl);
  //进行查询
  queryTask.execute(query, queryResult => {
    callBack(queryResult)
  })
}

/**
 * 关键字:打点、坐标定位   (分为只添加一个,也可以添加多个情况)
 * @param {*} self this
 * @param {Object} feature 特征信息
 * @param {String} icon  图标
 * @param {String} graphicsLayerId 图层ID  和callBack 二存一
 * @param {Function} callBack 回调函数
 */
export function PointUtil(self, feature, icon, graphicsLayerId, callBack) {
  let newPoint = new self.mapModular.Point(feature.attributes.GWM_X, feature.attributes.GWM_Y, self.mapModular.Map.spatialReference);
  let picSymbol = new self.mapModular.PictureMarkerSymbol(icon, 30, 30);
  let picGraphic = new self.mapModular.Graphic(newPoint, picSymbol);
  /** 
   * 如果有 graphicsLayerId ,直接添加绘制图层
   * 没有 返回绘制信息
   */
  if (graphicsLayerId) {
    let graphicsLayer;
    if (self.mapModular.Map.getLayer(graphicsLayerId)) {
      self.mapModular.Map.removeLayer(self.mapModular.Map.getLayer(graphicsLayerId))
    }
    graphicsLayer = new self.mapModular.GraphicsLayer({
      id: graphicsLayerId,
    });
    // 添加到图层
    graphicsLayer.add(picGraphic)
    // 将图层添加到地图
    self.mapModular.Map.addLayer(graphicsLayer);
    // 定位并居中
    self.mapModular.Map.centerAndZoom(newPoint, 11);
  } else {
    callBack(picGraphic)
  }

}

/**
 * 关键字:图层选中
 * @param {Object} self 
 * @param {Object} queryResult 
 * @param {String} graphicsLayerId 
 * @param {Function} callBack 
 */
export function selectLayers(self, queryResult, graphicsLayerId, callBack) {
  /* 是否存在图层 */
  let isTrue = false;
  // 清除图层绘制
  for (let i = 0; i < queryResult.features.length; i++) {
    self.mapModular.Map.graphicsLayerIds.map((item) => {
      if (item === graphicsLayerId) {
        self.mapModular.Map.getLayer(item).clear();
        isTrue = true;
      }
    });


    //获得该图形的形状
    let feature = queryResult.features[i];
    let geometry = feature.geometry;
    /**
       * 定义高亮图形的符号
       * 边框样式
       * new SimpleLineSymbol(style, color, width)
       * 面样式
       * new SimpleFillSymbol(style, outline, color)
       */
    //1.定义面的边界线符号
    let outline = new self.mapModular.SimpleLineSymbol(
      self.mapModular.SimpleLineSymbol.STYLE_SOLID,
      new self.mapModular.Color([64, 158, 255]),
      1
    );
    //2.定义面符号
    let PolygonSymbol = new self.mapModular.SimpleFillSymbol(
      self.mapModular.SimpleFillSymbol.STYLE_SOLID,
      outline,
      new self.mapModular.Color([3, 4, 31, 0.8])
    );
    //创建客户端图形
    let graphic = new self.mapModular.Graphic(geometry, PolygonSymbol);

    /**
 * 将客户端图形添加到map中
 * 1.创建“绘制图层”GraphicsLayer
 * 2.将图形(Graphic)添加到“绘制图层”
 * 3.将“绘制图层”添加到地图(map)上
 */

    if (!isTrue) {
      let graphicsLayer = new self.mapModular.GraphicsLayer({
        id: graphicsLayerId,
      });
      graphicsLayer.add(graphic);
      self.mapModular.Map.addLayer(graphicsLayer,1);
    } else {
      self.mapModular.Map.getLayer(graphicsLayerId).add(graphic);
    }

    // 返回选中的面
    if (typeof (callBack) == 'function') {
      callBack(feature.attributes)
    }

  }
}

/**
 * 关键字  图层过滤 (FeatureLayer)
 * @param {Array} layerIds 需要过滤图层的Id
 * @param {String} comExpression 过滤条件
 */
export function thematicLayerFiltering(self, layerIds, comExpression) {
  layerIds.map(item => {
    let legendStyleLayer = self.mapModular.Map._layers[item];
    if (legendStyleLayer) {
      legendStyleLayer.setDefinitionExpression(comExpression);
    }
  })
}
/**
 * 关键字 : 图层显示隐藏
 * @param {Object} self 
 * @param {String} layerId 图层ID
 * @param {Boolean} show  显示隐藏
 */
export function setVisibility(self, layerId, show) {
  let layer = self.mapModular.Map.getLayer(layerId);
  layer.setVisibility(show)
}

/**
 * 关键字:
 * 删除图层、清除图层
 * @param {Object} self 
 * @param {String} layerIds 图层ID(可以是数组,也可以是字符串)
 */
export function removeLayer(self, layerIds) {

  if (typeof (layerIds) === 'object') {
    layerIds.map(item => {
      if (self.mapModular.Map.getLayer(item)) {
        self.mapModular.Map.removeLayer(self.mapModular.Map.getLayer(item))
      }
    })
  } else {
    if (self.mapModular.Map.getLayer(layerIds)) {
      self.mapModular.Map.removeLayer(self.mapModular.Map.getLayer(layerIds))
    }
  }

}

/**
 * 关键字:
 *    根据条件对服务进行查询并渲染图层
 * @param {Object} self 
 * @param {String} serverUrl 服务地址
 * @param {String} layerId 图层Id
 * @param {String} where 判断条件
 * @param {Array} identification 区分条件
 * @param {Array} colors 颜色数组
 */
export function conditionalRenderLayer(self, serverUrl, layerId, where, identification, colors) {

  let featureLayer = new self.mapModular.FeatureLayer(
    serverUrl,
    {
      outFields: ["*"],
      id: layerId
    });

  //定义线符号
  let lineSymbol = new self.mapModular.SimpleLineSymbol(
    self.mapModular.SimpleLineSymbol.STYLE_SOLID,
    new self.mapModular.Color([64, 158, 255]),
    1
  );
  //定义面符号
  let fill = new self.mapModular.SimpleFillSymbol(self.mapModular.SimpleFillSymbol.STYLE_SOLID, lineSymbol, new self.mapModular.Color("#FFFFCC"));
  //定义唯一值渲染器,对字段alias进行渲染,fill是默认的渲染符号
  let renderer = new self.mapModular.UniqueValueRenderer('', where);
  /**
   * 根据"where == item"判断设置渲染的方式 
   * 
   */
  identification.map((item, index) => {
    renderer.addValue(item, new self.mapModular.SimpleFillSymbol(self.mapModular.SimpleFillSymbol.STYLE_SOLID, lineSymbol, new self.mapModular.Color(colors[index])));
  })

  featureLayer.setRenderer(renderer);
  self.mapModular.Map.addLayer(featureLayer);
}

/**
 * 关键字:
 *    根据条件(区间)对服务进行查询并渲染图层
 * @param {Object} self 
 * @param {String} serverUrl 服务地址
 * @param {String} layerId 图层Id
 * @param {String} where 判断条件
 * @param {Array} identification 区分条件
 * @param {Array} colors 颜色数组
 */

export function IntervalRendering(self, serverUrl, layerId, where, identification, colors){
  let featureLayer = new self.mapModular.FeatureLayer(
    serverUrl,
    {
      outFields: ["*"],
      id: layerId
    });

  //定义线符号
  let lineSymbol = new self.mapModular.SimpleLineSymbol(
    self.mapModular.SimpleLineSymbol.STYLE_SOLID,
    new self.mapModular.Color([64, 158, 255]),
    1
  );
  //定义面符号
  let fill = new self.mapModular.SimpleFillSymbol(self.mapModular.SimpleFillSymbol.STYLE_SOLID, lineSymbol, new self.mapModular.Color("#FFFFCC"));
  //定义唯一值渲染器,对字段alias进行渲染,fill是默认的渲染符号
  
  let renderer = new self.mapModular.ClassBreaksRenderer('', where);
  /**
   * 根据"where == item"判断设置渲染的方式 
   * 
   */
  identification.map((item, index) => {
    renderer.addBreak(item[0],item[1], new self.mapModular.SimpleFillSymbol(self.mapModular.SimpleFillSymbol.STYLE_SOLID, lineSymbol, new self.mapModular.Color(colors[index])));
  })

  featureLayer.setRenderer(renderer);
  self.mapModular.Map.addLayer(featureLayer);
}
/**
 * 关键字 : 定位到选中面范围
 * @param {Object} self 
 * @param {Object} queryResult  (queryResult.features)
 */
export function zoomMap(self, queryResult) {
  let extent = self.mapModular.GraphicsUtils.graphicsExtent(queryResult.features);
  self.mapModular.Map.centerAt(extent.getCenter());
  self.mapModular.Map.setExtent(extent);
}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

未来-更美好

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值