arcgis官网:https://arcgis.fenxianglu.cn/docs/load.html

官网英文版地址:https://developers.arcgis.com/javascript/latest/api-reference/esri-Map.html

 

一、集成到应用----@arcgis/core方式

1、引入ArcGIS API for JavaScript

yarn add @arcgis/core

或者指定安装版本

yarn add @arcgis/core@4.25

如果提示:'yarn' 不是内部或外部命令,也不是可运行的程序 或批处理文件。则先安装yarn,安装命令如下:

npm install -g yarn 

安装完成后,如下所示:

2、创建一个div,装载我们的地图

<div id="map" style="width: 100%;height: 80vh"></div>

3、引入arcgis

import Map from "@arcgis/core/Map.js";
import MapView from "@arcgis/core/views/MapView.js";

引入ArcGIS中的样式

import "@arcgis/core/assets/esri/themes/light/main.css";

4、在mounted创建地图

mounted(){
    this.map = new Map({
      //basemap: basemap,//如果使用本地ArcGIS server中发布的地图服务
      basemap: "streets-vector",//如果使用在线地图服务
      zoom: 24,//地图初始化缩放级别   只有使用在线地图服务该属性才有效
    });
    this.view = new MapView({
      container: "map",
      map: this.map,
      extent: {//初始化范围
        spatialReference: {
          wkid: 4326,//美国WGS_84坐标系
        },
        xmin: 99.298390123,
        ymin: 32.192839123,
        xmax: 125.2983901923,
        ymax: 50.281973892,
      },
      //中心点坐标
      center: [110.3289749234, 41.2394820934]
    })
  }

注意:不能在created中创建,否则报错:

[esri.views.MapView] #container element with id 'map' not found

效果如下:

清除放大缩小按钮

this.view.ui.remove("zoom");

把左上角放大缩小组件移到右下角

this.view.ui.move('zoom', 'bottom-right');

清除底部powered by ESRI

this.view.ui.remove("attribution");

效果如下:

完整代码如下:

<template>
  <div class="about">
    <div id="map" style="width: 100%;height: 80vh"></div>
  </div>
</template>
<script>
import "@arcgis/core/assets/esri/themes/light/main.css";
import Map from "@arcgis/core/Map.js";
import MapView from "@arcgis/core/views/MapView.js";

export default {
  name: 'AboutView',
  components: {

  },
  mounted(){
    this.map = new Map({
      basemap: "streets-vector",//如果使用在线地图服务
      zoom: 24,//地图初始化缩放级别   只有使用在线地图服务该属性才有效
    });
    this.view = new MapView({
      container: "map",
      map: this.map,
      extent: {//限定范围
        spatialReference: {
          wkid: 4326,//美国WGS_84坐标系
        },
        xmin: 99.298390123,
        ymin: 32.192839123,
        xmax: 125.2983901923,
        ymax: 50.281973892,
      },
      //中心坐标
      center: [110.3289749234, 41.2394820934]
    })
    this.view.ui.remove("zoom"); //清除放大缩小按钮
    this.view.ui.remove("attribution"); //清除底部powered by ESRI
  }
}
</script>

中心点

this.view = new MapView({
      container: "map",
      map: this.map,//中心点
      center: [110.3289749234, 41.2394820934]
    })

转到中心点

mapView.goTo({
  center: [110.123141243, 33.5322342]
})

获取中心点

console.log(mapView.center)

触发地图

可以使用设置本身中心点来触发地图。

mapView.set({center: [mapView.center.longitude, mapView.center.latitude]})

 

MapView的基础设置

// 设置旋转角度为 270
mapView.rotation = 270
// 设置缩放层级为 18
mapView.zoom = 18
// 设置中心点为 [-112, 38]
mapView.center = [-112, 38]
// 设置地图比例为 1:24000
mapView.scale = 24000

MapView的限定范围

this.view = new MapView({
            container: "map",
            map: this.map,
            extent: new Extent({
              spatialReference: {
                wkid: 4326,//坐标系
              },
              xmin: 73.481382,
              ymin: 18.173515,
              xmax: 122.18916,
              ymax: 53.521718,
            }),
          })

实例创建完成回调

mapView.when(function(){
    // This function will execute once the promise is resolved
}, function(error){
    // This function will execute if the promise is rejected due to an error
}); 

属性设置

mapView.set({
    center: [121.3022630323934, 29.868660680345652],
    zoom: 10
});

观察属性变动

mapView.watch(['zoom'], function(newV, oldV, propName) {
    console.log(newV, oldV, propName)
});

MapView.toScreen函数

将给定的map point 转换为屏幕点。屏幕点表示相对于视图左上角的像素点。

const mapPoint = {
  x: -49.97,
  y: 41.73,
  spatialReference:{
     wkid: 4326
  }
};
const screenPoint = mapView.toScreen(mapPoint);

再将屏幕点的位置赋值给弹框的左上角点,这样弹框会跟着地图的缩放而相应的变化。

常见的一些 WKID

  • 3857:Web墨卡托投影,用于大多数Web地图应用程序
  • 4326:WGS84地理坐标系,经纬度坐标系。
  • 102100 / 102200:ArcGIS Online 底图使用的Web墨卡托投影。
  • 3413 / 3031:南极和北极的极面投影。
  • 27700:英国国家格网,适用于英格兰、威尔士和苏格兰。

