ArcGIS JS 学习笔记4 实现地图联动

Posted 好吃的益达

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ArcGIS JS 学习笔记4 实现地图联动相关的知识,希望对你有一定的参考价值。

1.开篇

      守望屁股实在太好玩了,所以最近有点懒,这次就先写个简单的来凑一下数。这次我的模仿目标是天地图的地图联动。

image

天地的地图联动不仅地图有联动,而且鼠标也有联动,我就照着这个目标进行山寨。

2.准备

      地图联动其实就是当一张的extent发生了变化,另一张图的extent也要同步变化,这样就可以两张图的范围同步了。同理,这样就可以扩展到N张图进行联动。所以这次的目标就是实现添加任意的地图都要可以联动。首先依然是先看一下官方文档。找到有用的方法或者事件。

image

image

image

image

image

     整体的难点在于如何判断主地图(有鼠标动作的地图),通过官方文档,我们可以利用mouse-over事件来进行主地图的判断,在添加地图时,监听每张地图的mouse-over事件。

3.开始山寨

  1 //添加地图,相互联动
  2 addMap: function (map) {
  3     var self = this;
  4     if (this._maps.indexOf(map) != -1)return;//如果已经在联动地图集合就不添加
  5     var graphicLayer=new GraphicLayer({id:"mapLinkagerLayer"});
  6     var mouseHandler= map.on("mouse-over", function (evt) {//鼠标在哪个地图上,该地图就是激活地图
  7         self.activeMap = map;
  8         self. _clearActiveMapEvents();
  9         self._bindActiveMapEvents();
 10     });
 11 
 12     var graphic=new Graphic();
 13     graphic.setSymbol(this.mouseSymbol);
 14     map.addLayer(graphicLayer);
 15     graphicLayer.add(graphic)
 16 
 17     this._maps.push(map);
 18     this._mapMouseOverEventHandlers.push(mouseHandler);
 19     this._mouseGraphicLayers.push(graphicLayer);
 20     this._mouseGraphics.push(graphic);
 21 },
 22 
View Code

这里self. _clearActiveMapEvents()就是清除上一个主地图的相关事件;在清除上一个的事件后利用self._bindActiveMapEvents()对当前地图进行事件的绑定。这两个方法的具体内容我会在后面详细介绍。graphicLayer就是为了实现鼠标联动。

  1  //清除当前地图联动事件
  2         _clearActiveMapEvents: function () {
  3             this._activeMapEventHandlers.forEach(function (eventHandler) {
  4                 eventHandler.remove();
  5             });
  6             this._activeMapEventHandlers = [];
  7         },
View Code

这里我们先清除上一个主地图的所有事件,我把这些事件都放到this._activeMapEventHandlers集合中。

  1  //为当前地图添加联动
  2         _bindActiveMapEvents: function () {
  3             var self = this;
  4             //放大联动
  5             this._activeMapEventHandlers.push(this.activeMap.on("zoom-end", function (evt) {
  6                 self._maps.forEach(function (map) {
  7                     if (map != self.activeMap) {
  8                         map.setExtent(evt.extent);
  9                     }
 10                 });
 11             }));
 12             //平移联动
 13             this._activeMapEventHandlers.push(this.activeMap.on("pan-end", function (evt) {
 14                 self._maps.forEach(function (map) {
 15                     if (map != self.activeMap) {
 16                         map.setExtent(evt.extent);
 17                     }
 18                 });
 19             }));
 20 
 21             //鼠标联动
 22             this._activeMapEventHandlers.push(this.activeMap.on("mouse-move", function (evt) {
 23                 self._maps.forEach(function (map) {
 24                     var idx = self._maps.indexOf(map);
 25                     var graphicLayer=map.getLayer("mapLinkagerLayer")
 26                     var graphic=self._mouseGraphics[idx];
 27                     if (map != self.activeMap) {
 28                         graphicLayer.show();
 29                         graphic.setGeometry(evt.mapPoint);
 30                     }else{
 31                         graphicLayer.hide();//激活地图不显示联动鼠标
 32                     }
 33                 });
 34             }));
 35         }
 36     });
View Code

在主地图平移和放大后,通过遍历_maps 集合,并利用事件提供的extent参数和map.setExtent()方法来设置地图的联动。鼠标的联动则是通过监听mouse-move事件,获取事件中的mapPoint参数来进行鼠标Graphic的定位。至此核心的部分已经全部完成了。

