openLayers 3知識回顧

openlayers 知識


前段時間幫助同事重構一個地圖類的項目,而後就學習了openLayer3這個框架,可是官網上沒有中文版,也沒有詳細的例子解釋,我只能遇到看不懂的就翻譯成中文來用,爲了方便之後再用這個ol,可以更快的上手,就花了幾天的時間總結了ol的知識,ol功能很豐富,API也不少,沒有寫太多,只是寫了怎麼用的,只要學會了根本,就能夠很快的使用API去操做map。

另外,在總結知識的同時,還寫了demo,加深本身的理解,你們以爲不錯的話,給個star~ GitHubjavascript

那麼開始吧!

目錄

var map = new ol.Map({
    target:'map',
    layers:[],
    view:views,
    interactions:interactions,
    controls:controls,
})

map是openlayers的核心組件,全部的操做方法以及渲染都是掛載到map上面。建立的map對象須要傳一個對象進去,最多見的就有如下幾個屬性,數據庫

* target --> 地圖的掛載元素,就是在html元素裏聲明的id
* layers --> 層,是個數組,能夠放不少層,若是未定義,則將呈現沒有圖層的地圖,圖層是按照提供的順序渲染的,所以,若是您但願(例如)矢量圖層顯示在圖塊圖層的頂部,則它必須位於圖塊圖層以後。
* view  --> map的視圖,
* interactions --> 交互,好比鼠標事件致使放大,縮小,旋轉之類的,默認都是true
* controls --> 控件,相似與按鈕,有放大,縮小,全屏等的按鈕

最簡單的顯示地圖:json

document.body.innerHTML = `<div id="map" style="height:400px;width:100%"></div>`;

var map = new ol.Map({
    target:'map',
    layers:[new ol.layers.Tile({
        source: new ol.source.OSM()
    })],
    view: new ol.View({
        center:[0,0],
        projection: 'EPSG:4326',
        zoom:10,
    }),
    interactions: ol.interaction.defaults({
        doubleClickZoom:false,
        altShiftDragRotate:false
    }),
    controls: ol.control.defaults({
        attribution: false,
    })
})

map

這個map不是裏面的Map,而是初始化後的map,map = new ol.Map();在openlayers3 的API中,有不少方法,能夠經過方法去操做layers,view,interactions,controls。
打印map,能夠發現map裏面有不少屬性,能夠簡單知道map上有多少個層,target是誰,size是多少等等,也能夠經過API方法去獲取api

var target = map.getTarget();    // 獲取 target的值  -- map
var size = map.getSize();  // 獲取可視區域的寬高。

一樣的,也能夠在map上設置數組

map.addControl(new ol.control.FullScreen()); // 添加全屏控件
map.addLayers( new ol.layer.Vector({
    source:new ol.Source.Vector()
}))  // 添加一個矢量圖層

*map裏有一個函數方法,能夠經過點擊某個圖層或某個點而獲取到當前的層和信息。
forEachFeatureAtPixel(pixel, callback, opt_options)
params: pixel:座標
callback:回調函數,將使用兩個參數調用回調,第一個是feature,第二個是layers
opt_options:可選

map.on('click',function(e){
    var feature = map.forEachFeatureAtPixel(e.pixel,function(f){
        return f;
    })
    console.log(feature);   // ol.Feature
})

view

視圖.View對象表示地圖的簡單2D視圖。這是用於更改地圖的中心,分辨率和旋轉的對象。
一個視圖是由三種狀態肯定:center,resolution,zoom和rotation。每一個狀態具備相應的獲取和設置。

  • center:初始座標,好比:成都的位置 [104.06, 30.67],這樣地圖初始化會以成都爲中心展開(projection:'EPSG:4326')。
  • projection:一個視圖有一個projection。投影肯定中心的座標系,其單位肯定分辨率的單位(每像素的投影單位)。
    projection有兩種值,默認投影是球形墨卡託(EPSG:3857),是地圖的xy座標,另外一種就是經緯度座標,(EPSG:4326)是WGS84的一種。
    經過一個方法能夠進行EPSG:3857與EPSG:4326轉化。
    經緯度轉至xy(EPSG:4326->EPSG:3857)
    ol.proj.transform(coordinates,'EPSG:4326','EPSG:3857')
    xy轉至經緯度(EPSG:3857->EPSG:4326)
    ol.proj.transform(coordinates,'EPSF:3857','EPSG:4326')
  • zoom:計算視圖初始分辨率的縮放級別。至於resolution初始分辨率,在其未聲明時,zoom起做用。對應的它也有maxZoom,minZoom。
  • rotation:初始旋轉度,默認是0,(順時針正向旋轉,0表示北向),弧度制
