openLayers 3知識回顧

来源:https://www.cnblogs.com/sqh17/archive/2018/12/25/10174110.html
-Advertisement-
Play Games

openlayers 知識 前段時間幫助同事重構一個地圖類的項目,然後就學習了openLayer3這個框架,但是官網上沒有中文版,也沒有詳細的例子解釋,我只能遇到看不懂的就翻譯成中文來用,為了方便以後再用這個ol,能夠更快的上手,就花了幾天的時間總結了ol的知識,ol功能很豐富,API也很多,沒有寫 ...


openlayers 知識


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

另外,在總結知識的同時,還寫了demo,加深自己的理解,大家覺得不錯的話,給個star~ GitHub

那麼開始吧!

目錄

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 --> 控制項,類似與按鈕,有放大,縮小,全屏等的按鈕 

最簡單的顯示地圖:

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方法去獲取

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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 瀏覽器標題欄如何設置 只需要在HTML中的 <head></head> 內加入 “Link’’ 和 “Title” 標簽即可。獻上代碼: <Title> 標簽內寫入的內容為 “ 瀏覽器標題欄的標題 ” ; <Link> 屬性 rel = " icon " href = " 圖片路徑 " ; ...
  • 執行npm run build,自動將打包後的項目壓縮成zip文件,便於發送後端部署! ...
  • 一、問題描述 實際學習與工作中可能會有這樣的需求:在移動web中給有重疊的兩個元素都添加了點擊事件,當觸發上方的元素的時候同時也會透過該元素觸發下麵的元素。這就是點透,然而這並不是我想要的效果。 二、例子 下麵通過多種方式來模擬感受點透: 1、使用原生js 直接給兩個盒子綁定點擊事件: 在移動端如下 ...
  • 一、click等事件在移動端的延遲 click事件在移動端和pc端均可以觸發,但是在移動端有延遲現象。 由於早期移動設備瀏覽網頁時內容較小,為了增強用戶體驗,蘋果公司專門為移動設備設計了雙擊放大的功能,以確保用戶可以方便地放大網頁內容,但是當用戶單擊按鈕的時候,移動設備需要延遲約300ms執行,以判 ...
  • DOM1級主要定義的是HTML和XML文檔的底層結構。DOM2級和DOM3級在這個結構基礎上引入了更多的交互能力,也支持更高級的XML特性。為此DOM2級和DOM3級分為了很多的模塊(模塊直接具有某種關聯),分別描述了DOM的某個非常具體的子集。這些模塊如下: DOM2級核心:在1級核心基礎上構建, ...
  • 最近項目遇到問題,發現alert一個彈窗,在IE中,打開開發人員工具後,可以彈出,但是不打開無法彈出,最後發現是console.log的原因,註釋掉console相關的代碼,問題就解決了 有些版本的IE不支持console,會提示未定義console對象。 在相容IE的js代碼中,最好不好用cons ...
  • //兩個按鈕 <input class="btn-primary" type="button" value="全選" id="selectBtn" onclick="selectAll()"/><input class="btn-primary" type="button" value="反選" i ...
  • 準備:GIT的安裝,Gitlab賬戶登陸,webstorm的安裝 1.首先,你得先會在Gitlab中創建一個團體,在團體中創建一個項目,先建組,再建項目,網上哪裡都有教程,隨便找了個網址: https://jingyan.baidu.com/article/ae97a646fb90ffbbfd461 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...