阅读视图

发现新文章,点击刷新页面。

GDAL 实现数据空间查询

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

前言

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

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

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

1. 开发环境

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

时间:2025年

系统:Windows 11

Python:3.11.7

GDAL:3.11.1

2. 空间查询

GDAL中,有两个图层方法可以用于实现空间查询,分别是SetSpatialFilterSetSpatialFilterRect。此种查询方式为直接在源数据上操作,返回结果为查询图层。

"""
参数
    -geom:用于几何查询的几何对象
"""
SetSpatialFilter(geom)

"""
参数:
    -minx:最小x坐标
    -miny:最小y坐标
    -maxx:最大x坐标
    -maxy:最大y坐标
"""
SetSpatialFilterRect(minx,miny,maxx,maxy)

传入None值时重置查询。

sourceLayer.SetSpatialFilter(None)

在进行正式查询前和以前的文章一样,首先获取数据驱动,添加数据源,获取图层数据。定义一个方法SpatialFilter用于实现空间查询,该方法接受两个参数,一个sourcePath传递源数据图层路径,另一个selectPath用于定义查询图层路径。

"""
说明:图层属性过滤
参数:
    -sourcePath:待查询 Shp 文件路径
    -selectPath:查询 Shp 文件路径
"""
def SpatialFilter(sourcePath,selectPath):

在以下代码中完成图层数据的读取操作。

# 注册所有驱动
ogr.RegisterAll()

# 添加数据驱动
shpDriver = ogr.GetDriverByName("ESRI Shapefile")

checkFilePath(sourcePath,shpDriver)
checkFilePath(selectPath,shpDriver)

# 打开数据源
sourceDs = shpDriver.Open(sourcePath)
selectDs = shpDriver.Open(selectPath)

hasDs = sourceDs and selectDs

if hasDs is None:
    print("数据源打开异常,请检查路径!")
    return False

# 获取图层
sourceLayer = sourceDs.GetLayer(0)
selectLayer = selectDs.GetLayer(0)

下面对几何查询以及矩形查询两种实现方式进行介绍。

2.1. 几何查询

通过图层方法GetNextFeature获取第一个要素对象。

# 获取查询几何对象
queryFeat = selectLayer.GetNextFeature()
queryGeom = queryFeat.GetGeometryRef()

print(f"查询要素id:{queryFeat.GetField('Id')}")
print(f"查询几何对象:{queryGeom}")

将几何对象传入SetSpatialFilter方法进行空间过滤。

# 空间过滤
sourceLayer.SetSpatialFilter(queryGeom)

查询完成之后传入None值结束查询。

# 结束查询
sourceLayer.SetSpatialFilter(None)

以下为几何查询部分代码。

# 获取查询几何对象
queryFeat = selectLayer.GetNextFeature()
queryGeom = queryFeat.GetGeometryRef()

print(f"查询要素id:{queryFeat.GetField('Id')}")
print(f"查询几何对象:{queryGeom}")

# 获取要素数量
featureCount = sourceLayer.GetFeatureCount()
print(f"所有要素数量:{featureCount}")

# 空间过滤
sourceLayer.SetSpatialFilter(queryGeom)

queryFeatCount = sourceLayer.GetFeatureCount()
print(f"查询要素数量:{queryFeatCount}")

# 结束查询
sourceLayer.SetSpatialFilter(None)
finalFeatCount = sourceLayer.GetFeatureCount()
print(f"重置查询后要素数量:{finalFeatCount}")

print("n~~~~~~~方式一:结束几何查询~~~~~~~")

若有兴趣,还可以创建自定义几何对象进行空间查询。

# 自定义Geometry查询对象
customGeom = ogr.Geometry(ogr.wkbPolygon)
ringGeom = ogr.Geometry(ogr.wkbLinearRing)

ringGeom.AddPoint(102.884350,32.501570)
ringGeom.AddPoint(105.025865,74.974949)
ringGeom.AddPoint(50.417235,55.701314)
ringGeom.AddPoint(50.417235,32.501570)

ringGeom.CloseRings()
customGeom.AddGeometry(ringGeom)

# 获取要素数量
featureCount = sourceLayer.GetFeatureCount()
print(f"所有要素数量:{featureCount}")

# 空间过滤
sourceLayer.SetSpatialFilter(customGeom)

queryFeatCount = sourceLayer.GetFeatureCount()
print(f"查询要素数量:{queryFeatCount}")

# 结束查询
sourceLayer.SetSpatialFilter(None)
finalFeatCount = sourceLayer.GetFeatureCount()
print(f"重置查询后要素数量:{finalFeatCount}")

print("n~~~~~~~方式一:结束几何查询~~~~~~~")

