1. 程式人生 > >OpenLayers 3 之 地圖互動功能(interaction)詳解

OpenLayers 3 之 地圖互動功能(interaction)詳解

      地圖互動功能和上一篇講的地圖控制元件有些混淆,它們都控制著使用者與地圖的互動,區別是地圖控制元件的觸發都是一些可見的 HTML 元素觸發,如按鈕、連結等;而互動功能都是一些裝置行為觸發,都是不可見的,如滑鼠雙擊、滾輪滑動等,手機裝置的手指縮放等。

      地圖的互動功能包含很多,如地圖雙擊放大,滑鼠滾輪縮放,向量要素點選,地圖上繪製圖形等等。只要是涉及到與地圖的互動,就會涉及到 intercation 類,它定義了使用者與地圖進行互動的基本要素和事件。下面我們就來看看使用者與地圖都有那些互動,怎麼互動。

注: ‘自定義使用者互動型別’,‘定製化互動’ 或者 ‘互動優化’ 都超出了本文範圍。

有問題可以留言評論或者給我發郵件! [email protected]

一、interaction 介紹

      在 OpenLayers 3 中,表達互動功能的基類是 interaction,它是一個虛基類,不負責例項化,互動功能都繼承該基類, OpenLayers 3 中可例項化的子類及其功能如下:

  • doubleclickzoom interaction,雙擊放大互動功能;
  • draganddrop interaction,以“拖檔案到地圖中”的互動新增圖層;
  • dragbox interaction,拉框,用於劃定一個矩形範圍,常用於放大地圖;
  • dragpan interaction,拖拽平移地圖;
  • dragrotateandzoom interaction,拖拽方式進行縮放和旋轉地圖;
  • dragrotate interaction,拖拽方式旋轉地圖;
  • dragzoom interaction,拖拽方式縮放地圖;
  • draw interaction,繪製地理要素功能;
  • interaction defaults ,規定了預設新增的互動功能;
  • keyboardpan interaction,鍵盤方式平移地圖;
  • keyboardzoom interaction,鍵盤方式縮放地圖;
  • select interaction,選擇要素功能;
  • modify interaction,更改要素;
  • mousewheelzoom interaction,滑鼠滾輪縮放功能;
  • pinchrotate interaction,手指旋轉地圖,針對觸控式螢幕;
  • pinchzoom interaction,手指進行縮放,針對觸控式螢幕;
  • pointer interaction,滑鼠的使用者自定義事件基類;
  • snap interaction,滑鼠捕捉,當滑鼠距離某個要素一定距離之內,自動吸附到要素。

二、互動功能的種類和使用方法

1. interaction defaults - 預設新增的互動功能

該類規定了預設包含在地圖中的功能,主要是最為常用的功能,如縮放、平移和旋轉地圖等,具體功能有如下這些:

  • ol.interaction.DragRotate,滑鼠拖拽旋轉,一般配合一個鍵盤按鍵輔助;
  • ol.interaction.DragZoom,滑鼠拖拽縮放,一般配合一個鍵盤按鍵輔助;
  • ol.interaction.DoubleClickZoom,滑鼠或手指雙擊縮放地圖;
  • ol.interaction.PinchRotate,兩個手指旋轉地圖,針對觸控式螢幕;
  • ol.interaction.PinchZoom,兩個手指縮放地圖,針對觸控式螢幕;
  • ol.interaction.DragPan,滑鼠或手指拖拽平移地圖;
  • ol.interaction.KeyboardZoom,使用鍵盤 +- 按鍵進行縮放;
  • ol.interaction.KeyboardPan,使用鍵盤方向鍵平移地圖;
  • ol.interaction.MouseWheelZoom,滑鼠滾輪縮放地圖。

可以看出,很多都相容移動裝置的觸控式螢幕,鍵盤,滑鼠事件,這就是OpenLayers 3的改進,跨平臺改進。這些功能都是預設新增的,如果要更改預設的選項,需要在相應的選項設定為 false。如果想去掉預設的 DoubleClickZoom 功能,配置如下:

interactions: ol.interaction.defaults([
    doubleClickZoom: false
]),

這樣就去除了雙擊放大功能,去除其他的預設功能,是一樣的。

2. draw interaction - 繪圖功能