var view = new ol.View({
    center:[104.06,30.67],
    projection:'EPSG:4326',
    // center: ol.proj.transform([104.06,30,67],'EPSG:4326','EPSG:3857');    // 這個和上面的結合體。
    zoom:10,
    rotation:Math.PI/10,
})

視圖對應的也有get和set系列的方法,用於獲取和設置zoom,center,rotation等等,除此以外,還有約束方法,constrainRotation(),約束旋轉度,API上有詳細解釋。

map.getView()   // 就是當前視圖,view
view.getZoom()  // 獲取縮放級別;
view.getCenter() // 獲取初始中心座標
view.setCenter([20,30])  // 設置初始中心[20,30],也能夠用ol.proj.transform
view.constrainRotation(2,5) // 獲取此視圖的約束旋轉

layers

層,是一個對象數組,將那些與數據顯示方式相關的屬性組合在一塊兒,造成一個層,openlayer就是由一個一個的層造成的,包括地圖,瓦片地圖,圖片,圖形都是由layer造成而呈如今map上的
簡單的來講,layer能夠是一個地圖,也能夠是一個圖形,也能夠是個圖片,由於是個數組,能夠互相疊加的,[map,image,shape],在相同位置的狀況下,後者會覆蓋前者。

layer

根據這個圖片可知,layers有三種形式

  • ol.layer.Tile 瓦片,瓦片地圖源於一種大地圖解決方案,針對一整塊很是大的地圖進行切片,分紅不少相同大小的小塊地圖,在用戶訪問的時候,再一塊一塊小地圖加載,拼接在一塊兒,從而還原成一整塊大的地圖。這樣作的優勢在於,用戶在同一時間,同一個可見視圖內,只能看到地圖的一部分,而不是所有。提升用戶體驗。一般用這個做爲底圖。
  • ol.layer.Image 對應的是一整張圖,而不像瓦片那樣不少張圖,從而無需切片,也能夠加載一些地圖,適用於一些小場景地圖
  • ol.layer.Vector 矢量,使用直線和曲線來描述圖形,這些圖形的元素是一些點、線、矩形、多邊形、圓和弧線等等,它們都是經過數學公式計算得到的。因爲矢量圖形可經過公式計算得到,因此矢量圖形文件體積通常較小。矢量圖形最大的優勢是不管放大、縮小或旋轉等不會失真。

每一個形式都須要一個source,數據源,因此每個形式都對應一個數據源,Source和Layer是一對一的關係,有一個Source,必然須要一個Layer,而後把這個Layer添加到Map上,就能夠顯示出來了。

ol.layer.Tile

對於瓦片數據源,也有不少屬性,

  • opacity,改變透明度,默認是1
  • visible,可視,默認是true
  • zIndex,圖層渲染的z-index。在渲染時,將按照Z-index而後按位置對圖層進行排序
  • source 有不少形式,
  • 在線服務的Source
    • ol.source.OSM
    • ol.source.BingMaps
    • ol.source.TileImage
  • 支持協議標準的Source,包括ol.source.TileArcGISRest,ol.source.TileWMS,ol.source.WMTS,ol.source.UTFGrid,ol.source.TileJSON。若是要使用它們,首先你得先學習對應的協議,以後必須找到支持這些協議的服務器來提供數據源,這些服務器能夠是地圖服務提供商提供的,也能夠是本身搭建的服務器,關鍵是得支持這些協議。
  • ol.source.XYZ,並且如今不少地圖服務(在線的,或者本身搭建的服務器)都支持xyz方式的請求。國內在線的地圖服務,高德,天地圖等,均可以經過這種方式加載的
var OSMtile = new ol.layer.Tile({ 
    source:new ol.source.OSM()  
})
var qqTile = new ol.layer.Tile({
    source: new ol.source.XYZ({
        url: 'http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer/tile/{z}/{y}/{x}'
    }),
})
map.addLayer(OSMtile);  // 添加open street Map做爲底圖
map.addLayer(qqTile)  // 添加騰訊地圖

map.addLayer()這個方法就至關於初始化中的layers的數組中添加同樣,以下代碼,這倆是等價的,只不事後者更靈活些。

var map = new ol.Map({
    layers:[OSMtile,qqTile]
})  // 等價於下面
map.addLayer(OSMtile); 
map.addLayer(qqTile)