如下为几何查询输出结果:

如下为该要素在ArcGIS中查询显示结果。

2.2. 矩形查询

矩形查询主要调用SetSpatialFilterRect方法,传入x、y坐标即可。

# 获取要素数量
featureCount2 = sourceLayer.GetFeatureCount()
print(f"所有要素数量:{featureCount2}")

# 空间过滤
sourceLayer.SetSpatialFilterRect(-16.9994,23.1235,42.9111,49.5852,)
queryFeatCount2 = sourceLayer.GetFeatureCount()

如下为矩形查询输出结果:

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程序开头添加以下代码:

os.environ['PROJ_LIB'] = r'D:\Programs\Python\Python311\Libsite-packages\osgeo\data\proj'

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

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

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

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

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


    

GeoTools 开发合集(全)

OpenLayers 开发合集

GDAL 实现数据属性查询

GDAL 实现创建几何对象

GDAL 实现自定义数据坐标系

GDAL 实现矢量数据读写

GDAL 数据类型大全

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

GDAL 实现数据属性查询

^ 关注我,带你一起学GIS ^ 前言 在之前的文章中讲了如何使用GDAL或者ogr2ogr工具将txt以及csv文本数据转换为Shp格式,本篇教程在之前一系列文章的基础上讲解如何使用GDAL实现空间

GDAL 实现创建几何对象

^ 关注我,带你一起学GIS ^ 前言 在之前的文章中讲了如何使用GDAL或者ogr2ogr工具将txt以及csv文本数据转换为Shp格式,本篇教程在之前一系列文章的基础上讲解如何使用GDAL实现创建

GDAL 实现自定义数据坐标系

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

前言

在GIS开发中,经常需要进行数据的转换处理,特别是Shapefile数据的投影转换更是重中之重,如何高效、准确的将源数据坐标系转换到目标坐标系是我们需要研究解决的问题。

在之前的文章中讲了如何使用GDAL或者ogr2ogr工具将txt以及csv文本数据转换为Shp格式,本篇教程在之前一系列文章的基础上讲解如何使用GDAL实现自定义数据坐标系。

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

1. 开发环境

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

时间:2025年

系统:Windows 11

Python:3.11.7

GDAL:3.11.1

2. 数据重投影

定义一个方法ShpProjection用于实现Shp数据的投影转换,其中参数sourcePath为源数据路径,targetPath为目标文件路径。

"""
说明:Shapfile 文件重投影
参数:
    -sourcePath:Shp 源文件路径
    -targetPath:投影文件目标路径
"""
def ShpProjection(sourcePath,targetPath):

先检查源数据文件是否存在,若不存在则退出程序

# 检查Shp源文件是否存在
if os.path.exists(sourcePath):
    print("源文件存在!")
else:
    print(f"源文件不存在:{sourcePath}")
    return

添加Shp数据驱动用于创建Shp数据源和图层,GetDriverByName方法需要一个驱动器名称。还需要检查一下目标数据路径是否正常,只有在目标路径正常时才创建数据源。

# 获取Shp数据驱动
shpDriver = gdal.GetDriverByName("ESRI Shapefile")

# 检查Shp文件是否存在
if os.path.exists(targetPath):
    try:
        shpDriver.DeleteDataSource(targetPath)
        print("文件已删除!")
    except Exception as e:
        print(f"文件路径不存在!:{e}")
        return False
# 创建数据源
targetDataSource = shpDriver.CreateDataSource(targetPath)

获取源数据图层信息并创建坐标系统。osr模块下的SpatialReference方法用于定义空间参考信息。其中空间参考信息具有三种形式,可以传递字符串名称,EPSG代码或者wkt形式的坐标定义内容。如下采用name参数形式。

# 获取Shp数据图层
sourceDataSource = ogr.Open(sourcePath)
sourceLayer = sourceDataSource.GetLayer()

# 获取坐标系
srs = osr.SpatialReference(epsg=5646)
print(f"坐标系统名称:{srs.GetName()}")

打印坐标系统名称如下:

使用CreateLayer方法创建目标图层,本例中数据类型为LineString,所以geom_type参数为ogr.wkbLineString。之后遍历源图层数据,将属性字段和要素值写入投影图层之中。

# 创建Shp投影数据图层
geomType = sourceLayer.GetGeomType()
shpProjectLayer = targetDataSource.CreateLayer(
    "layer",
    srs=srs,
    geom_type=ogr.wkbLineString
)

# 获取源图层属性结构
layerDefn = sourceLayer.GetLayerDefn()
print(layerDefn.GetFieldCount())

fieldCount = layerDefn.GetFieldCount()

