分享一个openlayers编辑要素节点,并且支持撤销与恢复的小demo:
javascript
const baseMap = new ol.layer.Tile({
source: new ol.source.OSM(),
});
const feature = new ol.Feature({
geometry: new ol.geom.Polygon([[
[-1000000, 5000000],
[-1000000, 2500000],
[0, 2500000],
[0, 5000000],
[-1000000, 5000000],
]])
});
const vectorSource = new ol.source.Vector({
features: [feature]
});
const vectorLayer = new ol.layer.Vector({
source: vectorSource,
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#ffcc33',
width: 2,
}),
}),
});
const map = new ol.Map({
layers: [baseMap, vectorLayer], // 添加底图和矢量图层
view: new ol.View({
center: [-500000, 3750000], // 设置地图中心
projection: 'EPSG:3857', // 使用EPSG:3857坐标系
zoom: 4
}),
target: 'map'
});
// 历史管理器
const historyManager = {
undoStack: [],
redoStack: [],
snapshot: (feature) => {
historyManager.undoStack.push({
feature: feature,
geometry: feature.getGeometry().clone()
});
},
undo: () => {
if (historyManager.undoStack.length > 0) {
const state = historyManager.undoStack.pop();
const currentGeometry = state.feature.getGeometry().clone();
historyManager.redoStack.push({
feature: state.feature,
geometry: currentGeometry
});
state.feature.getGeometry().setCoordinates(state.geometry.getCoordinates());
}
},
redo: () => {
if (historyManager.redoStack.length > 0) {
const state = historyManager.redoStack.pop();
const currentGeometry = state.feature.getGeometry().clone();
historyManager.undoStack.push({
feature: state.feature,
geometry: currentGeometry
});
state.feature.getGeometry().setCoordinates(state.geometry.getCoordinates());
}
}
};
// 添加交互
const modify = new ol.interaction.Modify({
source: vectorSource,
insertVertexCondition: () => true // 允许插入顶点
});
modify.on('modifyend', (e) => {
e.features.forEach(feature => {
historyManager.snapshot(feature);
});
});
map.addInteraction(modify);
historyManager.snapshot(feature);
// 监听键盘事件
document.addEventListener('keydown', (e) => {
if ((e.ctrlKey || e.metaKey) && !e.altKey) {
switch (e.key.toLowerCase()) {
case 'z':
if (!e.shiftKey) {
e.preventDefault();
historyManager.undo();
}
break;
case 'y':
if (!e.shiftKey) {
e.preventDefault();
historyManager.redo();
}
break;
}
}
});