基于R-Tree的地理空间数据分析加速

news2024/11/24 15:53:11

几年前,我正在做一个业余项目。我想创建一个 Web 应用程序,推荐当地的特色景点,例如咖啡馆、书店或隐藏的酒吧。我的想法是在地图上显示用户触手可及的所有兴趣点。我的数据集中有数十万个点,我必须巧妙地过滤用户给定范围内的数据点。最简单的方法是计算用户与每个兴趣点之间的距离,并丢弃指定范围之外的所有点。尤其是对于像我这样的大数据集,这种方法通常会导致较长的处理时间。

当然,一定有更好的方法,因为响应时间在交互式应用程序中很重要。这时我遇到了数据结构 R 树。这些树用于快速空间访问和搜索。使用 R 树,我能够快速隔离靠近用户位置的兴趣点并将其显示在地图上。这使我的 Web 应用程序的响应时间大大提高——只需增加四行代码!

在本文中,我解释了什么是 R 树以及它们的工作原理。前两节以纽约市的街道树木为例进行了说明。第三节演示了如何在 Python 中使用此数据结构来加速地理空间数据处理程序。

NSDT工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器 - REVIT导出3D模型插件 - 3D模型语义搜索引擎 - Three.js虚拟轴心开发包 - 3D模型在线减面 - STL模型在线切割 

1、分析纽约市的树木

假设我们被要求分析纽约市街区与树木健康状况之间是否存在相关性。纽约市开放数据门户提供了街道树木普查数据集,其中包括树种、直径、健康状况感知和每棵树的地理位置。

首先,我们要计算上东区的街道树木数量。下面的伪代码片段遍历数据集树木并检查树木是否位于 upper_east_side 边界内:

total_count, tree_count = 0, 0
for tree in trees:
    total_count += 1
    if upper_east_side.contains(tree):
        tree_count += 1
print_results(num_tests=total_count, num_trees=tree_count)
>>> Total number of trees tested: 683,788
>>> Number of trees in Upper East Side: 8,807

我们发现上东区大约有 9000 棵树。但是,为了达到这个目标,我们总共测试了 684000 棵树。下面的动画显示了我们测试的树木距离我们的目标街区有数英里远,因此很容易被忽略。但是,我们如何才能将远处的树木排除在昂贵的计算之外,以实现显着的性能提升?

我们几乎免费获得的一条信息是多边形的边界框(可以通过其节点的最小值和最大值确定)。此外,测试一个点是否落在矩形内很简单,只需要四个比较操作(该点必须大于或等于左下角,并且小于或等于右上角)。现在,假设 bounding_box 是一个数据集,其中包含上东区周围一个紧密矩形中的所有树木(在下一节中,我们将了解如何轻松获得这样的矩形)。考虑到这一点,得出:

total_count, tree_count = 0, 0
for tree in bounding_box:
    total_count += 1
    if upper_east_side.contains(tree):
        tree_count += 1
print_results(num_tests=total_count, num_trees=tree_count)
>>> Total number of trees tested: 10,768
>>> Number of trees in Upper East Side: 8,807

动画右侧显示我们现在只测试潜在候选者。这些是与多边形紧邻的树,即落在其边界框内的点。通过忽略远处的树,我们能够将测试次数从 684k 减少到 11k — 减少了 60 倍!在下一节中,我们将看到 R 树正是利用了这个想法。

(左)纽约市的所有树木都经过测试 | (右)仅测试上东区边界框内的树木

2、用于空间搜索的数据结构

R 树是一种基于树的数据结构,用于高效地创建空间索引。R 树通常用于快速空间查询或加速最近邻搜索 [1]。一种常见的用例可能是存储兴趣点(例如餐馆、加油站、街道等)的空间信息。借助 R 树,可以快速检索距离某个位置一定距离内的所有兴趣点。作为回报,这些结果可以显示在地图或导航系统中。

R 树的基本思想很简单:树的叶节点保存空间数据,而分支节点对应于包含其所有子节点的最小边界框。通过这种结构,R 树将空间划分为矩形,随着树的增长,矩形会变得更加细化。下面的示例说明了这一点:

(左)R 树将曼哈顿划分为多个矩形 (右)相应的树结构

查询 R 树中的矩形,即我们想要检索此搜索窗口中包含的所有数据。请记住,每个非叶节点都对应一个包含其所有子节点的边界框。要完成搜索查询,我们只需沿着树的分支行进,并沿着与给定矩形相交的路径行进,直到到达叶节点。这些叶节点(因此我们的数据点)包含在搜索矩形中并满足查询。下面的动画演示了我们可以通过忽略不符合搜索条件的整个分支来大大减少搜索操作的数量。