当使用墨卡拖投影时,写法与4326不一样,如下所示:

this.view = new MapView({
            container: "map",
            map: this.map,
            // zoom: 6,
            spatialReference: 3857,
          })

如果如下所示写在extent里面,则无法显示地图

this.view = new MapView({
            container: "map",
            map: this.map,
            // zoom: 6,
            extent: new Extent({
               spatialReference: {
                 wkid: 3857
               },
              xmin: 73.481382,
              ymin: 18.173515,
              xmax: 122.18916,
              ymax: 53.521718,
            }),
          })

实际开发中建议用3857,因为EPSG:4326 感觉map 地图被上下压缩过一样,而 EPSG:3857 坐标系就很正常。

二、集成到应用----esri-loader方式

1、安装esri-loader

npm i esri-loader

2、创建一个div,装载我们的地图

<div id="map" style="width: 100%;height: 80vh"></div>

3、引入esri-loader

import {loadModules} from "esri-loader";

4、在mounted创建地图

  mounted() {
    loadModules([
      "esri/Map",
      "esri/views/MapView"]) // 传入需要使用的类
        .then(([Map, MapView]) => {
          this.map = new Map({
            basemap: "streets-vector",//如果使用在线地图服务
            zoom: 24,//地图初始化缩放级别   只有使用在线地图服务该属性才有效
          });
          this.view = new MapView({
            container: "map",
            map: this.map,
            extent: {//初始化范围
              spatialReference: {
                wkid: 4326,//美国WGS_84坐标系
              },
              xmin: 99.298390123,
              ymin: 32.192839123,
              xmax: 125.2983901923,
              ymax: 50.281973892,
            },
            //中心坐标
            center: [110.3289749234, 41.2394820934]
          })

        })
        .catch(err => {
          console.error('地图初始化失败', err);
        })
  }

效果如下:

完整代码:

<template>
  <div class="home">
    <div id="map" style="width: 100%;height: 80vh"></div>
  </div>
</template>

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

export default {
  name: 'HomeView',
  data() {
    return {
      map: null,
      view: null
    }
  },
  components: {
  },
  mounted() {
    loadModules([
      "esri/Map",
      "esri/views/MapView"]) // 传入需要使用的类
        .then(([Map, MapView]) => {
          this.map = new Map({
            basemap: "streets-vector",//如果使用在线地图服务
            zoom: 24,//地图初始化缩放级别   只有使用在线地图服务该属性才有效
          });
          this.view = new MapView({
            container: "map",
            map: this.map,
            extent: {//初始化范围
              spatialReference: {
                wkid: 4326,//美国WGS_84坐标系
              },
              xmin: 99.298390123,
              ymin: 32.192839123,
              xmax: 125.2983901923,
              ymax: 50.281973892,
            },
            //中心坐标
            center: [110.3289749234, 41.2394820934]
          })

        })
        .catch(err => {
          console.error('地图初始化失败', err);
        })
  }
}
</script>

缩放

this.map = new Map({
            basemap: "streets-vector",//如果使用在线地图服务
            zoom: 24,//地图初始化缩放级别   只有使用在线地图服务该属性才有效
          });

转到中心点及缩放

mapView.goTo({
  center: [102.92934063304513, 25.102234987110343],
  zoom: 10
})

 

三、使用本地ArcGIS server中发布的地图服务

arcgis本地化部署到tomcat

1、下载ArcGis418_api

官方下载地址:ArcGIS Developers

选择4.18

上面那个是api,下面那个是说明文档,下载后如下所示:

解压后如下所示:

2、部署到tomcat

在arcgis_js_api文件下找到Init.js和dojo.js两个文件。搜索HOSTNAME_AND_PATH_TO_JSAPI,替换Init.js和dojo.js里的baseUrl为:baseUrl:"/ArcGis418_api/dojo"

修改为:

将4.18目录拷贝到tomcat的webapp目录下,将4.18目录改名为ArcGis418_api

修改tomcat端口号为9999,然后启动tomcat。

3、创建一个div,装载我们的地图

<div id="map" style="width: 100%;height: 80vh"></div>

4、引入

import {loadModules, setDefaultOptions, loadCss} from 'esri-loader';
setDefaultOptions({url: "/ArcGis418_api" + '/init.js'});
loadCss("/ArcGis418_api" + "/esri/themes/light/main.css");

5、在mounted创建地图

mounted() {
    loadModules([ // 加载js
      'esri/layers/TileLayer',
      "esri/Map",
      "esri/views/MapView"]) // 传入需要使用的类
        .then(([TileLayer,Map, MapView]) => { // 注意顺序要与上面加载的js一致
          var url =  "底图服务器的地址";
          this.layer = new TileLayer({
            url: url
          });
          this.map = new Map({
            layers: this.layer // 添加图层
          });
          this.view = new MapView({
            container: "map",
            map: this.map,
            extent: {//初始化范围
              spatialReference: {
                wkid: 4326,//坐标系
              },
              xmin: 99.298390123,
              ymin: 32.192839123,
              xmax: 125.2983901923,
              ymax: 50.281973892,
            },
            //中心坐标
            center: [110.3289749234, 41.2394820934]
          })

        })
        .catch(err => {
          console.error('地图初始化失败', err);
        })
  }

6、效果如下:

四、添加marker点及文字标注

1、添加按钮的点击事件

<el-button @click="drawPoint">打点</el-button>

2、编写点击事件

drawPoint() {
      //重新绘制突出显示
      loadModules([
        'esri/Graphic',
        "esri/layers/GraphicsLayer"
      ]).then(([Graphic,GraphicsLayer]) => {
        // 图片标记样式
        let pictureMarkerSymbol = {
          type: 'picture-marker', // 图片标记
          url: require('@/assets/logo.png'),
          width: 8,
          height: 12,
          angle: 0
        }
        // 标注样式
        let textSymbol = {
          type: "text", // 文本标记
          color: "red",
          // haloColor: "black",
          // haloSize: "1px",
          text: "武汉",
          xoffset: 16,
          yoffset: 6,
          font: { // autocasts as new Font()
            size: 10,
            family: "sans-serif",
            weight: "normal"
          }
        };
        const point = { // 点坐标
          //Create a point
          type: "point",
          longitude: 114.303877,
          latitude: 30.574443,
        };
        // marker样式与点
        const pointGraphic = new Graphic({
          geometry: point,
          symbol: pictureMarkerSymbol,
          attributes: { // 添加属性
            name: "测试",
            des: "这是一个marker点",
          },
        });
        // 标注样式与点
        const pointGraphicText = new Graphic({
          geometry: point,
          symbol: textSymbol,
        });
        // 创建图层并将点添加到图层
        let graphicsLayer = new GraphicsLayer({
          id: "001",
          title: "markerLayer",
          graphics: [pointGraphic]
        });
        //将标注样式添加到图形中
        graphicsLayer.graphics.add(pointGraphicText);
        //将图层添加map中
        this.map.layers.add(graphicsLayer); // 添加一个图层到图层集合
      })
    }

上面是图片标记样式,还有简单标记样式,代码如下:

let markerSymbol = {
          type: "simple-marker",
          color: "#FFD600",
          outline: {
            // 自动转换为新的SimpleLineSymbol()
            color: "#121212",
            width: "2px",
          },
          size: "10px",
        };

效果如下:

添加图形

(1)、添加一个

mapView.graphics.add(pointGraphic)

(2)、添加多个

mapView.graphics.addMany([pointGraphic])

(3)、删除

mapView.graphics.remove(pointGraphic)

(4)、删除多个

mapView.graphics.removeMany([pointGraphic])

(5)、删除全部

mapView.graphics.removeAll()

添加和删除图层

//使用数组在地图的构造函数中添加图层
let fl = new FeatureLayer(url);
let gl = new GraphicsLayer();
let map = new Map({
  layers: [fl, gl]
});

// 使用Add()添加图层
map.add(fl)

// 使用Add()添加图层
map.addMany([fl, gl]);

// 使用图层集合添加图层
map.layers.addMany([fl, gl]);

// 使用layers集合的push方法添加图层
map.layers.push(fl, gl);

// 删除某个图层
map.layers.remove(fl)

// 使用图层集合删除图层
map.layers.removeMany([fl, gl]);

效果:

获得marker点的点击事件

drawPoint() {
      //重新绘制突出显示
      loadModules([
        'esri/Graphic',
        "esri/layers/GraphicsLayer"
      ]).then(([Graphic,GraphicsLayer]) => {
        // marker样式
        let pictureMarkerSymbol = {
          type: 'picture-marker',
          url: require('@/assets/logo.png'),
          width: 8,
          height: 12,
          angle: 0
        }
        // 标注样式
        let textSymbol = {
          type: "text", // autocasts as new TextSymbol()
          color: "red",
          // haloColor: "black",
          // haloSize: "1px",
          text: "武汉",
          xoffset: 16,
          yoffset: 6,
          font: { // autocasts as new Font()
            size: 10,
            family: "sans-serif",
            weight: "normal"
          }
        };
        const point = { // 点坐标
          //Create a point
          type: "point",
          longitude: 114.303877,
          latitude: 30.574443,
        };
        // marker样式与点
        const pointGraphic = new Graphic({
          geometry: point,
          symbol: pictureMarkerSymbol,
          attributes: {
            name: "测试",
            des: "这是一个marker点",
          },
        });
        // 标注样式与点
        const pointGraphicText = new Graphic({
          geometry: point,
          symbol: textSymbol,
        });
        // 创建图层并将点添加到图层
        let graphicsLayer = new GraphicsLayer({
          id: "001",
          title: "markerLayer",
          graphics: [pointGraphic]
        });
        //将标注样式添加到图层中
        graphicsLayer.graphics.add(pointGraphicText);
        //将图层添加map中
        this.map.layers.add(graphicsLayer); // 添加一个图层到图层集合


        let that = this;
        this.view.on("click", function (event) {
          that.view.hitTest(event.screenPoint).then((responses) => {
            if (responses.results.length > 0) {
              // marker graphic的attributes
              const data = responses.results[0].graphic.attributes;
              console.log("markerData", data);
            }
          });
        });
      })
    },

点击图标,效果如下:

五、多段线

1、添加按钮的点击事件

<el-button @click="handleClick">画线</el-button>

2、编写点击事件

