Openlayer【二】—— 绘制不同的点、线以及给其添加监听事件

Openlayer【二】—— 绘制不同的点、线以及给其添加监听事件

接上篇:OpenLayer初始化

在openlayer当中,图层Layer与地图源Source是一对一的关系。当创建了一个图层Layer,相应的需要给图层添加地图源Source,然后将图层Layer添加到地图Map上,就可以得到我们想要的地图了

在Source当中主要包含以下三种Tile、Image、Vector

  • ol.source.Tile对应的是瓦片数据源,现在网页地图服务中,绝大多数都是使用的瓦片地图,而OpenLayers 作为一个WebGIS引擎,理所当然应该支持瓦片。
  • ol.source.Image对应的是一整张图,而不像瓦片那样很多张图,从而无需切片,也可以加载一些地图,适用于一些小场景地图。
  • ol.source.Vector对应的是矢量地图源,点,线,面等等常用的地图元素(Feature),就囊括到这里面了。

1、绘制点

1.1、绘制单个默认点

所以在这一步,我们首先需要创建一个Layer和Source对象,并且把layer加到地图上,最后再往source对象当中添加对应点对象就完成了点的绘制,这里的点(Point)对象需要添加给到source.Vector的Feature元素当中

import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";const vectorSource = new VectorSource();
const vectorLayer = new VectorLayer({source: vectorSource
});
this.map.addLayer(vectorLayer);const marker = new Feature({geometry: new Point([120, 20])
});
vectorSource.addFeature(marker);

如上代码就添加了一个点到地图上了,在官网可以看到new Point()构造需要传递两个参数,一个是点的位置,一个是对象的布局,其是一个可选参数,默认参数是ol.geom.GeometryLayout.XY,还可以设置为ol.geom.GeometryLayout.XYZ、ol.geom.GeometryLayout.XYM 或 ol.geom.GeometryLayout.XYZM,可以通过以下代码进行调整对象的布局

import { GeometryLayout } from 'ol/geom/Geometry';var point = new Point([10, 20, 100]);
point.setLayout(GeometryLayout.XYZ);

1.2、绘制颜色填充的点

在Feature对象当中可以给整个对象统一设置样式,通过setStyle(),首先我们给点设置为圆形红色并且半径为6 单位(米)并且给圆的外面加上一个绿色宽度为3的边

marker.setStyle(new Style({image: new Circle({radius: 6,fill: new Fill({ color: "red" }),stroke: new Stroke({color: "green",width: 3})})})
);

1.3、绘制多个点

只需要循环创建圆点之后,将圆通过addFeature方法添加进去即可

const vectorSource = new VectorSource();
const vectorLayer = new VectorLayer({source: vectorSource
});
this.map.addLayer(vectorLayer);for (let i = 0; i < 500; i++) {const marker = new Feature({geometry: new Point(this.getRandomCoordinate())});marker.setStyle(new Style({image: new Circle({radius: 6,fill: new Fill({ color: "red" }),stroke: new Stroke({color: "green",width: 3})})}));vectorSource.addFeature(marker);
}/**
* 随机生成经纬度
*/
getRandomCoordinate() {const minLon = -180; // 最小经度const maxLon = 180; // 最大经度const minLat = -90; // 最小纬度const maxLat = 90; // 最大纬度const lon = Math.random() * (maxLon - minLon) + minLon;const lat = Math.random() * (maxLat - minLat) + minLat;return [lon, lat];
}

在这里插入图片描述

1.4、绘制图标点

绘制图标点只需要给style加上image的相关图标配置即可绘制图标到地图上,如下,这里的anchor表示图标的锚点(图标的中心位置)、opacity表示透明度、scale表示放大缩小层级,src指向对应的图标文件的位置、color表示图标的颜色(对图标进行着色)

marker.setStyle(new Style({image: new Icon({anchor: [0.5, 1],opacity: 1,scale: 1,src: require("./icon/point.png"),color: 'green'})})
);

其中对Icon的属性可以参考官方文档:OpenLayers v8.2.0 API - 类:图标

1.5、给图标点加上文字