(左)与搜索矩形(红色)不相交的边界框(黑色)被迭代忽略 (右)

3、Python 中的 R 树

Python 包 Rtree 提供了 R 树数据结构的实现,并附带许多方便的功能,例如最近邻搜索、交集搜索或多维索引。

我们可以方便地使用 Python 的包管理器 pip 安装该包:

pip install Rtree

3.1 基础知识

在处理点或多边形等几何图形之前,我们先介绍一下 Rtree 包的基本用法:

from rtree import index
idx = index.Index()
bbox_0 = (0.0, 0.0, 1.0, 1.0) # (left, bottom, right, top)
bbox_1 = (3.0, 3.0, 6.0, 6.0)
idx.insert(0, bbox_0)
idx.insert(1, bbox_1)

索引模块帮助我们构建空间索引。此索引通过插入对象的边界框自动建立。边界框通过指定其左、下、右和上坐标来定义。请注意,我们将边界框与标识符一起插入(在上面的示例中为 0 和 1)。ID 将帮助我们在执行查询时识别边界框:

search_window = (-1.0, -1.0, 2.0, 2.0) # ex. 1
list(idx.intersection(search_window))
>>> [0]
search_window = (4.0, 4.0, 5.0, 5.0)   # ex. 2
list(idx.intersection(search_window))
>>> [1]
search_window = (0.0, 0.0, 6.0, 6.0)   # ex. 3
list(idx.intersection(search_window))
>>> [0, 1]
search_window = (1.01, 1.01, 2.0, 2.0) # ex. 4
list(idx.intersection(search_window))
>>> []

查询给定矩形的索引,同样由其左、下、右和上坐标指定。交集方法的结果是搜索窗口内包含的对象的 ID(示例 1-3)。如果搜索窗口超出索引中的数据范围,则结果为空(示例 4)。类似地,我们使用最近方法来查找给定搜索窗口的 k 个最近对象:

k = 1
search_window = (1.01, 1.01, 2.0, 2.0)
list(idx.nearest(search_window, k))
>>> [0]

3.2 使用点、线和多边形

在上一节中,我们了解了如何通过插入对象的边界框来构建索引。现在我们要继续使用点、线和多边形来表示这些对象。Shapely 包提供了一种在 Python 中处理此类几何图形的简单方法:

from shapely.geometry import Point, LineString, Polygon
point = Point(0, 0)
line = LineString([(1, 0), (2, 1)])
polygon = Polygon([(3, 0), (3, 1), (4, 1)])
idx = index.Index()
idx.insert(0, point.bounds)   # bounds: (0.0, 0.0, 0.0, 0.0)
idx.insert(1, line.bounds)    # bounds: (1.0, 0.0, 2.0, 1.0)
idx.insert(2, polygon.bounds) # bounds: (3.0, 0.0, 4.0, 1.0)

上面,我们首先创建一个点、一条线和一个多边形。接下来,将这些对象的边界框插入到使用 ID 0、1 和 2 的索引中。现在我们查询索引以获取不同的搜索窗口:

search_window = (0.0, 0.0, 0.5, 0.5)  # ex. 1
list(idx.intersection(search_window))
>>> [0]
search_window = (0.0, 0.0, 2.0, 1.0)  # ex. 2
list(idx.intersection(search_window))
>>> [0, 1]
search_window = (0.0, 0.0, 4.0, 2.0)  # ex. 3
list(idx.intersection(search_window))
>>> [0, 1, 2]
k = 1
search_window = (1.0, 0.0, 2.5, 1.5)  # ex. 4
list(idx.nearest(search_window, k))
>>> [1]

下图显示了几何形状和搜索窗口:

绿色:点、线和多边形。红色:搜索窗口

3.3 搜索上东区的所有树木

我们终于拥有了提取上东区所有树木所需的一切!我们将在下面介绍一段代码片段,但完整版本可在此处找到。

绿色:纽约市的树木。蓝色:上东区。橙色:上东区的边界框

首先,我们使用 GeoPandas 包加载所有必需的几何图形:

import geopandas as gpd
from rtree import index
df_trees = gpd.read_file('2015 Street Tree Census.geojson')
df_upper_east_side = gpd.read_file('upper_east_side.geojson')
geom_upper_east_side = df_upper_east_side.loc[0, 'geometry']

接下来,我们创建一个包含纽约市所有树木的 R 树索引:

idx = index.Index()
for id, geom in zip(df_trees.index, df_trees.geometry):
    idx.insert(id, geom.bounds)