handleClick() {
      //重新绘制突出显示
      loadModules([
        'esri/Graphic'
      ]).then(([Graphic]) => {
        let paths = []
        paths.push([114.299975, 30.567826]) //经纬度
        paths.push([116.400306, 39.910481])
        paths.push([121.487427, 31.229783])
        // 添加线
        let polyline = {
          type: "polyline", // 多段线
          paths: paths,
        };

        let color = [48, 242, 120, 0.5]//颜色
        const width = 8;
        let polylineSymbol = { // 多段线的样式
          type: "simple-line",
          style: "solid",//实线,不设置也默认这个
          width: width,
          color: color
        }
        let polylineGraphic = new Graphic({
          geometry: polyline,
          symbol: polylineSymbol,
        });
        this.view.graphics.add(polylineGraphic); 
      })

    }

效果:

画虚线dash

let polylineSymbol = {
          type: "simple-line",
          style: "dash",//实线,不设置也默认这个
          width: width,
          color: color
        }

效果如下:

画一条白色的虚线和一条黑色的实线来实现铁路线的效果:

const width = 4;
        let polylineSymbol = {
          type: "simple-line",
          style: "solid",//实线,不设置也默认这个
          width: width+2,
          color: [3, 3, 3],// 黑色
          join: "round",
          miterLimit: 0.5
        }
        let polylineSymbol1 = {
          type: "simple-line",
          style: "dash",//虚线,不设置也默认这个
          width: width,
          color: "white",
          join: "round",
          miterLimit: 0.5
        }
        let polylineGraphic = new Graphic({
          geometry: polyline,
          symbol: polylineSymbol,
        });
        let polylineGraphic1 = new Graphic({
          geometry: polyline,
          symbol: polylineSymbol1,
        });
        this.view.graphics.add(polylineGraphic);
        this.view.graphics.add(polylineGraphic1);

效果如下:

更新 geometry

polylineGraphic.geometry = {
  type: "polyline",
  paths: [
    [  // 第1个 path
      [-97.06138,32.837,5],
      [-97.06133,32.836,6],
      [-97.06124,32.834,7]
    ], [  // 第2个 path
      [-97.06326,32.759],
      [-97.06298,32.755]
    ]
  ]
}

更新 symbol

polylineGraphic.symbol = {
  type: "simple-line",
  color: [226, 119, 40],
  width: 4
}

 

六、测距

1、添加按钮的点击事件

<el-button @click="measurePolyline">测距</el-button>

2、编写点击事件

measurePolyline() {
      let _this = this;
      loadModules([
        "esri/views/2d/draw/Draw",
        "esri/geometry/geometryEngine",
        "esri/geometry/Point",
        "esri/geometry/Polyline",
        "esri/layers/GraphicsLayer",
        "esri/Graphic",
        "dojo/domReady!",
      ]).then(
          ([Draw, GeometryEngine, Point, Polyline, GraphicsLayer, Graphic]) => {
            let lineLayer = _this.map.findLayerById("lineLayer");
            if (!lineLayer) {
              lineLayer = new GraphicsLayer({ //创建线图层
                id: "lineLayer",
              });
            }
            _this.map.layers.add(lineLayer);
            let draw = new Draw({
              //在view里创建draw
              view: _this.view,
            });
            let action = draw.create("polyline"); //创建画线实例
            _this.view.focus();
            action.on(
                [
                  "vertex-add", // 顶点添加事件
                  "vertex-remove", // 顶点移除事件
                  "cursor-update", // 鼠标移动事件
                  "redo",
                  "undo",
                  "draw-complete", // 鼠标双击绘制完成事件
                ],
                createPolyline
            );

            function createPolyline(event) {
              var vertices = event.vertices;
              var symbol = {
                type: "simple-marker",
                color: [255, 255, 255],
                size: 4,
                outline: {
                  color: [255, 0, 0],
                  width: 1.5, // points
                },
              };

              lineLayer.removeAll();
              var graphics = new Graphic({
                geometry: new Polyline({
                  paths: vertices,
                  spatialReference: _this.view.spatialReference,
                }),

                symbol: {
                  type: "simple-line", // autocasts as new SimpleFillSymbol
                  color: [255, 116, 3],
                  width: 2,
                  cap: "round",
                  join: "round",
                },
              });

              lineLayer.add(graphics);

              var firstTextSymbol = {
                type: "text",
                color: "blue",
                haloColor: "black",
                haloSize: "10px",
                text: "0.00千米",
                xoffset: "10px",
                yoffset: "10px",
                font: {
                  size: 12,
                  family: "sans-serif",
                  weight: "bold",
                },
              };

              var firstPoint = {
                type: "point",
                x: vertices[0][0],
                y: vertices[0][1],
                spatialReference: _this.view.spatialReference, //和底图相同的坐标系
              };
              var firstTextGraphics = new Graphic({
                geometry: firstPoint,
                symbol: firstTextSymbol,
              });
              var firstGraphics = new Graphic({
                geometry: firstPoint,
                symbol: symbol,
              });

              lineLayer.addMany([firstTextGraphics, firstGraphics]);

              let linePath = []; //线段坐标集合
              let pointStart = []; //起点
              pointStart.push(vertices[0][0]);
              pointStart.push(vertices[0][1]);
              linePath.push(pointStart);

              for (let i = 1; i < vertices.length; i++) {
                var point = {
                  type: "point",
                  x: vertices[i][0],
                  y: vertices[i][1],
                  spatialReference: _this.view.spatialReference, //和底图相同的坐标系
                };

                let xy = []; //鼠标当前经纬度
                xy.push(vertices[i][0]);
                xy.push(vertices[i][1]);
                linePath.push(xy);

                var line = new Polyline({
                  hasZ: false,
                  hasM: true,
                  paths: linePath,
                  spatialReference: _this.view.spatialReference,
                });

                let length = GeometryEngine.geodesicLength(line, "meters");
                let lengthText = lengthFormat(length); //单位转换
                var textSymbol = {
                  type: "text",
                  color: "blue",
                  haloColor: "black",
                  haloSize: "5px",
                  text: lengthText,
                  xoffset: "20px",
                  yoffset: "20px",
                  font: {
                    size: 12,
                    family: "sans-serif",
                    weight: "bold",
                  },
                };

                var textGraphics = new Graphic({
                  geometry: point,
                  symbol: textSymbol,
                });

                var Graphics = new Graphic({
                  geometry: point,
                  symbol: symbol,
                });
                //将标注和鼠标位置添加到地图
                lineLayer.addMany([textGraphics, Graphics]);
              }

              //长度单位转换
              function lengthFormat(length) {
                let lengthText;
                if (length < 2000) {
                  length = length.toFixed(2);
                  return (lengthText = length + "");
                } else {
                  length = (length / 1000).toFixed(2);
                  return (lengthText = length + "千米");
                }
              }
            }
          }
      );
    }

