OpenLayers 6 中实现“上一视图”、“下一视图”的视图切换功能,类似arcgis for js的Navigation

需求:

需要用OpenLayers实现视图切换,即在某一视图下,可以保存当前的视图状态,经过平移/缩放等改变视图的操作之后,通过点击按钮等交互动作可以回到上一视图,并且能够按顺序在保存的视图之间按顺序逐个切换。

分析:

核心部分是view状态的处理,实际只需要保存对应视图的extent即可。
视图的切换可以通过view.fit(extent)实现。
难点在视图状态的保留与切换,需要维护一个队列,并实现交互的逻辑。

实现:

难点的交互部分用了一个现成的轮子:ol-ext

ol-ext提供了一个扩展的interaction类:ol.interaction.UndoRedo,它维护了一个状态队列和位置指针,可以通过API实现对队列中的状态进行访问,并通过自定义的undo、redo函数实现操作的撤销跟回滚。

另外我还用了一个ol-ext中的按钮控件,用作界面交互操作(用法略)。

UndoRedo组件跟ol原生的其他组件用法类似:

	var undoInteraction = new ol.interaction.UndoRedo();
		map.addInteraction(undoInteraction);

然后向地图上添加按钮控件:

    var bar = new ol.control.Bar({
    			group: true,
    			controls: [
    				new ol.control.Button({
    					html: '<i class="fa fa-undo" ></i>',
    					title: '上一视图',
    					handleClick: function () {
    						undoInteraction.undo();
    					}
    				}),
    				new ol.control.Button({
    					html: '<i class="fa fa-repeat" ></i>',
    					title: '下一视图',
    					handleClick: function () {
    						undoInteraction.redo();
    					}
    				}),
    				new ol.control.Button({
    					html: '<i class="fa fa-save" ></i>',
    					title: '保存当前视图',
    					handleClick: function () {
    						saveExtent();
    					}
    				}),
    			]
    		});
    		mainbar.addControl(bar);

undoInteraction.undo()和 undoInteraction.redo()就是UndoRedo组件实现“上一步”“下一步”的API。按钮控件就很简单了,略过不谈。

接下来核心部分是逻辑处理:

    var extent = map.getView().calculateExtent(map.getSize());
    		undoInteraction.define(
    			'extent',
    			function (s) {
    				extent = s.before;
    				map.getView().fit(extent, {
    					nearest: true,
    					duration: 1000,
    					easing: ol.easing.easeOut
    				});
    			},
    			function (s) {
    				extent = s.after;
    				map.getView().fit(extent, {
    					nearest: true,
    					duration: 1000,
    					easing: ol.easing.easeOut
    				});
    			}
    		);
     
    		function saveExtent() {
    			var before = extent.slice();
    			extent = map.getView().calculateExtent(map.getSize())
    			// use blockStart / blockEnd to stack many undo in a same action
    			// undoInteraction.blockStart();
    			// Add undo style action
    			if(!ol.extent.equals(before, extent))
    			undoInteraction.push("extent", {
    				before: before,
    				after: extent
    			});
    			// undoInteraction.blockEnd();
    		}
    		saveExtent();

ol.interaction.UndoRedo的“驱动”部分是这样一个结构:

ol.interaction.UndoRedo.define("key", function undo(s), function redo(s))

需要保存状态的时候,要调用:

ol.interaction.UndoRedo.push("key",{

before:<beforeStatus>

after:<afterStatus>

})

传入undo和redo的参数s是一个状态指针,包含了相对当前状态的前一状态和后一状态;

保存当前状态的saveExtent()中,要做的事情是将变化前的extent保存给before,当前状态保存为after。

逻辑还是比较简单的。
全部代码:

 更多请见:http://www.mark-to-win.com/tutorial/175097.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值