ps!當添加地圖做爲底圖時,會發現騰訊底圖覆蓋率OSM地圖,是由於layer是一個數組,遵遁先來先渲染,後來居上的原則。
layer也有get/set方法,用來設置或獲取屬性,其實經過API就能夠知道響應方法去操做。

ol.layer.Image

關於靜態圖片層,運用的很少,通常做爲寫死的,不常常換的實例中。
一樣,ol.layer.Image也有數據源,通常就是ol.source.ImageStatic,ol.source.ImageCanvas等等。

var center = ol.proj.transform([104.06667, 30.66667], 'EPSG:4326', 'EPSG:3857');
// 計算靜態圖映射到地圖上的範圍,圖片像素爲 550*344,保持比例的狀況下,把分辨率放大一些
var extent = [center[0]- 550*1000/2, center[1]-344*1000/2, center[0]+550*1000/2, center[1]+344*1000/2];
var imageStatic = new ol.layer.Image({
    source: new ol.source.ImageStatic({
        url: '../pandaBase.jpg', // 靜態圖
        imageExtent: extent     // 映射到地圖的範圍
    })
})
map.addLayer(imageStatic);
ol.layer.Vector
矢量圖層,是用來渲染矢量數據的圖層類型,在OpenLayers裏,它是能夠定製的,能夠控制它的透明度,顏色,以及加載在上面的要素形狀等。經常使用於從數據庫中請求數據,接受數據,並將接收的數據解析成圖層上的信息。好比將鼠標移動到中國,相應的區域會以紅色高亮顯示出來,高亮即是矢量圖層的行爲

既然是個矢量圖,能夠改變大小,顏色,以及形狀。包含source數據源類,style類設置樣式,以及其餘的zIndex,opacity等等。
Feature類是Vector類用來在地圖上展現幾何對象,是Vector圖層類一個屬性。這個屬性是個*要素數組*。

source

對應的數據源ol.source.Vector也是個對象。最多見屬性的是featuresformat以及url。一般url和format一塊,url按理傳來的是geojson格式的矢量圖,須要format格式化一下。最經常使用仍是features。
ol.Feature

  • feature 具備幾何和其餘屬性屬性的地理要素的矢量對象,相似於GeoJSON等矢量文件格式中的要素。
  • Geometry類是feature對象的基本組成部分,Vector類採用Geometry類來存儲一個要素的幾何信息.經過feature名.getGeometry()獲取
  • feature類有兩個部分,Geometry對象和attributes屬性,attributes包含要素相關的數據。好比:{type:'circle'},經過getProperties().attributes去獲取。
    geometry
  • new ol.geom.Point([x1,y1]) 點
  • new ol.geom.LineString([[x1,y1],[x2,y2]]) 線
  • new ol.geom.LinearRing()
  • new ol.geom.MultiLineString([[[x1,y1],[x2,y2]],[[x3,y3],[x4,y4]],[...]]) 多條線
  • new ol.geom.MultiPoint([[x1,y1],[x2,y2],[...]]) 多個點
  • new ol.geom.Polygon([[[x1,y1],[x2,y2],[x3,y3],[x4,y4],[...],[x1,y1]]]) 幾何
    若是這些座標是經緯度座標的話,都須要座標轉換applyTransform(ol.proj.getTransform('EPSG:4326', 'EPSG:3857')),(部分圖形展現請看demo)
var polygon = new ol.geom.Polygon([[[110, 39], [116, 39], [116, 33], [110, 33], [110, 39]]]);
polygon.applyTransform(ol.proj.getTransform('EPSG:4326', 'EPSG:3857')); // 座標轉換
var square = new ol.Feature({
    geometry:polygon
})
layer.getSource().addFeature(square)
style
一個style對象,包含Style類,有7個屬性:
  • geometry 返回要爲此樣式渲染的幾何的要素屬性或幾何或函數
  • fill 填充樣式。
  • image 圖像樣式
    • icon : new ol.style.Icon()
      • anchor :[0.5,0.5]錨點,
      • color
      • src :圖標源
      • ...
    • circle: new ol.style.Circle()
      • fill :new ol.style.Fill()
      • radius : 半徑
      • stroke :new ol.style.Stroke()
    • regularShape :new ol.style.RegularShape()
      • fill :new ol.style.Fill()
      • points : 點數,幾個點
      • radius : 半徑
      • radius1 : 外半徑
      • radius2 : 內半徑
      • angle 0 形狀的角度以弧度表示。值爲0將使其中一個形狀的點朝上。
      • stroke :new ol.style.Stroke()
      • rotation : 0 旋轉度
      • ...
  • renderer 自定義渲染器。配置時fill,stroke和image將被忽略,而且將爲每一個幾何體的每一個渲染幀調用提供的函數。
  • stroke 邊線樣式
    • color 顏色
    • lineCap :butt, round, square 線帽
    • lineJoin :bevel, round, miter. 線條鏈接形狀
    • width 寬度
  • text 文字樣式
    • font :'10px sans-serif'
    • text
    • textAlign left','right','center','end' start'
    • fill :new ol.style.Fill()
    • stroke :new ol.style.Stroke()
    • backgroundFill
    • padding
  • zIndex 層級
    // set*()在從新呈現使用該樣式的要素或圖層以前,經過方法對樣式或其子項所作的任何更改都不會生效
