三十一、openlayers官网示例Draw Features解析——在地图上自定义绘制点、线、多边形、圆形并获取图形数据

官网demo地址:

Draw Features 

先初始化地图,准备一个空的矢量图层,用于显示绘制的图形。

initLayers() {
      const raster = new TileLayer({
        source: new XYZ({
          url: "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
        }),
      });

      const source = new VectorSource({ wrapX: false });

      this.vectorlayer = new VectorLayer({
        source: source,
      });
      this.map = new Map({
        layers: [raster, this.vectorlayer],
        target: "map",
        view: new View({
          center: [-11000000, 4600000],
          zoom: 4,
        }),
      });
    },

 想要在地图上绘制图形,需要用到一个交互类Draw,new Draw,设置绘制的图形类型。常见类型包括 'Point', 'LineString', 'Polygon', 'Circle', 'MultiPoint', 'MultiLineString', 'MultiPolygon'

addDrawInteraction() {
      this.draw = new Draw({
        source: this.vectorlayer.getSource(),
        type: this.type,
      });
      this.map.addInteraction(this.draw);
    },

Draw还有些常用参数

  1. clickTolerance:

    • 类型: number
    • 描述: 指定绘制时允许的点击距离容差(以像素为单位)。这是为了允许用户在移动鼠标时具有一定的容差,以便更容易地点击绘制。
    • 默认值: 6
  2. features:

    • 类型: ol.Collection<ol.Feature>
    • 描述: 一个 Collection 实例,用于存储绘制的特征。如果指定了此属性,绘制的特征将添加到该集合中。
  3. source:

    • 类型: ol.source.Vector
    • 描述: 一个 VectorSource 实例,用于存储绘制的特征。如果没有指定 features,绘制的特征将添加到此数据源中。
  4. dragVertexDelay:

    • 类型: number
    • 描述: 指定绘制顶点时拖动操作的延迟时间(以毫秒为单位)。
    • 默认值: 500
  5. snapTolerance:

    • 类型: number
    • 描述: 指定绘制时顶点的捕捉容差(以像素为单位)。这是为了使用户更容易将新顶点捕捉到现有顶点上。
    • 默认值: 12
  6. stopClick:

    • 类型: boolean
    • 描述: 是否停止点击事件。设置为 true 时,绘制交互将停止触发地图的点击事件。
    • 默认值: false
  7. maxPoints:

    • 类型: number
    • 描述: 绘制的最大顶点数。对于线和多边形,这个值可以限制绘制的顶点数量。
    • 默认值: Infinity
  8. minPoints:

    • 类型: number
    • 描述: 绘制的最小顶点数。例如,对于多边形,至少需要三个顶点来形成一个闭合的形状。
    • 默认值: 2
  9. style:

    • 类型: ol.style.StyleArray<ol.style.Style>ol.StyleFunction
    • 描述: 指定绘制过程中几何图形的样式。可以是一个样式实例、样式实例数组或一个样式函数。
  10. geometryFunction:

    • 类型: function
    • 描述: 自定义几何生成函数,用于在绘制时生成几何图形。该函数接收两个参数:coordinates(当前坐标数组)和 geometry(当前几何图形)。

下拉框切换时需要先移除之前的Draw,再实例化一个新的Draw添加到地图上。

  changeDrawType() {
      this.map.removeInteraction(this.draw);
      this.addDrawInteraction();
    },

使用removeLastPoint方法可以撤回最后绘制的一个点。

document.getElementById("undo").addEventListener("click",  ()=> {
      this.draw.removeLastPoint();
    });

 一般来说,在地图上绘制完图形肯定要拿到图形数据上传或者做其他的操作,我们来看看怎么获取数据。

方法一:直接从vectorlayer图层上获取 

this.vectorlayer.getSource().getFeatures()

方法二:使用Draw的参数features绑定数组

let featureArr = new Collection();
this.draw = new Draw({
    features: featureArr,
});

features绑定的数组不是普通的数组,Collection是openlayers内部定义的一个类似数组的集合。它拥有一些跟数组类似的方法。具体介绍和方法可以参考官网文档:

OpenLayers v9.2.4 API - Class: Collection

如果获取数据的时机是绘制完成之后点击按钮后获取,那两种方式没什么区别。但若是希望绘制完成后马上获取,使用this.vectorlayer.getSource().getFeatures()就会有一点小问题。。。

 this.draw.on("drawend", (e) => {
        console.log("draw", e.feature);
        console.log("获取数据:", this.vectorlayer.getSource().getFeatures());
  });

已经绘制了一个图形,但是并没有获取到 。this.vectorlayer.getSource().getFeatures()不能实时获取到绘制图形的数据,因为drawend事件里feature还没被加到图层上。