源码:

  1 /**
  2  * Created by Extra 
  3  * 地图联动辅助类
  4  * version:v1.0.0
  5  */
  6 define("dextra/modules/MapLinkager", [
  7     "dojo/_base/declare",
  8     "esri/layers/GraphicsLayer",
  9     "esri/graphic",
 10     "esri/symbols/SimpleMarkerSymbol"
 11 ], function ( declare,GraphicLayer,Graphic,SimpleMarkerSymbol) {
 12     var maplinkager = declare(null, {
 13         declaredClass: "dextra.modules.MapLinkager",
 14         _maps: null,//参与联动的地图控件集合
 15         _activeMapEventHandlers: null,//当前鼠标所在地图事件集合
 16         _mapMouseOverEventHandlers:null,//所有地图mouse-over事件集合
 17         _mouseGraphicLayers:null,//鼠标联动GraphicLayer
 18         activeMap: null,//当前激活地图
 19         mouseSymbol:null,//鼠标样式
 20         _mouseGraphics:null,//鼠标Graphic集合
 21 
 22         constructor: function () {
 23             this._maps = [];
 24             this._activeMapEventHandlers=[];
 25             this._mapMouseOverEventHandlers=[];
 26             this._mouseGraphicLayers=[];
 27             this.mouseSymbol=new SimpleMarkerSymbol({
 28                 "color": [255,0,0],
 29                 "size": 10,
 30                 "xoffset": 0,
 31                 "yoffset": 0,
 32                 "type": "esriSMS",
 33                 "style": "esriSMSCircle",
 34                 "outline": {
 35                     "color": [255,0,0],
 36                     "width": 1,
 37                     "type": "esriSLS",
 38                     "style": "esriSLSSolid"
 39                 }
 40             });
 41             this._mouseGraphics=[];
 42 
 43         },
 44 
 45         //添加地图,相互联动
 46         addMap: function (map) {
 47             var self = this;
 48             if (this._maps.indexOf(map) != -1)return;//如果已经在联动地图集合就不添加
 49             var graphicLayer=new GraphicLayer({id:"mapLinkagerLayer"});
 50             var mouseHandler= map.on("mouse-over", function (evt) {//鼠标在哪个地图上,该地图就是激活地图
 51                 self.activeMap = map;
 52                 self. _clearActiveMapEvents();
 53                 self._bindActiveMapEvents();
 54             });
 55 
 56             var graphic=new Graphic();
 57             graphic.setSymbol(this.mouseSymbol);
 58             map.addLayer(graphicLayer);
 59             graphicLayer.add(graphic)
 60 
 61             this._maps.push(map);
 62             this._mapMouseOverEventHandlers.push(mouseHandler);
 63             this._mouseGraphicLayers.push(graphicLayer);
 64             this._mouseGraphics.push(graphic);
 65         },
 66 
 67         //移除地图,取消联动
 68         removeMap: function (map) {
 69             var idx = this._maps.indexOf(map);
 70             this._maps.splice(idx, 1);
 71             var graphicLayer= this._mouseGraphicLayers.splice(idx, 1)[0];
 72             graphicLayer.clear();
 73             map.removeLayer(graphicLayer);
 74 
 75             this._mapMouseOverEventHandlers[idx].remove();
 76             this._mapMouseOverEventHandlers.splice(idx, 1);
 77             this._mouseGraphics.splice(idx, 1);
 78             this._clearActiveMapEvents();
 79 
 80         },
 81 
 82         //清除当前地图联动事件
 83         _clearActiveMapEvents: function () {
 84             this._activeMapEventHandlers.forEach(function (eventHandler) {
 85                 eventHandler.remove();
 86             });
 87             this._activeMapEventHandlers = [];
 88         },
 89 
 90         //为当前地图添加联动
 91         _bindActiveMapEvents: function () {
 92             var self = this;
 93             //放大联动
 94             this._activeMapEventHandlers.push(this.activeMap.on("zoom-end", function (evt) {
 95                 self._maps.forEach(function (map) {
 96                     if (map != self.activeMap) {
 97                         map.setExtent(evt.extent);
 98                     }
 99                 });
100             }));
101             //平移联动
102             this._activeMapEventHandlers.push(this.activeMap.on("pan-end", function (evt) {
103                 self._maps.forEach(function (map) {
104                     if (map != self.activeMap) {
105                         map.setExtent(evt.extent);
106                     }
107                 });
108             }));
109 
110             //鼠标联动
111             this._activeMapEventHandlers.push(this.activeMap.on("mouse-move", function (evt) {
112                 self._maps.forEach(function (map) {
113                     var idx = self._maps.indexOf(map);
114                     var graphicLayer=map.getLayer("mapLinkagerLayer")
115                     var graphic=self._mouseGraphics[idx];
116                     if (map != self.activeMap) {
117                         graphicLayer.show();
118                         graphic.setGeometry(evt.mapPoint);
119                     }else{
120                         graphicLayer.hide();//激活地图不显示联动鼠标
121                     }
122                 });
123             }));
124         }
125     });
126 
127     return maplinkager;
128 });
View Code