// 最簡單的呈現方式,複雜的請參考demo
var layer = new ol.layer.Vector({
    source: new ol.source.Vector({
        features:[new ol.Feature({
            geometry: new ol.geom.Point(ol.proj.transform([104, 30], 'EPSG:4326', 'EPSG:3857')),
        })]
    }),
    style: new ol.style.Style({
        image: new ol.style.Circle({
            radius: 30,
            fill: new ol.style.Fill({
                color: 'red'
            })
        })
    }),
    opacity:0.5
})
map.addLayer(layer)

一個層layer有一個featrue,也能夠有多個feature,由於Feature類是Vector類用來在地圖上展現幾何對象,是Vector圖層類一個屬性。這個屬性是個*要素數組*。
對於style樣式問題,feature的style的層級比layer.Vector的層級要高,因此feature的style會覆蓋layer的style。
ps:feature中的樣式不能以屬性名的形式寫,由於feature類中沒有style屬性名,只有geometry,因此要以方法的形式去添加,setStyle()。

其實關於layer,vector,API上都有其方法,包括set/get,雖然類有不少子類,子類又有不少子子類,也無妨,只要抓住想要操做的是哪個部分就行,是feature,仍是layer,仍是geometry等等。

styleFunction
feature中可使用styleFunction來設置本身爲所欲爲的樣式,經過官網API文檔能夠看到,其類型爲ol.FeatureStyleFunction,函數僅帶有一個參數resolution,在函數體內this指的是當前的feature,根據文檔說明,這個函數要返回一個style數組。
除了feature能夠設置樣式以外,layer也是能夠設置樣式的,一樣地也支持styleFunction,可是須要注意的是,其定義和feature的不同,類型爲ol.style.StyleFunction,該函數具備兩個參數,第一個參數爲feature,第二個參數爲resolution,一樣地,該函數須要返回style數組。

var layer = new ol.layer.Vector({
    source: new ol.source.Vector()
})
var map = new ol.Map({
    layers: [
        new ol.layer.Tile({
        source: new ol.source.OSM()
        }), 
        layer
    ],
    target: 'map',
    view: new ol.View({
        projection: 'EPSG:4326',
        center: [104, 30],
        zoom: 10
    })
});

var anchor = new ol.Feature({
    geometry: new ol.geom.Point([104, 30])
});
// 應用style function,動態的獲取樣式
anchor.setStyle(function(resolution){
    return [new ol.style.Style({
        image: new ol.style.Icon({
        src: '../img/anchor.png',
        scale: map.getView().getZoom() / 10
        })
    })];
});

layer.getSource().addFeature(anchor);

controls

地圖控件,包括縮放按鈕,標尺,版權說明,指北針等等,不會隨着地圖的放大而放大,縮小而縮小,就至關於position:fixed同樣,固定在某個地方。 在實現上,並非在畫布上繪製的,而是使用傳統的HTML元素來實現的,便於同地圖分離,也便於界面實現。
在openlayers 3 中,默認狀況下,在地圖上是不會顯示這麼多地圖控件的,只會應用ol.control.defaults()這個函數返回的地圖控件,默認包含了ol.control.Zoom,ol.control.Rotate和ol.control.Attribution這個控件。
OpenLayers 3目前內置的地圖控件類都在包ol.control下面:

  • ol.control.Attribution: 右下角的地圖信息控件
  • ol.control.FullScreen: 全屏控件
  • ol.control.MousePosition: 鼠標位置控件
  • ol.control.OverviewMap: 鳥瞰圖控件
  • ol.control.Rotate: 指北針控件
  • ol.control.ScaleLine: 比例尺控件
  • ol.control.Zoom: 縮放按鈕控件
  • ol.control.ZoomSlider: 縮放滾動條控件
  • ol.control.ZoomToExtent: 放大到設定區域控件