但,也不是没有解决办法,变成异步就可以。

setTimeout(() => {
    console.log("获取数据:", this.vectorlayer.getSource().getFeatures());
});

而使用Draw的features参数绑定Collection就不会有这个问题。

this.draw.on("drawend", (e) => {
        console.log("draw", e.feature);
        console.log("featureArr", this.featureArr);
  });

总的来说,两种方法都可以,甚至可以定义一个数组,每次绘制完都push一下当前绘制的feature。 具体怎么使用看业务需求喽。

  完整代码:


<template>
  <div class="box">
    <h1>Draw Features绘制图形</h1>
    <div id="map"></div>
    <div class="row">
      <div class="col-auto">
        <span class="input-group">
          <label class="input-group-text" for="type">Geometry type:</label>
          <select
            class="form-select"
            id="type"
            @change="changeDrawType"
            v-model="type"
          >
            <option value="Point">Point</option>
            <option value="LineString">LineString</option>
            <option value="Polygon">Polygon</option>
            <option value="Circle">Circle</option>
            <option value="None">None</option>
          </select>
          <input class="form-control" type="button" value="Undo" id="undo" />
        </span>
        <el-button type="primary" @click="getDrawFeatures">获取</el-button>
      </div>
    </div>
  </div>
</template>
 
<script>
import Draw from "ol/interaction/Draw.js";
import { createBox } from "ol/interaction/Draw";
import Map from "ol/Map.js";
import View from "ol/View.js";
import { OSM, Vector as VectorSource } from "ol/source.js";
import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer.js";
import XYZ from "ol/source/XYZ";
import Feature from "ol/Feature.js";
import Polygon from "ol/geom/Polygon.js";
import Point from "ol/geom/Point.js";
import { Collection } from "ol";
export default {
  data() {
    return {
      map: null,
      vectorlayer: null,
      type: "Point",
      draw: null,
      featureArr: new Collection(),
    };
  },
  methods: {
    getDrawFeatures() {
      console.log("方法一", this.vectorlayer.getSource().getFeatures());
      console.log("方法二", this.featureArr);
    },
    changeDrawType() {
      this.map.removeInteraction(this.draw);
      this.addDrawInteraction();
    },
    initLayers() {
      const raster = new TileLayer({
        source: new XYZ({
          url: "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
        }),
      });

      const source = new VectorSource({ wrapX: false });

      this.vectorlayer = new VectorLayer({
        source: source,
      });
      this.map = new Map({
        layers: [raster, this.vectorlayer],
        target: "map",
        view: new View({
          center: [-11000000, 4600000],
          zoom: 4,
        }),
      });
    },
    addDrawInteraction() {
      this.draw = new Draw({
        source: this.vectorlayer.getSource(),
        type: this.type,
        features: this.featureArr,
        //freehand: true, //是否启用自由绘制模式
      });
      this.map.addInteraction(this.draw);
      this.draw.on("drawend", (e) => {
        console.log("draw", e.feature);
        // console.log("获取数据:", this.vectorlayer.getSource().getFeatures());
        console.log("featureArr", this.featureArr);
        // setTimeout(() => {
        //   console.log("source", this.vectorlayer.getSource().getFeatures());
        // });
      });
    },
  },
  mounted() {
    this.initLayers();
    this.addDrawInteraction();

    document.getElementById("undo").addEventListener("click", () => {
      this.draw.removeLastPoint();
    });
  },
};
</script>
<style scoped>
#map {
  width: 100%;
  height: 500px;
}
.box {
  height: 100%;
}
</style>

     

