源码分析之Openlayers中GeometryCollection类
概述
本文主要介绍GeometryCollection类,GeometryCollection类继承于Geometry类,关于Geometry类,参考这篇文章源码分析之Openlayers中Geometry基类介绍
GeometryCollection类就是一组几何对象的集合.
源码分析
GeometryCollection类源码实现
GeometryCollection类源码实现如下:
class GeometryCollection extends Geometry {constructor(geometries) {super();this.geometries_ = geometries;this.changeEventKeys_ = [];this.listenGeometriesChange_();}unlistenGeometriesChange_() {this.changeEventsKeys_.forEach(unlistenByKey);this.changeEventsKeys_.length = 0;}listenGeometriesChange_() {const geometries = this.geometries_;for (let i = 0, ii = geometries.length; i < ii; ++i) {this.changeEventsKeys_.push(listen(geometries[i], EventType.CHANGE, this.changed, this));}}clone() {const geometryCollection = new GeometryCollection(cloneGeometries(this.geometries_));geometryCollection.applyProperties(this);return geometryCollection;}closestPointXY(x, y, closestPoint, minSquaredDistance) {if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {return minSquaredDistance;}const geometries = this.geometries_;for (let i = 0, ii = geometries.length; i < ii; ++i) {minSquaredDistance = geometries[i].closestPointXY(x,y,closestPoint,minSquaredDistance);}return minSquaredDistance;}containsXY(x, y) {const geometries = this.geometries_;for (let i = 0, ii = geometries.length; i < ii; ++i) {if (geometries[i].containsXY(x, y)) {return true;}}return false;}computeExtent(extent) {createOrUpdateEmpty(extent);const geometries = this.geometries_;for (let i = 0, ii = geometries.length; i < ii; ++i) {extend(extent, geometries[i].getExtent());}return extent;}getGeometries() {return cloneGeometries(this.geometries_);}getGeometriesArray() {return this.geometries_;}getGeometriesArrayRecursive() {/** @type {Array<Geometry>} */let geometriesArray = [];const geometries = this.geometries_;for (let i = 0, ii = geometries.length; i < ii; ++i) {if (geometries[i].getType() === this.getType()) {geometriesArray = geometriesArray.concat(geometries[i].getGeometriesArrayRecursive());} else {geometriesArray.push(geometries[i]);}}return geometriesArray;}getSimplifiedGeometry(squaredTolerance) {if (this.simplifiedGeometryRevision !== this.getRevision()) {this.simplifiedGeometryMaxMinSquaredTolerance = 0;this.simplifiedGeometryRevision = this.getRevision();}if (squaredTolerance < 0 ||(this.simplifiedGeometryMaxMinSquaredTolerance !== 0 &&squaredTolerance < this.simplifiedGeometryMaxMinSquaredTolerance)) {return this;}const simplifiedGeometries = [];const geometries = this.geometries_;let simplified = false;for (let i = 0, ii = geometries.length; i < ii; ++i) {const geometry = geometries[i];const simplifiedGeometry =geometry.getSimplifiedGeometry(squaredTolerance);simplifiedGeometries.push(simplifiedGeometry);if (simplifiedGeometry !== geometry) {simplified = true;}}if (simplified) {const simplifiedGeometryCollection = new GeometryCollection(simplifiedGeometries);return simplifiedGeometryCollection;}this.simplifiedGeometryMaxMinSquaredTolerance = squaredTolerance;return this;}getType() {return "GeometryCollection";}intersectsExtent(extent) {const geometries = this.geometries_;for (let i = 0, ii = geometries.length; i < ii; ++i) {if (geometries[i].intersectsExtent(extent)) {return true;}}return false;}isEmpty() {return this.geometries_.length === 0;}rotate(angle, anchor) {const geometries = this.geometries_;for (let i = 0, ii = geometries.length; i < ii; ++i) {geometries[i].rotate(angle, anchor);}this.changed();}scale(sx, sy, anchor) {if (!anchor) {anchor = getCenter(this.getExtent());}const geometries = this.geometries_;for (let i = 0, ii = geometries.length; i < ii; ++i) {geometries[i].scale(sx, sy, anchor);}this.changed();}setGeometries(geometries) {this.setGeometriesArray(cloneGeometries(geometries));}setGeometriesArray(geometries) {this.unlistenGeometriesChange_();this.geometries_ = geometries;this.listenGeometriesChange_();this.changed();}applyTransform(transformFn) {const geometries = this.geometries_;for (let i = 0, ii = geometries.length; i < ii; ++i) {geometries[i].applyTransform(transformFn);}this.changed();}translate(deltaX, deltaY) {const geometries = this.geometries_;for (let i = 0, ii = geometries.length; i < ii; ++i) {geometries[i].translate(deltaX, deltaY);}this.changed();}disposeInternal() {this.unlistenGeometriesChange_();super.disposeInternal();}
}
GeometryCollection类构造函数
GeometryCollection类构造函数接受一个参数geometries,geometries是一个包含多个几何对象数组,该参数会赋给全局变量this.geometries_,然后初始化一个变量this.changeEventsKeys_为空数组,最后调用this.listenGeometriesChange_方法.
GeometryCollection类的方法
GeometryCollection类的方法主要是对几何对象的一些操作,会去遍历this.geometries_变量,逐一进行操作.GeometryCollection类中的主要方法如下:
-
listenGeometriesChange_方法:该方法在构造函数中就会被调用,其核心逻辑就是循环遍历this.geometries_,调用listen方法注册每个几何对象的change事件监听,注册事件返回的keys值保存在全局变量this.changeEventsKeys_中.listen方法的实现可以参考这篇文章源码分析之Openlayers中的Observable类 -
unlistenGeometriesChange_方法:用于取消监听,重置this.changeEventKeys_为空数组,解绑方法unlistenByKey同样是在event.js中实现的. -
clone方法:clone方法会返回一个新的几何对象集合,其内部会先调用cloneGeometries方法去clone每一个Geometry,然后实例化GeometryCollection类,再会调用applyProperties去应用this,applyProperties方法是在Object类中实现的,主要就是复制属性. -
closestPointXY方法:用于获取对几何对象稽核最近的点坐标,以及修改并获取最短距离;方法接受四个参数目标点坐标x``y,最近点坐标以及最短距离,会先调用closestSquaredDistanceXY获取目标坐标点到边界范围的平方距离,若最短距离大于该参数最短平方距离,则返回参数minSquaredDistance;然后遍历this.geometries_,调用每一个几何对象的closestPointXY方法,修改最近点坐标和最短距离;最后返回最短距离 -
containsXY方法:同样地也是遍历this.geometries_,调用几何对象的containsXY方法;containsXY方法就是判断点是否在几何对象集合的边界上,返回一个布尔值。 -
computeExtent方法:获取几何对象集合的边界范围 -
getGeometries方法:获取几何对象集合的副本,调用cloneGeometries方法 -
getGeometriesArray方法:获取几何对象集合数组 -
getGeometriesArrayRecursive方法:将嵌套的几何对象(如子集合)展平成一个平坦的数组,即若几何对象数组中的数组项也是一个数组,那么就会递归调用它的getGeometriesArrayRecursive方法。 -
getSimplifiedGeometry方法:该方法就是用于简化几何,采用了Douglas-Peucker算法。这个算法常用于简化折线几何,减少点的数量,同时尽可能保持原始几何形状的准确性。简化通过一个容差值来控制简化的程度,容差值越大,简化的结果就越简单。getSimplifiedGeometry方法会先检查修订号,若当前几何对象的修订号与上次简化的修订号不一致这说明几何对象已经发生了变化,需要重新计算简化后的几何对象;然后会检查容差值,若容差值小于0或者小于已经记录的最大容差值,则不需要重新计算,直接返回当前对象;然后初始化一个空数组,simplifiedGeometries用于存储简化后的几何对象,再遍历this.geometries_,调用每个几何对象的getSimplifiedGeometry方法,简化每一个几何对象;若简化后的实例对象不等于原始对象,则将simplified赋值为true,然后实例化GeometryCollection类,生成一个几何对象集合实例并返回;若简化后的实例对象与原始对象相同,一个几何对象也没有被简化,则返回当前对象this. -
getType方法:获取类型,返回GeometryCollection -
intersectsExtent方法:遍历this.geometries_,然后调用每个几何对象的intersectsExtent方法,判断几何对象是否与extent相交;若有一个几何对象和extent相交则返回true;若一个都不相交,则返回false。 -
isEmpty方法:判断几何对象集合是否为空,返回一个布尔值。 -
rotate方法:遍历this.geometries_,然后调用每个几何对象的rotate方法,最后调用this.changed方法 -
scale方法:遍历this.geometries_,然后调用每个几何对象的scale方法,最后调用this.changed方法 -
setGeometries方法:会先调用cloneGeometries方法clone每个几何对象,然后调用this.setGeometriesArray方法 -
setGeometriesArray方法:会调用this.unlistenGeometriesChange_取消监听,然后设置this.geometries_,再调用this.listenGeometriesChange_方法注册监听,最后调用this.changed方法 -
applyTransform方法:遍历this.geometries_,然后调用每个几何对象的applyTransform方法,最后调用this.changed方法 -
translate方法:遍历this.geometries_,然后调用每个几何对象的translate方法,最后调用this.changed方法 -
disposeInternal方法:清理函数,调用this.unlistenGeometriesChange_取消监听,再调用父类的disposeInternal方法
总结
本文介绍了GeometryCollection类的源码实现,由此可以清晰理解GeometryCollection类主要还是一组多个对几何对象进行平移、旋转和缩放转换以及空间关系的判断等等。
相关文章:
源码分析之Openlayers中GeometryCollection类
概述 本文主要介绍GeometryCollection类,GeometryCollection类继承于Geometry类,关于Geometry类,参考这篇文章源码分析之Openlayers中Geometry基类介绍 GeometryCollection类就是一组几何对象的集合. 源码分析 GeometryCollection类源码实现 GeometryCollection类源码实现…...
常见LLM大模型总结
常见LLM大模型总结 模型名称发布机构主要特点参数规模应用场景GPT-4OpenAI强大的推理能力,支持多模态(图像文本),上下文理解更深1.7万亿参数聊天机器人、内容生成、代码生成ChatGPTOpenAI面向对话优化,支持多轮对话记…...
向量检索+大语言模型,免费搭建基于专属知识库的 RAG 智能助手
随着生成式人工智能技术的飞速发展,越来越多的人和企业开始应用AI到日常的工作和生活中。但公域的AI助手其数据来自互联网上的大量公开文本,虽然具有广泛的知识,但在面对一些特定领域的专业问题时,可能会出现回答不够准确或深入的…...
基础11C++中的异常处理以及swap
一、异常处理手段 抛出异常:throw 异常 作用:让调用者看见这个异常,如果调用者不理睬,就让调用者的调用者看见 接住异常: try {可能异常的code} catch(异常类型) {处理方式} 异常类型:一般为const &,防…...
写作词汇积累:得偿所望、可见一斑、搭腔
得偿所望 【得偿所望】是指经过长时间的期盼和努力,最终实现了自己的愿望或目标。 【得偿所望】强调了愿望实现后的满足感和成就感,是一个充满正能量和积极情感的词语。 【得偿所望】与【得偿所愿】在表达上也具有相似的含义,都指愿望得到了…...
android jetpack compose Model对象更新变量 UI不更新、不刷新问题
以前是搞老本行Android原生开发的,因为工作原因,一直在用vue小程序;因为一些工作需要,又需要用到Android原生开发,建了个项目,打开源码一看,天塌了!!!我以前的…...
数据库概论
目录 1、数据库管理系统(DBMS) 1.1 DBMS的主要功能 1. 数据库的定义功能 2. 数据库的操纵功能 3. 数据库的运行控制功能 4. 数据库的维护 5. 数据字典(Data Dictionary,DD) 2、数据模型 2.1 信息和数据(了解) 2.2 数据模型的三个层次 2.3 信息世界中的基…...
基于python使用UDP协议对飞秋进行通讯—DDOS
基于飞秋的信息传输 声明:笔记的只是方便各位师傅学习知识,以下代码、网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负。 老规矩,封面在文末! 飞秋介绍 (…...
数据库管理-第275期 Oracle 23ai:画了两张架构图(20241225)
数据库管理275期 2024-12-25 数据库管理-第275期 Oracle 23ai:画了两张架构图(20241225)1 系统管理分片2 用户定义分片总结 数据库管理-第275期 Oracle 23ai:画了两张架构图(20241225) 作者:胖…...
使用Streamlit部署机器学习模型
机器学习: 计算机能够从经验中学习,而无需明确编程。机器学习是目前最热门的领域之一,世界各地的顶级公司都在使用它来改善他们的服务和产品。但是没有使用在Jupyter Notebook中训练的机器学习模型。因此,我们需要部署这些模型&am…...
依图科技简介
依图科技(YITU Technology)是中国一家全球领先的人工智能(AI)公司,成立于2012年,总部位于上海。公司专注于计算机视觉、语音识别和自然语言处理等核心AI技术,致力于推动AI技术在医疗、安防、金融…...
苍穹外卖day07缓存部分分析
苍穹外卖Day07部分聚焦于缓存功能的实现与优化,通过引入redis缓存机制,结合Spring Cache 注解,降低了数据库负载,提升其响应速度。 以下是清除缓存功能代码: RestController RequestMapping("/admin/dish"…...
OCR实践-Table-Transformer
前言 书接上文 OCR实践—PaddleOCR Table-Transformer 与 PubTables-1M table-transformer,来自微软,基于Detr,在PubTables1M 数据集上进行训练,模型是在提出数据集同时的工作, paper PubTables-1M: Towards comp…...
HarmonyOS NEXT 实战之元服务:静态案例效果---电台推荐
背景: 前几篇学习了元服务,后面几期就让我们开发简单的元服务吧,里面丰富的内容大家自己加,本期案例 仅供参考 先上本期效果图 ,里面图片自行替换 效果图1完整代码案例如下: Index import { authentica…...
微信小程序 不同角色进入不同页面、呈现不同底部导航栏
遇到这个需求之前一直使用的小程序默认底部导航栏,且小程序默认入口页面为pages/index/index,要使不同角色呈现不同底部导航栏,必须要在不同页面引用不同的自定义导航栏。本篇将结合分包(subPackages)展开以下三步叙述…...
MATLAB符号计算-符号表达式基础运算操作
1.1.2符号变量取值域的限定 默认复数域 【例1-1-2】解不等式 1.1.3创建符号表达式 对符号对象进行各种运算(算术运算、关系运算、逻辑运算),即可创建符号表达式。 1.算术运算与转置 【例1-1-3】 f5是f4的共轭转置 f6是f4的转置 2.关系…...
服务器被攻击怎么办
当服务器遭受恶意流量攻击,如DDoS(分布式拒绝服务)或CC(Challenge Collapsar)攻击时,传统的防护措施可能不足以应对。此时,采用高防IP服务可以有效缓解攻击压力,确保业务连续性和数据…...
精准识别花生豆:基于EfficientNetB0的深度学习检测与分类项目
精准检测花生豆:基于EfficientNet的深度学习分类项目 在现代农业生产中,作物的质量检测和分类是确保产品质量的重要环节。针对花生豆的检测与分类需求,我们开发了一套基于深度学习的解决方案,利用EfficientNetB0模型实现高效、准…...
【UE5 C++课程系列笔记】13——GameInstanceSubsystem的简单使用
目录 概念 基本使用案例 效果 步骤 概念 UGameInstanceSubsystem 类继承自 USubsystem,它与 GameInstance 紧密关联,旨在为游戏提供一种模块化、可方便扩展和管理的功能单元机制。在整个游戏运行期间,一个 GameInstance 可以包含多个 UGa…...
实用工具推荐----Doxygen使用方法
目录 目录 1 软件介绍 2 Doxygen软件下载方法 3 Doxygen软件配置方法 4 标准注释描述 4.1 块注释 和 特殊描述字符 4.1.1 函数描述示例 4.1.2结构体数组变量示例 特别注意: 4.2单行注释 4.2.1 单个变量注释示例 特别注意: 4.2.2对于枚举变量…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...
数据分析六部曲?
引言 上一章我们说到了数据分析六部曲,何谓六部曲呢? 其实啊,数据分析没那么难,只要掌握了下面这六个步骤,也就是数据分析六部曲,就算你是个啥都不懂的小白,也能慢慢上手做数据分析啦。 第一…...