繪圖互動允許繪製幾何地理要素,可選引數為一個物件,包含引數如下:

/**
 * @typedef {{features: (ol.Collection.<ol.Feature>|undefined),
 *     source: (ol.source.Vector|undefined),
 *     snapTolerance: (number|undefined),
 *     type: ol.geom.GeometryType,
 *     minPointsPerRing: (number|undefined),
 *     style: (ol.style.Style|Array.<ol.style.Style>|ol.style.StyleFunction|undefined),
 *     geometryName: (string|undefined),
 *     condition: (ol.events.ConditionType|undefined)}}
 * @api
 */
  • features,繪製的要素的目標集合;
  • source,繪製的要素的目標圖層來源,即目標圖層的 source屬性 ;
  • snapTolerance,自動吸附完成點的畫素距離,也就是說當滑鼠位置距離閉合點小於該值設定的時候,會自動吸附到閉合點,預設值是 12;
  • type,繪製的地理要素型別,ol.geom.GeometryType型別,包含 PointLineStringPolygonMultiPointMultiLineString 或者 MultiPolygon
  • minPointsPerRing,繪製一個多邊形需要的點數最小值,數值型別,預設是 3
  • style,要素素描的樣式,是 ol.style.Style物件之一;
  • geometryName,繪製的地理要素的名稱,string型別;
  • condition,一個函式,接受一個ol.MapBrowserEvent型別的引數,返回一個布林值表示是否應該呼叫事件處理函式。預設情況下,增加一個頂點,型別為 ol.events.ConditionType

給地圖新增該互動功能,首先需要例項化一個ol.interaction.Draw,必須指定 sourcetype屬性:

    var draw = new ol.interaction.Draw({
      source: source,
      type: "Polygon"
    });

然後將該功能新增到地圖中map.addInteraction(draw)

這裡我們在頁面中新增一個 HTML select 元素,通過選擇要素型別,繪製相應的要素型別:

<select id="type">
  <option value="None">None</option>
  <option value="LineString">LineString</option>
  <option value="Polygon">Polygon</option>
</select>

定義一個函式用於新增該互動功能:

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 ol.interaction.Draw({
      source: source,
      type: value
    });
    map.addInteraction(draw);
  }
}

繫結select值變化觸發的事件:

typeSelect.onchange = function(e) {
  map.removeInteraction(draw);
  addInteraction();
};

最後首先執行繫結函式addInteraction();,然後點選滑鼠進行繪製:

這裡寫圖片描述

繪製LineString

這裡寫圖片描述

繪製Polygon

這裡只是使用 LineStringPloygon 做了例子,還有 PointCircle 可以使用。對該類稍微定製,就可以定製繪製的圖形,如箭頭,這個就可以用於動態標繪系統,使用WFS協議和伺服器建立通訊。

3. dragrotateandzoom interaction - 滑鼠拖拽進行縮放和旋轉地圖

拖拽實現旋轉和縮放地圖的功能。首先定義該互動物件:

/* *
 * 定義地圖的互動功能
 */
 var interactions = ol.interaction.defaults().extend([
    new ol.interaction.DragRotateAndZoom()
 ]);

然後在 map 中加入互動物件:

這裡寫圖片描述

      這個功能的使用方法是首先按住鍵盤的 shift 按鈕,然後使用滑鼠點住地圖一點,然後拖拽滑鼠圍繞地圖中心旋轉,地圖就會選擇相應的角度;如果拖拽滑鼠遠離地圖中心,就會實現地圖的放大,靠近地圖中心,地圖就會縮小。

      該功能是兩個單獨功能的合體: dragzoom 和 dragrotate,一個負責拖拽縮放,一個負責拖拽旋轉,和以上的功能一樣,就不再贅述了。

4. dragbox interaction - 拉框互動

      在地圖上拉出一個矩形框,一般配合使用一個輔助按鍵,如Shift,常用於放大功能。該功能是預設新增在地圖中的,預設情況下,按下Shift,然後拖動滑鼠拉框,然後地圖就會將框內內容放大。

拉框
放大結果

