OpenLayers 3中的Popover叠加层不会超出视图范围

时间:2015-12-10 19:18:37

标签: javascript twitter-bootstrap-3 openlayers-3

在OpenLayers叠加示例中:

http://openlayers.org/en/v3.11.2/examples/overlay.html

如果您点击地图顶部附近,则会隐藏大部分叠加层。有没有CSS技巧,或OpenLayers设置(我不想使用autoPan,这似乎不适用于弹出窗口),这将使整个popover显示,即使它超出地图视图?

这是一个说明问题的屏幕截图。

enter image description here

4 个答案:

答案 0 :(得分:1)

autoPan适用于弹出广告,请参阅此处:http://openlayers.org/en/v3.11.2/examples/popup.html

但是,我在使用autoPan时遇到了一些麻烦,所以我就这样做了(Fiddle demo):

// move map if popop sticks out of map area:
var extent = map.getView().calculateExtent(map.getSize());
var center = map.getView().getCenter();
var pixelPosition = map.getPixelFromCoordinate([ coordinate[0], coordinate[1] ]);
var mapWidth = $("#map").width();
var mapHeight = $("#map").height();
var popoverHeight = $("#popup").height();
var popoverWidth = $("#popup").width();
var thresholdTop = popoverHeight+50;
var thresholdBottom = mapHeight;
var thresholdLeft = popoverWidth/2-80;
var thresholdRight = mapWidth-popoverWidth/2-130;
if(pixelPosition[0] < thresholdLeft || pixelPosition[0] > thresholdRight || pixelPosition[1]<thresholdTop || pixelPosition[1]>thresholdBottom) {
    if(pixelPosition[0] < thresholdLeft) {
        var newX = pixelPosition[0]+(thresholdLeft-pixelPosition[0]);
    } else if(pixelPosition[0] > thresholdRight) {
        var newX = pixelPosition[0]-(pixelPosition[0]-thresholdRight);
    } else {
        var newX = pixelPosition[0];
    }
    if(pixelPosition[1]<thresholdTop) {
        var newY = pixelPosition[1]+(thresholdTop-pixelPosition[1]);
    } else if(pixelPosition[1]>thresholdBottom) {
        var newY = pixelPosition[1]-(pixelPosition[1]-thresholdBottom);
    } else {
        var newY = pixelPosition[1];
    }
    newCoordinate = map.getCoordinateFromPixel([newX, newY]);   
    newCenter = [(center[0]-(newCoordinate[0]-coordinate[0])), (center[1]-(newCoordinate[1]-coordinate[1])) ]
    map.getView().setCenter(newCenter);
}

答案 1 :(得分:0)

我将此代码添加到此fiddle demo

中的Popover官方示例中
   $a = 10;
   echo number_format($a, 2);

答案 2 :(得分:0)

为使弹出窗口始终显示在地图视图中,我反转了ol3自动平移功能 这样,弹出窗口就会从要素向视图偏移,而不是平移视图。 我不确定为什么这么多ol3小提琴不再加载地图。

http://jsfiddle.net/bunjil/L6rztwj8/48/

  var getOverlayOffsets = function(mapInstance, overlay) {
  const overlayRect = overlay.getElement().getBoundingClientRect();
  const mapRect = mapInstance.getTargetElement().getBoundingClientRect();
  const margin = 15;
  // if (!ol.extent.containsExtent(mapRect, overlayRect)) //could use, but need to convert rect to extent
  const offsetLeft = overlayRect.left - mapRect.left;
  const offsetRight = mapRect.right - overlayRect.right;
  const offsetTop = overlayRect.top - mapRect.top;
  const offsetBottom = mapRect.bottom - overlayRect.bottom;
  console.log('offsets', offsetLeft, offsetRight, offsetTop, offsetBottom);

  const delta = [0, 0];
  if (offsetLeft < 0) {
    // move overlay to the right
    delta[0] = margin - offsetLeft;
  } else if (offsetRight < 0) {
    // move overlay  to the left
    delta[0] = -(Math.abs(offsetRight) + margin);
  }
  if (offsetTop < 0) {
    // will change the positioning instead of the offset to move overlay down.
    delta[1] = margin - offsetTop;
  } else if (offsetBottom < 0) {
    // move overlay up - never happens if bottome-center is default.
    delta[1] = -(Math.abs(offsetBottom) + margin);
  }
  return (delta);
};

/**
 * Add a click handler to the map to render the popup.
 */
map.on('click', function(evt) {
  var coordinate = evt.coordinate;
  var hdms = ol.coordinate.toStringHDMS(ol.proj.transform(
    coordinate, 'EPSG:3857', 'EPSG:4326'));

  content.innerHTML = '<p>You clicked here:</p><code>' + hdms +
    '</code>';

  //overlay.setPosition(coordinate);
  overlay.setOffset([0, 0]); // restore default
  overlay.setPositioning('bottom-right'); // restore default
  //overlay.set('autopan', true, false); //only need to do once.
  overlay.setPosition(coordinate);
  const delta = getOverlayOffsets(map, overlay);
  if (delta[1] > 0) {
    overlay.setPositioning('bottom-center');
  }
  overlay.setOffset(delta);
})

在这个小提琴中,setPositioning()不起作用,因此,当您单击顶部附近时,弹出式窗口位于鼠标下方-最好设置setPositioning('bottom-center');

automove将是很好的feature来补充自动平移功能。

答案 3 :(得分:0)

如果没有“ autoPan”选项的弹出框,则您必须检查范围的限制(顶部/底部/右侧-左侧被跳过,因为弹出框位于特征的中心右侧)。因此,可以将Jonatas Walker的先前答案扩展一点:

            var bs_element = $('.popover');
            var popup_height = bs_element.height();
            var popup_width = bs_element.width();
            var clicked_pixel = evt.pixel;
            var view = map.getView();
            var center = view.getCenter();

            var height_left = clicked_pixel[1] - popup_height / 2;  // from top
            var height_left2 = clicked_pixel[1] + popup_height / 2; // from bottom
            var width_left = clicked_pixel[0] + popup_width; // from right

            var center_px = map.getPixelFromCoordinate(center);
            var new_center_px = center_px;

            var needs_recenter = false;

            if (height_left2 > $("#map").height()) {
                new_center_px[1] = height_left2 - center_px[1] + 30;
                needs_recenter = true;
            }
            else if (height_left < 0) {
                new_center_px[1] = center_px[1] + height_left;
                needs_recenter = true;
            }

            if (width_left > $("#map").width()) {
                new_center_px[0] = width_left - center_px[0] + 30;
                needs_recenter = true;
            }

            if (needs_recenter)
                view.setCenter(map.getCoordinateFromPixel(new_center_px));