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

时间:2014-11-12 03:17:59

标签: events observable interaction undo-redo openlayers-3

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

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

侦听观察到的几何要素更改的处理程序可用于此目的但由于该功能的几何而太昂贵每次像素移动都会改变修改。

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

1 个答案:

答案 0 :(得分:2)

从OpenLayers 3.7.0开始, ol.interaction.Modify 会发出modifystartmodifyend。文档:this Q+A

每次修改后随机决定是否应该保留或撤销的示例(http://openlayers.org/en/v3.7.0/apidoc/ol.ModifyEvent.html):

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事件。