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 数据读取转换(全)

相关推荐
于慨16 小时前
Lambda 表达式、方法引用(Method Reference)语法
java·前端·servlet
石小石Orz16 小时前
油猴脚本实现生产环境加载本地qiankun子应用
前端·架构
从前慢丶16 小时前
前端交互规范(Web 端)
前端
CHU72903516 小时前
便捷约玩,沉浸推理:线上剧本杀APP功能版块设计详解
前端·小程序
GISer_Jing17 小时前
Page-agent MCP结构
前端·人工智能
王霸天17 小时前
💥别再抄网上的Scale缩放代码了!50行源码教你写一个永不翻车的大屏适配
前端·vue.js·数据可视化
小领航17 小时前
用 Three.js + Vue 3 打造炫酷的 3D 行政地图可视化组件
前端·github
@大迁世界17 小时前
2026年React大洗牌:React Hooks 将迎来重大升级
前端·javascript·react.js·前端框架·ecmascript
PieroPc17 小时前
一个功能强大的 Web 端标签设计和打印工具,支持服务器端直接打印到局域网打印机。Fastapi + html
前端·html·fastapi
悟空瞎说17 小时前
深入 Vue3 响应式:为什么有的要加.value,有的不用?从设计到源码彻底讲透
前端·vue.js