现在,我们生成一个潜在候选者列表,即上东区边界框内的所有树木:

search_window = geom_upper_east_side.bounds
potential = list(idx.intersection(search_window))

最后,我们遍历所有潜在候选人,提取完全位于上东区的候选人:

trees = []
for tree in df_trees.loc[potential, 'geometry']:
    if geom_upper_east_side.contains(tree):
        trees.append(tree)

print_results(num_data=len(df_trees), num_tests=len(potential), num_trees=len(trees))
>>> Total number of trees in dataset: 683,788
>>> Total number of trees tested: 10,768
>>> Number of trees in Upper East Side: 8,807

4、结束语

在本文中,我们了解了 R 树如何通过将底层空间划分为矩形来组织地理信息。这种结构使 R 树在空间查找方面非常快。在我们的纽约市街道树示例中,使用 R 树将操作数量减少了 60 倍。我们还了解了如何在 Python 中使用 R 树。在我们的示例中,仅用四行代码就实现了加速:初始化索引(1 行)、构建索引(2 行)以及使用交集函数查找附近的候选对象(1 行)。

那么为什么不到处都使用 R 树呢?虽然我们通过减少搜索操作数量来节省时间,但构建索引会浪费时间。对于后者,我们实际上必须遍历整个数据集。这使得 R 树不适用于只需要少量搜索的应用程序或索引经常更改的应用程序(因为树重新平衡)。

自 1984 年 Antonin Guttman 发明 R 树以来,R 树已经取得了长足的进步。如今,R 树已应用于各种应用,例如计算机图形学 、视频游戏 、交通控制系统 ,最突出的是空间数据管理数据库 。也许,你下一次进行地理空间数据分析时,R 树也会派上用场!


原文链接:用R树加速空间数据分析 - BimAnt

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

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

相关文章

DVWA - Brute Force

DVWA - Brute Force 等级:low ​ 直接上bp弱口令爆破,设置变量,攻击类型最后一个,payload为用户名、密码简单列表 ​ 直接run,长度排序下,不一样的就是正确的用户名和密码 ​ 另解: 看一下…

3DMAX网格插入插件使用方法讲解

3DMAX网格插入插件使用方法 3DMAX网格插入插件,在选择的面上安门窗、打螺丝、挖洞、插入眼耳口鼻及其它网格模型等可以分分钟搞定!它通过将面选择替换为库中的资源来加快建模过程。非常适合硬网格和有机建模! 【适用版本】 3dMax2013及更高版…

快速欧氏聚类与普通欧氏聚类比较

1、前言 文献《FEC: Fast Euclidean Clustering for Point Cloud Segmentation》介绍了一种快速欧氏聚类方法,大概原理可以参考如下图,具体原理可以参考参考文献。 2、时间效率比较:快速欧氏聚类VS普通欧氏聚类 网上搜集的快速欧式聚类,与自己手写的普通欧式聚类进行对比,…

网络知识:这些特殊的IP地址,具体的用途你都知道吗

目录 一、0.0.0.0 二、255.255.255.255 限制广播地址 三、127.0.0.1 本机地址 四、224.0.0.1 组播地址 五、169.254.x.x 六、10.x.x.x、172.16。x。x~172.31。x。x、192.168。x。x 私有地址 对于计算机网络来说,IP地址是非常重要的概念&#xff0c…

Objective-C 学习笔记 | 协议(property)

Objective-C 学习笔记 | 协议(property) Objective-C 学习笔记 | 协议(property) Objective-C 学习笔记 | 协议(property) iOS 应用经常会用 UITableView 实例来显示数据,但是它本身不包含数据…

采集罗克韦尔AB、西门子等PLC数据发布成HTTP接口

