1. 程式人生 > >Openlayers之地圖標註

Openlayers之地圖標註

1、標註的簡介

標註簡單點說就是通過圖示、文字等方式將我們想展示的內容顯示在地圖上,著重突出人們所關注的專題內容,從而為使用者提供個性化的地圖服務;

2、標註方式

在Openlayers3裡面,有兩種對地理位置點進行標註的方法,一種是通過建立向量圖層然後設定其樣式的方法,還有一種就是建立Overlay覆蓋層的方法;對於第一種方式,本質上建立的還是一個向量物件,只是將其表現形式更換了一下,用Style樣式進行包裝;而第二種方式則是建立的一個單獨的覆蓋層,然後通過設定其屬性進行某些資訊的展示;至於具體使用哪一種方式,還是得根據具體來看;

3、程式碼實現

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <script src="../lib/jquery/jquery.js"></script>
    <script src="../lib/ol/ol.js"></script>
    <link href="../css/ol.css" rel="stylesheet" />
    <style type="text/css">
        body, html, div, ul, li,img
        {
            border:none;
            padding:0px;
            margin:0px;
        }
        #menu
        {
            width:100%;
            height:20px;
            padding:5px 10px;
            left:10px;
            font-size:14px;
            font-family:"微軟雅黑";
        }
        .checkbox
        {
            margin:5px 15px;
        }
        .marker
        {
            width:20px;
            height:20px;
            border:1px solid #088;
            border-radius:10px;
            background-color:#0FF;
            opacity:0.5;
        }
        .address
        {
            text-decoration:none;
            color:#aa3300;
            font-size:14px;
            font-weight:bold;
            text-shadow:black 0.1em 0.1em 0.2em;
        }
    </style>
    <script type="text/javascript">
        $(function () {
            //北京地理座標
            var beijing = ol.proj.fromLonLat([116.28, 39.54]);
            //武漢地理座標
            var wuhan = ol.proj.fromLonLat([114.21,30.37]);

            //初始化地圖
            var map = new ol.Map({
                target: 'map',
                layers: [
                    new ol.layer.Tile({
                        source:new ol.source.OSM()
                    })
                ],
                view: new ol.View({
                    center: beijing,
                    zoom: 6,
                    minZoom:2
                })
            });

            //建立標籤的樣式
            var createLabelStyle = function (feature) {
                //返回一個樣式
                return new ol.style.Style({
                    //把點的樣式換成ICON圖示
                    image: new ol.style.Icon({
                        //控制標註圖片和文字之間的距離
                        anchor: [0.5, 60],
                        //標註樣式的起點位置
                        anchorOrigin: 'top-right',
                        //X方向單位:分數
                        anchorXUnits: 'fraction',
                        //Y方向單位:畫素
                        anchorYUnits: 'pixels',
                        //偏移起點位置的方向
                        offsetOrigin: 'top-right',
                        //透明度
                        opacity: 0.75,
                        //圖片路徑
                        src: '../images/label/blueIcon.png'
                    }),
                    //文字樣式
                    text: new ol.style.Text({
                        //對齊方式
                        textAlign: 'center',
                        //文字基線
                        textBaseline: 'middle',
                        //字型樣式
                        font: 'normal 14px 微軟雅黑',
                        //文字內容
                        text: feature.get('name'),
                        //填充樣式
                        fill: new ol.style.Fill({
                            color: '#aa3300'
                        }),
                        //筆觸
                        stroke: new ol.style.Stroke({
                            color: '#ffcc33',
                            width: 2
                        })
                    })
                });
            };

            //初始化要素
            var iconFeature = new ol.Feature({
                //點要素
                geometry: new ol.geom.Point(beijing),
                //名稱屬性
                name: '北京市',
                //人口屬性
                population: 2115
            });
            //為點要素新增樣式
            iconFeature.setStyle(createLabelStyle(iconFeature));

            //初始化向量資料來源
            var vectorSource = new ol.source.Vector({
                //指定要素
                features:[iconFeature]
            });

            //初始化向量圖層
            var vectorLayer = new ol.layer.Vector({
                //資料來源
                source:vectorSource
            });
            //將向量圖層新增到map中
            map.addLayer(vectorLayer);

            //初始化覆蓋層標註
            var marker = new ol.Overlay({
                //位置座標
                position: wuhan,
                //覆蓋層如何與位置座標匹配
                positioning: 'center-center',
                //覆蓋層的元素
                element: document.getElementById('marker'),//ToDo 此處不能用JQuery方式$('#marker')獲取元素
                //事件傳播到地圖視點的時候是否應該停止
                stopEvent:false
            });
            //將覆蓋層新增到map中
            map.addOverlay(marker);

            //設定覆蓋層的title屬性
            marker.getElement().title = '武漢市';
            //初始化文字覆蓋層
            var text = new ol.Overlay({
                //位置
                position: wuhan,
                //覆蓋層的元素
                element: document.getElementById('address')
            });
            //將文字覆蓋層新增到map中
            map.addOverlay(text);
            //設定文字覆蓋層的內容為之前建立的覆蓋層的title屬性
            text.getElement().innerText = marker.getElement().title;

            //地圖的點選事件
            map.on('click', function (evt) {
                //獲取單選按鈕的選項
                var type = $('input[name="label"]:checked').val();
                //獲取位置座標
                var point = evt.coordinate;
                //如果型別是向量標註則新增向量標籤,否則新增覆蓋標籤
                if (type == 'vector') {
                    addVectorLabel(point);
                } else if (type == 'overlay') {
                    addOverlayLabel(point);
                } 
            });

            //新增向量標籤
            function addVectorLabel(coordinate) {
                //初始化一個新的點要素
                var newFeature = new ol.Feature({
                    geometry: new ol.geom.Point(coordinate),
                    name: '標註點'
                });
                //設定點的樣式
                newFeature.setStyle(createLabelStyle(newFeature));
                //將當前要素新增到向量資料來源中
                vectorSource.addFeature(newFeature);
            }

            //新增覆蓋標註
            function addOverlayLabel(coordinate) {
                //建立一個div元素
                var elementDiv = document.createElement('div');
                //設定div元素的樣式類
                elementDiv.className = 'marker';
                //設定div元素的title屬性
                elementDiv.title = '標註點';

                //獲取id為label的div標籤
                var overlay = document.getElementById('label');
                //將新建立的div標籤新增到overlay中
                overlay.appendChild(elementDiv);

                //建立一個a標籤元素
                var elementA = document.createElement('a');
                //設定a標籤的樣式類
                elementA.className = 'address';
                //設定a標籤的連結地址
                elementA.href = '#';
                //設定a標籤的超連結文字
                setInnerText(elementA, elementDiv.title);
                //將a標籤元素新增到div標籤元素中
                elementDiv.appendChild(elementA);

                //新建一個覆蓋層
                var newMarker = new ol.Overlay({
                    //設定位置為當前滑鼠點選的座標
                    position: coordinate,
                    //設定覆蓋層與位置之間的匹配方式
                    positioning: 'center-center',
                    //覆蓋層元素
                    element: elementDiv,
                    //事件傳播到地圖視點的時候是否應該停止
                    stopEvent:false
                });
                //將覆蓋層新增到map中
                map.addOverlay(newMarker);

                //新建一個文字覆蓋層
                var newText = new ol.Overlay({
                    //設定位置為當前滑鼠點選的座標
                    position: coordinate,
                    //覆蓋層元素
                    element:elementA
                });
                //將文字覆蓋層新增到map中
                map.addOverlay(newText);
            }

            //設定文字內容
            function setInnerText(element,text) {
                if (typeof element.textContent == 'string') {
                    element.textContent = text;
                } else {
                    element.innerText = text;
                }
            }
        });
    </script>
</head>
<body>
    <div id="menu">
        <label class="checkbox">
            <input type="radio" name="label" value="vector" checked="checked" />
            Vector Label
        </label>
        <label class="checkbox">
            <input type="radio" name="label" value="overlay" />
            Overlay Label
        </label>
    </div>
    <div id="map"></div>
    <div id="label" style="display:none">
        <div id="marker" class="marker" title="Marker">
            <a class="address" id="address" target="_blank" href="http://www.openlayers.org">標註點</a>
        </div>
    </div>
</body>
</html>
4、結果展示

初始化頁面


選中第一個單選按鈕,在地圖頁面上的任何地方點選,將會新增向量標註


選中第二個單選按鈕,則在頁面任意地方單擊,將新增覆蓋標註