GDAL 实现数据属性查询

^ 关注我,带你一起学GIS ^

前言

在GIS开发中,属性查询是非常普遍的操作,这是每一个GISer都要掌握的必备技能。实现高效的数据查询功能可以提升用户体验,提升数据可视化效率。

在之前的文章中讲了如何使用GDAL或者ogr2ogr工具将txt以及csv文本数据转换为Shp格式,本篇教程在之前一系列文章的基础上讲解如何使用GDAL实现空间数据属性查询功能。

如果你还没有看过,建议从以上内容开始。

1. 开发环境

本文使用如下开发环境,以供参考。

时间:2025年

系统:Windows 11

Python:3.11.7

GDAL:3.11.1

2. 属性查询

定义一个方法AttributeFilter用于实现空间数据属性查询,该方法接受一个shpPath路径参数。

python 复制代码
"""说明:图层属性过滤参数:    -shpPath:Shp 文件路径"""def AttributeFilter(shpPath):

还是老规矩,第一步添加Shp数据驱动。

scss 复制代码
# 注册所有驱动ogr.RegisterAll()# 添加数据驱动shpDriver = ogr.GetDriverByName("ESRI Shapefile")

打开数据源,进行属性过滤。图层对象有个方法SetAttributeFilter可以进行简单的属性查询,只需传入字段名以及字段值,查询结束后将查询条件设置为None退出查询。

使用此种方式是直接在源数据图层上进行操作。

scss 复制代码
with shpDriver.Open(shpPath) as ds:    if ds is None:        print("数据源打开异常,请检查路径!")        return False    # 获取图层    layer = ds.GetLayer(0) # Shp图层默认值为0    # 获取要素数量    featureCount = layer.GetFeatureCount()    print(f"所有要素数量:{featureCount}")    # "学校"要素数量    layer.SetAttributeFilter("type='学校'")    featureCount1 = layer.GetFeatureCount()    print(f"'学校'要素数量:{featureCount1}")    layer.SetAttributeFilter(None)    featureCount2 = layer.GetFeatureCount()    print(f"退出查询后要素数量:{featureCount2}") 

属性表中总共有45条记录,查询记录与其保持一致。

除了上面介绍的SetAttributeFilter方法外,还有另外一种方式,就是SQL语句查询。数据源对象具有一个方法ExecuteSQL用于查询指定数据,大多情况下只需要传入一条SQL语句即可。查询结束之后调用ReleaseResultSet方法退出查询。

使用此种方式将会返回一个满足查询条件的新图层

scss 复制代码
# 复杂查询# queryLayer = ds.ExecuteSQL("SELECT * FROM geoPoint WHERE TYPE='饭店'")# 升序# queryLayer = ds.ExecuteSQL("SELECT * FROM geoPoint WHERE TYPE='饭店' ORDER BY Id ASC")# 降序queryLayer = ds.ExecuteSQL("SELECT * FROM geoPoint WHERE TYPE='饭店' ORDER BY Id DESC")queryFeatCount = queryLayer.GetFeatureCount()print(f"nSQL查询要素数量:{queryFeatCount}n")for feature in queryLayer:    # 获取字段    field = feature.GetField("id")    # print(f"要素Id:{field}")    fieldValue = feature.GetField("type")    for i in range(fieldCount):        fieldDefn = featureDefn.GetFieldDefn(i)        fieldName = fieldDefn.GetName()        fieldType = fieldDefn.GetType()        fieldTypeName = fieldDefn.GetTypeName()        fieldValue = feature.GetField("type")    print(f"id:{field},value:{fieldValue}n")ds.ReleaseResultSet(queryLayer)ds = None

选择类型为"饭店"的POI点,并以Id字段降序排列。

sql 复制代码
SELECT * FROM geoPoint WHERE TYPE='饭店' ORDER BY Id DESC

查询结果显示如下:与实际数据显示结果一致。

