OpenLayers 3如何在OpenLayer 2中将Feature Modified事件注册为"featuremodified"

abd*_*hab 6 events interaction undo-redo observable openlayers-3

我需要使用OpenLayers 3矢量编辑实现撤消/重做功能(就像http://dev.openlayers.org/examples/modify-feature.html中针对OpenLayers 2所示).

要跟踪的几何形状的变化特点,我要管理的存储堆栈将在用户交互持有的特点改变的几何定义.我知道OpenLayers 3提供了可观察对象.所以ol.Feature或者ol.Feature.getGeometry()可以观察到更改,但我正在寻找发出的显式事件ol.interaction.Modify,当交互开始或结束向量编辑操作时应该通知我(就像OpenLayers 2中的事件"beforefeaturemodified""featuremodified"事件一样).

侦听观察到的几何体特征变化的处理程序可以用于此目的但是它太昂贵,因为修改后的特征的几何形状随着每个像素移动而改变.

我已经浏览了OpenLayers 3 的官方文档,但找不到OpenLayers 2提供的各种事件.在大多数情况下,文档仅提到更改事件.我想知道这些事件是否不是Openlayer 3架构的考虑因素.如果是这样,任何建议如何扩展现有ol.interaction.Modify以包含自定义事件?谢谢.

Alv*_*tam 3

从 OpenLayers 3.7.0 开始,ol.interaction.Modify发出modifystartmodifyend。文档:http://openlayers.org/en/v3.7.0/apidoc/ol.ModifyEvent.html

每次修改后随机决定是否应保留或撤销的示例(http://jsfiddle.net/rbha7f83/1/):

var select = new ol.interaction.Select({
    style: overlayStyle
});

// The modify interaction does not listen to geometry change events.
// Changing the feature coordinates will make the modify interaction
// unaware of the actual feature coordinates.
// A possible fix: Maintain a collection used by Modify, so we can reload
// the features manually. This collection will always contain the same
// features as the select interaction.
var selectSource = new ol.Collection();
select.on('select', function (evt) {
    evt.selected.forEach(function (feature) {
        selectSource.push(feature);
    });
    evt.deselected.forEach(function (feature) {
        selectSource.remove(feature);
    });
});

var modify = new ol.interaction.Modify({
    features: selectSource, // use our custom collection
    style: overlayStyle
});

var map = new ol.Map({
    interactions: ol.interaction.defaults().extend([select, modify]),
    layers: [layer],
    target: 'map',
    view: new ol.View({
        center: [0, 1000000],
        zoom: 2
    })
});

var originalCoordinates = {};
modify.on('modifystart', function (evt) {
    evt.features.forEach(function (feature) {
        originalCoordinates[feature] = feature.getGeometry().getCoordinates();
    });
});
modify.on('modifyend', function (evt) {
    evt.features.forEach(function (feature) {
        if (feature in originalCoordinates && Math.random() > 0.5) {
            feature.getGeometry().setCoordinates(
                originalCoordinates[feature]
            );
            delete originalCoordinates[feature];

            // remove and re-add the feature to make Modify reload it's geometry
            selectSource.remove(feature);
            selectSource.push(feature);
        }
    });
})
Run Code Online (Sandbox Code Playgroud)

请注意,事件在每次交互之前和之后发出。拖动顶点然后单击顶点将其删除(均在同一要素上)将触发两个modifystartmodifyend事件。