给图标加文字和前面设置图标一样,都是直接给style当中添加属性即可,这里添加的是text属性。这里的fill的color表示文字的填充颜色为白色、font属性可以设置文字大小和字体类型、text表示展示的文字内容、scale是一个数组表示横向(x)和纵向(y)的放大缩小层级、offsetX和offsetY分别表示文本在水平和垂直上的偏移量、最后的storke表示文字的描边

feature.setStyle(new Style({image: new Icon({anchor: [0.5, 1],opacity: 1,scale: 1,src: require("./icon/point.png"),color: "green"}),text: new Text({fill: new Fill({color: "rgba(255,255,255,0.9)"}),font: "16px monospace",text: "文字",scale: [1, 1],offsetY: -30,stroke: new Stroke({ color: "rgba(0,0,0,0.9)", width: 2 })})})
);

这里对Text的属性可以参考官方文档:OpenLayers v8.2.0 API - 类:文本

1.6、鼠标移入和鼠标移出点事件监听

1.6.1、实现事件监听

在这里可以在给每一个Feature初始化好了之后通过map的pointermove事件(当鼠标在地图上进行移动时触发事件)用来监听,并且获取当前鼠标移动的位置是否包含了这个Feature对象,之后通过目标的featureTarget(地图监听得到的)和最开始初始化得到的进行对比,如果相同则表示鼠标移入到了当前图标,获取对应的样式scale(放大缩小的层级)设置为2即为放大一倍,不相同表示移出,设置会成原来的样式,

当然同理,这里我简化了样式的设置,如果给图标设置了文字的属性可以通过originalStyle.getText().setScale([2, 2])把字体也给放大一倍,其余的样式也同理如此进行设置即可。这样就给页面添加了一些交互事件使得页面看起来更加活泼一点。

