地圖交互功能和上一篇講的地圖控件有些混淆,它們都控制着用戶與地圖的交互,區別是地圖控件的觸發都是一些可見的 HTML 元素觸發,如按鈕、鏈接等;而交互功能都是一些設備行為觸發,都是不可見的,如鼠標雙擊、滾輪滑動等,手機設備的手指縮放等。 地圖的交互功能包含很多,如地圖雙擊放大,鼠標滾輪縮放,矢量要素點選,地圖上繪制圖形等等。只要是涉及到與地圖的交互,就會涉及到 intercation
類,它定義了用戶與地圖進行交互的基本要素和事件。下面我們就來看看用戶與地圖都有那些交互,怎么交互。
注: ‘自定義用戶交互類型’,‘定制化交互’ 或者 ‘交互優化’ 都超出了本文范圍。
一、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
類型,包含Point
、LineString
、Polygon
、MultiPoint
、MultiLineString
或者MultiPolygon
; - minPointsPerRing,繪制一個多邊形需要的點數最小值,數值類型,默認是
3
; - style,要素素描的樣式,是
ol.style.Style
對象之一; - geometryName,繪制的地理要素的名稱,
string
類型; - condition,一個函數,接受一個
ol.MapBrowserEvent
類型的參數,返回一個布爾值表示是否應該調用事件處理函數。默認情況下,增加一個頂點,類型為ol.events.ConditionType
。
給地圖添加該交互功能,首先需要實例化一個ol.interaction.Draw
,必須指定 source
和type
屬性:
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
和 Ploygon
做了例子,還有 Point
和 Circle
可以使用。對該類稍微定制,就可以定制繪制的圖形,如箭頭,這個就可以用於動態標繪系統,使用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
, TopoJSON
和 IGC
。首先實例化一個 draganddrop
interaction:
var dragAndDropInteraction = new ol.interaction.DragAndDrop({ formatConstructors: [ ol.format.GeoJSON, ol.format.KML ] });
formatConstructors 表示想要支持的格式,這里我選擇了支持兩種常見的格式:GeoJSON
和 KML
,然后將該交互添加到地圖中:
var interactions = ol.interaction.defaults().extend([ new ol.interaction.DragRotateAndZoom(), dragAndDropInteraction ]);
如果想在添加數據的時候定義一些額外行為,比如縮放到添加到數據的范圍,需要注冊 interaction 的事件-dragAndDropInteraction.on('addfeatures', function(event) {});
6. keyboard interaction - 鍵盤交互功能
包含 ol.interaction.KeyboardZoom
和 ol.interaction.KeyboardPan
,分別是鍵盤縮放和鍵盤平移。默認添加到地圖中,但是只有當焦點在包含地圖的 HTML 元素上,才可用。可以通過修改 ol.Map
的 keyboardEventTarget
屬性,修改鍵盤事件的關聯 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),自定義事件。這三個事件發生有先后順序,首先是觸發按下,之后是移動事件,最后是抬起事件。只要配置相關的屬性,包含handleDownEvent
,handleDragEvent
,handleMoveEvent
,handleUpEvent
分別對應鼠標的 down
、drag
、move
和up
四種事件。例如配置鼠標的按下左鍵事件,當按下鼠標左鍵時候,就會觸發 functionName
函數 :
new ol.interaction.Pointer({ handleDownEvent: functionName })
10. snap interaction - 鼠標捕捉
當修改和繪制矢量要素時,鼠標距離某個要素一定距離之內,自動吸附到要素。
可以配置的選項有 具有捕捉吸附功能的要素集
或者 矢量圖層
,發生捕捉的最大距離(像素為單位)
,使用方法如下:
new ol.interaction.Snap({ features: 要素集(ol.Collection), pixelTolerance: 捕捉發生的距離,像素數,默認為10, source: 具有捕捉功能的圖層(ol.source.Vector) })
三、總結
交互功能比較多,主要涉及用戶與地圖交互需要的基本功能:縮放、平移拖拽、旋轉,為了提高兼容性,除了針對鼠標和鍵盤的交互,還有針對觸摸屏的縮放、旋轉和平移拖拽。
比較有用的有勾繪draw
、選擇要素select
、modify
、捕捉吸附snap
和 鼠標自定義事件pointer
。這些交互功能可以共同構建一個動態標繪系統
,在客戶端增加或者修改空間數據,提交給服務器,更新數據。