var map = new ol.Map({
    target:'map',
    layers:[new ol.layers.Tile({
        source: new ol.source.OSM()
    })],
    view: new ol.View({
        center:[0,0],
        projection: 'EPSG:4326',
        zoom:10,
    })
    controls: ol.control.defaults({
        attribution: false, // 信息false
        rotate: false,    // 旋轉false
        zoom: false      //   縮放false
    })
})

map.getControls()是獲取控件的信息,
若是想要添加其餘的控件,可使用map中的一個方法,map.addControl()

map.addControl(ol.control.OverviewMap)  // 添加鳥瞰圖控件

控件不是在畫布上繪製的,而是用html實現的,因此樣式問題能夠按照css+html的形式去修改。

interactions

交互,就是人與機之間的交互模式,好比用鼠標左鍵雙擊地圖能夠放大地圖,按住鼠標左鍵拖動地圖能夠移動瀏覽地圖,用滾動鼠標中間的滑輪能夠放大縮小地圖等等。這些都是openLayers內置的,其實也能夠本身去interact。

內置的交互

內置的交互在map中都是默認的。

var map = new ol.Map({
    interactions: ol.interaction.defaults().extends()
    // .... 其他代碼
})

ol.interaction.defaults()默認包含如下交互:

  • 鼠標
    • 按住alt+shift鍵,用鼠標左鍵拖動地圖,就能讓地圖旋轉,對應的交互類爲ol.interaction.DragRotate。
    • 用鼠標左鍵雙擊地圖,就能夠放大地圖,對應的交互類爲ol.interaction.DoubleClickZoom。
    • 用鼠標左鍵,拖拽地圖,就能夠平移地圖,對應的交互類爲ol.interaction.DragPan。
    • 滾動鼠標中間的滑輪,就能夠縮放地圖,對應的交互類爲ol.interaction.MouseWheelZoom。
    • 按住shift鍵,同時用鼠標左鍵在地圖上拖動,就能夠放大地圖,對應的交互類爲ol.interaction.DragZoom。
  • 觸摸屏
    • 在觸摸屏上,用兩個手指在觸摸屏上旋轉,就能夠旋轉地圖,對應的交互類爲ol.interaction.PinchRotate。
    • 在觸摸屏上,用兩個手指在觸摸屏上縮放,就能夠縮放地圖,對應的交互類爲ol.interaction.PinchZoom。
  • 鍵盤(注意:須要設置tabindex,才能使div得到鍵盤事件,就是在聲明id的那個div中添加:tabindex="0")
    • 用鍵盤上的上下左右鍵,就能夠平移地圖,對應的交互類爲ol.interaction.KeyboardPan。
    • 用鍵盤上的+/-鍵,就能夠縮放地圖,對應的交互類爲ol.interaction.KeyboardZoom。

若是想要取消某個交互事件

var map = new ol.Map({
    interactions: ol.interaction.defaults({
        mouseWheelZoom: false, // 取消滾動鼠標中間的滑輪交互
        shiftDragZoom: false, // 取消shift+wheel左鍵拖動交互
    })
    // .... 其他代碼
})

extend()爲擴展

var map = new ol.Map({
    interactions: ol.interaction.defaults().extend()
    // .... 其他代碼
})

map.getInteraction()是獲取控件的信息,
若是想要添加其餘的交互,可使用map中的一個方法,map.addInteraction()

map.addInteraction(new ol.interaction.MouseWheelZoom);

關於new Interaction(),總共有7個子類,能夠用在extend([])中,也能夠用addInteraction()

  • DoubleClickZoom interaction,雙擊放大交互功能;
  • DragAndDrop interaction,以「拖文件到地圖中」的交互添加圖層;
  • DragBox interaction,拉框,用於劃定一個矩形範圍,例子經常使用於放大地圖;
  • DragPan interaction,拖拽平移地圖;
  • DragRotateAndZoom interaction,拖拽方式進行縮放和旋轉地圖;
  • DragRotate interaction,拖拽方式旋轉地圖;
  • DragZoom interaction,拖拽方式縮放地圖;
  • Draw interaction,繪製地理要素功能;
  • KeyboardPan interaction,鍵盤方式平移地圖;
  • KeyboardZoom interaction,鍵盤方式縮放地圖;
  • Select interaction,選擇要素功能;
  • Modify interaction,更改要素;
  • MouseWheelZoom interaction,鼠標滾輪縮放功能;
  • PinchRotate interaction,手指旋轉地圖,針對觸摸屏;
  • PinchRoom interaction,手指進行縮放,針對觸摸屏;
  • Pointer interaction,鼠標的用戶自定義事件基類;
  • Snap interaction,鼠標捕捉,當鼠標距離某個要素必定距離以內,自動吸附到要素。