let source = new VectorSource();
for (let i = 0; i < 10; i++) {let feature = new Feature({id: "ddss",geometry: new Point(this.getRandomCoordinate())});feature.setStyle(new Style({image: new Icon({scale: 1,src: require("./icon/point.png")})}));this.map.on("pointermove", function(event) {const featureTarget = this.forEachFeatureAtPixel(event.pixel, function(feature) {return feature;});if (feature === featureTarget) {// 鼠标进入const originalStyle = feature.getStyle();originalStyle.getImage().setScale(2);feature.setStyle(originalStyle);} else {// 鼠标移出const originalStyle = feature.getStyle();originalStyle.getImage().setScale(1);feature.setStyle(originalStyle);}});source.addFeature(feature);
}
let layer = new VectorLayer({opacity: 1
});
layer.setSource(source);
this.map.addLayer(layer);
1.6.2、上述实现存在的问题 —— n次监听

在这里其实乍一看这样子用来实现事件监听没什么问题,每一个点都给加上了监听事件,而且去页面上测试一下当鼠标移入移出图标的大小确实会发生变化。那问题究竟在哪呢?

大数据量的情况:

在上面只初始化了10个点到页面上,当初始化100个点呢?1000个点呢?10000个点呢?在里面是循环加上的监听事件,而这个监听事件是很消耗性能的,10个点100个点看起来还不卡,但是1000个点就明显会有卡顿了,当鼠标移入后要两三秒后才回放大,当10000个点整上去之后整个页面直接卡死了,这个时候就需要给这段代码进行优化了,如何优化这个呢?很显然只需要把监听事件挪出来,由10000次监听变成1次监听就好了,后面监听完之后再去判断给哪个图标去放大缩小也就只有n次循环的事了。用循环n次+1次监听来替换掉n次监听性能消耗一下子就被降下去了。

1.6.3、解决方案 —— 一次监听+n次循环

在前面去掉那个事件监听,在把图层Layer添加进去之后,再进行监听,实现如下,在移动的时候进行监听,在监听的时候获取到feature对象也就是单个点对象,之后遍历地图层级上所有的点进行相等匹配,如果满足条件则修改其大小、文字,反之还原成原始样式。

this.map.addLayer(layer);this.map.on("pointermove", event => {const featureTarget = this.map.forEachFeatureAtPixel(event.pixel, feature => {return feature;});source.getFeatures().forEach(feature => {const originalStyle = feature.getStyle();if (feature === featureTarget) {originalStyle.getImage().setScale(2);originalStyle.getText().setScale([1, 1]);featureTarget.setStyle(originalStyle);} else {console.log("鼠标移出");originalStyle.getImage().setScale(1);originalStyle.getText().setScale([0, 0]);feature.setStyle(originalStyle);}});
});

在这里插入图片描述

2、绘制线

2.1、绘制单个默认线

绘制线和绘制点是一样一样的,就是将点对象换成线对象即可。这里的LineString就是线对象。实例化线对象和点对象也是一样,入参分别是一个坐标和一个布局。之后就是创建一个Source把线的Feature添加进去,再创建一个Layer添加到Source里面,最后将Layer线图层添加给到Map即可。这个的LineString对象的坐标可以添加多个,表示多个点连成的线。

let featureLine = new Feature({geometry: new LineString([[120,20],[130,22],[135,26]])
});
let source = new VectorSource();
source.addFeature(featureLine);
let layer = new VectorLayer({ opacity: 1 });
layer.setSource(source);
this.map.addLayer(layer);

2.2、添加样式线

和前面给点添加样式一样,这里只需要给线加上Style也就是给线加上了样式,这里还可以直接把style加给Layer图层,那么这个图层下所有的线都会应用这个样式。

const vectorLayer = new VectorLayer({source: new VectorSource(),style: new Style({stroke: new Stroke({color: "red",width: 2})})
});

这里的stroke对象可以参考官网:OpenLayers v8.2.0 API - 类:Stroke

2.3、给线添加文字

同2.2一样把text属性添加到Style当中去,但是这里设置的样式是layer的,所以字是在图层上的,如果你需要吧字添加到线上面去,就需要在得到线的Feature对象featureLine,给他重新设置样式

text: new Text({// 这里就省略了,和给点加的text属性一致
});lineFeature.setStyle(new Style({stroke: new Stroke({...省略}),text: new Text({fill: new Fill({...省略})})
);

在这里插入图片描述

2.4、选中线

在进行选中线的操作和上面选中点是一样的,可以直接沿用前面的方法进行操作。但是这里还可以通过Select对象用来判断线是否被选中的事件

import { Select } from 'ol/interaction'
import { pointerMove } from 'ol/events/condition';const interaction = new Select({condition: pointerMove, // 设置条件为鼠标移动layers: [vectorLayer], // 设置监听的图层style: function() {const style = lineFeature.getStyle();// 修改线的样式const stroke = style.getStroke();stroke.setWidth(5);// 修改文字样式const text = style.getText();text.setScale([1, 1]);// 返回新的样式return new Style({stroke,text});}
});// 将交互对象添加到地图上
this.map.addInteraction(interaction);

这里的Select对象用于选择矢量特征的交互。默认情况下,所选功能包括 样式不同,因此这种交互可用于视觉突出显示, 以及为其他操作选择功能。同样的在这里对于上面鼠标移入点事件也可以通过该方法进行实现,这里就不做说明了。

属性说明
condition设置监听事件,默认是singleClick单击事件,还可以设置以下事件
pointerMove:鼠标移动时触发事件。 singleClick:鼠标单击时触发事件。 dblclick:鼠标双击时触发事件。 pointerDown:鼠标按下时触发事件。 pointerUp:鼠标释放时触发事件。 pointerEnter:鼠标进入图层时触发事件。 pointerLeave:鼠标离开图层时触发事件。 pointerDrag:鼠标拖动时触发事件。
layers从中选择要素的图层列表
style所选要素的样式,未设置则使用默认样式

这里的Select对象可以参考官网:OpenLayers v8.2.0 API - 类:Select

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/149486.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

浅谈无线测温产品在菲律宾某工厂配电项目的应用

摘要&#xff1a;配电系统是由多种配电设备和配电设施所组成的变换电压和直接向终端用户分配电能的一个电力网络系统。由于配电系统作为电力系统的一个环节直接面向终端用户&#xff0c;它的完善与否直接关系着广大用户的用电可靠性和用电质量&#xff0c;因而在电力系统中具有…

第14届蓝桥杯青少组python试题解析:23年5月省赛

选择题 T1. 执行以下代码&#xff0c;输出结果是&#xff08;&#xff09;。 lst "abc" print(lstlst)abcabc abc lstlst abcabc T2. 执行以下代码&#xff0c;输出的结果是&#xff08;&#xff09;。 age {16,18,17} print(type(sorted(age)))<class set&…

C++基础从0到1入门编程(三)

系统学习C 方便自己日后复习&#xff0c;错误的地方希望积极指正 往期文章&#xff1a; C基础从0到1入门编程&#xff08;一&#xff09; C基础从0到1入门编程&#xff08;二&#xff09; 参考视频&#xff1a; 1.黑马程序员匠心之作|C教程从0到1入门编程,学习编程不再难 2.系统…

企业计算机服务器中了faust勒索病毒怎么办,faust勒索病毒解密文件恢复

网络技术的不断应用发展&#xff0c;为企业注入了新的生产运营方式&#xff0c;计算机服务器为企业的数据存储提供了便利&#xff0c;让企业的生产运营得到了有力保障&#xff0c;近期&#xff0c;云天数据恢复中心陆续接到很多企业的求助&#xff0c;企业的计算机服务器遭到了…

基于单片机设计的电子指南针(LSM303DLH模块(三轴磁场 + 三轴加速度)

一、前言 本项目是基于单片机设计的电子指南针&#xff0c;主要利用STC89C52作为主控芯片和LSM303DLH模块作为指南针模块。通过LCD1602液晶显示屏来展示检测到的指南针信息。 在日常生活中&#xff0c;指南针是一种非常实用的工具&#xff0c;可以帮助我们确定方向&#xff0…

人工智能-循环神经网络通过时间反向传播

到目前为止&#xff0c;我们已经反复提到像梯度爆炸或梯度消失&#xff0c; 以及需要对循环神经网络分离梯度。 例如&#xff0c;我们在序列上调用了detach函数。 为了能够快速构建模型并了解其工作原理&#xff0c; 上面所说的这些概念都没有得到充分的解释。 本节将更深入地探…

MTK Pump Express 快速充电原理分析

1 MTK PE 1.1 原理 在讲正文之前&#xff0c;我们先看一个例子。 对于一块电池&#xff0c;我们假设它的容量是6000mAh&#xff0c;并且标称电压是3.7V&#xff0c;换算成Wh(瓦时)为单位的值是22.3Wh(6000mAh*3.7V)&#xff1b;普通的充电器输出电压电流是5V2A(10W)&#xff0c…

纯CSS实现炫酷文本阴影效果

如图所示&#xff0c;这是一个文本阴影效果&#xff0c;阴影有多个颜色&#xff0c;鼠标悬停时文本阴影效果消失&#xff0c;文本回到正常的效果。让我们逐步分解代码&#xff0c;看看如何使用纯CSS实现这个效果的。 基于以上动图可以分析出以下是本次实现的主要几个功能点&am…

【软件工程师从0到1】- Java面向对象基础 (知识汇总)

前言 介绍&#xff1a;大家好啊&#xff0c;我是hitzaki辰。 社区&#xff1a;&#xff08;完全免费、欢迎加入&#xff09;日常打卡、学习交流、资源共享的知识星球。 自媒体&#xff1a;我会在b站/抖音更新视频讲解 或 一些纯技术外的分享&#xff0c;账号同名&#xff1a;hi…

QTcpSocket发送结构体的做法

作者&#xff1a;朱金灿 来源&#xff1a;clever101的专栏 为什么大多数人学不会人工智能编程&#xff1f;>>> QTcpSocket发送结构体其实很简单:使用QByteArray类对象进行封装发送&#xff0c;示例代码如下&#xff1a; /* 消息结构体 */ struct stMsg {int m_A…

CLIP浅谈

CLIP论文地址&#xff1a;Learning Transferable Visual Models From Natural Language Supervision CLIP代码地址&#xff1a;https://github.com/openai/CLIP 简介 CLIP是OpenAI在2021年2月发表的一篇文章&#xff0c;它的主要贡献有以下2点&#xff1a; 1&#xff09;将图…

无损音频播放软件 Colibri mac中文版特点介绍

Colibri for mac是一款轻量级的音频播放器软件。它具有简洁的界面设计和快速启动速度&#xff0c;能够提供流畅的音频播放体验。Colibri支持多种常见的音频格式&#xff0c;包括MP3、FLAC、ALAC、AAC等。它还提供了一些实用的功能&#xff0c;如音频均衡器、音频增益控制、播放…

酒糟废水处理设备有哪些

酒糟废水处理设备有以下几种&#xff1a; 格栅&#xff1a;用于拦截大颗粒悬浮物&#xff0c;以保护后续处理设备。调节池&#xff1a;用于调节水质和水量&#xff0c;使废水在处理过程中保持稳定。混凝反应池&#xff1a;通过添加混凝剂&#xff0c;使废水中的小颗粒悬浮物凝…

小程序开通电子发票

总目录 文章目录 总目录前言结语 前言 随着人工智能的不断发展&#xff0c;机器学习这门技术也越来越重要&#xff0c;很多人都开启了学习机器学习&#xff0c;本文就介绍了机器学习的基础内容。 首先登录商户号&#xff1a;https://pay.weixin.qq.com/index.php/core/home/lo…

探索SPI:深入理解原理、源码与应用场景

文章目录 一、初步认识1、概念2、工作原理3、作用场景 二、源码分析1、ServiceLoader结构2、相关字段3、核心方法 三、案例connector连接器小案例1、新建SPI项目2、创建扩展实现项目1-MongoDB3、创建扩展实现项目2-Oracle4、测试 Spring应用1、创建study工程2、创建forlan-test…

uniapp Android如何授权打开系统蓝牙Bluetooth?

uniapp Android如何授权打开系统蓝牙&#xff1f; 使用uniapp开发蓝牙项目过程中&#xff0c;涉及到检测手机系统蓝牙是否打开功能&#xff0c;这里介绍Android&#xff0c;iOS暂时没有找到优方法。朋友们如果有好的方案&#xff0c;欢迎评论分享~ 文章目录 uniapp Android如何…

AWS云服务器EC2实例实现ByConity快速部署

1. 前言 亚马逊是全球最大的在线零售商和云计算服务提供商。AWS云服务器在全球范围内都备受推崇&#xff0c;被众多业内人士誉为“云计算服务的行业标准”。在国内&#xff0c;亚马逊AWS也以其卓越的性能和服务满足了众多用户的需求&#xff0c;拥有着较高的市场份额和竞争力。…

华为笔记本MateBook D 14 2021款锐龙版R7集显非触屏(NbM-WFP9)原装出厂Windows10-20H2系统

链接&#xff1a;https://pan.baidu.com/s/13Kyy95GME-asli4woNN_ww?pwdbqa8 提取码&#xff1a;bqa8 HUAWEI华为MateBookD14原厂Win10系统自带所有驱动、出厂主题壁纸、系统属性专属LOGO标志、Office办公软件、华为电脑管家等预装程序

05_SHELL编程之文本处理工具SED

typora-root-url: pictures课程目标 掌握sed的基本语法结构 熟悉sed常用的命令&#xff0c;如打印p&#xff0c;删除d&#xff0c;插入i等 Windows&#xff1a;​ Linux&#xff1a; vim vi gedit nano emacs 一、sed介绍 1. sed的工作流程 首先sed把当前正在处理的行保存…

el-table中el-popover失效问题

场景&#xff1a;先有一个数据表格&#xff0c;右侧操作栏为固定列&#xff0c;另外有一个字段使用了el-popover来点击弹出框来修改值&#xff0c;发现不好用&#xff0c;点击后无法显示弹出框&#xff0c;但当没有操作栏权限时却意外的生效了。 这种问题真是不常见&#xff0…