第一篇博客,感谢下带我这个门外汉入了GIS行业的导师李治江老师~

由于打算写一个空间数据引擎,在空间索引和属性索引方面搜集了一些开源实现,本文用以对比C++ GIS开发中常见的空间索引实现的效率

测试环境

操作系统 Windows 7 Professional SP1
CPU Inter Core i7-3520M @ 2.9GHz
内存 8GB
系统盘硬盘 SanDisk SDSSDXP120G
数据盘硬盘 HGST HTS725050A7E630
开发环境 Visual Studio 2008 SP1

实验对象

空间筛选的大致流程基本都是:
1. 矩形框初筛,通过待查询矩形框与数据外包矩形相交快速判断
2.对初筛后缩小了的数据集进行相交、包含、相切、相离等精确判断
空间索引就是提高第一步矩形运算效率的算法
其实不管什么实现,矩形相交的快速判断方法是固定的,四个边界数值的比较,除非写汇编、写机器码,否则不太有提升空间。而空间索引的算法优劣,主要在于如何减少无关数据的访问次数
空间数据至少是二维数据,常用的一维索引(如BTree/Bitmap索引等)无法满足需求,常用的空间索引算法有BSP树、K-D-B树、R树、R+树和CELL树(摘自百度百科,补充四叉树)。

本文要对比的是一些常见的C++空间索引开源实现

loop 最原始的循环,每个节点都访问
shapelib-qix shapelib提供的默认空间索引算法,基于四叉树的实现。支持硬盘、内存两种模式
shapelib-sbn 从gdal-1.10起添加的对ArcGIS生成的sbn格式的空间索引支持,笔者将其编译入了最新的shapelib中。仅支持硬盘模式
geos geos提供了若干种空间索引算法,本文对其中的STRTree和QuadTree分别进行了测试。仅支持内存模式
spatialindex 提供了多种基于RTree的空间索引算法,还包括时空GIS所需要的多版本索引算法等。本文仅对二维数据索引,因此仅探讨RTree。支持硬盘、内存两种模式

对比方法

测试数据

郑州市矢量数据
数据类型:Line
数据量:1554304条
x_min:454250.000000
x_max:479750.045600
y_min:3839499.634654
y_max:3862000.032000
空间参考:Xian_1980_3_Degree_GK_CM_114E

对比逻辑

对上述数据的打开数据、创建索引、索引查询范围R内数据n次、相关清理作为一次完整流程,记录索引创建时间、索引内存占用情况、查询时间、查询到数据结果数量作为横向对比参考。重复如上操作t次,取平均值。
其中
R:x_min:465701.923
R:x_max:469994.306
R:y_min:3852567.173
R:y_max:3855717.229
n:100
t:5

对比结果

Method Mode Insert(ms) Memory(MB) Query(ms) QueryCount 说明
Loop-vector Memory 2801.2 77.274219 1523.8 60854 使用std::vector作为数据的存取容器
Loop-list Memory 2856.4 106.534375 1367.2 60854 使用std::list作为数据的存取容器
Loop Disk 0.0 0.000000 264532.0 60854 打开数据逐条IO判断
Qix Memory 3499.8 75.525781 745.8 62240 在内存中创建qix索引查询
Qix Disk 3730.6 0.000000 2010.2 62240 使用硬盘中的qix索引查询
Sbn Disk 0.0 10.158594 898.2 63047 使用硬盘中的sbn索引查询
Geos-STRTree Memory 3100.4 136.578125 2878.8 60854 在内存中创建geos::strtree索引查询
Geos-QuadTree Memory 4194.4 302.792969 383.4 64288 在内存中创建geos::quadtree索引查询
SpatialIndex-RTree Memory 83795.2 72.734375 3087.8 60854 在内存中创建rtree索引查询(原始insert接口)
SpatialIndex-RTree Memory-BulkLoad 13041.0 90.471875 2874.6 60854 在内存中创建rtree索引查询(使用bulkload提升创建速度)
SpatialIndex-RTree Disk-BulkLoad 13348.8 18.336719 4249.6 60854 使用硬盘中的rtree索引查询(使用bulkload提升创建速度)

优缺点对比

优点 缺点
qix 1.索引速度极快
2.支持硬盘、内存两种模式
1.仅支持shp数据(仔细研究下代码应该也能把索引部分跟SHPHandle的耦合解开)
sbn 1.硬盘索引速度极快 1.暂无生成sbn的代码,仅能用作只读索引
2.仅支持shp数据
3.仅支持硬盘模式(不过速度其实已经很快了,是否内存化可能不太重要)
geos 1.内存四叉树索引速度为最快 1.仅支持内存模式(对数据量过大的情况应对性不好)
2.geos源码中存在一处内存释放未决,需要使用者对插入索引树的内存做管理,使用较为不便(建议修改源码)
3.内存占用较大
spatialindex 1.支持硬盘、内存两种模式 1.索引生成较慢(做大数据量的实时编辑数据时可能会有效率问题)

综上考虑,可能会在后续的索引中使用spatialindex

对比缺陷

哎,说到缺陷,还请各位看客多多留下宝贵意见