這些子類均可以查API,有詳細解釋。這些子類中,有個經常使用的屬性condition或方法handleEvent(mapBrowserEvent)

condition

表明的是事件名稱,好比:click,doubleClick,主要是依據ol.events。主要有如下幾種,默認是singleClick

  • altKeyOnly 僅按下alt鍵則返回true
  • shiftKeyOnly 僅按下shift鍵則返回true
  • altShiftKeysOnly 僅按下alt鍵+shift則返回true
  • always
  • never
  • click,只要是點擊,包括singleClick,doubleClick都返回true
  • doubleClick
  • singleClick
  • focus 若是地圖具備焦點,則返回true。此條件須要具備tabindex屬性的地圖目標元素,例如
  • mouseOnly 從鼠標設備發起爲true
  • noModifierKeys 沒有組合鍵則返回true
  • pointerMove 指針移動時返回true
  • targetNotEditable 若是目標元素不可編輯,則返回true,即不是input,select或textarea元素false。
  • platformModifierKeyOnly
  • primaryAction 從一個主指針在與表面接觸或起源若是按下鼠標左鍵

handleEvent(mapBrowserEvent)

function (mapBrowserEvent){
    return ol.events.condition.click(mapBrowserEvent) && ol.events.condition.shiftKeyOnly(mapBrowserEvent);
}
Select

是個選擇圖形的類,用於交互.
new ol.interaction.Select(options)
options是個對象參數,包括:

  • style
  • layers 應從中選擇要素的圖層列表。或者,能夠提供過濾功能。將爲地圖中的每一個圖層調用該函數,並應返回true您想要選擇的圖層。若是該選項不存在,則全部可見圖層都將被視爲可選擇。
  • condition 類型爲 ol.events.ConditionType,規定了什麼狀況下觸發 select 操做,默認不須要特殊條件進行觸發。
  • addCondition
  • removeCondition
  • toggleCondition 獲取module:ol/MapBrowserEvent-MapBrowserEvent和返回布爾值的函數,以指示是否應該處理該事件。這是condition事件的補充。默認狀況下, module:ol/events/condition-shiftKeyOnly即按下shift以及condition事件,若是當前未選中,則將該功能添加到當前選擇,若是是,則將其刪除。見add而remove 若是你想使用的,而不是一個觸發不一樣的事件。
  • multi 用於肯定默認行爲是否應僅在單擊的地圖位置選擇單個feature或全部(重疊)feature。默認值false表示單選。
  • features
  • filter 過濾 見demo
  • wrapX 當地圖水平顯示多個相同位置時,是否顯示多個勾繪任務,默認爲 false
    select點擊事件
selectSingleClick.on('select', function (event) {
    console.log(event)
})

該select也有set/get方法,用來獲取或者設置屬性,好比獲取選中的features,獲取全部屬性名稱和值的對象getProperties。

Draw

