TRICK系列:Openlayers 中實現(xiàn)Draw通過鍵盤按鍵取消全部繪制、取消上一步繪制

前言

Draw是OpenLayers中常用的一個組件,默認是單擊繪制,雙擊結束繪制。

但是在實際工程中常常需要在繪制過程中使用按鍵來取消全部繪制、取消上一步繪制,如何做到呢?

閑言少敘,直接上干貨。
原理

在draw中是不處理鍵盤的按鍵事件的,只有當鼠標的左右鍵按下的時候,才會觸發(fā)ol/MapBrowserEvent 類的事件,所以我們無法使用Openlayers的機制來實現(xiàn)使用按鍵的目的。此時就需要引入方便又強大的jQuery了。通過jQuery監(jiān)聽document對象的按鍵事件,來實現(xiàn)我們?nèi)∠炕蛘呷∠弦徊降睦L制。
操作

直接上代碼吧

import Map from 'ol/Map';
import View from 'ol/View';
import Draw from 'ol/interaction/Draw';
import {
    Tile as TileLayer,
    Vector as VectorLayer
} from 'ol/layer';
import {
    OSM,
    Vector as VectorSource
} from 'ol/source';
import $ from 'jquery'
var raster = new TileLayer({
    source: new OSM()
});
 
var source = new VectorSource({
    wrapX: false
});
 
var vector = new VectorLayer({
    source: source
});
 
var map = new Map({
    layers: [raster, vector],
    target: 'map',
    view: new View({
        center: [-11000000, 4600000],
        zoom: 4
    })
});
 
var typeSelect = document.getElementById('type');
 
var draw; // global so we can remove it later
function addInteraction() {
    var value = typeSelect.value;
    if (value !== 'None') {
        draw = new Draw({
            source: source,
            type: typeSelect.value,
 
        });
        map.addInteraction(draw);
    }
}
 
typeSelect.onchange = function () {
    map.removeInteraction(draw);
    addInteraction();
};
addInteraction();
 
 
$(document).keyup(function (event) {
    if (event.keyCode == 27)
        draw.abortDrawing();
    else if (event.keyCode == 90 && event.ctrlKey) {
        console.log(draw);
        if (typeSelect.value== 'Circle')
            draw.abortDrawing();
        else
            draw.removeLastPoint()
 
    }
})

需要注意的是,這個函數(shù)只有Openlayers 6.3之后才有,那么在之前的老版本里(比如5.x甚至6.0.x、6.1.x),需要自己把這個邏輯實現(xiàn)出來,重載Draw類添加一個abortDrawing()公有成員:

import Map from 'ol/Map';
import View from 'ol/View';
import Draw from 'ol/interaction/Draw';
import {
    Tile as TileLayer,
    Vector as VectorLayer
} from 'ol/layer';
import {
    OSM,
    Vector as VectorSource
} from 'ol/source';
import $ from 'jquery'
 
 
class DrawPlus extends Draw{
     constructor(options){
         super(options);
     } 
     abortDrawing() {
      this.abortDrawing_();
      }
}
   
 
 
var raster = new TileLayer({
    source: new OSM()
});
 
var source = new VectorSource({
    wrapX: false
});
 
var vector = new VectorLayer({
    source: source
});
 
var map = new Map({
    layers: [raster, vector],
    target: 'map',
    view: new View({
        center: [-11000000, 4600000],
        zoom: 4
    })
});
 
var typeSelect = document.getElementById('type');
 
var draw; // global so we can remove it later
function addInteraction() {
    var value = typeSelect.value;
    if (value !== 'None') {
        draw = new DrawPlus({
            source: source,
            type: typeSelect.value,
 
        });
        map.addInteraction(draw);
    }
}
 
typeSelect.onchange = function () {
    map.removeInteraction(draw);
    addInteraction();
};
addInteraction();
 
 
$(document).keyup(function (event) {
    if (event.keyCode == 27)
        draw.abortDrawing();
    else if (event.keyCode == 90 && event.ctrlKey) {
        console.log(draw);
        if (typeSelect.value== 'Circle')
            draw.abortDrawing();
        else
            draw.removeLastPoint()
 
    }
})