效果:

点击测距后,在地图上点击就可以测量两点之间的距离,要想结束测距则双击。

 

七、多边形

<template>
  <div class="about">
    <div id="map" style="width: 100%;height: 80vh"></div>
  </div>
</template>

<script>
import "@arcgis/core/assets/esri/themes/light/main.css";
import Map from "@arcgis/core/Map.js";
import MapView from "@arcgis/core/views/MapView.js";
import Graphic from "@arcgis/core/Graphic"
export default {
  name: "polygon",
  mounted() {
    const map = new Map({
      basemap: 'dark-gray',
    })

    const mapView = new MapView({
      map,
      container: 'map',
      center: [102.92934063304513, 25.102234987110343],
      extent: {//初始化范围
        spatialReference: {
          wkid: 4326,//坐标系
        },
        xmin: 73.481382,
        ymin: 18.173515,
        xmax: 122.18916,
        ymax: 53.521718,
      },
    })

    const polygonGraphic = new Graphic({
      geometry: {
        type: "polygon", // 多边形
        rings: [
          [
            [81.99385,41.423614],
            [84.311909,41.062564],
            [82.214617,38.363399],
            [81.99385,41.423614]
          ]
        ]
      },
      symbol: {
        type: "simple-fill",
        color: [227, 139, 79, 0.8],
        style: "solid",
        outline: {
          color: "red",
          width: 2
        }
      }
    })

    mapView.graphics.add(polygonGraphic)
  }
}
</script>

效果如下:

测量多边形面积

1、添加按钮的点击事件

<el-button @click="measurePolygon">侧面积</el-button>

2、编写点击事件

measurePolygon() {
      let _this = this;
      loadModules([
        "esri/Map",
        "esri/Color",
        "esri/symbols/SimpleLineSymbol",
        "esri/views/MapView",
        "esri/layers/TileLayer",
        "esri/views/draw/Draw",
        "esri/geometry/geometryEngine",
        "esri/geometry/Point",
        "esri/geometry/Polyline",
        "esri/geometry/Polygon",
        "esri/layers/GraphicsLayer",
        "esri/Graphic",
        "dojo/domReady!",
      ]).then(
          ([
             Map,
             Color,
             SimpleLineSymbol,
             MapView,
             TileLayer,
             Draw,
             GeometryEngine,
             Point,
             Polyline,
             Polygon,
             GraphicsLayer,
             Graphic,
           ]) => {
            let polygonLayer = _this.map.findLayerById("polygonLayer"); //绘制面图层
            if (!polygonLayer) {
              polygonLayer = new GraphicsLayer({
                id: "polygonLayer",
              }); //绘制线图层
            }

            //画面按钮事件
            let draw = new Draw({
              //在view里创建draw
              view: _this.view,
            });
            let action = draw.create("polygon"); //创建画线实例
            _this.view.focus();
            action.on(
                [
                  "vertex-add", // when a vertex is added  鼠标单击
                  "vertex-remove", // when a vertex is removed 移除
                  "cursor-update", // when the pointer moves 鼠标移动
                  "draw-complete", // when the drawing is completed 鼠标双击
                ],
                function (evt) {
                  createPolygon(evt.vertices);
                }
            );
            // };

            //画面和测量面积
            function createPolygon(vertices) {
              polygonLayer.removeAll();
              let symbol = {
                //点样式
                type: "simple-marker",
                color: [47, 79, 79],
                width: 0.5,
                size: 4,
                outline: {
                  color: [0, 0, 0],
                  width: 1,
                },
              };
              let fillSymbol = {
                //面样式
                type: "simple-fill", // autocasts as new SimpleFillSymbol()
                color: [3, 255, 240, 0.1],
                outline: {
                  // autocasts as new SimpleLineSymbol()
                  color: [255, 116, 3],
                  width: 2,
                },
              };

              let polygon = new Polygon({
                rings: vertices,
                spatialReference: _this.view.spatialReference,
              });

              let polygonGraphics = new Graphic({
                geometry: polygon,
                symbol: fillSymbol,
              });
              polygonLayer.add(polygonGraphics);
              let area = GeometryEngine.geodesicArea(polygon, "square-meters");
              let areaText = areaFormat(area);
              let center = polygon.centroid;
              let pointCenter = {
                type: "point",
                longitude: center.longitude,
                latitude: center.latitude,
              };
              let textSymbol = {
                //面积标注
                type: "text",
                color: "white",
                haloColor: "black",
                haloSize: "2px",
                text: areaText,
                //xoffset: '50px',
                //yoffset: '-5px',
                font: {
                  size: 12,
                  family: "sans-serif",
                  weight: "bold",
                },
              };
              let textGraphics = new Graphic({
                //标注为面中心位置
                geometry: pointCenter,
                symbol: textSymbol,
              });
              polygonLayer.add(textGraphics);

              for (let i = 0; i < vertices.length; i++) {
                let point = {
                  type: "point",
                  x: vertices[i][0],
                  y: vertices[i][1],
                  spatialReference: _this.view.spatialReference,
                };

                let pointGraphics = new Graphic({
                  geometry: point,
                  symbol: symbol,
                });
                polygonLayer.add(pointGraphics);
              }
              _this.map.layers.add(polygonLayer);
            }

            //面积单位转换
            function areaFormat(area) {
              let areaText;
              if (area < 2000) {
                area = area.toFixed(2);
                return (areaText = area + "平方米");
              } else {
                area = (area / 10000).toFixed(2);
                return (areaText = area + "平方千米");
              }
            }
          }
      );
    },

