OpenLayers - layer Perspective

brief introduction

This article mainly explains how to realize the layer perspective function by controlling the layer, level and size.
It mainly uses the layer monitoring event prerender to monitor the layer before rendering and postrender to monitor the layer after rendering.

Implement DEMO

Initialize map

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <style type="text/css">
    .map {
      height: 500px;
      width: 100%;
    }
  </style>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.6.1/css/ol.css" />
  <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.6.1/build/ol.js"></script>
  <body>
    <div id="map" class="map"></div>
  </body>
  <script>
    // layer 
    var roads = new ol.layer.Tile({
      source: new ol.source.XYZ({
        url: 'https://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}'
      })
    })

    // Layer 2
    var imagery = new ol.layer.Tile({
      source: new ol.source.XYZ({
        url: 'http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}'
      })
    })

    // example
    const container = document.getElementById('map')

    var map = new ol.Map({
      target: container,
      layers: [roads, imagery],
      view: new ol.View({
        center: ol.proj.fromLonLat([37.41, 8.82]),
        zoom: 4
      })
    })

  </script>
</html>

[external chain picture transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-s23xvbu5-164540454518)( https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/cbcfa6a5e6874f1ca4956cf13fd589af ~tplv-k3u1fbpfcp-watermark. image)]

  • Here we have created two layers. Remember that the default levels of layers are those added later than those in front.
  • To achieve the effect of layer perspective, in fact, it is to draw layers in a fixed range on the basic layer to achieve the effect.

Get the coordinate position of the mouse on the map

    // Map pixel location
    let mousePosition = null

    container.addEventListener('mousemove', function (event) {
      // getEventPixel(event) returns the location of map pixels according to the current location of the event.
      mousePosition = map.getEventPixel(event)

      // Re render map
      map.render()
    })

    container.addEventListener('mouseout', function () {
      mousePosition = null
      map.render()
    })
  1. Create a global variable (mousePosition) to save the geographical location of the mouse in real time.
  2. Obtain the current position window position by listening to the mouse in event of the container, and convert it to geographical position using getEventPixel().
  3. Listen for the mouse out event of the container to cancel the geographical location.
  4. Each monitoring requires redrawing the map for updating the content of the perspective layer.

Listen for layer events

    // radius
    let radius = 75
    // Before layer rendering
    imagery.on('prerender', function (event) {
      const ctx = event.context
      ctx.save() // preservation
      ctx.beginPath()
      if (mousePosition) {
        ctx.arc(mousePosition[0], mousePosition[1], radius, 0, 2 * Math.PI)
        ctx.lineWidth = (5 * radius) / radius
        ctx.strokeStyle = 'rgba(0,0,0,0.5)'
        ctx.stroke()
      }
      // Use clipping to load only the data in the circle
      ctx.clip()
    })

    // After layer rendering
    imagery.on('postrender', function (event) {
      const ctx = event.context
      ctx.restore()
    })
  1. The circle is drawn here. You can customize other graphics.
  2. Through the layer event prerender, the layer instance canvas returned in listening before layer rendering. Be sure to save the status CTX Save(), obtain the coordinates of the mouse through mousePosition, draw graphics at will, and use clip() to cut the canvas to show only the cut content.
  3. After rendering through the postrender layer. Restore the saved canvas content display.

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-xpyswbin-164540454521)( https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c074dbafaee84a5d8b822484471b3672 ~tplv-k3u1fbpfcp-watermark. image)]

Additional functions

document.addEventListener('keydown', function (evt) {
      console.log(100)
      if (evt.keyCode === 38) {
        console.log(1)
        // If the user presses the '↑' key, the radius of the telescope increases by 5 pixels
        radius = Math.min(radius + 5, 150)
        map.render()
        evt.preventDefault()
      } else if (evt.keyCode === 40) {
        // If the user presses the '↓' key, the radius of the telescope will be reduced by 5 pixels
        radius = Math.max(radius - 5, 25)
        map.render()
        evt.preventDefault()
      }
    })
  • Listen to global keyboard events and modify the shape of the perspective layer we draw. Of course, it should be noted that the map is also required after modification Render() redraws the map to show the latest effect.

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-kpln49mc-164540454522)( https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0d6f8227876c4507b265096082e2cc9d ~tplv-k3u1fbpfcp-watermark. image)]

Keywords: Javascript Front-end css

Added by ankrah on Sun, 20 Feb 2022 20:24:18 +0200