智能网关IGT-DSER集成了多种PLC的原厂协议,方便实现各种PLC的原厂协议转换为HTTP协议的服务端,通过网关的参数配置软件绑定JSON文件的字段与PLC寄存器地址,即可接收来自客户端的GET、PUT和POST命令,解析和打包JSON文件(JSON文件格…

去哪儿网PMO张璐受邀为第十三届中国PMO大会演讲嘉宾

全国PMO专业人士年度盛会 去哪儿网PMO张璐女士受邀为PMO评论主办的2024第十三届中国PMO大会演讲嘉宾,演讲议题为“数字化助力组织目标落地”。大会将于6月29-30日在北京举办,敬请关注! 议题简要 本次议题将分享去哪儿流程标准化&工具化…

我用chatgpt写了一款程序

众所周知,Chatgpt能够帮助人们写代码,前几天苏音试着完全用Chatgpt写一款Python程序 有一句话我很赞同,未来能代替人的不是AI,是会使用AI的人。 最终,写下来效果还不错,完全提升了我的办公效率。 开发前…

告密者斯诺登:永远不要信任 OpenAI 或其 ChatGPT 等产品|TodayAI

为什么 OpenAI 变得越来越难以信任 OpenAI,一家以开发先进人工智能技术而闻名的公司,正面临越来越多的信任危机。近期,一些令人不安的迹象使人们对这家公司的透明度和安全性产生了质疑。 首先,在 OpenAI 的旧金山办公室外&#…

顺安蜘蛛池四川官网下载

baidu搜索:如何联系八爪鱼SEO? baidu搜索:如何联系八爪鱼SEO? baidu搜索:如何联系八爪鱼SEO? 虽然影视泛目录很火,但超度站群版本自出现以来-直流量稳定,可惜这两年起站全靠域名。但话说回来,咱不能否认,只要用的域名好,做啥泛目录都有好…

湖北省小学毕业学籍照片采集流程及教师手机拍摄方法说明

随着教育信息化的不断推进,学籍管理也越来越规范和便捷。湖北省小学毕业学籍照片采集作为学籍管理的重要组成部分,对于确保学生信息的准确性和完整性具有重要意义。本文将详细介绍湖北省小学毕业学籍照片采集的流程,并提供教师使用手机拍摄照…

如何用优盘加密自己的电脑:人离后自动锁定

看电影的时候,看到有人展示,用优盘加密自己的电脑,人走开的时候拔下优盘,自动上锁。似乎很科幻,其实这样的软件非常多,不论是成品商业用的还是免费的,都非常多,很多版权管理比较强的…

结合gin框架在沙箱环境下实现电脑网站支付和当面支付

文章目录 配置支付宝开放平台编写代码测试电脑网站支付当面扫码支付 配置支付宝开放平台 支付宝开放平台 点击链接,扫码进入后,点击沙箱: 点击沙箱应用,可以看到APPID,接口加签方式选择系统默认密钥就行&#xff0…

前端JS必用工具【js-tool-big-box】学习,打开全屏和关闭全屏

这一小节,我们说一下 js-tool-big-box 工具库中,打开全屏和关闭全屏的方法学习。 我们知道,浏览器想打开全屏,按一下 F11 键就可以了,但一来这个功能不一定所有使用的用户都知道,二来在一些例如大屏的需求…

前端实现获取后端返回的文件流并下载

前端实现获取后端返回的文件流并下载 方法一:使用Axios实现文件流下载优点缺点 方法二:使用封装的Request工具实现文件流下载优点缺点 方法三:直接通过URL跳转下载优点缺点 结论 在前端开发中,有时需要从后端获取文件流&#xff0…

【解决方案】数据采集工作站数据传不上去?

数据采集工作站扮演着至关重要的角色,它们负责收集、处理和传输各种传感器和设备的数据。然而,有时会遇到数据传输失败的问题。本文将详细探讨数据采集工作站数据传不上去的可能原因及其解决方案。(更多了解采集器设备可前往苏州稳联&#xf…

芯片封测从入门到精通

文章目录 📑前言一、作者简介二、书籍亮点三、内容简介四、适读人群 📑前言 在科技日新月异的今天,芯片作为现代电子设备的核心部件,其性能与可靠性直接决定了整个产品的竞争力。而芯片封测,作为确保芯片性能与可靠性…

闭包、内存泄漏、垃圾回收详解

首先要说清楚这个话题&#xff0c;必须要先清楚什么是垃圾回收&#xff0c;要清楚什么是垃圾回收呢&#xff0c;必须要知道什么是垃圾&#xff0c;所谓的垃圾就是不再需要的内存&#xff0c;需要或者不需要是由人为来决定的 <!DOCTYPE html> <html lang"en"…

原生APP和H5 APP的区别

原生APP和H5 APP是两种常见的移动应用开发方式。它们在技术架构、性能表现、开发成本、用户体验等方面都有着明显的区别。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1. 技术架构 原生APP&#xff1a;原生APP是使用手机操作系统的…

表格识别工具哪个好?简单操作,一键识别表格

随着2024年高考的圆满结束&#xff0c;考生们迎来了新的挑战——志愿填报。这不仅是一个技术活&#xff0c;更是一个信息战。 面对海量的高校信息和复杂的数据表格&#xff0c;考生们需要一种快速、准确的方法来整理和分析这些数据。幸运的是&#xff0c;现代科技提供了多种表…