Openlayers示例19 | Magnify(放大)

Magnify

此示例使用postrender事件侦听器对围绕指针位置的圆圈中的图像进行过采样。此事件的侦听器可以访问 Canvas 上下文并可以操作图像数据。

在地图上移动以查看效果。使用 ↑ 向上和 ↓ 向下箭头键调整放大的圆圈大小。

<!DOCTYPE html>
<html lang="zn">

<head>
  <meta charset="UTF-8">
  <!-- 引入OpenLayers CSS样式 -->
  <link rel="stylesheet"
    href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.13.0/css/ol.css">
  <!-- 引入OpenLayers JS库 -->
  <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.13.0/build/ol.js"></script>
  <!-- css代码 -->
  <style>
    .map {
      width: 100%;
      height: 500px;
    }
  </style>
  <title>Magnify</title>
</head>
<body>
  <div id="map" class="map"></div>
</body>
<script>
  const key = 'Get your own API key at https://www.maptiler.com/cloud/';
  const attributions =
    '<a href="https://www.maptiler.com/copyright/" target="_blank">&copy; MapTiler</a> ' +
    '<a href="https://www.openstreetmap.org/copyright" target="_blank">&copy; OpenStreetMap contributors</a>';

  const imagery = new ol.layer.Tile({
    source:new ol.source.OSM()
    // source: new ol.source.XYZ({
    //   attributions: attributions,
    //   url: 'https://api.maptiler.com/tiles/satellite/{z}/{x}/{y}.jpg?key=' + key,
    //   maxZoom: 20,
    //   crossOrigin: '',
    // }),
  });

  const container = document.getElementById('map');

  const map = new ol.Map({
    layers: [imagery],
    target: container,
    view: new ol.View({
      center: ol.proj.fromLonLat([-109, 46.5]),
      zoom: 6,
    }),
  });

  let radius = 75;
  document.addEventListener('keydown', function (evt) {
    if (evt.which === 38) {
      radius = Math.min(radius + 5, 150);
      map.render();
      evt.preventDefault();
    } else if (evt.which === 40) {
      radius = Math.max(radius - 5, 25);
      map.render();
      evt.preventDefault();
    }
  });

  // get the pixel position with every move
  let mousePosition = null;

  container.addEventListener('mousemove', function (event) {
    mousePosition = map.getEventPixel(event);
    map.render();
  });

  container.addEventListener('mouseout', function () {
    mousePosition = null;
    map.render();
  });

  // after rendering the layer, show an oversampled version around the pointer
  imagery.on('postrender', function (event) {
    if (mousePosition) {
      const pixel = ol.render.getRenderPixel(event, mousePosition);
      const offset = ol.render.getRenderPixel(event, [
        mousePosition[0] + radius,
        mousePosition[1],
      ]);
      const half = Math.sqrt(
        Math.pow(offset[0] - pixel[0], 2) + Math.pow(offset[1] - pixel[1], 2)
      );
      const context = event.context;
      const centerX = pixel[0];
      const centerY = pixel[1];
      const originX = centerX - half;
      const originY = centerY - half;
      const size = Math.round(2 * half + 1);
      const sourceData = context.getImageData(originX, originY, size, size).data;
      const dest = context.createImageData(size, size);
      const destData = dest.data;
      for (let j = 0; j < size; ++j) {
        for (let i = 0; i < size; ++i) {
          const dI = i - half;
          const dJ = j - half;
          const dist = Math.sqrt(dI * dI + dJ * dJ);
          let sourceI = i;
          let sourceJ = j;
          if (dist < half) {
            sourceI = Math.round(half + dI / 2);
            sourceJ = Math.round(half + dJ / 2);
          }
          const destOffset = (j * size + i) * 4;
          const sourceOffset = (sourceJ * size + sourceI) * 4;
          destData[destOffset] = sourceData[sourceOffset];
          destData[destOffset + 1] = sourceData[sourceOffset + 1];
          destData[destOffset + 2] = sourceData[sourceOffset + 2];
          destData[destOffset + 3] = sourceData[sourceOffset + 3];
        }
      }
      context.beginPath();
      context.arc(centerX, centerY, half, 0, 2 * Math.PI);
      context.lineWidth = (3 * half) / radius;
      context.strokeStyle = 'rgba(255,255,255,0.5)';
      context.putImageData(dest, originX, originY);
      context.stroke();
      context.restore();
    }
  });
</script>
</html>
posted @   槑孒  阅读(187)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
点击右上角即可分享
微信分享提示