如何使用Openlayers3绘制椭圆

时间:2015-07-27 07:29:10

标签: javascript openlayers-3 ellipse

我正在开展一个我们正在使用OpenLayers3的项目。

我们需要让用户能够在地图上绘制各种功能。 Here是在地图上绘制要素的官方示例。

我们需要在地图上绘制椭圆,但官方没有给出这样的功能。我想知道是否可以自定义几何体,以便我们可以在地图上绘制椭圆。

6 个答案:

答案 0 :(得分:1)

在绘制交互中,您可以指定geometryFunction作为参数。您正在绘制时,此功能将绘制其他几何图形。目前,Circle模式中的绘制互动是什么,see the code

请查看the draw interaction api了解更多信息。

答案 1 :(得分:1)

大多数测绘系统都没有提供椭圆几何或特征。在Android中使用谷歌地图时我有同样的要求,我解决它的方法是通过椭圆的参数方程计算顶点来使用多边形。

x = h + a * cos(t)

y = k + b * sin(t)

请查看this post以查看示例。

答案 2 :(得分:1)

对于将来会进行搜索的人们,我希望它会有所帮助。 在开放层V5.3中创建椭圆的工作代码:

// this works for a static image (pixels) but the idea can be on any coordinate system 
addEllipseFeature(center, semiMajor, semiMinor) {
    let coordinates = [] ;
    const radinas = Math.PI / 180 ;
    for (let angle = 1; angle <= 360; angle ++) {
      const px = center[0] + semiMajor * Math.cos(radinas * angle);
      const py = center[0] + semiMinor * Math.sin(radinas * angle);
      coordinates.push([px, py]);
    }
    const geoJson = {
      'type': 'Feature',
      'geometry': {
        'type': 'Polygon',
        'coordinates': []
      }
    };
    const featureId = source.getFeatures().length;
    coordinates = this.convertCoordinates('Polygon', [coordinates]);
    geoJson.geometry.coordinates = coordinates ;
    const polygonFeature = (new GeoJSON()).readFeature(geoJson);
    polygonFeature.setId(featureId );
    const layerStyle = [  new Style({
      stroke: new Stroke({
        color: 'blue',
        width: 3
      }),
      fill: new Fill({
        color: 'rgba(0, 0, 255, 0.1)'
      })
    })];
    polygonFeature.setStyle(layerStyle);
    source.addFeature(polygonFeature);
    return featureId;
}

enter image description here

答案 3 :(得分:0)

绘制一个圆,将其转换为圆形多边形,然后缩放x和y方向。两次单击足以定义沿轴的椭圆的中心和半径。对于倾斜的椭圆形,需要单击三下,中心点一下,每个半径一下,第三下也设置旋转。

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

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

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

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

  var typeSelect = document.getElementById('type');

  var draw; // global so we can remove it later
  function addInteraction() {
    var value = typeSelect.value;
    var maxPoints;
    if (value !== 'None') {
      var geometryFunction;
      if (value === 'Square') {
        value = 'Circle';
        geometryFunction = ol.interaction.Draw.createRegularPolygon(4);
      } else if (value === 'Box') {
        value = 'Circle';
        geometryFunction = ol.interaction.Draw.createBox();
      } else if (value === 'Star') {
        value = 'Circle';
        geometryFunction = function(coordinates, geometry) {
          var center = coordinates[0];
          var last = coordinates[1];
          var dx = center[0] - last[0];
          var dy = center[1] - last[1];
          var radius = Math.sqrt(dx * dx + dy * dy);
          var rotation = Math.atan2(dy, dx);
          var newCoordinates = [];
          var numPoints = 12;
          for (var i = 0; i < numPoints; ++i) {
            var angle = rotation + i * 2 * Math.PI / numPoints;
            var fraction = i % 2 === 0 ? 1 : 0.5;
            var offsetX = radius * fraction * Math.cos(angle);
            var offsetY = radius * fraction * Math.sin(angle);
            newCoordinates.push([center[0] + offsetX, center[1] + offsetY]);
          }
          newCoordinates.push(newCoordinates[0].slice());
          if (!geometry) {
            geometry = new ol.geom.Polygon([newCoordinates]);
          } else {
            geometry.setCoordinates([newCoordinates]);
          }
          return geometry;
        };
      } else if (value === 'Ellipse') {
        value = 'Circle';
        geometryFunction = function(coordinates, geometry) {
          var center = coordinates[0];
          var last = coordinates[1];
          var dx = center[0] - last[0];
          var dy = center[1] - last[1];
          var radius = Math.sqrt(dx * dx + dy * dy);
          var circle = new ol.geom.Circle(center, radius);
          var polygon = ol.geom.Polygon.fromCircle(circle, 64);
          polygon.scale(dx/radius, dy/radius);
          if (!geometry) {
            geometry = polygon;
          } else {
            geometry.setCoordinates(polygon.getCoordinates());
          }
          return geometry;
        };
      } else if (value === 'Oblique Ellipse') {
        value = 'LineString';
        maxPoints = 3;
        geometryFunction = function(coordinates, geometry) {
          var center = coordinates[0];
          var first = coordinates[1];
          var dx = center[0] - first[0];
          var dy = center[1] - first[1];
          var radius1 = Math.sqrt(dx * dx + dy * dy);
          if (coordinates.length > 2) {
            var last = coordinates[2];
            dx = center[0] - last[0];
            dy = center[1] - last[1];
          }
          var radius2 = Math.sqrt(dx * dx + dy * dy);
          var rotation = Math.atan2(dy, dx);
          var circle = new ol.geom.Circle(center, radius1);
          var polygon = ol.geom.Polygon.fromCircle(circle, 64);
          polygon.scale(radius2/radius1, 1);
          polygon.rotate(rotation, center);
          if (!geometry) {
            geometry = polygon;
          } else {
            geometry.setCoordinates(polygon.getCoordinates());
          }
          return geometry;
        };
      }
      draw = new ol.interaction.Draw({
        source: source,
        type: value,
        maxPoints: maxPoints,
        geometryFunction: geometryFunction
      });
      map.addInteraction(draw);
    }
  }


  /**
   * Handle change event.
   */
  typeSelect.onchange = function() {
    map.removeInteraction(draw);
    addInteraction();
  };

  addInteraction();
html, body {
    margin: 0;
    padding: 0;
    width: 100%;
    height: 100%;
}
.map {
    width: 100%;
    height: 90%;
}
<link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet" />
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<div id="map" class="map"></div>
<form class="form-inline">
  <label>Shape type &nbsp;</label>
  <select id="type">
    <option value="Ellipse">Ellipse</option>
    <option value="Oblique Ellipse">Oblique Ellipse</option>
    <option value="Circle">Circle</option>
    <option value="Square">Square</option>
    <option value="Box">Box</option>
    <option value="Star">Star</option>
    <option value="None">None</option>
  </select>
</form>

答案 4 :(得分:0)

从Mike的代码开始,使用OL 6.1.1:

const circle = new Circle(
    fromLonLat([longitude, latitude]),
    radius
)

// fromCircle is a function inside Polygon class
const ellipse = fromCircle(circle, 100)
ellipse.scale(1, bigRadius / smallRadius) 

// OL is counterclockwise rotation
ellipse.rotate(-(angleDegree * Math.PI) / 180, circle.getCenter())

this.yourLayer.getSource().addFeature(
    new Feature({
      geometry: ellipse
    })
)

致谢

答案 5 :(得分:0)

感谢@Ezri Y,我制作了一个工作示例并添加了更多功能。

here