【问题标题】:Cancel vertex drag for an editable polyline取消可编辑多段线的顶点拖动
【发布时间】:2018-02-19 11:26:22
【问题描述】:

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

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

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

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

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

但这不起作用,有人知道这是否可能或我需要在这里做什么?

【问题讨论】:

    标签: javascript leaflet leaflet.draw


    【解决方案1】:

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

    的可编辑折线上实现这一点
    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>

    【讨论】:

    • 谢谢,__vertex 对我来说像是一个内部属性,它是官方支持的吗?
    • 它确实是 Leaflet.Editable 添加的一个内部属性,用于跟踪顶点。官方支持?可能不是,但它在源代码中的所有地方都使用过,使用起来应该是相当安全的。
    • 嗨,我也在研究同样的情况,但是对于顶点上的取消删除事件,每当我点击顶点时,它就会从多边形中删除,所以取消
    猜你喜欢
    • 2015-09-21
    • 2015-03-16
    • 1970-01-01
    • 2018-01-19
    • 2018-04-11
    • 1970-01-01
    • 2023-04-07
    • 2020-04-24
    • 2011-12-16
    相关资源
    最近更新 更多