效果:

 

八、缩放

1、添加按钮的点击事件

<el-button @click="zoomOut">放大</el-button>
<el-button @click="zoomIn">缩小</el-button>

2、编写点击事件

zoomOut() {
      this.view.zoom++;
    },
    zoomIn() {
      this.view.zoom--;
    },

效果:

 

九、拖拽

1、添加按钮的点击事件

<el-button @click="drag">拖拽</el-button>

2、编写点击事件

drag(){
      this.dragFlag=!this.dragFlag;
      // 监听拖拽
      var that = this
      this.view.on("drag", function (event) {
        if (!that.dragFlag) {
          event.stopPropagation();
        }
      });
    }

设置初始值

// 初始化属性
data() {
    return {
        dragFlag: true,
        }
    }

效果

点击拖拽按钮可以进行切换

 

十、复位

1、添加按钮的点击事件

<el-button @click="resetSite">复位</el-button>

2、编写点击事件

// 复位
    resetSite() {
      let _this = this;
      loadModules([
        "esri/geometry/Extent",
        "esri/geometry/SpatialReference",
        "dojo/domReady!",
      ]).then(([Extent, SpatialReference]) => {
        var ext = new Extent({
          spatialReference: new SpatialReference({ wkid: 4326 }),
          xmin: 73.481382,
          ymin: 18.173515,
          xmax: 122.18916,
          ymax: 53.521718,
        });
        //中心坐标
        _this.view.center = [114.308786, 30.593342]
        _this.view.extent = ext;
      });
    },

3、mounted中创建地图

loadModules([
      'esri/layers/TileLayer',
      "esri/Map",
      "esri/views/MapView",
      "esri/geometry/Extent"]) // 传入需要使用的类
        .then(([TileLayer,Map, MapView,Extent]) => {
          var url =  "本地的底图服务器地址";
          this.layer = new TileLayer({
            url: url
          });
          this.map = new Map({
            layers: this.layer
          });
          this.view = new MapView({
            container: "map",
            map: this.map,
            // zoom: 6,
            extent: new Extent({
              spatialReference: {
                wkid: 4326,//坐标系
              },
              xmin: 73.481382,
              ymin: 18.173515,
              xmax: 122.18916,
              ymax: 53.521718,
            }),
            //中心坐标
            // center: [114.308786, 30.593342]
          })

          // this.view.map.ground.surfaceColor = "#FFB6C1";
          this.view.ui.remove("zoom"); //清除放大缩小按钮
          this.view.ui.remove("attribution"); //清除底部powered by ESRI
        })
        .catch(err => {
          console.error('地图初始化失败', err);
        })

注意:当你在Extent中设置了xmin、ymin、xmax、ymax后,还设置center的话,mounted中创建的地图时,center会有限覆盖xmin、ymin、xmax、ymax的配置。

效果:

当你放大如下所示:

点击复位按钮,效果如下:

十一、弹层Popup

右键点击地图任何地方弹出弹层

