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 结果,结果以包含不同结果类型的数组组织。
以下图层类型将在检测到相交时返回所有特性:FeatureLayer
、CSVLayer
、GeoJSONLayer
、GeoRSSLayer
、GraphicsLayer
、KMLLayer
、MapNotesLayer
、OGCFeatureLayer
、StreamLayer
和 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"}); });
光标离开地图,样式就消失。