GDAL库中对于矢量数据的读取中可以设置一些过滤器来对矢量图形进行筛选,对于Shapefile格式来说,如果数据量太大,设置这个过滤器时间慢的简直无法忍受。好在GDAL1.10版本开始支持读取Shapefile文件的空间索引文件(.sbn / .sbx)来进行加速。下面就同样的数据同样的代码来对GDAL1.9.0和GDAL1.11.0两个版本进行测试时间,比较下速度(看到结果你肯定会张大嘴巴的~~)。

首先是测试代码,功能很简单,两个shp文件,一个点文件,一个面文件。面文件很大,需要根据点文件中的点来查询到对应的面文件中的图形。在此感谢“午夜风”提供的数据进行测试。图1是使用ArcMap打开两个数据显示的效果,图2是两个数据的数据量以及要素个数。

图1 使用ArcMap打开的效果

图2 两个数据的数据量和要素个数

下面是测试代码,只贴出来关键部分的函数。

void SearchSampleDataFromSHP_liml()
{
const char* pszPoints = "C:\\Users\\LiMinlu\\Desktop\\SHP\\C5Pointnew.shp";
const char* pszPolygs = "C:\\Users\\LiMinlu\\Desktop\\SHP\\C5.shp"; // 注册驱动以及配置项
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO");
CPLSetConfigOption("SHAPE_ENCODING","");
OGRRegisterAll(); //打开两个数据
OGRSFDriver* poDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName("ESRI Shapefile"); OGRDataSource* pPntDS = poDriver->Open(pszPoints, false);
if (pPntDS==NULL)
{
cout<<"打开文件:" <<pszPoints << "失败"<<endl;
return ;
} OGRDataSource* pPlgDS = poDriver->Open(pszPolygs, false);
if (pPlgDS==NULL)
{
cout<<"打开文件:" <<pszPolygs << "失败"<<endl;
return ;
} OGRFeature *pPntFeature = NULL, *pPlgFeature = NULL; OGRLayer* pPntLayer = pPntDS->GetLayer(0);
pPntLayer->ResetReading();
pPntFeature = pPntLayer->GetFeature(0); int nFeildCount = pPntFeature->GetFieldCount();
int nFeatureCount = pPntLayer->GetFeatureCount(); OGRLayer* pPlgLayer = pPlgDS->GetLayer(0);
pPlgLayer->ResetReading();
pPlgFeature = pPlgLayer->GetFeature(0); int nPlgFeildCount = pPlgFeature->GetFieldCount(); for (int i=0;i<nFeatureCount; i++)
{
pPntFeature = pPntLayer->GetFeature(i);
double dValue = pPntFeature->GetFieldAsDouble(nFeildCount-1);
OGRPoint *pPoint = (OGRPoint *)pPntFeature->GetGeometryRef(); //设置面图层的过滤属性
pPlgLayer->ResetReading();
pPlgLayer->SetSpatialFilter((OGRGeometry*)pPoint); pPlgFeature = pPlgLayer->GetNextFeature(); if(pPlgFeature == NULL)
{
OGRFeature::DestroyFeature(pPntFeature);
continue;
} OGRFeature::DestroyFeature(pPntFeature);
OGRFeature::DestroyFeature(pPlgFeature);
} OGRDataSource::DestroyDataSource(pPntDS);
OGRDataSource::DestroyDataSource(pPlgDS);
}

下面是main函数以及输出时间的一个小函数。

void ShowTime()
{
time_t t = time(0);
char tmp[64];
strftime( tmp, sizeof(tmp), "%Y/%m/%d %X", localtime(&t) );
puts( tmp );
} int _tmain(int argc, _TCHAR* argv[])
{
ShowTime();
SearchSampleDataFromSHP_liml();
ShowTime(); system("pause");
return 0;
}

首先来看看使用GDAL1.9.0版本的时间,处理时间如图3所示。(注意,以下测试时间全部使用Release版本进行测试所得)

图3 使用GDAL1.9.0所用时间

再看看GDAL1.11.0所用的时间,处理时间如图4所示。

图4 使用GDAL1.11.0所用时间

由上面两个处理时间可以看到,在GDAL1.11.0版本处理时间大幅度提高(100倍啊),所以用到了空间索引这块的同学还是将GDAL的版本更新一下吧。

我们知道shapefile文件一般必须的是3个文件,后缀名是shp、dbf和shx。如果数据有投影信息的话再加一个prj文件。这种标准的shp文件是我们常用的,使用GDAL创建的话也会生成这么几个文件。但是当用ArcMap打开的时候,会自动多出来几个文件,后缀名是sbn和sbx,可能还有个xml文件。如图2所示。这两个文件就是ArcMap自动生成的空间索引文件(ESRI spatial index files)。

