利用OpenLayers3在地圖上顯示標記並點選標記後顯示彈出框
前言
在上一篇《利用全能電子地圖下載器+GeoWebCache釋出Arcgis Server快取瓦片過程全記錄》中,我們利用GeoWebCache作為瓦片地圖伺服器釋出了瓦片地圖。雖然在其中可以直接瀏覽,但是在GeoWebCache1.10.0中,官方內建的是OpenLayers2的版本,這個版本比較老舊,不能很好的適應諸如觸屏裝置等應用環境。所以,我想利用OpenLayers2的升級版OpenLayers3來進行地圖顯示,並增加顯示地圖示記和點選標記後顯示彈出框的功能,這兩個也是比較常用的。
這篇文章可能會比較長,我會對在標題中提到的總目標(在地圖上顯示標記並點選標記後顯示彈出框
模組分解如下:
1、顯示瓦片地圖
2、在地圖上顯示標記
3、在點選標記後顯示彈出框
Let’s Start~
環境
- GeoWebCache:1.10.0
- OpenLayers:3.13.1
Part I 顯示瓦片地圖
效果
思路
GeoWebCache本身就是一個WMS服務,所以只需要利用OpenLayers3與這個WMS服務對接即可。
實現步驟
Step1:建立HTML檔案,並引入OpenLayers的相關js與css檔案
<link rel="stylesheet" type="text/css" href="../ol.css" />
<script src="../ol.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
Step2:建立一個div,只需要一個ID屬性
<div id="map"></div>
需要記住這個id值,後面的指令碼會用到
Step3:獲取投影座標系,建立map物件
//獲取投影座標系
var pos = ol.proj.get('EPSG:3857');
var map = new ol.Map({
//地圖容器div的ID
target: 'map',
//地圖容器中載入的圖層
layers: [],
view: new ol.View({
//設定地圖投影座標系
projection: pos,
//設定地圖載入時的初始中心點
center: [13276805.940731, 3008561.497087],
//縮放級別
zoom: 19
}),
});
相關API:
1、new ol.Map
2、new ol.View
關於View構造引數的說明:
1、center
引數的獲取方式:
a、在GeoWebCache中進入地圖瀏覽模式,利用瀏覽器的開發者工具(這裡以Google Chrome為例)開啟NetWork選項卡
b、隨機點選Type值為png的連線,在Preview選項卡中,要是有瓦片地圖的狀態,而不是網格的狀態,並記下URL,後續步驟要使用
這是我們想要的效果:
這不是我們想要的效果:
c、找到URL中的BBOX引數
BBOX=13280473.174523,3009173.884415,13281084.670715,3009785.380607
d、將前兩個值,這裡是13280473.174523
和3009173.884415
填入center
屬性即可。
2、zoom
引數:為下載瓦片地圖時選擇的地圖級別。
注意二者要對應起來,zoom
資訊可以在Header(如果是Chrome瀏覽器的除錯視窗)中找到
Step4:建立瓦片地圖層
var mlayer = new ol.layer.Tile({
source: new ol.source.TileWMS({
url: 'http://XXX.xxx.com/geowebcache/service/wms',
params: {
'LAYERS': 'fzgl',
'FORMAT': 'image/png',
'SRS': 'EPSG:3857'
},
tileGrid: new ol.tilegrid.TileGrid({
resolutions: [156543.0339, 78271.51696, 39135.75848, 19567.87924, 9783.939621, 4891.96981, 2445.984905, 1222.992453, 611.496226, 305.748113, 152.874057, 76.437028, 38.218514, 19.109257, 9.554629, 4.777314, 2.388657, 1.194329, 0.597164, 0.298582],
origin: [-20037508.3427892, 20037508.3430388]
})
})
})
相關API:
1、new ol.layer.Tile
2、new ol.source.TileWMS
3、new ol.tilegrid.TileGrid
關於Tile物件的構造引數的說明:
1、url
引數:如果你的Web Server(eg.Tomcat)沒有經過特殊配置的話,直接替換XXX.xxx.com為你的地址即可
2、params
引數、FORMAT
引數、SRS
引數,都可以從Step3中記下的URL裡的對應引數位置找到
3、resolutions
引數:可以從geowebcache對應的地圖預覽的網頁原始碼找到
4、origin
引數:可以從Arcgis瓦片的conf.xml中找到
4、這幾個引數是最基本的,如果有缺失或填寫錯誤,地圖將無法正常渲染
Step5:將建立好的瓦片地圖層新增進Map中
map.addLayer(mlayer)
相關API
1、map.addLayer
Done!
例項演示,點這裡
Part II 在地圖上顯示標記
效果
思路
在地圖上顯示標記,相當於在原來的瓦片地圖層上由新疊加了一層,在OpenLayers中稱為向量層。可以把這種疊加的原理理解為PS中的圖層,通過各種圖層的疊加,達到我們想要的效果。這些地圖上的圖示,就存在與向量層上。所以,我們只需要建立向量層,並新增進map中即可。
實現步驟
Step1:建立空的向量容器
注:在OpenLayers中,每一個地圖上的圖示,稱做一個Feature,這個向量容器就是用來裝Feature的
var vectorSource = new ol.source.Vector({});
相關API:
1、new ol.source.Vector
Step2:建立Feature,並新增進向量容器中
//建立圖示特性
var iconFeature = new ol.Feature({
geometry: new ol.geom.Point([t1, t2], "XY"),
name: "my Icon",
});
//將圖示特性新增進向量中
vectorSource.addFeature(iconFeature);
相關API:
1、new ol.Feature
2、new ol.geom.Point
3、vectorSource.addFeature
幾點說明:
1、上面程式碼中的t1、t2即要顯示標記的位置,填入你想讓標記出現的經緯度即可。
Step3:建立標記的樣式
//建立圖示樣式
var iconStyle = new ol.style.Style({
image: new ol.style.Icon({
opacity: 0.75,
src: "http://openlayers.org/en/v3.9.0/examples/data/icon.png"
}),
});
相關API:
1、new ol.style.Style
2、new ol.style.Icon
Step4:建立向量層,並新增進map層
//建立向量層
var vectorLayer = new ol.layer.Vector({
source: vectorSource,
style: iconStyle
});
//新增進map層
map.addLayer(vectorLayer);
相關API:
1、new ol.layer.Vector
Done!
示例演示,點這裡
Part III 在點選標記後顯示彈出框
效果
思路
這個是在這幾個案例中最複雜的一個了。
分析:在OpenLayers3中,彈出框是一個Overlay,overlay的中文是覆蓋物的意思,彈出框不就是一個覆蓋物嗎?
這裡又牽扯到一個新的知識點,那就是地圖的事件監聽,在map類中有一個on方法,但這個方法的確能對點選事件進行監聽,但是是對整個map的。也就是說,我點選地圖上的任何位置,都會觸發這個監聽事件,效果上並不是我們想要的。我們想要的是在點選標記後才觸發監聽事件。幸運的是,OpenLayers在map類中為我們提供了一個函式,叫forEachFeatureAtPixe
,這個函式的工作原理有點類似物理中的光電門,這個函式會對所給定的畫素範圍進行掃描,如果發現Feature(標記就是一個Feature),就會觸發回掉函式。那麼如何給定點選畫素呢?OpenLayers又很貼心地給我們準備了getEventPixe
函式,這個函式會在事件觸發時,返回對應的畫素範圍。
總結思路: 在點選地圖時觸發getEventPixel
函式返回區域->呼叫forEachFeatureAtPixel
進行畫素區域掃描,如果發現Feature,則啟用彈出框。
實現步驟
Step1:在HTML中新增一個div,用於顯示彈出框
<div id="popup" class="ol-popup">
<a href="#" id="popup-closer" class="ol-popup-closer"></a>
<div id="popup-content"></div>
</div>
1、這裡所有的id都需要記錄
2、這裡還需要對彈出框設定樣式,例子CSS樣式將在文章最後的原始碼中給出
Step2:在js中獲取HTML元素
var container = document.getElementById("popup");
var content = document.getElementById("popup-content");
var popupCloser = document.getElementById("popup-closer");
1、container:最外層包含所有元素的div
2、content:顯示彈出框具體內容的div
3、popupCloser:彈出框的關閉按鈕,是一個a標籤
Step3:建立一個Overlay
var overlay = new ol.Overlay({
//設定彈出框的容器
element: container,
//是否自動平移,即假如標記在螢幕邊緣,彈出時自動平移地圖使彈出框完全可見
autoPan: true
});
相關API:
1、new ol.Overlay
Step4:在map上繫結點選事件監聽
map.on('click',function(e){
//在點選時獲取畫素區域
var pixel = map.getEventPixel(e.originalEvent);
map.forEachFeatureAtPixel(pixel,function(feature){
//coodinate存放了點選時的座標資訊
var coodinate = e.coordinate;
//設定彈出框內容,可以HTML自定義
content.innerHTML = "<p>你點選的座標為:" + coodinate + "</p>";
//設定overlay的顯示位置
overlay.setPosition(coodinate);
//顯示overlay
map.addOverlay(overlay);
});
});
相關API:
1、map.on
2、map.getEventPixel
3、map.forEachFeatureAtPixel
4、overlay.setPosition
5、map.addOverlay
Done! 至此,在地圖上點選標記時,就會有彈出框顯示了~
示例演示,點這裡
演示與示例程式碼合集
本文用到的API合集
參考資料
1、Openlayers3 載入Geowebcache 釋出的 ArcGIS 切片地圖
2、Openlayer 3 的點選彈出框
寫在最後
由於OpenLayers3幾乎沒有中文的API,於是乎就去翻譯了,翻譯了兩天,部分語句採用了Google Translate的翻譯結果。如果出現錯誤可以在評論區反饋~多謝諒解~~其實翻譯一遍在結合程式碼理解會更清晰一些~