【学习笔记之Openlayers3】补充篇之鹰眼控件(OverviewMap)

本篇文章主要讲关于Openlayers3中鹰眼控件或者说鸟瞰图控件(ol.control.OverviewMap)不显示以及不能实现通过拖动控件中区域使主地图也跟着移动的解决方法。

一、加载OverviewMap控件

有人曾经遇见过加载了控件,但是控件打开却是一片空白,对比官网的例子看是一样的,但是官网显示,自己的却没有显示,不知道是什么原因。这种情况有两种:在线地图和离线的瓦片地图。
使用在线地图数据源(ol.source.OSM,必应地图或者谷歌地图的数据源)一般情况不会出现鹰眼控件中空白的情况
使用离线地图资源(自己用Geoserver或者GeoWebCache发布的资源)可能会出现下面这种情况:
情况图片
这种情况有可能是因为你主地图和鹰眼图的坐标系不同导致的。上图就是我主地图用的EPSG:4326坐标系,而鹰眼图使用的是默认的,就会导致其实鹰眼图显示出来了,但是位置与主地图不对应,可能跑到哪一片汪洋中,所以会变成蓝色。离线地图也是一样,因为离线地图的切片不是范围内的都是白色,所以看到的是白色,让我们错认为没显示。当主地图坐标系使用默认的时候。如图:
更改后
都采用Openlayers3默认的墨卡托坐标系,鹰眼地图就会显示出来了。
基本上在线资源地图是没问题了,如果离线地图还是显现不出来,那我只能把我杀手锏交给你了(其实就是最后的解决方案)。通过官方文档:
官方API
在OverviewMap中可以添加参数layers,官方给出的是:如果不设置会使用主地图的layers,这里我们可以将我们离线的瓦片地图资源的layer加入到这个参数里面就行了。
鹰眼图加layer
上图是以在线资源为例,你可以将数据源换成自己GeoServer或者GeoWebCache发布的底图地址即可。

针对坐标系不同导致的鹰眼图,可能有小伙伴想说:我就不想用默认的坐标系,想用自己的坐标系进行展示怎么办?
其实这个也好办,看到OverviewMap中的view参数了吗?有些机智的小伙伴或许已经猜到了,你猜的不错,在view里我们可以设置鹰眼图的坐标系。如图:
设置View
这样我们就能保证坐标系一致了。我自己遇到的以及自己的解决方案都在这里了。希望能够帮到遇见这种问题的人。

二、关于鹰眼图无法拖动的解决方法

    我使用的openlayers版本是:3.19版本的,发表这篇博文的时候官方已经发布了3.20.1版本。但从官方示例中依然没能解决鹰眼图无法拖动的问题。现将我自己实现的方法写在这里,希望能够帮助各位小伙伴,也为自己方法记录一下,以便后期回顾(或许后期官方会将这个问题解决的,期待官方后面的更新吧)

其实当初做的时候也百度了很多,但是一直没找到解决方案。然后想到了万能的谷歌,所以特地去墙外查了一下,果然功夫不负有心人找到了相关的资料。资料原文地址

    不得不说stackoverflow是个很好的网站,这里面总是能找到自己想找的解决方案。

链接中的回答者是自己写了一个新的控件去实现可拖动的鹰眼图。当时看见他把对应的JS都贴出来,真是激动得要命(哈哈,只要将代码复制过去这个问题就能解决了,好开森)。但是我将代码拷贝到自己的项目中去,然后添加这个控件,发现并不能使用。可能还需要更改其他设置吧,但奈何自己技术水平不高,不知道怎么搞。然后我就想到将两个控件进行比较。发现了其中的奥妙所在:
增加的方法

相比ol-debug.js中的OverviewMap多了三个方法:onStartDrag,onDrag,onEndDrag。正是这三个方法解决了无法鹰眼图拖动的问题。然后我就讲这些方法做了一些调整加入到ol-debug.js中的OverviewMap中,果然鹰眼图可以拖动并且拖动时主地图也会跟着动,基本上实现了我想要的结果。下面把代码贴出来:

1.先在构造OverviewMap 控件的时候注册这三个事件