mounted() {
    loadModules([
      'esri/layers/TileLayer',
      "esri/Map",
      "esri/views/MapView",
      "esri/geometry/Extent"]) // 传入需要使用的类
        .then(([TileLayer,Map, MapView,Extent]) => {
          var url =  "本地地图服务器地址";
          this.layer = new TileLayer({
            url: url
          });
          this.map = new Map({
            layers: this.layer // 添加图层
          });
          this.view = new MapView({
            container: "map",
            map: this.map,
            // zoom: 6,
            extent: new Extent({
              spatialReference: {
                wkid: 4326,//美国WGS_84坐标系
              },
              xmin: 73.481382,
              ymin: 18.173515,
              xmax: 122.18916,
              ymax: 53.521718,
            }),
            //中心坐标
            // center: [114.308786, 30.593342]
          })

          // this.view.map.ground.surfaceColor = "#FFB6C1";
          this.view.ui.remove("zoom"); //清除放大缩小按钮
          this.view.ui.remove("attribution"); //清除底部powered by ESRI

          this.view.on('click', (result) => { // 单击事件
            const {
              longitude,
              latitude
            } = result.mapPoint
            this.view.popup.open({
              title: '标题',
              content: `<p>这是一段内容,经度:`+longitude+`纬度:`+latitude+`</p>`,
              location: result.mapPoint // 或 [longitude, latitude]
            })
          })
        })
        .catch(err => {
          console.error('地图初始化失败', err);
        })
  },

效果如下:

控制左键单击和右键单击显示不同的效果:

// 设置view.popup.autoOpenEnabled = false;后,鼠标的三个键都可以触发点击事件,没有任何设置,只有滚轮和右键会触发点击事件。
          this.view.popup.autoOpenEnabled = false; // autoOpenEnabled:Popup指示需要允许或禁止单击事件传播
          this.view.on('click', (result) => {
            //右键
            if (result.button == 2) {
              const {
                longitude,
                latitude
              } = result.mapPoint
              this.view.popup.open({
                title: '标题',
                content: `<p>这是右键单击弹出的一段内容,经度:`+longitude+`纬度:`+latitude+`</p>`,
                location: result.mapPoint // 或 [longitude, latitude]
              })
            }
            //左键
            if (result.button == 0) {
              const {
                longitude,
                latitude
              } = result.mapPoint

              this.view.popup.open({
                title: '标题',
                content: `<p>这是左键单击弹出的一段内容,经度:`+longitude+`纬度:`+latitude+`</p>`,
                location: result.mapPoint // 或 [longitude, latitude]
              })
            }
          })

注意:需要设置this.view.popup.autoOpenEnabled = false;,否则左键点击地图没有反应。效果如下:

点击事件的属性:

覆盖物弹层:点击了多边形才会弹框

mounted() {
    const map = new Map({
      basemap: 'dark-gray',
    })

    const mapView = new MapView({
      map,
      container: 'map',
      center: [102.92934063304513, 25.102234987110343],
      extent: {//初始化范围
        spatialReference: {
          wkid: 4326,//坐标系
        },
        xmin: 73.481382,
        ymin: 18.173515,
        xmax: 122.18916,
        ymax: 53.521718,
      },
    })

    const polygonGraphic = new Graphic({
      geometry: {
        type: "polygon",
        rings: [
          [
            [81.99385,41.423614],
            [84.311909,41.062564],
            [82.214617,38.363399],
            [81.99385,41.423614]
          ]
        ]
      },
      symbol: {
        type: "simple-fill",
        color: [227, 139, 79, 0.8],
        style: "solid",
        outline: {
          color: "red",
          width: 2
        }
      },
      attributes: {
        id: 'polygon_1'
      }
    })

    mapView.graphics.add(polygonGraphic)

    mapView.on('click', (e) => { // 单击事件
      mapView.hitTest(e).then((e2) => {
        e2.results.forEach(e3 => {
          let attrs = e3.graphic.attributes
          if(attrs.id === 'polygon_1') { // 判断是否点击了多边形图层
            mapView.popup.open({
              title: '标题',
              content: `<p>这是点击多边形才弹出的一段内容</p>`,
              location: e.mapPoint
            })
          }
        })
      })
    })
  }

点击检测 hitTest

返回与指定屏幕坐标相交的每个图层的 Hit Test 结果,结果以包含不同结果类型的数组组织。

以下图层类型将在检测到相交时返回所有特性:FeatureLayerCSVLayerGeoJSONLayerGeoRSSLayerGraphicsLayerKMLLayerMapNotesLayerOGCFeatureLayerStreamLayer 和 WFSLayer

VectorTileLayer 的 Hit Test 结果包含一个具有属性的图形,指示与屏幕点相交的矢量 tile 风格的图层 ID 和名称。对于实际特征的详细属性和空间信息,返回的结果中并没有提供。

MediaLayer 的 Hit Test 结果如果检测到相交的元素,则包含所有媒体元素。RouteLayer 的 Hit Test 结果如果检测到相交的元素,则包含所有路径元素。

常用于捕获覆盖物,精确点击对象。

mapView.on('click', (e) => {
  mapView.hitTest(e).then((e2) => {
    // ...
  })
})

效果如下

内置弹层:将弹层代码内置到多边形代码内

mounted() {
    const map = new Map({
      basemap: 'streets-vector',
    })

    const mapView = new MapView({
      map,
      container: 'map',
      center: [102.92934063304513, 25.102234987110343],
      extent: {//初始化范围
        spatialReference: {
          wkid: 4326,//坐标系
        },
        xmin: 73.481382,
        ymin: 18.173515,
        xmax: 122.18916,
        ymax: 53.521718,
      },
    })

    const polygonGraphic = new Graphic({
      geometry: {
        type: "polygon",
        rings: [
          [
            [81.99385,41.423614],
            [84.311909,41.062564],
            [82.214617,38.363399],
            [81.99385,41.423614]
          ]
        ]
      },
      symbol: {
        type: "simple-fill",
        color: [227, 139, 79, 0.8],
        style: "solid",
        outline: {
          color: "red",
          width: 2
        }
      },
      popupTemplate: {
        title: '标题',
        content: `<p>这是内置弹层中弹出的一段内容</p>`,
        overwriteActions: true // 覆盖现有的弹出操作
      }
    })

    mapView.graphics.add(polygonGraphic)
  }

