首页 > 解决方案 > 如何在openlayers中设置绘图圆半径的限制?

问题描述

我想将最大半径选项设置为 ol.interaction.draw(圆的类型)。但我找不到任何正式添加的选项。

如果半径超过限制,我可以处理“drawend”事件并手动取消它。但这并不是我想要的。如果达到半径的限制,绘图事件不应该结束。绘制的圆应该停止扩展。用户可以通过绘制交互不断改变半径,直到第二次点击(同时用户可以再次将其绘制得更低)。

希望我能很好地解释我的问题。

开放层 v3

标签: openlayersopenlayers-3

解决方案


您可以使用几何函数,它生成的自定义几何是具有最大半径的圆

<!doctype html>
<html lang="en">
  <head>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.7.0/css/ol.css" type="text/css">
    <style>
      html, body, .map {
        margin: 0;
        padding: 0;
        width: 100%;
        height: 100%;
      }
      #map {
        position: relative;
      }
      #form {
        z-index: 1;
        opacity: 1;
        position: absolute;
        bottom: 0;
        left: 0;
        margin: 0;
      }
    </style>
    <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.7.0/build/ol.js"></script>
  </head>
  <body>
    <div id="map" class="map"></div>
    <form id="form">
    <label>
      Max radius
      <input id="slider" type="range" min="1" max="200" value="100" />
      +<span id="output"></span> meters
    </label>
    </form>
    <script type="text/javascript">

const raster = new ol.layer.Tile({
  source: new ol.source.OSM()
});

const source = new ol.source.Vector({ wrapX: false });

const vector = new ol.layer.Vector({
  source: source
});

const map = new ol.Map({
  layers: [raster, vector],
  target: "map",
  view: new ol.View({
    center: [-11000000, 4600000],
    zoom: 4
  })
});

const slider = document.getElementById("slider");
const output = document.getElementById("output");
const scale = 5000;
slider.addEventListener("input", function () {
  output.innerText = slider.value * scale;
});
output.innerText = slider.value * scale;

const draw = new ol.interaction.Draw({
  source: source,
  type: 'Circle',
  geometryFunction: function (coordinates, geometry) {
    const center = coordinates[0];
    const last = coordinates[coordinates.length - 1];
    const dx = center[0] - last[0];
    const dy = center[1] - last[1];
    const maxRadius = slider.value * scale;
    const radius = Math.min(Math.sqrt(dx * dx + dy * dy), maxRadius);
    if (!geometry) {
      geometry = new ol.geom.Circle(center, radius);
    } else {
      geometry.setCenterAndRadius(center, radius);
    }
    return geometry;
  }
});
map.addInteraction(draw);

    </script>
  </body>
</html>


推荐阅读