是個繪製圖形的類,默認支持繪製的圖形類型包含 Point(點)、LineString(線)、Polygon(面)和Circle(圓)。觸發的事件包含 drawstart和drawend,分別在勾繪開始時候(單擊鼠標)和結束時候觸發(雙擊鼠標)。
new ol.interaction.Draw(options)
options是個對象參數,包括:

  • type: 幾何類型(加粗爲默認)
    • Point
    • LineString
    • LinearRing
    • Polygon
    • MultiPoint
    • MultiLineString
    • MultiPolygon
    • GeometryCollection
    • Circle
  • source 數據源,若是想要保存繪製的圖形,須要有一個載體來存儲繪製的圖形,好比新建一個layer,這個layer的source就是該繪製的source。
    • var drawLayer = new ol.layer.Vector({
            source:new ol.source.Vector()
        }) // 新建一個層
        map.addLayer(drawLayer)
        var draw = new ol.interaction.Draw({
            source: drawLayer.getSource(), // 數據源就是新建層的數據源
            type: 'Point',
        })
        map.addInteraction(draw);
  • style
  • stopClick
  • condition 類型爲 ol.events.ConditionType,規定了什麼狀況下觸發 draw 操做,默認不須要特殊條件進行觸發。
  • clickTolerance: 數值類型,單位是像素,判斷用戶鼠標(PC)或者手指(移動設備)的行爲是添加點,仍是按住鼠標或者手指不鬆開進行拖拽地圖,默認值是 6 像素,也就是說當按下鼠標和擡起鼠標左鍵之間的這段時間段內,若是地圖被拖動沒有超過 6 像素,那麼默認爲添加一個點,相反若是超過了 6 像素,那麼不會添加點,只是平移一下地圖。
  • snapTolerance 數值,像素爲單位,默認值是 12 像素,當必定位置內最後一個點吸附到第一個點,對多邊形時有用
  • features
  • maxPoints 表示繪製單個要素(面和線)最多的點數限制,默認沒有限制
  • minPoints 表示繪製單個要素(面和線)須要的最少點數,面默認爲 3,線默認爲 2
  • geometryName 字符串類型,繪製的 geometry 的名稱。
  • geometryFunction 由於默認type只有四種:Point(點)、LineString(線)、Polygon(面)和Circle(圓),此方法就是能夠用來繪製規則或者本身想要繪製的圖形的方法,該函數有兩個參數,一個是座標集合、一個是勾繪的 geometry 類型,返回構造好的 geometry 對象,用來初始化要素。
    • var draw = new ol.interaction.Draw({ // 繪製矩形
            type: 'LineString',
            maxPoints: 2,
            geometryFunction: function(coordinates, geometry){
                if(!geometry){
                    geometry = new ol.geom.Polygon(null);
                }
                var start = coordinates[0];
                var end = coordinates[1];
                geometry.setCoordinates([
                    [start, [start[0], end[1]], end, [end[0], start[1]], start]
                ]);
                return geometry;
            }
            // 其他代碼塊
        })
    • 上面的例子用LineString的形式去繪製矩形,這裏的原理就是捕捉鼠標點擊的點,而後獲取限制的兩個點的座標,用來初始化一個矩形框。
  • wrapX 當地圖水平顯示多個相同位置時,是否顯示多個勾繪任務,默認爲 false
  • freehand 默認是false,是否以曲線的形式,不是規範化的,看demo-freehandDraw.html
  • freehandCondition 類型同condition,也是 ol.events.ConditionType,這個選項規定了什麼狀況下觸發不用重複點擊繪製模式,即拖拽鼠標就能夠繪製圖形的模式,默認狀況下是按下 shift 按鍵,這種模式對於不容易繪製的曲線比較方便,並且釋放 shift 狀況下,若是沒有完成繪製,能夠繼續使用點擊繪製。(就是須要輔助鍵,例如shift,ctrl時,會以曲線形式繪畫)--demo-secondDraw.html,按shift繪畫能夠發現。
    drawstart/drawend
// 繪製結束時進行回調
draw.addEventListener('drawend', function (evt) {
    // 獲取繪製圖形的全部座標點(終止點是起始點)
    var feature = evt.feature
    var geometry = feature.getGeometry()
    var coordinate = geometry.getCoordinates()
    // console.log(coordinate)
    var lent = coordinate[0].length // 座標點個數
})
Modify

用於修改要素幾何的交互。要修改已添加到現有源的功能,請使用該source選項構建修改交互,若是要修改集合中的要素(例如,選擇交互使用的集合),請使用該features選項構建交互。必須使用source或features構建交互
默認狀況下,交互將容許在alt 按下鍵時刪除頂點。要配置具備不一樣刪除條件的交互,請使用該deleteCondition選項。
new ol.interaction.Modify(options)
options是一個參數對象,以下:

  • condition
  • style
  • source
  • features
  • wrapX
  • insertVertexCondition 一個函數,它接受module:ol/MapBrowserEventMapBrowserEvent並返回一個布爾值,以指示是否能夠將新頂點添加到草圖要素中。默認是module:ol/events/condition-always。 同deletCondition
  • deleteCondition 獲取module:ol/MapBrowserEventMapBrowserEvent和返回布爾值的函數,以指示是否應該處理該事件。默認狀況下, module:ol/events/condition-singleClick與 module:ol/events/conditionaltKeyOnly在頂點缺失的結果。看demo-modifyDifficult.html(先選中後操做)
Snap

在修改或繪製矢量要素時處理矢量要素的捕捉。這些功能能夠來自一個module:ol/source/Vector或module:ol/Collection-Collection 任何交互對象,容許用戶使用鼠標與功能進行交互能夠從捕捉中受益,只要它以前添加。

快照交互會修改地圖瀏覽器事件coordinate和pixel 屬性,以強制對其進行的任何交互進行快照。
new ol.interaction.Snap(options) 看API
options:

  • features 應提供此選項或來源。
  • edge 抓住邊緣。默認值時true
  • vertex 捕捉到頂點。默認值是true
  • source 捕捉此來源的功能。應提供此選項或功能

