在Leaflet上检测用户启动的平移/缩放操作

时间:2015-08-13 15:16:33

标签: javascript leaflet

我有一张Leaflet地图,用于位置共享。当用户共享其位置时,会在地图中添加显示其位置的标记,供所有其他用户查看。无论何时添加,移动或删除一个标记,它都会自动调整地图以显示所有标记。我还添加了一个自定义控件,可以打开和关闭自动调整行为。这一切都很好,但我还想使地图足够智能,以便在用户平移或缩放地图时自动关闭自动调整行为。

事实证明这非常困难,因为我无法找到一种好方法来区分用户是启动平移/缩放操作还是自动调整。我最初是在听panstart和zoomstart事件,但这些事件也是由自动调整触发的。我想我可以设置一个标志,告诉它在自动调整引起缩放/平移时不要关闭自动调整。我在关闭自动调整以响应panstart和zoomstart之前先检查此标志,然后在收到panend和zoomend时将其清除。

这似乎可以正常工作,直到发生自动调整,不会导致平移或缩放。让我们假设我们有一个大的自动拟合标记簇,并且中间的一个被移除。由于绑定框未更改,因此不会触发平移或缩放,因此不会清除告知其不关闭自动调整的标记。下次用户平移或缩放地图时,它不会像应该的那样关闭自动调整,因为它认为它仍然处于自动调整操作的中间。

如何在用户直接平移或缩放地图时可靠地关闭自动调整,但在通过其他方式平移或缩放时将其保持打开状态? < / p>

以下是相关代码:

var markers = [];        // Map markers are stored in this array.
var autoFit = true;      // Whether auto-fit is turned on
var lockAutoFit = false; // Temporarily lock auto-fit if true
var map;                 // Leaflet map object

function initMap() {
    // Leaflet map initialized here
    map.on('movestart zoomstart', function() {
        if (!lockAutoFit) {
            autoFit = false;
        }
    });
    map.on('moveend zoomend', function() {
        lockAutoFit = false;
    });
}

function toggleAutoFit() {
    autoFit = !autoFit;

    if (autoFit) {
        lockAutoFit = true;
        fitMap();
    }
}

function addOrUpdateMarker(marker, coords) {
    lockAutoFit = true;
    // do the marker update here
    fitMap();
}

function removeMarker(marker) {
    lockAutoFit = true;
    // remove the marker here
    fitMap();
}

// Pans and zooms the map so that all markers fit in the map view.
// Invoked whenever a marker is added, moved or deleted, or when
// the user turns on auto-fit.
function fitMap() {
  if (!autoFit || !markers.length) {
    return;
  }

  map.fitBounds(new L.featureGroup(markers).getBounds());
}

4 个答案:

答案 0 :(得分:4)

我最终围绕fitBoundssetView来电设置了一个标记,例如:

isProgramaticZoom = true
map.fitBounds(new L.featureGroup(markers).getBounds());
isProgramaticZoom = false

然后关闭自动调整的代码:

map.on('zoomstart', function() {
  if (!isProgramaticZoom) {
    //turn off auto-fit
  }
})

map.on('dragstart', function() {
  //turn off auto-fit
})

不幸的是,仍然不理想,但应该做的伎俩

答案 1 :(得分:0)

你可以使用drag,dragstart,dragend - 至少对于地图平移。对于地图缩放,我认为没有这样的等价物。

答案 2 :(得分:0)

这是一个古老的问题,但正如我最近发现的那样,我认为它仍然足够相关,因此一个解决方案值得给予。

我遵循了这个解决方案:Leaflet User Triggered Events

使用:

map.on('dragstart', function (e) {
    if (e.hard) {
        // moved by bounds
    } else {
       // moved by drag/keyboard
    }
});

无证件的e.hard部分是解决方案;评论不言而喻。

另外,您可能希望使用moveend代替dragstart

答案 3 :(得分:-1)

Leaflet reference表示它有@classmethod def from_crawler(cls, crawler, *args, **kwargs): o = cls(*args, **kwargs) crawler.signals.connect(o.spider_closed, signal=signals.spider_closed) return o zoomstartzoomend个事件。