很多應用中都需要用到地圖聯動、多屏對比、二三維分屏、大屏顯示,有圖形可視化的地方就有事件響應觸發:鼠標按下、移動、鼠標滾輪,由此觸發了地圖上坐標或范圍的變化,將這些變化發送給另一個地圖並響應這些變化,即完成地圖聯動。
下面以二維地圖分屏和二三維地圖分屏分別說明實現思路(以ArcGIS開發為例,其他思路可參考)。
1、二維地圖分屏對比(地圖空間參考一般會一致)
1)頁面布局,將網頁布局設計成1~N個DIV;
2)事件監聽,對鼠標在地圖上的事件進行監聽,一個地圖事件觸發后,其他地圖響應。
※※※ MouseDown、MouseOver、MouseWheel,3個主要事件響應,對應地圖上pan-end、mouse-move、zoom-end,地圖聯動變化核心:【map.setExtent(evt.extent)】,參考代碼如下:
//放大聯動 this._activeMapEventHandlers.push(this.activeMap.on("zoom-end", function (evt) { self._maps.forEach(function (map) { if (map != self.activeMap) { map.setExtent(evt.extent); } }); })); //平移聯動 this._activeMapEventHandlers.push(this.activeMap.on("pan-end", function (evt) { self._maps.forEach(function (map) { if (map != self.activeMap) { map.setExtent(evt.extent); } }); })); //鼠標聯動 this._activeMapEventHandlers.push(this.activeMap.on("mouse-move", function (evt) { self._maps.forEach(function (map) { var idx = self._maps.indexOf(map); var graphicLayer = map.getLayer("layer") var graphic = self._mouseGraphics[idx]; if (map != self.activeMap) { graphicLayer.show(); graphic.setGeometry(evt.mapPoint); } else { graphicLayer.hide(); } }); }));
2、二三維分屏聯動對比
與二維相比,三維在地圖空間參考上具有差異性,三維地圖一般是WGS84、WGS84魔卡托,還有諸如國內火星坐標系(CGCS2000)等,會導致投影坐標存在投影轉換,二維平面坐標就是XY(另加Scale),三維立體坐標擁有XYZ(另加Scale),以及XYZ上的旋傾角,遵循右手笛卡爾坐標系,見下圖:
pitch是圍繞X軸旋轉,也叫做俯仰角;yaw是圍繞Y軸旋轉,也叫偏航角;roll是圍繞Z軸旋轉,也叫翻滾角。
由此可見,二三維聯動的核心:二維的中心(X,Y)+Scale(縮放系數),三維的“七參數”:(X,Y,Z,Pitch,Yaw,Roll,Scale(縮放系數)),轉換投影變動就能實現。
ArcGIS JS二三維聯動同步具體設計實現與二維類似,給出核心同步代碼參考:
var synchronizeView = function(view, others) { others = Array.isArray(others) ? others : [others]; var viewpointWatchHandle; var viewStationaryHandle; var otherInteractHandlers; var scheduleId; var clear = function() { if (otherInteractHandlers) { otherInteractHandlers.forEach(function(handle) { handle.remove(); }); } viewpointWatchHandle && viewpointWatchHandle.remove(); viewStationaryHandle && viewStationaryHandle.remove(); scheduleId && clearTimeout(scheduleId); otherInteractHandlers = viewpointWatchHandle = viewStationaryHandle = scheduleId = null; }; //鼠標事件監聽、動畫交互 var interactWatcher = view.watch('interacting,animation', function(newValue) { if (!newValue) { return; } if (viewpointWatchHandle || scheduleId) { return; } //同步聯動視圖(每個地圖的View),viewpoint:Camera,rotation,scale scheduleId = setTimeout(function() { scheduleId = null; viewpointWatchHandle = view.watch('viewpoint', function(newValue) { others.forEach(function(otherView) { otherView.viewpoint = newValue; }); }); }, 0); //視圖交互響應 otherInteractHandlers = others.map(function(otherView) { return watchUtils.watch(otherView, 'interacting,animation', function( value) { if (value) { clear(); } }); }); viewStationaryHandle = watchUtils.whenTrue(view, 'stationary', clear); }); return { remove: function() { this.remove = function() {}; clear(); interactWatcher.remove(); } } };
以上介紹了地圖開發中常用到的分屏對比實現思路,僅供參考。
版權聲明:歡迎轉載,轉載請說明出處。