meface/docs/article/gis/openlayers/overlay.md

12 KiB
Raw Blame History

title date author tags categories
内容叠加层 2020-12-25 ac
Overlay
Openlayers
GIS

Overlay

ol.Overlay是一个用于在地图上展示信息的一个小部件Widget作为内容叠加层添加到map可以出现在地图上的任何位置。部件需要一个HTML模版来展示需要显示的内容Overlay部件控制出现的位置,像气泡一样,锚指向设置的位置上。

image-20201214154539548

构造参数Option

<!--创建叠加层-->
var popup = new ol.Overlay({
    //设置该叠加层的标识方便在map中获取该图层map.getOverlayById
	id:'bubble',
    //HTMLElement元素也是叠加层内容内容模版
    element: document.getElementById('popup'),
    //设置偏移量[x,y],像素为单位
    // offset:[200,200],
    //该叠加层的锚点 值为Coordinate
    position:ol.proj.fromLonLat([113.958334, 22.535640]),
    //设置锚点相对于叠加层内容的位置'bottom-left', 'bottom-center', 'bottom-right', 'center-left', 'center-center', 'center-right', 'top-left', 'top-center', and 'top-right'.
    positioning:"center-center",
    //是否应该停止在viewport中的事件传播。默认true图层会在ol-overlaycontainer-stopevent里面false则会在ol-overlaycontainer中
    stopEvent:true,
    //是否替换第一个overlay容器
    insertFirst:false,
    autoPan: true,//当气泡显示在窗口边缘存在气泡显示不完全时view视图将移动到显示整个气泡的视图
    autoPanAnimation: {
		duration: 250
	},
	// className:"customClass"//添加自定义样式
});

应用

场景一

已知特定的点位,对其进行注记或说明。

image-20201214154539548

<!doctype html>
<html >
  <head>
    <link rel="stylesheet" href="css/ol.css" type="text/css">
    <style>
      .map {
        height: 400px;
        width: 100%;
      }
      .ol-popup {
        position: absolute;
        background-color: white;
        box-shadow: 0 1px 4px rgba(0,0,0,0.2);
        padding: 15px;
        border-radius: 10px;
        border: 1px solid #cccccc;
        bottom: 12px;
        left: -50px;
        min-width: 280px;
      }
      .ol-popup:after, .ol-popup:before {
        top: 100%;
        border: solid transparent;
        content: " ";
        height: 0;
        width: 0;
        position: absolute;
        pointer-events: none;
      }
      .ol-popup:after {
        border-top-color: white;
        border-width: 10px;
        left: 48px;
        margin-left: -10px;
      }
      .ol-popup:before {
        border-top-color: #cccccc;
        border-width: 11px;
        left: 48px;
        margin-left: -11px;
      }
      .ol-popup-closer {
        text-decoration: none;
        position: absolute;
        top: 2px;
        right: 8px;
      }
      .ol-popup-closer:after {
        content: "✖";
      }
    </style>
    <script src="lib/ol.js"></script>
    <title>OpenLayers example</title>
    <meta charset="UTF-8">
  </head>
  <body>
    <h2>Overlay 地图注记</h2>
    <div id="map" class="map"></div>
    <!--popup容器-->
    <div id="popup" class="ol-popup">
      <a href="#" id="popup-closer" class="ol-popup-closer"></a>
      <div id="popup-content">
        叠加层的内容(模版)
      </div>
    </div>

    <script type="text/javascript">
        var map = new ol.Map({
            layers: [
                //加载瓦片图层
                new ol.layer.Tile({
                    source:new ol.source.OSM(),
                    name:"世界地图(OSM瓦片)",
                    id:"osm"
                })
            ],
            target: document.getElementById('map'),
            view: new ol.View({
                center: [12703928.421141896,2575539.5219027703],
                zoom: 11
            })
        });
        //根据已知坐标点指定气泡位置
        var shenzhen = ol.proj.fromLonLat([114.05 ,22.55]);

        <!--创建叠加层-->
        var popup = new ol.Overlay({
            //Overlay 的基本属性
            id:'pipe',//设置该叠加层的标识方便在map中获取该图层map.getOverlayById
            element: document.getElementById('popup'),//HTMLElement元素也是叠加层内容
            // offset:[200,200],//设置偏移量[x,y],像素为单位
            position:shenzhen,//该叠加层的锚点 值为Coordinate
            positioning:"center-center",//
            stopEvent:true,//是否应该停止在viewport中的事件传播。默认true图层会在ol-overlaycontainer-stopevent里面false则会在ol-overlaycontainer中
            insertFirst:true,//是否替换第一个overlay容器
            autoPan: true,
            autoPanAnimation: {
                duration: 2500
            },
            // className:"abcclass"
        });

        popup.setPosition(shenzhen);
        map.addOverlay(popup);

        //绑定气泡的关闭按钮的点击事件,隐藏气泡
        document.getElementById('popup-closer').onclick = function() {
            popup.setPosition(undefined);
            clickPopup.setPosition(undefined);
            this.blur();
            return false;//取消a标签的默认行为点击a标签的默认行为是会跳转页面的
        };
    </script>
  </body>
</html>

场景二

点击矢量要素,展示要素信息。获取要素信息的方法可以使用map中的getFeaturesAtPixel()方法获取layers集合中的矢量图层在该像素点处的要素集合,也可以使用矢量数据源ol.source.Vector中的getFeaturesAtCoordinate方法获取要素信息。当然也可以使用select控件选择要素。

image-20201214170455692

