我们可以让 ol.Overlay 在 OpenLayers 3 上可拖动吗?

Can we make ol.Overlay draggable on OpenLayers 3?

我正在尝试使 ol.overlay 可拖动,但我做不到。我找到了这个示例 (http://openlayers.org/en/v3.2.1/examples/drag-features.html?q=drag),但它是使用 ol.Features 完成的,我需要的是一个叠加层,因为我可以使用自定义 -html div-显示我需要的东西。我还找到了一个非常有趣的例子,它可以做我想做的事,但它是使用 google maps v3 完成的,我需要它用于 ol3。
提前致谢。

更新:

不需要这种 ol.Map.prototype.forEachOverlayAtPixel 方法(参见 https://github.com/openlayers/ol3/issues/5760)。

只需在 DOM 覆盖元素上注册一个 mousedown 侦听器即可。 Fiddle updated.


ol.Overlay 在 OL3 中是一个糟糕的类型,但通过一些工作,是的,你可以实现它。 ol.Feature是无所不能的,如果你真的需要ol.Overlay我想出了这个demo fiddle.

想法是:

  • 侦听pointerdown地图事件并检查点击像素处是否有叠加层;

    • ol.Map.prototype.forEachOverlayAtPixel - 刚刚为问题
    • 创建
  • 停用 ol.interaction.DragPan - 地图平移;

  • 监听pointermove并设置叠加位置;

  • 监听 pointerup 并恢复 ol.interaction.DragPan;

您可以简单地在叠加层 div 上注册一个 'mousedown' 事件侦听器。在该侦听器中,在 window 上注册 'mousemove' 和 'mouseup' 事件。要更新 'mousemove' 上的位置,请使用 ol.Map#getEventPixel() 方法,该方法将 'mousemove' 事件作为参数。在 'mouseup',您只需注销 window 个侦听器。

marker_el.addEventListener('mousedown', function(evt) {
  function move(evt) {
    marker.setPosition(map.getEventCoordinate(evt));
  }
  function end(evt) {
    window.removeEventListener('mousemove', move);
    window.removeEventListener('mouseup', end);
  }
  window.addEventListener('mousemove', move);
  window.addEventListener('mouseup', end);
});

有关工作示例,请参阅 http://jsfiddle.net/rnzgfg89/6/

我想在讨论中补充一点。我喜欢 Jonatas 的解决方案,但如果叠加层不是很小,它会跳动一点,除非你在叠加层的中心准确点击,所以我通过找到点击和当前位置之间的距离来改进他的解决方案覆盖元素。然后在设置位置时使用这些距离,以便鼠标在叠加层上的位置不会随着您拖动叠加层而改变。

let deltaX, deltaY

const getAdjustedCoords = coordinate => {
  const resultCoord = [coordinate[0] - deltaX, coordinate[1] - deltaY] 
  return resultCoord
}

marker_el.addEventListener('mousedown', function(evt) {
  dragPan.setActive(false);
  let markerpos = marker.getPosition();
  let clickPixel = [evt.x, evt.y]
  let clickCoords = map.getCoordinateFromPixel(clickPixel)
  
  deltaX = clickCoords[0] - markerpos[0]
  deltaY = clickCoords[1] - markerpos[1]
  marker.set('dragging', true);
  console.info('start dragging');
});

map.on('pointermove', function(evt) {
  if (marker.get('dragging') === true) {
    marker.setPosition(getAdjustedCoords(evt.coordinate));
  }
});

map.on('pointerup', function(evt) {
  if (marker.get('dragging') === true) {
    console.info('stop dragging');
    dragPan.setActive(true);
    marker.set('dragging', false);
  }
});

这是我的 fiddle:https://jsfiddle.net/sxc24re8/

干杯!