从地图到智能地图:空间索引技术如何改变我们的世界

图源:@WL
为什么空间索引很有用?
在处理地理空间数据时,空间索引是一个至关重要的功能,它决定了我们如何高效地从海量的地理数据中检索出所需的信息。想象一下,如果你正在处理一个包含数千万乃至数亿条记录的数据库,这些记录可能涵盖全球各城市、街道和建筑物的详细信息。在没有合适的索引的情况在,每次查询都可能不得不扫描整个数据集,这将是非常低效的。空间索引的引入,正是为了优化这一过程,确保查询操作既迅速又高效。在这篇文章中,我将讨论空间索引是如何实现的,以及它的优点和局限性。
什么是空间索引?
首先让我们重温下普通索引,普通索引就像我们经常会在书的末尾看到的:一个包含名词及其出现位置的列表。它可以帮助我们快速查找感兴趣的名词在特定内容中的引用。如果没有它,我们就不得不手动翻阅书中的每一页进行寻找。
在数据库中,查询和搜索一直都是十分常见且重要的功能。索引的引入通常使查找数据比遍历整个数据库更快,并且我们可以根据关注的列创建索引。而在对地理空间数据的处理中,通常需要执行诸如“交叉路口”或“在…附近”之类的操作。怎样才能建立一个空间索引,使这些操作尽可能快呢?接下来,让我们看一下数据库中的地理空间数据:

两个不相交的湖泊 图源:@WL (由Mapmost平台制作)
假设我们想要通过查询来确定这两个湖泊是否相交。通过构造,空间数据库将根据包含几何图形的边界框创建索引

两个湖泊的边界框 图源:@WL (由Mapmost平台制作)
为了判断这两个湖泊是否相交,数据库将比较两个边界框是否有任何共同区域,正如图所显示的。然而这可能直接导致错误的结论。为了解决这个问题,像PostGIS这样的空间数据库通常会将这些大的边界框分割成越来越小的边界框。

划分了小边界框的两个湖泊 图源:@WL (由Mapmost平台制作)
这种分区策略采用了一种叫做 R 树的结构进行存储。R树是一种具有层级特性的数据组织形式,它记录了一个较大的父级边界框,父级边界框下包含其所有子级边界框,以及子级边界框的子级,依次类推,形成了一个层级嵌套的体系。在这个结构中,每个父级边界框都完整地覆盖了其所有子级边界框的位置。

R-树结构示例 图源:@WL
得益于R-树结构的优势,判断“相交”与否将十分迅速:在执行相交查询时,数据库会遍历这棵树,检查每个节点的边界框,询问“当前的边界框是否与我们感兴趣的地理特征相交?”如果是,它将继续检查该边界框内的所有子框,并重复相同的相交检验。在这个过程中,数据库能够迅速地遍历整个树形结构,同时忽略那些显然不相交的分支,显著提高了查询效率。最终,系统会根据查询要求,返回所有与查询条件相交的数据。
空间索引到底有多快?
GeoPandas库同时提供了判断两个几何特征是否相交的普通方法,以及通过建立R-Tree空间索引后求解两个几何特征交集的方法,让我们采用GeoPandas库进行一个简单的对比测试吧,步骤如下。
第一步:数据准备,这里我们使用纽约市公共设施的数据集(通过开放数据下载,有需要的同学关注公众号获取)。
第二步:环境安装,通过anaconda官网下载安装包一键安装conda,接着通过conda搭建python环境,并安装GeoPandas及其依赖。
conda create -n geo_env
conda activate geo_env
conda config --env --add channels conda-forge
conda config --env --set channel_priority strict
conda install python=3 geopandas
第三步:编写测试用例,我们主要使用geopandas.GeoSeries.intersects()方法进行普通"交集"运算;通过调用geopandas.GeoSeries.sindex属性生成指定数据集的R-Tree空间索引;使用geopandas.sindex.SpatialIndex.query()方法利用建立的索引进行两个几何体的交集查询。
第四步:运行程序,结果:

从测试结果中,可以看出通过依次将34171条数据与固定的某个几何图形做“交集”运算,在不采用R-Tree空间索引的情况下耗时3.4秒,而使用了R-Tree空间索引之后耗时则是其十分之一不到。
R-Tree空间索引一定好用吗?
是否存在使用了R-Tree索引后没有任何好处的情况?是的。其中之一,便是由R-Tree空间索引存储数据的方式造成的。事实证明,原始数据的分布会影响边界框放入R-Tree中的位置。具体来说,如果大量数据集中在同一个地理空间中,它们往往会拥有相同的父节点,因此会被分组到相同的分支中。这将会导致树结构的倾斜,从而在查询时无法达到预期的优化。
Mapmost平台作为智能地图的工厂,在空间数据处理的API背后,自研并使用了多种结合特定场景的空间索引算法,致力于为用户提供极致性能体验,赶快扫码体验吧。
相关文章:
从地图到智能地图:空间索引技术如何改变我们的世界
图源:WL 为什么空间索引很有用? 在处理地理空间数据时,空间索引是一个至关重要的功能,它决定了我们如何高效地从海量的地理数据中检索出所需的信息。想象一下,如果你正在处理一个包含数千万乃至数亿条记录的数据库,…...
深入理解AI Agent架构,史上最全解析!赶紧码住!
AI Agent框架(LLM Agent):LLM驱动的智能体如何引领行业变革,应用探索与未来展望 1. AI Agent(LLM Agent)介绍 1.1. 术语 Agent:“代理” 通常是指有意行动的表现。在哲学领域,Agen…...
苹果iOS/ iPadOS18 RC 版、17.7 RC版更新发布
iPhone 16 / Pro 系列新机发布后,苹果一同推出了 iOS 18 和 iPadOS 18 的 RC 版本,iOS 18 RC 的内部版本号为22A3354,本次更新距离上次发布 Beta/RC 间隔 12 天。 在 iOS 18 中,苹果给我们带来了 Apple Intelligence,这…...
CAN集线器(工业级、隔离式)
型号: MS-HUB-C 概述 MS-HUB 是一款可通过一路 CAN ,一路 RS-232为主口扩展出 7 路 CAN 从口的工业级光电隔离型 CAN 分配器。可以有效的实现 CAN 网络的中继、扩展与隔离。采用先进的自动流控技术自动侦测CAN 信号流向。MS-HUB 具备光电隔离功能&#x…...
代码随想录训练营 Day57打卡 图论part07 53. 寻宝(prim,kruskal算法)
代码随想录训练营 Day57打卡 图论part07 卡码53. 寻宝 题目描述 在世界的某个区域,有一些分散的神秘岛屿,每个岛屿上都有一种珍稀的资源或者宝藏。国王打算在这些岛屿上建公路,方便运输。 不同岛屿之间,路途距离不同,…...
Hibernate QueryPlanCache 查询计划缓存引发的内存溢出
目录 1.排查方式2.结论3.解决办法 前言:在生产环境中有一个后端程序多次报oom然后导致程序中断。 1.排查方式 通过下载后端程序产生的oom文件,将oom文件导入MemoryAnalyzer程序分析程序堆内存使用情况。 1、将oom文件导入MemoryAnalyzer后可以看到概览信…...
前端开发的观察者模式
什么是观察者设计模式 观察者模式(Observer Pattern)是前端开发中常用的一种设计模式。它定义了一种一对多的依赖关系,使得当一个对象的状态发生改变时,其所有依赖对象都能收到通知并自动更新。观察者模式广泛应用于事件驱动的系…...
Pycharm 输入三个引号没有自动生成函数(方法)注释
配置项路径:pycharm–>Settins–>Tools–>Python Integrated Tools–>Docstrings–>Docstrings format选择对应的工程,如果有多个工程的话将 Docstrings format 的值从 Plain 换成 reStructuredText...
lammps后处理:多帧孔洞体积和孔隙率的计算
本文介绍lammps后处理技巧:多帧孔洞体积和孔隙率的计算方法。 在前面的专栏中,已经介绍了单帧孔洞体积的计算方法,有不少粉丝朋友咨询多帧孔洞体积的计算方法。 在上一次案例代码的基础上,稍加修改,添加一个for循环遍历所有的帧即可实现多帧孔洞体积的计算。 计算的结果…...
免费且实用:UI设计常用的颜色参考网站和一些Icon设计网站
用心去分享!请给我点个关注和点赞收藏!谢谢各位努力的人才! 1.在UI设计的时候,没有灵感,怎么办?可以参考这个网站(需要魔法能量) 网址如下: Color Hunt - Color Palette…...
log4j日志封装说明—slf4j对于log4j的日志封装-正确获取调用堆栈
日志是项目中必用的东西,日志产品里最普及应该就是log4j了。(logback这里暂不讨论。) 先看一下常用的log4j的用法,一般来说log4j都会配合slf4j或者common-logging使用,这里已slf4j为例。添加gradle依赖: dependencies { compile(l…...
JVM面试真题总结(六)
文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 解释GC的标记-整理算法及其优点 GC(垃圾收集ÿ…...
C语言代码练习(第十八天)
今日练习: 48、猴子吃桃问题。猴子第1天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。第2天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时&…...
linux上使用rpm的方式安装mysql
1.从mysql官网上下载需要的版本,根据操作系统版本,CPU架构,下载让rpm bundle,这个版本是个完整版,包含其他所有版本 上传到服务器的一个目录,进行解压 执行tar -xvf mysql*.tar tar -xvf mysql*.tar 2.卸载老版本m…...
html 中如何使用 uniapp 的部分方法
示例代码: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><…...
Samtec连接器小课堂 | 连接器电镀常识QA
【摘要/前言】 像大多数电子元件一样,无数子元件和工艺的质量直接影响到成品的质量和性能。对于PCB级连接器,这些因素包括针脚材料、塑料类型、模制塑料体的质量、尾部的共面性、表面处理(电镀)的质量、选择正确的连接器电镀、制…...
大模型备案全网最详细流程解读(附附件+重点解读)
文章目录 一、语料安全评估 二、黑盒测试 三、模型安全措施评估 四、性能评估 五、性能评估 六、安全性评估 七、可解释性评估 八、法律和合规性评估 九、应急管理措施 十、材料准备 十一、【线下流程】大模型备案线下详细步骤说明 十二、【线上流程】算法备案填报…...
基于2143规则编码的uint8_t如何转换成float
2143格式存储的float类型数据在解码时,需要将1和2互换,3和4互换,然后 通过数组转float,进行转换 uint8_t data[] {0x72, 0x02, 0xc8, 0x42}; // 字节数组 float bytesToFloat(uint8_t data[]) { uint32_t x; memcpy(&x, da…...
[项目][WebServer][整体框架设计]详细讲解
目录 0.框架 && 前言1.TcpServer类1.功能2.类设计 2.HttpServer类1.功能2.类设计 3.Request类 && Response类1.功能2.Request类设计3.Response类设计 4.EndPoint类1.功能2.类设计 5.Task类1.功能2.类设计 6.ThreadPool类1.功能2.类设计 0.框架 && 前言…...
SprinBoot+Vue网上购物商城的设计与实现
目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍:CSDN认证博客专家,CSDN平台Java领域优质…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
mac 安装homebrew (nvm 及git)
mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用: 方法一:使用 Homebrew 安装 Git(推荐) 步骤如下:打开终端(Terminal.app) 1.安装 Homebrew…...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
微服务通信安全:深入解析mTLS的原理与实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言:微服务时代的通信安全挑战 随着云原生和微服务架构的普及,服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...
自然语言处理——文本分类
文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益(IG) 分类器设计贝叶斯理论:线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别, 有单标签多类别文本分类和多…...
