OpenLayer3 之 实现拉框放大功能

来源:互联网 发布:选择linux内核启动 编辑:程序博客网 时间:2024/06/05 04:51

几天前,有人给我发邮件询问如何实现划定一个矩形区域实现放大功能,即所谓的“拉框放大”,在 ol3 中,其实已有实现鼠标拖拽放大地图功能,默认需要配合 shift,按住shift,拖拽鼠标的同时,地图会放大,该组件名为 ol.interaction.DragZoom,该组件的缺点是不实用(哪一个非专业人员会想的按住shift拖动)。本文首先介绍该组件的实现,随后基于该组件,在地图上放置拉框按钮,实现一个较为实用的拖拽放大功能。

本文完整代码共享在了GitHub中:https://github.com/QingyaFan/openlayers3-examples

ol.interaction.DragZoom

拉框放大,首先你要拉框,然后根据用户拉出的矩形区域放大到合适地图视口的最大级别。拉框也不必我们实现,ol3 也已经有实现:ol.interaction.DragBox,为了基于 dragbox 组件实现拉框,ol.interaction.DragZoom继承了ol.interaction.DragBox。具体实现如下:

// dragzoom 构造函数ol.interaction.DragZoom = function(opt_options) {  var options = opt_options ? opt_options : {};  // 触发拉框放大功能的情形  // 此处为按下 shift 键,mac 是 cmd 键  var condition = options.condition ? options.condition :  ol.events.condition.shiftKeyOnly;  // 放大过程的时间  this.duration_ = options.duration !== undefined ? options.duration : 200;  // 是放大还是缩小,默认放大  this.out_ = options.out !== undefined ? options.out : false;  // 调用 dragbox 的构造函数,并将样式赋予 dragbox,如果没有指定,默认 `ol-dragzoom`  ol.interaction.DragBox.call(this, {    condition: condition,    className: options.className || 'ol-dragzoom'  });};// 继承 dragzoomol.inherits(ol.interaction.DragZoom, ol.interaction.DragBox);

处理完拉框,那么当拉框结束时,需要获取用户框定的区域,并实现地图的缩放,这里利用了 dragbox 的 boxend 事件:

ol.interaction.DragZoom.prototype.onBoxEnd = function() {  // 获取 map 实例  var map = this.getMap();  var view = /** @type {!ol.View} */ (map.getView());  var size = /** @type {!ol.Size} */ (map.getSize());  // 获取用户框定的坐标范围  var extent = this.getGeometry().getExtent();  // 设置为拉框缩小时应进行的处理  if (this.out_) {    var mapExtent = view.calculateExtent(size);    var boxPixelExtent = ol.extent.createOrUpdateFromCoordinates([      map.getPixelFromCoordinate(ol.extent.getBottomLeft(extent)),      map.getPixelFromCoordinate(ol.extent.getTopRight(extent))]);    var factor = view.getResolutionForExtent(boxPixelExtent, size);    ol.extent.scaleFromCenter(mapExtent, 1 / factor);    extent = mapExtent;  }  var resolution = view.constrainResolution(view.getResolutionForExtent(extent, size));  var center = ol.extent.getCenter(extent);  center = view.constrainCenter(center);  // 设置缩放时动画效果  view.animate({    resolution: resolution,    center: center,    duration: this.duration_,    easing: ol.easing.easeOut  });};

实现拉框放大控件

在地图上放置拉框按钮,样式依赖了 bootstrap:

<div id="map" class="map">  <div class="x-zoom-icons">    <span id="zoom_in" class="glyphicon glyphicon-zoom-in"></span>  </div></div>

接下来初始化空间,并绑定触发事件:

var dragzoomActive = false;// 初始化一个拉框控件var dragZoom = new ol.interaction.DragZoom({  condition: ol.events.condition.always,  // out: true, // 此处为设置拉框完成时放大还是缩小});map.addInteraction(dragZoom);dragZoom.setActive(false);// 绑定放大缩小按钮事件document.querySelector("#zoom_in").addEventListener('click', function() {  if (dragzoomActive) {    dragZoom.setActive(false);    dragzoomActive = false;    document.querySelector("#map").style.cursor = "default";  } else {    dragZoom.setActive(true);    dragzoomActive = true;    document.querySelector("#map").style.cursor = "crosshair";  }}, false);

这样就可以很好的实现拉框放大,当然,如果你不喜欢默认的框样式,你可以修改,默认使用的 ol-dragzoom这个类名,你也可以在初始化时指定,这在上面的代码注释中说明了。实现的效果如下:


这里写图片描述

拉框后:


这里写图片描述

总结

实现起来还是很容易,不过这个交互组件并不能动态设置 out_ 属性,这样我们不得不实例化两个 dragzoom 实例,才能同时实现放大和缩小,有待改进,有时间看看能不能 push 一下。

好的,就这样。

本文完整代码共享在了GitHub中:https://github.com/QingyaFan/openlayers3-examples

1 0
原创粉丝点击