# 添加属性字段
for i in range(fieldCount):
    fieldDefn = layerDefn.GetFieldDefn(i)
    shpProjectLayer.CreateField(fieldDefn)

for feature in sourceLayer:
    shpProjectLayer.CreateFeature(feature)

if __name__  == "__main__":

    sourcePath"E:\data\test_data\geojson\river.shp"
    targetPath"E:\data\test_data\geojson\river_project.shp"

    ShpProjection(sourcePath,targetPath)

运行成功之后在ArcGIS中打开图层属性显示如下:

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

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

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

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

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


    

GeoTools 开发合集(全)

OpenLayers 开发合集

GDAL 实现矢量数据读写

GDAL 数据类型大全

百度宣布,良心画图工具停服!

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

GIS 数据转换:使用 GDAL 将 Shp 转换为 GeoJSON 数据

GIS 数据转换:使用 GDAL 将 GeoJSON 转换为 Shp 数据

GIS 数据转换:使用 GDAL 将 TXT 转换为 Shp 数据

GDAL 实现矢量数据读写

GIS 数据的读写作为一个基础操作,是每一个GISer的必修课。在使用GDAL读取矢量数据时,需要掌握其基本的数据结构与类型,了解常用的数据读取方法,这样开发时才会起到事半功倍的效果。

在之前的文章中讲了如何使用GDAL或者ogr2ogr工具将txt以及csv文本数据转换为Shp格式,本篇教程在之前一系列文章的基础上讲解GDAL实现矢量数据读写。

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

1. 开发环境

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

时间:2025年

系统:Windows 11

Python:3.11.7

GDAL:3.11.1

2. 矢量数据读取接口

GDAL中,矢量数据模型遵循下图所示结构,数据驱动->数据源->图层->属性。

2.1. 获取数据源

GDAL中可以使用Open方法直接打开数据源,进而读取图层数据。在GDAL Python API中,DriverDataset 类在Raster API文档中,既适用于矢量数据,也适用于栅格数据。

"""
说明:用于打开数据源
参数:
    -utf8_path:字符串,数据源路径
    -update:布尔值类型,默认值False,是否以更新模式打开数据集(默认为只读模式)
返回值:返回数据集或者None
"""
def Open(utf8_path,update=False)

如下以只读模式打开Shp数据源。

dataSource = ogr.Open(shpPath,False) # False表示只读,True表示可写

除了ogrOpen方法之外,也可以使用gdal模块的打开方法

2.2. 获取图层

GDAL获取图层的常用方法为GetLayer,该方法只有一个参数。iLayer值固定为0,对shapefile图层来说是可选项。

"""
说明:从数据集获取图层
参数:
    -iLayer:整型或字符串,图层名称或者基于0的图层索引值。
返回值:返回图层或者None
"""
def GetLayer(iLayer=0)

获取数据集中索引值为0的图层。

 # 获取图层
layer = dataSource.GetLayer(0)

除了GetLayer方法之外,还有一个GetLayerByIndex方法用于获取图层。

"""
说明:根据索引获取图层
参数:
    -index:整型,图层索引值。
返回值:返回图层或者None
"""
def GetLayerByIndex(index)

图层索引值处于0GetLayerCount() - 1之间。

最后还有个GetLayerCount方法用于获取图层数量。

从数据集中获取图层数量。

 # 获取图层数量
layerCount = dataset.GetLayerCount()
print(f"图层数量:{layerCount}")

2.3. 获取投影信息

GetProjectionGetProjectionRef方法都可以用于读取坐标系统,两者都返回一个字符串类型WKT格式的数据集空间参考信息。

从图层获取投影信息。

 # 图层投影
projectionRef = layer.GetProjectionRef()
print(f"空间参考:{projectionRef}")

此外还有一个方法GetSpatialRef也可用于获取数据集空间参考信息。

从图层获取空间参考信息。

 # 图层空间参考
spatialRef = layer.GetSpatialRef()
print(f"空间参考:{spatialRef}")

2.4. 获取要素

在知道FId(要素编号)的情况下,可以直接使用GetFeature方法获取要素。

 # 获取指定要素
feature = layer.GetFeature(0)

也可以通过GetNextFeature方法遍历要素特征,并且返回一个要素Feature。此方法适用于少数几个OGRLayer.GetNextFeature()效率不高的驱动程序,但总体而言,OGRLayer.GetNextFeature()是一个更自然的API。

从图层读取要素特征。

 # 获取要素
feature = layer.GetNextFeature()
limitCount = 0
 # 限制打印前十个要素
while feature and limitCount < 10:
    print(f"打印第【{limitCount+1}】个要素")

