取消可编辑折线的顶点拖动

Cancel vertex drag for an editable polyline

我正在使用 Leaflet.Editable 插件并试图确定当用户单击线的第一个或最后一个点时我是否可以取消多段线拖动操作。我只希望他们能够沿着线拖动'mid-points',线的末端需要保持在原来的位置。

我看过 editable:vertex:dragstart 活动,但这似乎不允许我取消活动。我认为这是因为传递给此事件处理程序的参数不是 cancelablevertexevent 类型,因此没有我可以调用的 cancel() 方法。

有点击和 editable:vertex:clickeditable:vertex:rawclick 事件,但这些事件在 dragstart 事件之后触发(它们会触发,因为您需要释放鼠标按钮!)

我尝试在给定条件下在我的处理程序中返回 false

section.on('editable:vertex:dragstart', (e) => {
    if(e.vertex.latlngs[0] === e.vertex.latlng) {
        return false;
    }
});

但这行不通,有人知道这是否可行或我需要在这里做什么吗?

您可以禁用所需顶点上的可拖动功能,而不是取消事件。要在定义为

的可编辑折线上实现这一点
var section = L.polyline(/* your coords */).addTo(map);
section.enableEdit();

抓住第一个和最后一个点:

var coords = section.getLatLngs();
var disabled = [coords[0], coords[coords.length-1]];

并且,由于顶点继承自 L.Marker,您可以调用 vertex.dragging.disable(); :

disabled.forEach(function(latlng) {
    var vertex = latlng.__vertex;
    vertex.dragging.disable();
});

最后,一个演示

var startPoint = [43.1, 1.2];
var map = L.map('map', {editable: true}).setView(startPoint, 9),
    tilelayer = L.tileLayer('http://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png', {maxZoom: 11, attribution: 'Data \u00a9 <a href="http://www.openstreetmap.org/copyright"> OpenStreetMap Contributors </a> Tiles \u00a9 HOT'}).addTo(map);


var section = L.polyline([[43.0, 1.15], [43.1, 1.2], [43.2, 1.5],[43.25, 1.2]]).addTo(map);
section.enableEdit();

var coords = section.getLatLngs();
var disabled = [coords[0], coords[coords.length-1]];
// icon from http://www.iconarchive.com/show/vista-map-markers-icons-by-icons-land/Map-Marker-Chequered-Flag-Right-Chartreuse-icon.html
var goalpost = L.icon({
    iconUrl: 'http://icons.iconarchive.com/icons/icons-land/vista-map-markers/24/Map-Marker-Chequered-Flag-Right-Chartreuse-icon.png',
    iconSize: [24, 24],
    iconAnchor: [0, 24],
});
disabled.forEach(function(latlng) {
    var vertex = latlng.__vertex;
    vertex.dragging.disable();
    vertex.setIcon(goalpost);
});
html, body {
    height: 100%;
    margin: 0;
}
#map {
    width: 100%;
    height: 100%;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.1/leaflet.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.1/leaflet.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-editable/1.1.0/Leaflet.Editable.min.js"></script>
<div id='map'></div>


或者如果您觉得使用内部 属性 太危险,您可以扩展 L.Editable.PolylineEditor 以覆盖负责创建顶点的方法并将其传递给您的折线:

var AnchoredPolylineEditor = L.Editable.PolylineEditor.extend({
    addVertexMarker: function (latlng, latlngs, opts) {
        return new this.tools.options.vertexMarkerClass(latlng, latlngs, this, opts || {});
    },
    addVertexMarkers: function (latlngs) {
        for (var i = 0, l = latlngs.length; i < l; i++) {
            this.addVertexMarker(latlngs[i], latlngs, {
                draggable: (i>0) && (i<l-1)
            });
        }
    }
});

var section = L.polyline([[43.0, 1.15], [43.1, 1.2], [43.2, 1.5],[43.25, 1.2]], {
    editorClass: AnchoredPolylineEditor
}).addTo(map);
section.enableEdit();

还有一个演示

var startPoint = [43.1, 1.2];
var map = L.map('map', {editable: true}).setView(startPoint, 9),
    tilelayer = L.tileLayer('http://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png', {maxZoom: 11, attribution: 'Data \u00a9 <a href="http://www.openstreetmap.org/copyright"> OpenStreetMap Contributors </a> Tiles \u00a9 HOT'}).addTo(map);
    
    
var AnchoredPolylineEditor = L.Editable.PolylineEditor.extend({
    addVertexMarker: function (latlng, latlngs, opts) {
        return new this.tools.options.vertexMarkerClass(latlng, latlngs, this, opts || {});
    },
    addVertexMarkers: function (latlngs) {
        for (var i = 0, l = latlngs.length; i < l; i++) {
            this.addVertexMarker(latlngs[i], latlngs, {
                draggable: (i>0) && (i<l-1)
            });
        }
    }
});

var section = L.polyline([[43.0, 1.15], [43.1, 1.2], [43.2, 1.5],[43.25, 1.2]], {
  editorClass: AnchoredPolylineEditor
}).addTo(map);
section.enableEdit();
html, body {
    height: 100%;
    margin: 0;
}
#map {
    width: 100%;
    height: 100%;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.1/leaflet.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.1/leaflet.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-editable/1.1.0/Leaflet.Editable.min.js"></script>
<div id='map'></div>