1. 程式人生 > >利用OpenLayers3在地圖上顯示標記並點選標記後顯示彈出框

利用OpenLayers3在地圖上顯示標記並點選標記後顯示彈出框

前言

在上一篇《利用全能電子地圖下載器+GeoWebCache釋出Arcgis Server快取瓦片過程全記錄》中,我們利用GeoWebCache作為瓦片地圖伺服器釋出了瓦片地圖。雖然在其中可以直接瀏覽,但是在GeoWebCache1.10.0中,官方內建的是OpenLayers2的版本,這個版本比較老舊,不能很好的適應諸如觸屏裝置等應用環境。所以,我想利用OpenLayers2的升級版OpenLayers3來進行地圖顯示,並增加顯示地圖示記點選標記後顯示彈出框的功能,這兩個也是比較常用的。
這篇文章可能會比較,我會對在標題中提到的總目標(在地圖上顯示標記並點選標記後顯示彈出框

)進行模組分解,並配上所用的API解析,化整為零嘛~各位也可以各取所需~
模組分解如下:
1、顯示瓦片地圖
2、在地圖上顯示標記
3、在點選標記後顯示彈出框
Let’s Start~

環境

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.1745233009173.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! 至此,在地圖上點選標記時,就會有彈出框顯示了~
示例演示,點這裡

演示與示例程式碼合集

GitHub
演示合集

本文用到的API合集

Openlayer3.13.1的幾個API的部分翻譯

參考資料

1、Openlayers3 載入Geowebcache 釋出的 ArcGIS 切片地圖
2、Openlayer 3 的點選彈出框

寫在最後

由於OpenLayers3幾乎沒有中文的API,於是乎就去翻譯了,翻譯了兩天,部分語句採用了Google Translate的翻譯結果。如果出現錯誤可以在評論區反饋~多謝諒解~~其實翻譯一遍在結合程式碼理解會更清晰一些~