官方例子Snap Interaction

事件
簡單例子
var map = new ol.Map({
    layers: [
        new ol.layer.Tile({
        source: new ol.source.OSM()
        })
    ],
    target: 'map',
    view: new ol.View({
        center: ol.proj.transform(
            [104, 30], 'EPSG:4326', 'EPSG:3857'),
        zoom: 10
    })
});

// 監聽singleclick事件
map.on('singleclick', function(event){
    // 經過getEventCoordinate方法獲取地理位置,再轉換爲wgs84座標,並彈出對話框顯示
    alert(ol.proj.transform(map.getEventCoordinate(event), 'EPSG:3857', 'EPSG:4326'));
})

任意的事件應用,必然會有三個步驟:

  • 找準事件發送者,好比上面這個例子,map就是事件發送者。 如何找到它呢? 通常都是要交互的對象。
  • 找準事件名稱,好比上面例子中的singleclick,切忌不要隨便想象,或者按照慣例來寫名稱-condition,
  • 編寫事件響應函數,在OpenLayers中,事件發送者都會有一個名字爲on的函數,調用這個函數,就能監聽指定的事件,響應函數listener具備一個參數event,這個event類就對應於API文檔中事件名稱後邊括號裏的類。
    forEachFeatureAtPixel(pixel, callback, opt_options)

    註銷事件
  • // 建立事件監聽器
      var singleclickListener = function(event){
          alert('...');
          // 在響應一次後,註銷掉該監聽器
          map.un('singleclick', singleclickListener);
      };
      map.on('singleclick', singleclickListener);
  • // 使用once函數,只會響應一次事件,以後自動註銷事件監聽
      map.once('singleclick', function(event){
          alert('...');
      })
    自定義事件

    要添加自定義事件,須要知道這樣一個事實:ol.Feature繼承於ol.Object,而ol.Object具備派發事件(dispatchEvent)和監聽事件(on)的功能。

  • dispatchEvent(event) 分發一個事件,並調用偵聽此類事件的全部監聽器,event參數能夠是字符串,也能夠是具備type屬性的Object
  • on(type, listener) 觸發type類型的監聽器。

// 爲地圖註冊鼠標移動事件的監聽
map.on('pointermove', function (event) {
    map.forEachFeatureAtPixel(event.pixel, function (feature) {
        // 爲移動到的feature發送自定義的mousemove消息
        feature.dispatchEvent({ type: 'mousemove', event: event });
        // feature.dispatchEvent('mousemove');
    });
});

// 爲feature1(以前建立的一個feature)註冊自定義事件mousemove的監聽
feature1.on('mousemove', function (event) {
    // 修改feature的樣式爲半徑100像素的園,用藍色填充
    this.setStyle(new ol.style.Style({
        image: new ol.style.Circle({
            radius: 100,
            fill: new ol.style.Fill({
                color: 'blue'
            })
        })
    }));
});
dispatchEvent的參數具備type和event屬性,必須這樣構造嗎?在回答這個問題以前,須要先看一下API文檔,發現參數類型爲goog.events.EventLike,說明它其實用的是google的closure庫來實現的,經過closure庫的源碼咱們知道,派發的事件若是是一個對象,那麼必須包含type屬性,用於表示事件類型。其餘的屬性能夠自由定義,好比此處定義了event屬性,並設置對應的值,爲的是讓鼠標事件傳遞給feature1的監聽函數。dispatchEvent的參數會被原封不動的傳遞給事件響應函數,對應代碼`feature1.on('mousemove', function(event){}`裏參數event,能夠經過調試窗口看到此處的event和dispatchEvent的參數是同樣的。注意事件名稱是能夠自定義的,只要派發和監聽使用的事件名稱是一致的就能夠。

除了能夠經過dispatchEvent({type: 'mousemove', event: event})這種形式派發一個事件以外,還能夠經過dispatchEvent('mousemove')這中形式直接發送mousemove事件。

總結

openlayers功能不少,有的地方本身因時間有限尚未深刻了解,可是大部分是夠用了,有大部分都是參考資料的,由於講的很通透,因此就拿過來了。,對於openylayers3,必定多看看官方例子,例子有不少吸取的知識點,特別有用。有時間後會本身補上這一環節,你們若是有疑問或者我不對的地方請下方評論或私信。你們一塊兒進步加油!

參考資料

openlayer3
OpenLayers 3 Primer

相關文章
相關標籤/搜索