GetFeatureCount方法用于获取图层要素数量。

 # 获取图层要素数量
layerFeatureCount = layer.GetFeatureCount()
print(f"要素数量:{layerFeatureCount}")

2.5. 获取属性结构

GetLayerDefn方法用于获取图层属性表,返回要素定义信息。

获取图层属性。

 # 获取图层属性
layerProperty = layer.GetLayerDefn()

GetFieldCount方法用于获取字段数量。

读取图层要素数量。

 # 获取图层名称
layerName = layer.GetName()
 # 获取图层要素数量
layerFeatureCount = layer.GetFeatureCount()

GetFieldDefn用于获取字段定义信息,其中包括字段名称,字段类型。

读取属性表结构。

 # 获取图层属性
layerProperty = layer.GetLayerDefn()
 # 获取图层字段数量
fieldCount = layerProperty.GetFieldCount()
print(f"字段数量:{fieldCount}")

 # 获取字段信息
for j in range(fieldCount):
    # 获取字段属性对象
    fieldProperty = layerProperty.GetFieldDefn(j)
    # 获取字段属性名称
    fieldName = fieldProperty.GetName()
    # 获取字段属性类型
    fieldType = fieldProperty.GetTypeName()

    print(f"第 【{j}】 个字段名称:{fieldName},字段类型:{fieldType}")

GetField用于获取属性字段值,参数可以是字符串字段名,也可以是字段索引值。

GetGeometryRef方法用于获取要素几何对象信息。

读取几何对象。

 # 读取几何属性
geom = feature.GetGeometryRef()

2.6. 获取图层范围

GetExtent获取图层四至范围。

 # 获取范围
extent = layer.GetExtent()

3. 矢量数据修改接口

Driver(驱动程序)是一个知道如何执行特定功能的对象与某种数据类型(如shapefile),为了读写数据,就需要一个合适的驱动程序。

本文以下的数据修改都已shapefile驱动为例进行讲解。

3.1. 获取目标数据驱动

首先需要导入ogr模块用于处理矢量数据。GetDriverByName方法可以根据名称获取数据驱动。

from osgeo import ogr,osr

 # 获取Shp数据驱动
shpDriver = ogr.GetDriverByName('ESRI Shapefile')

3.2. 创建数据源

CreateDataSource方法根据文件路径创建数据源。

 # 创建Shp数据源
shpDataSource = shpDriver.CreateDataSource(shpPath)

3.3. 创建图层

通过CreateLayer方法创建图层,该方法具有四个参数,图层名称、坐标系统以及几何类型是必传。

 # 创建点图层
layer = shpDataSource.CreateLayer("points",srs,ogr.wkbPoint)

3.4. 创建属性字段

通过CreateField方法创建属性字段。

if field not in [lonField, latField]:
    # 创建字段定义
    fieldDefn = ogr.FieldDefn(field, ogr.OFTString)
    fieldDefn.SetWidth(254)
    # 直接创建字段,不要存储 FieldDefn 对象
    layer.CreateField(fieldDefn)

3.5. 创建几何对象

要素对象方法SetGeometry可以创建几何对象。

 # 创建几何对象
point = ogr.Geometry(ogr.wkbPoint)
point.AddPoint(lon,lat)
feature.SetGeometry(point)

3.6. 创建要素

通过图层方法CreateFeature创建要素。

 # 创建要素
feature = ogr.Feature(layer.GetLayerDefn())

 # 设置属性
for field in fieldnames:
    if field not in [lonField, latField]:
        feature.SetField(field, str(row[field]))
 # 创建几何
point = ogr.Geometry(ogr.wkbPoint)
point.AddPoint(lon,lat)
feature.SetGeometry(point)

 # 保存要素
layer.CreateFeature(feature)

4. 关闭数据源

为了防止内存泄露问题发生,在确定数据读取完成后需要关闭数据源。

 # 关闭数据源
dataSource = None

 # 关闭要素
feature.Destroy()
 # feature = None

小提示

GDAL中的方法采用大驼峰命名法

OpenLayers示例数据下载,请在公众号后台回复:ol数据
全国信息化工程师-GIS 应用水平考试资料,请在公众号后台回复:GIS考试

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

GeoTools 开发合集(全)

OpenLayers 开发合集

GDAL 数据类型大全

百度宣布,良心画图工具停服!

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

自然资源部:我国地理信息产业总产值将超9000亿元

GIS 数据转换:使用 GDAL 将 Shp 转换为 GeoJSON 数据

GIS 数据转换:使用 GDAL 将 GeoJSON 转换为 Shp 数据

GIS 数据转换:使用 GDAL 将 TXT 转换为 Shp 数据

❌