按照GDAL的官方文档说明,目前GDAL库只支持读取空间索引文件,还不支持创建,所以如果要处理大数据量的shp文件,可以先用ArcMap打开让其创建好空间索引文件再用GDAL处理。此外GDAL还支持读写UMN MapServer使用的四叉树索引文件(.qix)。具体可以参考GDAL官网中的Shapefile格式页面(网址是:http://www.gdal.org/drv_shapefile.html)。

GDAL1.11版本对SHP文件索引加速测试的更多相关文章

  1. GDAL1.11版本号对SHP文件索引加速測试

    GDAL库中对于矢量数据的读取中能够设置一些过滤器来对矢量图形进行筛选.对于Shapefile格式来说.假设数据量太大,设置这个过滤器时间慢的简直无法忍受.好在GDAL1.10版本号開始支持读取Sha ...

  2. C#、C++用GDAL读shp文件(转载)

    C#.C++用GDAL读shp文件 C#用GDAL读shp文件 (2012-08-14 17:09:45) 标签: 杂谈 分类: c#方面的总结 1.目前使用开发环境为VS2008+GDAL1.81 ...

  3. geotools导入shp文件到Oracle数据库时表名带下划线的问题解决

    问题: 最近在做利用geotools导入shp文件到Oracle表中,发现一个问题Oracle表名带下划线时导入失败,问题代码行: dsOracle.getFeatureWriterAppend(or ...

  4. shp系列(一)——利用C++进行shp文件的读(打开)与写(创建)开言

    博客背景和目的 最近在用C++写一个底层的东西,需要读取和创建shp文件.虽然接触shp文件已经几年了,但是对于shp文件内到底包含什么东西一直是一知半解.以前使用shp文件都是利用软件(如ArcGI ...

  5. 空间矢量数据(.shp文件)之JAVA操作

    Shape文件由ESRI开发.一个ESRI(Environmental Systems Research Institute)的shape文件包含一个主文件,一个索引文件,和一个dBASE表. 当中主 ...

  6. WFS: postgresql(postgis)和shp文件查询效率对比

    对GeoServer上的WFS的各种数据源查询效率感兴趣,做个测试.本次测试了Postgresql.geopackage.shp文件三种数据源的查询效率,无论是本机还是服务器环境,pg存储查询效率都比 ...

  7. GeoJson的生成与解析,JSON解析,Java读写geojson,geotools读取shp文件,Geotools中Geometry对象与GeoJson的相互转换

    GeoJson的生成与解析 一.wkt格式的geometry转成json格式 二.json格式转wkt格式 三.json格式的数据进行解析 四.Java读写geojson 五.geotools读取sh ...

  8. 在Windows下安装64位压缩包版mysql 5.7.11版本的方法

    为了学习数据库,自己去网上下载了最新版本的Windows64位的mysql 5.7.11,但是花了很长的时间在安装的问题上,同时也借鉴了几位前辈的博文来帮助自己解决在安装过程中遇到的问题,安装成功之后 ...

  9. [转载]Linux 环境下编译 0.11版本内核 kernel

    最近在看<.如果Clobber/Modify 为空,则其前面的冒号(:)必须省略. 2.如果Output,Input,Clobber/Modify都为空,Output,Input之前的冒号(:) ...

随机推荐

  1. SpringMvc+Spring+MyBatis 基于注解整合

    最近在给学生们讲Spring+Mybatis整合,根据有的学生反映还是基于注解实现整合便于理解,毕竟在先前的工作中团队里还没有人完全舍弃配置文件进行项目开发,由于这两个原因,我索性参考spring官方 ...

  2. Map 探索

    关于Map问题我一直了解的不是很透彻,下面进行比较系统的总结一下. 1.

  3. js中一个对象当做参数传递时候?

    高程中讲到:'ECMAScript 中所有函数的参数都是按值传递'. 这就像把值从一个变量复制到另一个变量一样. 那引用类型的值也是像基本类型一样? 直接看栗子一: var person = { na ...

  4. 批量录入快递地址-快宝地址服务(PHP代码示例)

    快递地址写错了怎么办?快递地址写的不详细怎么办?怎么皮批量录入收件人地址?微商怎么批量录入发件人地址?快宝地址清洗,有效的解决了寄送快递时,批量录入收件人信息.发件人信息时,纠正地址数据,不完整地址识 ...

  5. 编程英语之KNN算法

    School of Computer Science The University of Adelaide   Artificial Intelligence Assignment 2   Semes ...

  6. os和sys模块的区别及其常用方法总结

    官方解释:os: This module provides a portable way of using operating system dependent functionality. 翻译:提 ...

  7. Python3 错误和异常

    Python有两种错误很容易辨认:语法错误和异常. 语法错误 Python 的语法错误或者称之为解析错,是初学者经常碰到的,如下实例 >>> while True print('He ...

  8. Python3 元组

    Python 的元组与列表类似,不同之处在于元组的元素不能修改. 元组使用小括号,列表使用方括号. 元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可. 如下实例: tup1 = ('Goog ...

  9. sql server 的osql 使用例子

    一次性执行一个语句并输出到文件: osql -Usa -dSCGWYDJ2012 -P -S192.168.56.1 -Q "exit( SELECT top 1 * FROM A08)&q ...

  10. MacOS下安装rvm的几点注意

    如果用以下链接无法下载的话: curl -sSL https://get.rvm.io | bash -s stable #或者 curl -L https://rvm.io | bash -s st ...