普通视图
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开发 相关内容,欢迎关注 ![]()
![]()
![]()
GIS 数据转换:使用 GDAL 将 Shp 转换为 GeoJSON 数据
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中,Driver和Dataset 类在Raster API文档中,既适用于矢量数据,也适用于栅格数据。
"""
说明:用于打开数据源
参数:
-utf8_path:字符串,数据源路径
-update:布尔值类型,默认值False,是否以更新模式打开数据集(默认为只读模式)
返回值:返回数据集或者None
"""
def Open(utf8_path,update=False)
![]()
如下以只读模式打开Shp数据源。
dataSource = ogr.Open(shpPath,False) # False表示只读,True表示可写
除了ogr的Open方法之外,也可以使用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)
图层索引值处于0和GetLayerCount() - 1之间。
![]()
最后还有个GetLayerCount方法用于获取图层数量。
![]()
从数据集中获取图层数量。
# 获取图层数量
layerCount = dataset.GetLayerCount()
print(f"图层数量:{layerCount}")
2.3. 获取投影信息
GetProjection和GetProjectionRef方法都可以用于读取坐标系统,两者都返回一个字符串类型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之路 公众号已经接入了智能助手,可以在对话框进行提问,也可以直接搜索历史文章进行查看。
![]()
![]()
GIS 数据转换:使用 GDAL 将 Shp 转换为 GeoJSON 数据