<!doctype html>
<html >
  <head>
    <link rel="stylesheet" href="css/ol.css" type="text/css">
    <style>
      .map {
        height: 400px;
        width: 100%;
      }
      .ol-popup {
        position: absolute;
        background-color: white;
        box-shadow: 0 1px 4px rgba(0,0,0,0.2);
        padding: 15px;
        border-radius: 10px;
        border: 1px solid #cccccc;
        bottom: 12px;
        left: -50px;
        min-width: 280px;
      }
      .ol-popup:after, .ol-popup:before {
        top: 100%;
        border: solid transparent;
        content: " ";
        height: 0;
        width: 0;
        position: absolute;
        pointer-events: none;
      }
      .ol-popup:after {
        border-top-color: white;
        border-width: 10px;
        left: 48px;
        margin-left: -10px;
      }
      .ol-popup:before {
        border-top-color: #cccccc;
        border-width: 11px;
        left: 48px;
        margin-left: -11px;
      }
      .ol-popup-closer {
        text-decoration: none;
        position: absolute;
        top: 2px;
        right: 8px;
      }
      .ol-popup-closer:after {
        content: "✖";
      }
    </style>
    <script src="lib/ol.js"></script>
    <title>OpenLayers example</title>
    <meta charset="UTF-8">
  </head>
  <body>
    <h2>Openlayers 内容叠加层</h2>
    <div id="map" class="map"></div>
    <!--popup容器-->
    <div id="popup" class="ol-popup">
      <a href="#" id="popup-closer" class="ol-popup-closer"></a>
      <div id="popup-content">
        叠加层的内容
      </div>
    </div>
    <script type="text/javascript">
        var vectorSource = new ol.source.Vector({
            format: new ol.format.GeoJSON({geometryName:"geom"}),
            loader: function (extent, resolution, projection) {
                var proj = projection.getCode();
                var url = 'http://localhost:8080/geoserver/wfs?service=WFS&' +
                    'version=1.1.0&request=GetFeature&typename=test:tiger_roads&' +
                    'outputFormat=application/json&srsname=' + proj + '&' +
                    'bbox=' + extent.join(',') + ',' + proj;
                var xhr = new XMLHttpRequest();
                xhr.open('GET', url);
                var onError = function () {
                    vectorSource.removeLoadedExtent(extent);
                }
                xhr.onerror = onError;
                xhr.onload = function () {
                    if (xhr.status == 200) {
                        vectorSource.addFeatures(
                            vectorSource.getFormat().readFeatures(xhr.responseText));
                    } else {
                        onError();
                    }
                }
                xhr.send();
            },
            strategy: ol.loadingstrategy.bbox
        });
        var nyc = ol.proj.fromLonLat([-73.92722, 40.774221]);
        var map = new ol.Map({
            layers: [
                //加载瓦片图层
                new ol.layer.Tile({
                    source:new ol.source.OSM(),
                    name:"世界地图(OSM瓦片)",
                    id:"osm"
                }),
                new ol.layer.Vector({
                    source: vectorSource,
                    id: "nyc"
                })
            ],
            target: document.getElementById('map'),
            view: new ol.View({
                center: nyc,
                zoom: 11
            })
        });

        <!--创建叠加层-->
        var popup = new ol.Overlay({
            //Overlay 的基本属性
            id:'bubble',//设置该叠加层的标识方便在map中获取该图层map.getOverlayById
            element: document.getElementById('popup'),//HTMLElement元素也是叠加层内容
            // offset:[200,200],//设置偏移量[x,y],像素为单位
            position:nyc,//该叠加层的锚点 值为Coordinate
            positioning:"bottom-right",//设置锚点相对于叠加层内容的位置'bottom-left', 'bottom-center', 'bottom-right', 'center-left', 'center-center', 'center-right', 'top-left', 'top-center', and 'top-right'.
            stopEvent:true,//是否应该停止在viewport中的事件传播。默认true图层会在ol-overlaycontainer-stopevent里面false则会在ol-overlaycontainer中
            insertFirst:false,//是否替换第一个overlay容器
            autoPan: true,//当气泡显示在窗口边缘存在气泡显示不完全时view视图将移动到显示整个气泡的视图
            autoPanAnimation: {
                duration: 2500
            },
            // className:"customClass"//添加自定义样式
        });

        popup.setPosition(nyc);
        map.addOverlay(popup);

        //绑定气泡的关闭按钮的点击事件,隐藏气泡
        document.getElementById('popup-closer').onclick = function(e) {
            console.log("closer");
            popup.setPosition(undefined);
            this.blur();
            return false;//取消a标签的默认行为点击a标签的默认行为是会跳转页面的
        };
        map.on('click',function(e){
            var features = map.getFeaturesAtPixel(e.pixel,{
                //设置点击要素的容差
                'hitTolerance':5
            });
            if(features){
                var popupWidget = map.getOverlayById('bubble');
                popupWidget.setPosition(e.coordinate);
                var featurtesInfo = createInfoTemplate(features);
                var content = document.getElementById('popup-content');
                content.innerHTML = featurtesInfo;
            }else{
                popupWidget.setPosition(undefined);
            }
        })
        function createInfoTemplate(features) {
            var template = '<table>'+
                    '<tr><th>gid</th><th>cfcc</th><th>name</th></tr>';
            for(var i=0;i<features.length;i++){
                var property = features[i].values_;
                template += '<tr><td>'+property["gid"]+'</td><td>'+property["cfcc"]+'</td><td>'+property["name"]+'</td></tr>';
            }
            return template;
        }
    </script>
  </body>
</html>