ol.control.OverviewMap = function(opt_options) {

  var options = opt_options ? opt_options : {};

  /**
   * @type {boolean}
   * @private
   */
  this.collapsed_ = options.collapsed !== undefined ? options.collapsed : true;

  /**
   * @private
   * @type {boolean}
   */
  this.collapsible_ = options.collapsible !== undefined ?
      options.collapsible : true;

  if (!this.collapsible_) {
    this.collapsed_ = false;
  }

  var className = options.className !== undefined ? options.className : 'ol-overviewmap';

  var tipLabel = options.tipLabel !== undefined ? options.tipLabel : 'Overview map';

  var collapseLabel = options.collapseLabel !== undefined ? options.collapseLabel : '\u00AB';

  if (typeof collapseLabel === 'string') {
    /**
     * @private
     * @type {Node}
     */
    this.collapseLabel_ = document.createElement('span');
    this.collapseLabel_.textContent = collapseLabel;
  } else {
    this.collapseLabel_ = collapseLabel;
  }

  var label = options.label !== undefined ? options.label : '\u00BB';


  if (typeof label === 'string') {
    /**
     * @private
     * @type {Node}
     */
    this.label_ = document.createElement('span');
    this.label_.textContent = label;
  } else {
    this.label_ = label;
  }

  var activeLabel = (this.collapsible_ && !this.collapsed_) ?
      this.collapseLabel_ : this.label_;
  var button = document.createElement('button');
  button.setAttribute('type', 'button');
  button.title = tipLabel;
  button.appendChild(activeLabel);

  ol.events.listen(button, ol.events.EventType.CLICK,
      this.handleClick_, this);

  var ovmapDiv = document.createElement('DIV');
  ovmapDiv.className = 'ol-overviewmap-map';

  /**
   * @type {ol.Map}
   * @private
   */
  this.ovmap_ = new ol.Map({
    controls: new ol.Collection(),
    interactions: new ol.Collection(),
    target: ovmapDiv,
    view: options.view
  });
  var ovmap = this.ovmap_;

  if (options.layers) {
    options.layers.forEach(
        /**
       * @param {ol.layer.Layer} layer Layer.
       */
        function(layer) {
          ovmap.addLayer(layer);
        }, this);
  }

  var box = document.createElement('DIV');
  box.className = 'ol-overviewmap-box';
  box.style.boxSizing = 'border-box';

  /**
   * @type {ol.Overlay}
   * @private
   */
  this.boxOverlay_ = new ol.Overlay({
    position: [0, 0],
    positioning: ol.Overlay.Positioning.BOTTOM_LEFT,
    element: box
  });
  this.ovmap_.addOverlay(this.boxOverlay_);

  var cssClasses = className + ' ' + ol.css.CLASS_UNSELECTABLE + ' ' +
      ol.css.CLASS_CONTROL +
      (this.collapsed_ && this.collapsible_ ? ' ol-collapsed' : '') +
      (this.collapsible_ ? '' : ' ol-uncollapsible');
  var element = document.createElement('div');
  element.className = cssClasses;
  element.appendChild(ovmapDiv);
  element.appendChild(button);

  var render = options.render ? options.render : ol.control.OverviewMap.render;

  ol.control.Control.call(this, {
    element: element,
    render: render,
    target: options.target
  });

  /* 下面代码为解决鹰眼图无法拖动而添加*/
  this.dragging = null;
  box.addEventListener("mousedown",this.onStartDrag.bind(this));
  $(document.body).on("mousemove", this.onDrag.bind(this));    
  $(document.body).on("mouseup", this.onEndDrag.bind(this));
};

2.添加这三个事件的实现方法:

ol.control.OverviewMap.prototype.onStartDrag = function (e) {
    // remember some data to use during onDrag or onDragEnd
    var box = $(e.target);
    this.dragging = {
        el: box,
        evPos: { top: e.pageY, left: e.pageX },
        elPos: box.offset()
    };
};

ol.control.OverviewMap.prototype.onDrag = function (e) {
    if (this.dragging) {
        //set the position of the box to be oldPos+translation(ev)
        var curOffset = this.dragging.el.offset();
        var newOffset = {
            top: curOffset.top + (e.pageY - this.dragging.evPos.top),
            left: curOffset.left + (e.pageX - this.dragging.evPos.left)
        };
        this.dragging.evPos = { top: e.pageY, left: e.pageX };
        this.dragging.el.offset(newOffset);
    }
};

ol.control.OverviewMap.prototype.onEndDrag = function (e) {
    if (this.dragging) {
        //see ol3.qtibia.ro href at the top of the class to understand this
        var map = this.getMap();
        var offset = this.dragging.el.position();
        var divSize = [this.dragging.el.width(), this.dragging.el.height()];
        var mapSize = map.getSize();
        var c = map.getView().getResolution();
        var xMove = offset.left * (Math.abs(mapSize[0] / divSize[0]));
        var yMove = offset.top * (Math.abs(mapSize[1] / divSize[1]));
        var bottomLeft = [0 + xMove, mapSize[1] + yMove];
        var topRight = [mapSize[0] + xMove, 0 + yMove];
        var left = map.getCoordinateFromPixel(bottomLeft);
        var top = map.getCoordinateFromPixel(topRight);
        var extent = [left[0], left[1], top[0], top[1]];        
        map.getView().fit(extent, map.getSize());
        map.getView().setResolution(c);
        //reset the element at the original position so that when the main map will trigger
        //the moveend event, this event will be replayed on the box of the minimap
        this.dragging.el.offset(this.dragging.elPos);
        this.dragging = null;
    }
};

猜你喜欢

转载自blog.csdn.net/u013420816/article/details/53868905