鼠标左键点击,效果如下:

 

隐藏停靠控制按钮

停靠控制按钮如下:

代码如下:

mounted() {
    const map = new Map({
      basemap: 'streets-vector',
    })

    const mapView = new MapView({
      map,
      container: 'map',
      center: [102.92934063304513, 25.102234987110343],
      extent: {//初始化范围
        spatialReference: {
          wkid: 4326,//坐标系
        },
        xmin: 73.481382,
        ymin: 18.173515,
        xmax: 122.18916,
        ymax: 53.521718,
      },
    })

    const polygonGraphic = new Graphic({
      geometry: {
        type: "polygon",
        rings: [
          [
            [81.99385,41.423614],
            [84.311909,41.062564],
            [82.214617,38.363399],
            [81.99385,41.423614]
          ]
        ]
      },
      symbol: {
        type: "simple-fill",
        color: [227, 139, 79, 0.8],
        style: "solid",
        outline: {
          color: "red",
          width: 2
        }
      },
      popupTemplate: {
        title: '标题',
        content: `<p>这是内置弹层中弹出的一段内容</p>`,
        overwriteActions: true // 覆盖现有的弹出操作
      }
      // attributes: {
      //   id: 'polygon_1'
      // }
    })
    mapView.popup.dockOptions = {
      buttonEnabled: false,
    }
    mapView.graphics.add(polygonGraphic)
  }

效果如下:

 

十二、地图控件 - Widget

1、指南针

(1)、引入

import Compass from "@arcgis/core/widgets/Compass"

(2)、mounted中创建地图

mounted() {
    const map = new Map({
      basemap: 'streets-vector',
    })

    const mapView = new MapView({
      map,
      container: 'map',
      center: [102.92934063304513, 25.102234987110343],
      extent: {//初始化范围
        spatialReference: {
          wkid: 4326,//坐标系
        },
        xmin: 73.481382,
        ymin: 18.173515,
        xmax: 122.18916,
        ymax: 53.521718,
      },
    })
    const compass = new Compass({
      view: mapView,
    })
    mapView.ui.add(compass, {
      position: "top-right"
    })
  }

效果如下:

 

2、打印

(1)、引入

import Print from "@arcgis/core/widgets/Print.js"

(2)、mounted中创建地图

mounted() {
    const map = new Map({
      basemap: 'streets-vector',
    })

    const mapView = new MapView({
      map,
      container: 'map',
      center: [102.92934063304513, 25.102234987110343],
      extent: {//初始化范围
        spatialReference: {
          wkid: 4326,//坐标系
        },
        xmin: 73.481382,
        ymin: 18.173515,
        xmax: 122.18916,
        ymax: 53.521718,
      },
    })
    const print = new Print({
      view: mapView,
      printServiceUrl:
          "https://utility.arcgisonline.com/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export%20Web%20Map%20Task",
    })
    mapView.ui.add(print, {
      position: "top-right",
    })
  }

效果如下:

文件格式如下:

导出JPG效果如下:

 

3、缩放

缩放是默认地图UI控件,初始化 MapView 即存在,

不过也可以修改其显示位置。

mapView.ui.move('zoom', 'top-right')

效果如下:

十三、事件 - Event

1、单击事件

// 设置view.popup.autoOpenEnabled = false;后,鼠标的三个键都可以触发点击事件,没有任何设置,只有滚轮和右键会触发点击事件。
          this.view.popup.autoOpenEnabled = false; // autoOpenEnabled:Popup指示需要允许或禁止单击事件传播
          this.view.on('click', (result) => {
            //右键
            if (result.button == 2) {
              const {
                longitude,
                latitude
              } = result.mapPoint
              this.view.popup.open({
                title: '标题',
                content: `<p>这是右键单击弹出的一段内容,经度:`+longitude+`纬度:`+latitude+`</p>`,
                location: result.mapPoint // 或 [longitude, latitude]
              })
            }
            //左键
            if (result.button == 0) {
              const {
                longitude,
                latitude
              } = result.mapPoint

              this.view.popup.open({
                title: '标题',
                content: `<p>这是左键单击弹出的一段内容,经度:`+longitude+`纬度:`+latitude+`</p>`,
                location: result.mapPoint // 或 [longitude, latitude]
              })
            }
          })

2、鼠标移动事件

this.view.on("pointer-move", function (event) {// event.x和event.y为鼠标的坐标,通过下面的代码给mark-move类的标签设置样式,即跟着鼠标移动
            $(".mark-move").css({left: (event.x - 5), top: (event.y - 5), display: "block"});
          })

鼠标移动,就让mark-move类的块级标签跟着cursor光标走。

3、鼠标离开事件

this.view.on("pointer-leave", function (event) {
            $(".mark-move").css({display: "none"});
          });

光标离开地图,样式就消失。

 

posted on 2023-11-07 17:53  周文豪  阅读(4961)  评论(0编辑  收藏  举报