Openlayers 4 - 在同一坐标处修改交互和多个功能
Openlayers 4 - Modify interaction & multiple feature at the same coordinate
我在具有多个特征的矢量图层上启用了修改交互。将功能移动到新位置效果很好。但是,如果同一坐标上有更多特征,则所有特征都会同时移动。 See example on codepen.
var raster = new ol.layer.Tile({
source: new ol.source.OSM()
});
var data = new ol.Collection();
data.push(new ol.Feature({
geometry: new ol.geom.Point([0, 0])
}));
var f = new ol.Feature({
geometry: new ol.geom.Point([0, 0])
});
f.setStyle(new ol.style.Style({
image: new ol.style.Circle({
radius: 10,
fill: new ol.style.Fill({
color: [255, 255, 255, 0.5]
}),
zIndex: Infinity
}),
}));
data.push(f);
var vector = new ol.layer.Vector({
source: new ol.source.Vector({
features: data
})
});
var modify = new ol.interaction.Modify({
features: data
});
var map = new ol.Map({
interactions: ol.interaction.defaults().extend([modify]),
layers: [raster, vector],
target: 'map',
view: new ol.View({
center: [0, 0],
zoom: 12
})
});
有什么办法可以避免这种情况吗?我找到的唯一解决方案是:
- 我有 select 与 select 功能的交互
- 使用翻译交互移动其中一项功能
或
- 在指针移动事件中检测一个或多个特征是否在坐标处,然后 select 其中之一
- 添加 selected 特征以修改特征层并移动它
还有其他方法吗?
注册
RM
还有一个办法。您可以在地图上注册一个 'pointermove' 处理程序,您可以在其中获取最顶层的要素,并将其设置为修改交互作用于源上的唯一要素。有关完整示例,请参阅 https://codepen.io/ahocevar/pen/YxjyRd。
除了在您的代码中,您会将修改交互连接到源而不是集合,并且该源 (modifySource
) 与矢量图层的源分开并且最初为空。在 pointermove
处理程序中,您只需向该源添加一个功能:
function pointermove(e) {
if (e.dragging) {
return;
}
var features = map.getFeaturesAtPixel(e.pixel, {
layerFilter: function(l) {
return l == vector;
}
});
if (features && features[0] != modifySource.getFeatures()[0]) {
modifySource.clear();
modifySource.addFeature(features[0]);
}
}
map.on("pointermove", pointermove);
另请注意,必须在将修改交互添加到地图之前注册此处理程序。
我在具有多个特征的矢量图层上启用了修改交互。将功能移动到新位置效果很好。但是,如果同一坐标上有更多特征,则所有特征都会同时移动。 See example on codepen.
var raster = new ol.layer.Tile({
source: new ol.source.OSM()
});
var data = new ol.Collection();
data.push(new ol.Feature({
geometry: new ol.geom.Point([0, 0])
}));
var f = new ol.Feature({
geometry: new ol.geom.Point([0, 0])
});
f.setStyle(new ol.style.Style({
image: new ol.style.Circle({
radius: 10,
fill: new ol.style.Fill({
color: [255, 255, 255, 0.5]
}),
zIndex: Infinity
}),
}));
data.push(f);
var vector = new ol.layer.Vector({
source: new ol.source.Vector({
features: data
})
});
var modify = new ol.interaction.Modify({
features: data
});
var map = new ol.Map({
interactions: ol.interaction.defaults().extend([modify]),
layers: [raster, vector],
target: 'map',
view: new ol.View({
center: [0, 0],
zoom: 12
})
});
有什么办法可以避免这种情况吗?我找到的唯一解决方案是:
- 我有 select 与 select 功能的交互
- 使用翻译交互移动其中一项功能
或
- 在指针移动事件中检测一个或多个特征是否在坐标处,然后 select 其中之一
- 添加 selected 特征以修改特征层并移动它
还有其他方法吗?
注册 RM
还有一个办法。您可以在地图上注册一个 'pointermove' 处理程序,您可以在其中获取最顶层的要素,并将其设置为修改交互作用于源上的唯一要素。有关完整示例,请参阅 https://codepen.io/ahocevar/pen/YxjyRd。
除了在您的代码中,您会将修改交互连接到源而不是集合,并且该源 (modifySource
) 与矢量图层的源分开并且最初为空。在 pointermove
处理程序中,您只需向该源添加一个功能:
function pointermove(e) {
if (e.dragging) {
return;
}
var features = map.getFeaturesAtPixel(e.pixel, {
layerFilter: function(l) {
return l == vector;
}
});
if (features && features[0] != modifySource.getFeatures()[0]) {
modifySource.clear();
modifySource.addFeature(features[0]);
}
}
map.on("pointermove", pointermove);
另请注意,必须在将修改交互添加到地图之前注册此处理程序。