5. draganddrop interaction - 拖拽檔案到地圖

      將空間資料使用滑鼠或者手指拖拽到地圖中,解析成一個圖層新增到地圖中。目前只支援向量資料,未來可能支援更多的空間資料格式。目前,支援的格式包括 GeoJSON, GML, KML, GPX, OSMXML, TopoJSONIGC。首先例項化一個 draganddrop interaction:

var dragAndDropInteraction = new ol.interaction.DragAndDrop({
  formatConstructors: [
    ol.format.GeoJSON,
    ol.format.KML
  ]
});

formatConstructors 表示想要支援的格式,這裡我選擇了支援兩種常見的格式:GeoJSONKML,然後將該互動新增到地圖中:

 var interactions = ol.interaction.defaults().extend([
    new ol.interaction.DragRotateAndZoom(),
    dragAndDropInteraction
 ]);

      如果想在新增資料的時候定義一些額外行為,比如縮放到新增到資料的範圍,需要註冊 interaction 的事件-dragAndDropInteraction.on('addfeatures', function(event) {});, 以下為拖拽一個KML檔案到地圖中:

這裡寫圖片描述
這裡寫圖片描述

6. keyboard interaction - 鍵盤互動功能

      包含 ol.interaction.KeyboardZoomol.interaction.KeyboardPan,分別是鍵盤縮放和鍵盤平移。預設新增到地圖中,但是隻有當焦點在包含地圖的 HTML 元素上,才可用。可以通過修改 ol.MapkeyboardEventTarget 屬性,修改鍵盤事件的關聯 HTML 元素。

  ol.interaction.KeyboardZoom,使用鍵盤+- 進行地圖縮放;ol.interaction.KeyboardPan,使用方向鍵平移地圖。

7. modify 和 select interaction

      select 就像名字暗示的一樣,是用來選中要素的;而 modify 是修改要素的,主要是通過拖拽方式修改點的座標。

這裡寫圖片描述

選中後的原圖
這裡寫圖片描述

拖拽幾個點後效果

模擬選中並修改要素的互動功能需要新增如下程式碼:

var select = new ol.interaction.Select();
var moddify = new ol.interaction.Modify({
    features:select.getFeatures()
});

features:select.getFeatures()目的為修改選中的要素。 然後將兩個互動功能新增到 map 中就可以使用其功能了。

8. pinchrotate ,pinchzoom interaction - 兩個手指縮放和旋轉地圖

這兩個功能針對觸控式螢幕,兩個手指按住地圖,增減距離來實現縮放,旋轉手指,地圖跟著旋轉。預設新增到地圖中。

9. pointer interaction - 自定義滑鼠事件

      針對滑鼠的行為按下(Down)、移動(Move)和擡起(Up),自定義事件。這三個事件發生有先後順序,首先是觸發按下,之後是移動事件,最後是擡起事件。只要配置相關的屬性,包含handleDownEventhandleDragEventhandleMoveEventhandleUpEvent分別對應滑鼠的 downdragmoveup四種事件。例如配置滑鼠的按下左鍵事件,當按下滑鼠左鍵時候,就會觸發 functionName函式 :

new ol.interaction.Pointer({
    handleDownEvent: functionName
})

10. snap interaction - 滑鼠捕捉

當修改和繪製向量要素時,滑鼠距離某個要素一定距離之內,自動吸附到要素。

這裡寫圖片描述

再靠近就會吸附到黃色的點

這裡寫圖片描述

可以配置的選項有 具有捕捉吸附功能的要素集 或者 向量圖層發生捕捉的最大距離(畫素為單位),使用方法如下:

new ol.interaction.Snap({
    features: 要素集(ol.Collection),
    pixelTolerance: 捕捉髮生的距離,畫素數,預設為10,
    source: 具有捕捉功能的圖層(ol.source.Vector)
})

三、總結

      互動功能比較多,主要涉及使用者與地圖互動需要的基本功能:縮放、平移拖拽、旋轉,為了提高相容性,除了針對滑鼠和鍵盤的互動,還有針對觸控式螢幕的縮放、旋轉和平移拖拽。

      比較有用的有勾繪draw、選擇要素selectmodify、捕捉吸附snap 和 滑鼠自定義事件pointer。這些互動功能可以共同構建一個動態標繪系統,在客戶端增加或者修改空間資料,提交給伺服器,更新資料。

OK,寫完了。

有問題可以留言評論或者給我發郵件! [email protected]