DEMO:

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>DExtra-HeatMap</title>
  6     <link rel="stylesheet" href="https://js.arcgis.com/3.16/esri/css/esri.css">
  7     <style>
  8         html, body, #map {
  9             padding: 0;
 10             margin: 0;
 11             height: 100%;
 12         }
 13     </style>
 14     <script>
 15         var dojoConfig = {
 16             parseOnLoad: true,
 17             packages: [{
 18                 name: \'custom\',
 19                 location: location.pathname.replace(/\\/[^/]+$/, \'\') + \'/custom\'//从cdn加载自己定义的模块方法
 20             },
 21                 {
 22                     name: \'dextra\',
 23                     location: \'/extra.arcgis.3.x/dist/\'//从cdn加载自己定义的模块方法
 24                 }]
 25         };
 26         console.log(location.pathname.replace(/\\/[^/]+$/, \'\'));
 27     </script>
 28 
 29     <script src="https://js.arcgis.com/3.16/"></script>
 30 
 31     <script>
 32         require([
 33             "dojo/_base/array",
 34             "dojo/on","dojo/dom",
 35             "esri/map",
 36             "esri/geometry/Point",
 37             "dextra/layers/GoogleVectorLayer",
 38             "dextra/layers/GoogleImageLayer",
 39             "dextra/layers/GoogleTerrienLayer",
 40             "dextra/modules/MapLinkager",
 41             "dojo/domReady!"], function (array,on,dom,Map, Point, GoogleVectorLayer, GoogleImageLayer,GoogleTerrienLayer,MapLinkager) {
 42             var map1 = new Map("map1", {
 43                 center: [102.8, 25.1],
 44                 zoom: 10,
 45             });
 46             var googleVecLayer = new GoogleVectorLayer();
 47             map1.addLayer(googleVecLayer);
 48 
 49 
 50             var map2 = new Map("map2", {
 51                 center: [102.8, 25.1],
 52                 zoom: 10,
 53             });
 54             var googleimageLayer = new GoogleImageLayer();
 55             map2.addLayer(googleimageLayer);
 56 
 57             var map3 = new Map("map3", {
 58                 center: [102.8, 25.1],
 59                 zoom: 10,
 60             });
 61             var googleterrienLayer = new GoogleTerrienLayer();
 62             map3.addLayer(googleterrienLayer);
 63 
 64             var mapLinker=new MapLinkager();
 65             mapLinker.addMap(map1);
 66             mapLinker.addMap(map2);
 67             mapLinker.addMap(map3);
 68 
 69 
 70             on(dom.byId("btn1"),"click",function(evt){
 71                 mapLinker.removeMap(map1);
 72             })
 73             on(dom.byId("btn2"),"click",function(evt){
 74                 mapLinker.removeMap(map2);
 75             })
 76 
 77             on(dom.byId("btn3"),"click",function(evt){
 78                 mapLinker.removeMap(map3);
 79             });
 80 
 81             on(dom.byId("btn4"),"click",function(evt){
 82                 mapLinker.addMap(map1);
 83             });
 84             on(dom.byId("btn5"),"click",function(evt){
 85                 mapLinker.addMap(map2);
 86             })
 87             on(dom.byId("btn6"),"click",function(evt){
 88                 mapLinker.addMap(map3);
 89             })
 90         });
 91 
 92 
 93     </script>
 94 </head>
 95 <body>
 96 <button id="btn1">Remove Map1</button>
 97 <button id="btn2">Remove Map2</button>
 98 <button id="btn3">Remove Map3</button>
 99 
100 <button id="btn4">Add Map1</button>
101 <button id="btn5">Add Map2</button>
102 <button id="btn6">Add Map3</button>
103 
104 
105 <div id="map1" style="width:49%;float:left"></div>
106 <div id="map2" style="width:49%; float:right"></div>
107 <div id="map3" style="width:49%; "></div>
108 </body>
109 </html>
View Code

有图有真相:

imageimage

demo的布局就请不要吐槽了。。。求放过。。。。

欢迎转载 http://www.cnblogs.com/deliciousExtra/p/5600212.html

以上是关于ArcGIS JS 学习笔记4 实现地图联动的主要内容,如果未能解决你的问题,请参考以下文章

ArcGIS JS 学习笔记4 实现地图联动

ArcGIS JS 学习笔记1 用ArcGIS JS 实现仿百度地图的距离量测和面积量测

ArcGIS JS 学习笔记1 用ArcGIS JS 实现仿百度地图的距离量测和面积量测

ArcGIS JS 学习笔记3 实现百度风格的BubblePopup

ArcGIS JS 学习笔记3 实现百度风格的BubblePopup

ArcGIS JS 学习笔记2 实现仿百度的拖拽画圆