1.最最百思不得其解的是,除了四叉树的两个索引算法和sbn索引,其他索引居然都比内存生生循环要慢,真是打脸打的厉害啊。。。

2014-09-10 自圆其说的一种解释

2.对比没有考虑不同数据特点下索引算法的优劣,如数据外包矩形均匀分布或有明显集中是否有影响

3.对不同算法中的可控参数尚未做纵向对比

4.未对比更大数据量的索引稳定性(之前使用过sqlite的rtree,发现超过1000万条记录就会导致索引建立极慢无比,且因为sqlite的rtree实现是通过虚表+关联外键方式实现,实用性较差,因此没有放在此次对比中)

附上源码,敬请指正:

http://pan.baidu.com/s/1kTJttrh

C++常见空间索引效率对比相关推荐

  1. 数组常见的遍历循环方法、数组的循环遍历的效率对比

    1 遍历数组的方法 1-1.for / while 最普通的循环 效率最高 兼容ie6 tips:for循环更适用于循环的开始和结束已知,循环次数固定的场合:while循环更适合于条件不确定的场合 1 ...

  2. 【Python | opencv+PIL】常见操作(创建、添加帧、绘图、读取等)的效率对比及其优化

    一.背景 本人准备用python做图像和视频编辑的操作,却发现opencv和PIL的效率并不是很理想,并且同样的需求有多种不同的写法并有着不同的效率.见全网并无较完整的效率对比文档,遂决定自己丰衣足食 ...

  3. Java List去重 Lis集合去重 List去重效率对比 List去重复元素效率对比 List去重效率

    Java  List去重 Lis集合去重 List去重效率对比 List去重复元素效率对比 List去重效率 --- List 去重复元素的几种办法 一.概述 面试的时候,有个常见的问题:" ...

  4. 常见NoSQL的对比及使用场景(Redis,memcached,mongodb)

    转自:https://my.oschina.net/liyurong/blog/1921898 1. NoSQL NoSQL(Not Only SQL),泛指非关系型的数据库(mysql.oracle ...

  5. [python]关于字符串查找和re正则表达式的效率对比

    最近需要在python中做大日志文件中做正则匹配 开始直接在for in 中每行做re.findall,后来发现,性能不行,就在re前面做一个基本的字符串包含判断 (str in str),如果不包含 ...

  6. 三种基本排序的实现及其效率对比:冒泡排序、选择排序和插入排序

    1 public class ThreeTypesOfBaseSort { 2 // ========================== 三种基本排序的效率对比 ================== ...

  7. php遍历数组哪个效率高,PHP遍历数组的三种方法及效率对比分析

    PHP遍历数组的三种方法及效率对比分析 发布于 2015-03-04 21:55:27 | 129 次阅读 | 评论: 0 | 来源: 网友投递 PHP开源脚本语言PHP(外文名: Hypertext ...

  8. 常见消息队列对比(ActiveMQ、ZeroMQ、kafka、RabbitMQ)?

    常见消息队列对比? 消息队列是分布式应用间交换信息的重要组件,消息队列可驻留在内存或磁盘上, 队列可以存储消息直到它们被应用程序读走. 通过消息队列,应用程序可以在不知道彼此位置的情况下独立处理消息, ...

  9. python和c运行速度的对比实验_Python中单线程、多线程和多进程的效率对比实验...

    原标题:Python中单线程.多线程和多进程的效率对比实验 文 | 饒木陽 Python是运行在解释器中的语言,查找资料知道,python中有一个全局锁(GIL),在使用多进程(Thread)的情况下 ...

最新文章

  1. TensorFlow之张量
  2. Kubernetes上领先的开源Serverless解决方案有哪些
  3. java常用框架总结
  4. android之Itent.ACTION_PICK Intent.ACTION_GET_CONTENT妙用
  5. RocketMQ 核心
  6. 基于EasyDarwin实现幼儿园监控类项目
  7. ZooKeeper快速入门
  8. how SAP UI5 Manifest.json is loaded
  9. jquery技巧总结-转载
  10. 用python制作一款录屏小工具
  11. Java基础——注解的初步认识
  12. 什么是工业微型计算机,2008年(下)全国自考工业用微型计算机试卷02241
  13. yum源配置的三种方法
  14. EXCEL滚动条控件制作动态图表
  15. Activity启动流程(二)system_server进程处理启动Activity请求
  16. python关闭excel进程_python win32com关闭Excel进程
  17. 链塔智库联合清华发布《2018区块链技术应用白皮书》
  18. 关于色环电阻的读数和功率
  19. 【智能推荐】阿里云智能推荐AIRec文档说明与SDK测试
  20. 数据结构-广义表详解(类C语言版)

热门文章

  1. 链接跳转(本页面跳转)
  2. Excle~学习好曲折
  3. ubuntu安装pylint
  4. IOS 使用照相机和图片库
  5. LeetCode 398. 随机数索引
  6. 学生考勤及行为管理系统_学生考勤管理系统
  7. 在Linux配置Git SSH的详细步骤;git配置ssh详细教程;
  8. java装箱与拆箱原理_深入理解Java中的装箱和拆箱
  9. python 读取 MNIST 数据集,并解析为图片文件
  10. 【博学谷学习记录】超强总结,用心分享|大数据之ZooKeeper