头图

看过之前的文章,对于OpenLayers会有一个大致的了解。下面我们继续讲解 OpenLayer如何创建信息窗口。
下面示例是以 OpenLayersV8.2.0版本 作为依赖包

信息窗体

在Openlayer中,信息窗体属于覆盖物(Overlay),和高德地图的信息窗体类似。Web端,信息窗体与点标记的区别是:前者是通过DOM节点构成,后者是矢量图形。
我们也可以通过覆盖物(Overlay)来创建点标记,不过这个要看开发场景,如果数据量巨大,推荐使用矢量点标记,反之覆盖物点标记也可以。

Overlay

ol.Overlay是覆盖物API,主要用途就是在地图之上覆盖DOM元素,作为弹窗、提示窗、标注信息等,通过给定的经纬度,它会固定在对应的点位上,移动地图或拖动地图,覆盖物(Overlay)与地图的相对位置不变。

  • ol.Overlay:显示在地图上并附加到单个地图位置的元素。与Control一样,套印格式也是可见的小部件。与“控件”不同,它们不在屏幕上的固定位置,而是与地理坐标绑定,因此平移地图将移动“覆盖”。

    const popup = new Overlay({
    element: document.getElementById('popup'),
    autoPan: true,
    positioning: 'bottom-center',
    stopEvent: false,
    offset: [0, 0],
    autoPanAnimation: { duration: 250 }
    // ...更多属性
    });
    popup.setPosition(coordinate);
    map.addOverlay(popup);

    关于ol.OverlayAPI更多属性配置,可以查看官方文档:ol.Overlay

    示例

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <title>点聚合 Map</title>
      <link rel="stylesheet" href="./8.2.0/theme/ol.css">
      <script src="./8.2.0/en/latest/ol/dist/ol.js"></script>
      <!-- <script src="https://cdn.jsdelivr.net/npm/ol@v8.2.0/dist/ol.js"></script>
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@v8.2.0/ol.css"> -->
      <style>
          #infowindow {
              background: rgba(0, 0, 0, 0.66);
              border-radius: 5px;
              padding: 5px;
              color: #fff;
          }
      </style>
    </head>
    
    <body>
      <div id="map" style="height: 95vh; border: 6px solid;"></div>
      <div id="infowindow"></div>
    
      <script>
          const url = 'https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer/tile/{z}/{y}/{x}'
          let map = new ol.Map({
              target: 'map',
              layers: [
                  new ol.layer.Tile({
                      source: new ol.source.XYZ({
                          url: url
                      })
                  })
              ],
              view: new ol.View({
                  center: [116.39, 39.91],
                  zoom: 11,
                  projection: 'EPSG:4326'
              })
          });
          // 地图点击事件
          map.on('click', (e) => {
              console.log(e);
          })
    
    
          const element = document.getElementById('infowindow');
          let infowindow = null;
          const coordinate = [
              [
                  116.28288330078125,
                  39.91595224314723
              ],
              [
                  116.49848999023439,
                  39.881633003379434
              ]
          ]
    
          // 以下是点标记代码
          // 创建Style样式
          const iconStyle = new ol.style.Style({
              image: new ol.style.Icon({
                  anchor: [0.5, 0.5],
                  color: 'blue',
                  src: './img/point.png',
                  width: 30
              }),
              text: new ol.style.Text({
                  text: '点标记',
                  offsetY: -25,
                  fill: new ol.style.Fill({ color: 'blue' })
              })
          })
          // 创建Feature要素
          const features = coordinate.map((item) => {
              const Feature = new ol.Feature({
                  // 创建geometry
                  geometry: new ol.geom.Point(item),
                  name: 'Marker'
              })
              Feature.positon = item;
              return Feature;
          })
          // 创建Vector图层
          const vectorLayer = new ol.layer.Vector({
              source: new ol.source.Vector(),
              style: iconStyle
          })
          features.forEach((item) => vectorLayer.getSource().addFeature(item))
          map.addLayer(vectorLayer);
          // 点标注点击
          map.on('click', (evt) => {
              const Feature = map.forEachFeatureAtPixel(evt.pixel, (feature) => {
                  return feature
              })
              if (Feature && Feature.get('name') === 'Marker') {
                  console.log('Marker点标注', Feature);
                  const positon = Feature.positon;
                  if (!infowindow) {
                      addInfoWindow(positon);
                  } else {
                      element.innerHTML = positon.toString();
                      infowindow.setPosition(positon);
                  }
    
              }
          })
          // 以上是点标记代码
    
          // 创建覆盖物
          function addInfoWindow(positon) {
              infowindow = new ol.Overlay({
                  element: element,
                  autoPan: true,
                  positioning: 'bottom-center',
                  stopEvent: false,
                  offset: [0, -32],
                  autoPanAnimation: { duration: 250 }
              })
              map.addOverlay(infowindow);
              element.innerHTML = positon.toString();
              infowindow.setPosition(positon);
          }
      </script>
    </body>
    
    </html>

    当点击点标记,信息窗体即会展示。来预览下覆盖物(Overlay)上图的效果吧!
    image.png

    总结

  • 在openlayer中,信息窗体属于覆盖物(Overlay);
  • 覆盖物(Overlay)的主体是DOM元素节点,移动地图或拖动地图,主体会伴随相对位置不变;
  • ol.Overlay覆盖物(Overlay)也可用来创建点标记、文本等;

HerryLo
238 声望11 粉丝

喜爱JavaScript和NodeJs;