还可以统计以下每种类型要素的数量。

scss 复制代码
# 统计每种类型的要素数量finalFeatCount = layer.GetFeatureCount()print(f"n最终查询要素数量:{finalFeatCount}n")countLayer = ds.ExecuteSQL("SELECT DISTINCT type FROM geoPoint")newFeature = countLayer.GetNextFeature()while newFeature:    # countTypeLayer = ds.ExecuteSQL("SELECT COUNT(*) FROM geoPoint WHERE type='"+newFeature.GetField('type')+"'")    countTypeLayer = ds.ExecuteSQL("SELECT COUNT(*) FROM geoPoint WHERE type='"+newFeature.GetField(0)+"'")    print(f"{newFeature.GetField(0)} {countTypeLayer.GetFeature(0).GetFieldAsString(0)}")    ds.ReleaseResultSet(countTypeLayer)    newFeature = countLayer.GetNextFeature()ds.ReleaseResultSet(countLayer)

查询结果显示如下:最后不要忘记关闭数据源。

ini 复制代码
ds = None

3. 注意事项

windows开发环境中同时安装GDALPostGIS,其中投影库PROJ的环境变量指向PostGIS的安装路径,在运行GDAL程序时,涉及到要素、几何与投影操作时会导致异常。具体意思为GDAL不支持PostGIS插件中的投影库版本,需要更换投影库或者升级版本。

RuntimeError: PROJ: proj_identify: D:Program FilesPostgreSQL13sharecontribpostgis-3.5projproj.db contains DATABASE.LAYOUT.VERSION.MINOR = 2 whereas a number >= 5 is expected. It comes from another PROJ installation.

解决办法为修改PROJ的环境变量到GDAL支持的版本或者在GDAL程序开头添加以下代码:

python 复制代码
os.environ['PROJ_LIB'] = r'D:ProgramsPythonPython311Libsite-packagesosgeodataproj'

图片效果

OpenLayers示例数据下载,请在公众号后台回复:ol数据

全国信息化工程师-GIS 应用水平考试资料,请在公众号后台回复:GIS考试

GIS之路 公众号已经接入了智能 助手,可以在对话框进行提问,也可以直接搜索历史文章进行查看。

都看到这了,不要忘记点赞、收藏 + 关注

本号不定时更新有关 GIS开发 相关内容,欢迎关注


GeoTools 开发合集(全)

OpenLayers 开发合集

GDAL 实现创建几何对象

GDAL 实现自定义数据坐标系

GDAL 实现矢量数据读写

GDAL 数据类型大全

GDAL 实现 GIS 数据读取转换(全)

相关推荐
光影少年8 分钟前
前端SSR和ssg区别
前端·vue.js·人工智能·学习·react.js
广州华水科技13 分钟前
北斗形变监测传感器在水库安全监测中的应用与发展
前端
凯瑟琳.奥古斯特43 分钟前
Bootstrap快速上手指南
开发语言·前端·css·bootstrap·html
精益数智工坊1 小时前
拆解制造业仓库物料管理流程:如何通过标准化仓库物料管理流程解决账实不符难题
大数据·前端·数据库·人工智能·精益工程
恶猫1 小时前
网页自动化模拟操作时,模拟真实按键触发事件【终级方案】
前端·javascript·自动化·vue·网页模拟
小羊Yveesss1 小时前
2026年前端开发新趋势:智能协同、工具革新与场景深耕
前端·ai
Dxy12393102161 小时前
HTML中的Canvas可以干哪些事情
前端·html
悟乙己1 小时前
解析 Agent 时代的 HTML PPT SKILLS: html-ppt-skill
前端·html·powerpoint
ZC跨境爬虫1 小时前
跟着 MDN 学 HTML day_2:(表单分组与高级输入控件实战)
前端·javascript·css·ui·html
ppandss12 小时前
JavaWeb从0到1-DAY4-AJAX
前端·ajax·okhttp