传单:在光标位置而不是 LineString 中心打开弹出窗口

Leaflet: open popup at cursor position instead of LineString center

我有一张带有 LineString 的传单地图。

// a GeoJSON LineString
var geojson = {
  "type": "Feature",
  "geometry": {
    "type": "LineString",
    "coordinates": [[-101.123, 40.2500], [-101.123, 40.2503]]
  }
};

// create map and add json
var map = L.map('map');
var geojsonLayer = new L.GeoJSON(geojson).addTo(map);
map.fitBounds(geojsonLayer.getBounds())

// add popup for the line
geojsonLayer.eachLayer(function (layer) {
  var popup = L.popup();
  popup.setContent('text');

  layer.bindPopup(popup);
  layer.on('click mouseover', function () {
    layer.openPopup();
  });
});

当我越过它时,会在 LineString 中心打开一个弹出窗口。

如何让它在光标位置打开?

这是一个简单的工作示例:http://jsfiddle.net/wuu8Lv2t/1/

不要让层打开弹出窗口,而是使用 openOn(map) 设置事件坐标的位置 e.latlng

// add popup for the line
geojsonLayer.eachLayer(function (layer) {
  var popup = L.popup();
  popup.setContent('text');
  layer.bindPopup(popup);

  layer.on('mouseover', function (e) {
    var popup = e.target.getPopup();
    popup.setLatLng(e.latlng).openOn(map);
  });

  layer.on('mouseout', function(e) {
     e.target.closePopup();
  });

  layer.on('mousemove', function (e) {
    e.target.closePopup();
    var popup = e.target.getPopup();
    popup.setLatLng(e.latlng).openOn(map);
  });
});

请注意,在您的问题中有一个错误:您不能在事件处理程序中使用变量 layer,您必须使用 e.target(参见 doc)。

这里是an answer from Per Liedman,一个传单维护者:

You can achieve this by creating a new popup and adding at the desired location, instead of binding it. Since a bound popup can be opened by other means than a mouse click, it can't know where to open.

这里是对应的代码:

// a GeoJSON LineString
var geojson = {
  "type": "Feature",
  "geometry": {
    "type": "LineString",
    "coordinates": [[-101.123, 40.2500], [-101.123, 40.2503]]
  }
};

// create map and add json
var map = L.map('map');
var geojsonLayer = new L.GeoJSON(geojson).addTo(map);
map.fitBounds(geojsonLayer.getBounds())

// add popup for the line
geojsonLayer.eachLayer(function (layer) {

  layer.on('click mouseover', function (e) {
    var popup = L.popup()
        .setLatLng(e.latlng)
        .setContent('text')
        .openOn(map);
  });
});

修改示例见此处:http://jsfiddle.net/uwdnvfy6/

接受的答案(来自@YaFred)非常好,关键是更新功能layer.on('mousemove'...。但是,正如所写的那样,每次鼠标移动时关闭和打开弹出窗口都会使其闪烁。相反,在 layer.('mousemove... 中,您只需要更新位置的行:

// add popup for the layer
geojsonLayer.eachLayer(function (layer) {
  var popup = L.popup();
  popup.setContent('text');
  layer.bindPopup(popup);

  layer.on('mouseover', function (e) {
    var popup = e.target.getPopup();
    popup.setLatLng(e.latlng).openOn(map);
  });

  layer.on('mouseout', function(e) {
     e.target.closePopup();
  });

  // update popup location
  layer.on('mousemove', function (e) {
    popup.setLatLng(e.latlng).openOn(map);
  });
});