events - OpenLayers 3 如何在 OpenLayer 2 中将功能修改事件注册为 "featuremodified"

标签 events observable interaction undo-redo openlayers-3

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

为了跟踪特征几何变化,我必须管理一个内存堆栈,该堆栈将在用户交互时保存特征变化的几何定义。我知道 OpenLayers 3 提供了可观察的对象。因此,可以观察 ol.Featureol.Feature.getGeometry() 的变化,但我正在寻找 ol.interaction.Modify< 发出的显式事件,当交互开始或结束矢量编辑操作时应该通知我(就像“beforefeaturemodified”“featuremodified”事件在 OpenLayers 2 中)。

监听观察到的几何特征变化的处理程序可以用于此目的,但它太昂贵了,因为特征的几何每个像素移动都会改变修改。

我已经通过官方documentation OpenLayers 3 的但找不到 OpenLayers 2 提供的各种事件。在大多数情况下,文档仅提到 change 事件。我想知道 Openlayer 3 的架构是否没有考虑此类事件。如果是这样,有什么建议我可以扩展现有的 ol.interaction.Modify 来合并自定义事件吗?谢谢。

最佳答案

从 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);
        }
    });
})

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

关于events - OpenLayers 3 如何在 OpenLayer 2 中将功能修改事件注册为 "featuremodified",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26878659/

相关文章:

F#:取消订阅 FSharp.Control.Reactive.Observable

javascript - 如何观察第三方对象的属性值变化?

android - 我可以构建一个应用程序与另一个我不拥有的应用程序交互吗?

javascript - 在 jQuery 中,如何以百分比设置元素的位置?

c# - WPF- 验证错误事件不会触发

angular - tslint 错误阴影名称 : 'Observable'

asp.net-mvc - MVC 组件 GUI 方法

javascript - 使用 JS 添加到 DOM 后与 DOM 进行交互

javascript - 如何不让别人点击导航器的返回按钮?

c# - 在 C# 中修改 ComboBox SelectedIndex 而不触发事件