撤销 OL3 中的最后一个点会删除最后一条线段。

15

我需要在我的Web应用程序中添加一个功能,用于撤销上一个点。已经有一些解决方案,例如this可以在一定程度上处理这个问题:

var undo = false; // set this to true in the Esc key handler
var draw = new ol.interaction.Draw({
// ...
geometryFunction: function(coords, geom) {
    if (!geom) {
        geom = new ol.geom.LineString(null);
    }
    if (undo) {
        if (coords.length > 1) {
            coords.pop();
        }
        undo = false;
    }
    geom.setCoordinates(coords);
    return geom;
    }
});

但似乎有一个错误或问题我无法解决。

使用此plunker,您可以尝试我要解释的内容:

如果您用一些顶点画了一条线,然后按“ESC”撤销操作,直到线上的最后一个点被删除,然后在与刚才撤销的点相同位置结束或足够接近该位置,那么最后一段将被删除,为什么?

通过图例解释:

1- 画一条线段

enter image description here

2- 撤销最后一个(第三个)点 在此输入图片描述

3- 在(或靠近)相同的位置结束线条。 在此输入图片描述

4- 移除最后一段。 在此输入图片描述

我试了几次,这种情况确实会发生。如果您添加的点不靠近被移除的点,或者添加了多个点,则不会发生。

编辑

看起来OL3会检查几何图形的最后两个坐标,如果它们相同,则决定结束绘制会话并移除最后一个坐标。我尝试了以下代码:

function geometryChange(coordinates, geometry){
if (!geometry) {
    geometry = new ol.geom.LineString(null);   
} 
if (undo){
    var coords = geometry.getCoordinates();
    console.info(coords);
    console.info(coordinates);
    var diff = coordinates.length - coords.length;
    if (diff > 0) {
        var lastCoordinates= coordinates[coordinates.length-1];
        console.info(coordinates);
        coordinates.splice(coordinates.length - (diff+1), diff,lastCoordinates);
        console.info(coordinates);
        coordinates.pop();
        console.info(coordinates);
        undo=false;
        if (coords.length === 1){
            undone=true;
            lineStringdraw.finishDrawing();
            undone=false;
            var emptyFeature = vector2.getSource().getFeatures()[vector2.getSource().getFeatures().length-1];
            vector2.getSource().removeFeature(emptyFeature);
            featureID-=1;
        }
    }
}
//console.info(coordinates);
geometry.setCoordinates(coordinates);
//coordinates= geometry.getCoordinates();
return geometry;    
}

结果更加有趣。当我撤销最后一个点时,如果我想在靠近那个点的位置添加一个点(不用双击完成线条),OL会认为绘图已经完成并触发drawend事件(我为某些目的使用了这个事件,但令人惊讶的是它无缘无故地被触发)。


我无法复现这种行为,如果您能展示屏幕录像会更容易一些。您的图像序列看起来不像同一个线串。 - Jonatas Walker
@JonatasWalker:希望这可以帮到你...https://www.youtube.com/watch?v=BYrWWlNRYM4 - msc87
@JonatasWalker:你有时间看一下那个视频吗?我还在为这个问题苦恼。非常感谢任何见解! - msc87
1
在创建Plunker时,没有removeLastPoint。您应该依赖它。演示分叉的Plunker - Jonatas Walker
你检查了我的上一个 Plunker 吗? - Jonatas Walker
显示剩余2条评论
1个回答

2

尝试更改您代码中的这部分内容:

var keydown = function(evt){
var charCode = (evt.which) ? evt.which : evt.keyCode;
if (charCode === 27 && drawing === true){ //esc key
    var geom = drawing_feature.getGeometry();
    geom.setCoordinates(geom.getCoordinates().slice(0, -1));
}
};

转换为:

var keydown = function(evt){
var charCode = (evt.which) ? evt.which : evt.keyCode;
if (charCode === 27 && drawing === true){ //esc key
    var geom = drawing_feature.getGeometry();
    var coordsLength = geom.getCoordinates().length;
    geom.setCoordinates(geom.getCoordinates().slice(0, coordsLength-1));
}
};

如果您可以使用removeLastPoint方法,请尝试以下操作。
var keydown = function(evt){
var charCode = (evt.which) ? evt.which : evt.keyCode;
if (charCode === 27 && drawing === true){ //esc key
draw.removeLastPoint();
}
};

那么geometryFunction应该是什么? - msc87
1
我成功地重现了你的情况。对我来说,slice(0,-1)似乎不正确,因为slice需要起始和结束点。所以-1不是一个合适的结束点,除非我漏掉了什么。我已经在你的plunker中进行了更改,看起来可以完成工作。你试过了吗?也许你不需要geometryFunction。 - pavlos
我将尝试移除geometryFunction以查看结果是否正确。我需要进行一些几何变换,例如捕捉线串的第一个和/或最后一个点,因此我应该确保在没有geometryFunction的情况下也能处理它们。 - msc87
1
你可以随时使用 removeLastPoint 方法。我会尝试更新我的答案,以展示这个选项。 - pavlos
它没有起作用...我不知道为什么,但似乎因为它是实验性的,这是可以预料的... - msc87
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接