文件列表: OL3Demo\.DS_Store OL3Demo\css\base.css OL3Demo\css\js_demo.css OL3Demo\css\ol.css OL3Demo\demos\.DS_Store OL3Demo\demos\Controls\Animation.htm OL3Demo\demos\Controls\CanvasTiles.htm OL3Demo\demos\Controls\FullScreen.htm OL3Demo\demos\Controls\LayerControl.htm OL3Demo\demos\Controls\LayerSpy.htm OL3Demo\demos\Controls\Measure.htm OL3Demo\demos\Controls\MousePosition.htm OL3Demo\demos\Controls\Operation.htm OL3Demo\demos\Controls\OverviewMap.htm OL3Demo\demos\Controls\ScaleLine.htm OL3Demo\demos\Controls\ZoomSlider.htm OL3Demo\demos\data\geojson\countries-110m.json OL3Demo\demos\data\geojson\countries.geojson OL3Demo\demos\data\geojson\GeoJSON.json OL3Demo\demos\data\geojson\samples.json OL3Demo\demos\data\geolocation-orientation.json OL3Demo\demos\data\geolocation_marker_heading.png OL3Demo\demos\data\gml\gml.xml OL3Demo\demos\data\gml\topp-states-wfs.xml OL3Demo\demos\data\gpx\fells_loop.gpx OL3Demo\demos\data\kml\2012-02-10.kml OL3Demo\demos\data\kml\2012_Earthquakes_Mag5.kml OL3Demo\demos\data\kml\kml.xml OL3Demo\demos\DataHandler.ashx OL3Demo\demos\Drawing\DrawFeatures.htm OL3Demo\demos\Drawing\FeaturesStyle.htm OL3Demo\demos\Drawing\ModifyFeatures.htm OL3Demo\demos\Drawing\MoveFeatures.htm OL3Demo\demos\Drawing\SaveFeatures.htm OL3Demo\demos\Labels\AddClusterLabels.htm OL3Demo\demos\Labels\AddLabels.htm OL3Demo\demos\Labels\AddPopup.htm OL3Demo\demos\MultiData\LoadBasicMaps.htm OL3Demo\demos\MultiData\LoadOpenData.htm OL3Demo\demos\MultiData\LoadPublicMaps.htm OL3Demo\demos\MultiData\LoadTiandituMap.htm OL3Demo\demos\MultiData\MapExport.htm OL3Demo\demos\MultiData\OSM.htm OL3Demo\demos\MultiData\OverLayerMaps.htm OL3Demo\demos\OGC\LoadWCSMap.htm OL3Demo\demos\OGC\LoadWFSFeatrue.htm OL3Demo\demos\OGC\LoadWMSMap.htm OL3Demo\demos\OGC\LoadWMTSMap.htm OL3Demo\demos\OGC\WFS_Transaction.htm OL3Demo\demos\Others\AddPOI.htm OL3Demo\demos\Others\CreatCharts.htm OL3Demo\demos\Others\Geolocation.htm OL3Demo\demos\Others\Heatmap.htm OL3Demo\demos\Others\HotSpots.htm OL3Demo\demos\Others\LoadPublicMaps.htm OL3Demo\demos\Others\MilitaryPlotting.htm OL3Demo\demos\Others\MultiViewLinkage.htm OL3Demo\demos\Others\ProjectionTransformation.htm OL3Demo\demos\Others\SimulateGeolocation.htm OL3Demo\demos\Others\副本 LoadPublicMaps.htm OL3Demo\demos\RegDataHandler.ashx OL3Demo\demos\Web.config OL3Demo\images\ArrowIcon\arbitrary_area.png OL3Demo\images\ArrowIcon\arrow.png OL3Demo\images\ArrowIcon\arrow1.png OL3Demo\images\ArrowIcon\arrowcross.png OL3Demo\images\ArrowIcon\assembly.png OL3Demo\images\ArrowIcon\circle.png OL3Demo\images\ArrowIcon\CircleClosedangleCompass.png OL3Demo\images\ArrowIcon\closedangle.png OL3Demo\images\ArrowIcon\curve_flag.png OL3Demo\images\ArrowIcon\custom_arrow.png OL3Demo\images\ArrowIcon\custom_tail_arrow.png OL3Demo\images\ArrowIcon\custom_tail_arrow_.png OL3Demo\images\ArrowIcon\DoubleClosedangleCompass.png OL3Demo\images\ArrowIcon\double_arrow.png OL3Demo\images\ArrowIcon\fourstar.png OL3Demo\images\ArrowIcon\rect_flag.png OL3Demo\images\ArrowIcon\rhombus.png OL3Demo\images\ArrowIcon\SameDirectionClosedangleCompass.png OL3Demo\images\ArrowIcon\singleLine_arrow.png OL3Demo\images\ArrowIcon\smooth_curve.png OL3Demo\images\ArrowIcon\stright_arrow.png OL3Demo\images\ArrowIcon\tail_arrow.png OL3Demo\images\ArrowIcon\triangle.png OL3Demo\images\ArrowIcon\triangle_flag.png OL3Demo\images\ArrowIcon\VaneCompass.png OL3Demo\images\content\dotted.png OL3Demo\images\label\bj.png OL3Demo\images\label\blueIcon.png OL3Demo\images\label\icon.png OL3Demo\images\label\restaurant.png OL3Demo\images\label\国有企业.png OL3Demo\images\left\app.png OL3Demo\images\left\app_current.png OL3Demo\images\left\channel.png OL3Demo\images\left\channel_current.png OL3Demo\images\left\cloud.png OL3Demo\images\left\cloud_current.png OL3Demo\images\left\custom.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值