当前位置: 首页 > news >正文

三十一、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><selectclass="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>

     

http://www.lryc.cn/news/356299.html

相关文章:

  • 医疗科技:UWB模块为智能医疗设备带来的变革
  • Java面试题大全(从基础到框架,中间件,持续更新~~~)
  • 零知识证明在隐私保护和身份验证中的应用
  • 15.微信小程序之async-validator 基本使用
  • 元宇宙vr科普馆场景制作引领行业潮流
  • kotlin基础之高阶函数
  • 【Python音视频技术】用moviepy实现图文成片功能
  • 【Linux】权限的理解之权限掩码(umask)
  • UVa1466/LA4849 String Phone
  • 使用Word表格数据快速创建图表
  • JAVA面试题大全(十三)
  • 搜维尔科技:第九届元宇宙数字人设计大赛入围作品名单
  • SMB工具横向移动
  • cesuim
  • 2023、2024国赛web复现wp
  • day34 贪心算法 455.分发饼干 376. 摆动序列
  • 养老院管理系统基于springboot的养老院管理系统java项目
  • 跳台阶扩展问题
  • 超清高帧,成像升级 | SWIR短波红外相机500万像素992芯片
  • 攻击渗透思考题
  • Flutter 中的 Opacity 小部件:全面指南
  • 【介绍下如何在SQL中添加数据】
  • 【Linux学习】深入了解Linux中进程状态及其转换
  • 【Python设计模式11】建造者模式
  • coredump文件生成配置
  • jmeter线程组(下篇)
  • Stable Diffusion【写实模型】:逼真,逼真,超级逼真的国产超写实摄影大模型万享XL
  • Android 13 配置默认DN
  • 系统开发与运行知识
  • 算法训练 | 二叉树Part1 | 递归遍历、迭代遍历、统一迭代