12_OSR模块和空间参考系

本文介绍了如何在Python中使用osr模块定义和操作地理坐标系(经纬度)和投影坐标系(米制),包括WGS84、UTM投影及EPSG编码的应用。通过实例展示了如何创建、转换和验证不同的空间参考系,并探讨了栅格和矢量数据的坐标获取方法。
部署运行你感兴趣的模型镜像

OSR模块和空间参考系

定义地理坐标系

地理坐标系封装在osr.SpatialReference类中。

主要有两种坐标系:经纬度的地理坐标系和米的投影坐标系。

# -*- coding: utf-8 -*-
# 学习时间: 2022/11/26 17:05

__author__ = 'He XK'
from osgeo import ogr, osr, gdal

# 定义SR空间参考对象
sr = osr.SpatialReference()
# 给SR对象设定地理坐标系为WGS84
sr.SetWellKnownGeogCS('WGS84')
# 导出成wkt格式
wkt = sr.ExportToWkt()
print(wkt)

输出结果:
GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]

注意:

以上声明坐标系统采用的参数是'WGS84'。也可以使用标准的EPSG声明方式,比如用'EPSG:4326'进行等价的代替。

可以通过sr.ImportFromWkt(wkt)方法将自定义的wkt格式写入SR中。

在哪里查看SetWellKnownGeoCS的const参数?

定义投影系统

定义在WGS84基准面下的北半球UTM17带。

sr.SetProjCS(char const * name="unnamed")设置一个定义用户名字的投影坐标系统并确定系统被投影过,应该是参数是用户随意输入,只表示用于定义坐标系的名称;

sr.SetWellKnownGeogCS(...)设定一个坐标系统,EPSG中已有的各种参数;

sr.SetUTM(int zone, int north=1)设置投影转换参数细节,包含两个参数,zone表示投影带号,north表示是否为北半球,默认是True

sr.SetProjCS('UTM 17 (WGS84) in northern hemisphere.')
sr.SetWellKnownGeogCS('WGS84')
sr.SetUTM(17 , True)
wkt = sr.ExportToWkt()
pprint(wkt)  # pretty print

关于地理坐标系和投影坐标系

sr = osr.SpatialReference()
sr.SetWellKnownGeogCS('EPSG:4214')
wkt = sr.ExportToWkt()
pprint(wkt)
print(sr.IsGeographic())  # 1


sr2 = osr.SpatialReference()
sr2.SetProjCS('4214 ZONE 18 > 4573 metre')
sr2.SetWellKnownGeogCS('EPSG:4214')
sr2.SetUTM(18, 1)
wkt2 = sr2.ExportToWkt()
pprint(wkt2)
print(sr2.IsProjected())   # 1

地理坐标系:Degree

投影坐标系:Metre

投影坐标系是以地理坐标系为基准面。

EPSG:4214为例,表示Beijing 1954地理坐标系。

SR只设定了地理基准面,所以sr.IsGeographic()的判断为True

SR2依据此地理基准面进行投影,同时设定18带,经过sr2.IsProjected()的判断为True


可以 漂亮的输出所有空间参考系信息。

print(sr2.ExportToPrettyWkt())

可以输出空间投影坐标系的长半轴SemiMajor、短半轴SemiMinor和扁率InvFlattening

print(sr2.GetSemiMajor())  # 6378245.0
print(sr2.GetSemiMinor())  # 6356863.018773047
print(sr2.GetInvFlattening())  # 298.3

可以获取投影坐标系中的各种参数。

名称可以用ExportToPrettyWkt输出后获取查看。

print(sr2.GetAttrValue('PROJCS'))  # 4214 ZONE 18 > 4573 metre
print(sr2.GetAttrValue('GEOGCS'))  # Beijing 1954
print(sr2.GetAttrValue('DATUM'))  # Beijing_1954
print(sr2.GetAttrValue('PRIMEM'))  # Greenwich
print(sr2.GetAttrValue('PROJECTION'))  # Transverse_Mercator

栅格数据的空间参考

数据集的坐标系统由OpenGIS WKT字符串定义,它包含了:

  1. 一个总体的坐标系名;

  2. 一个地理图形坐标系统名;

  3. 一个基准面定义;

  4. 一个椭球体的名字。长半轴(semi-major axis)和反扁率(inverse flattening);

  5. 本初子午线(prime meridian)名和其与格林威治子午线的偏移值;

  6. 投影的方法类型(如横轴莫卡托);

  7. 投影的参数列表(如中央经线等);

  8. 一个单位的名称和其到米和弧度单位的转换参数;

  9. 轴线的名称和顺序;

  10. 在预定义的权威坐标系中的编码(如EPSG)。


tif1 = gdal.Open('I:\\MasterLife\\资源与环境遥感\\实验作业一\\caijian2.tif')

print(tif1.GetProjection())
print(tif1.GetProjectionRef())

两个获得的结果一致,均输出栅格影像的投影坐标系。


地理仿式变换参数。

adfGeoTransform[0] /* top left x */
adfGeoTransform[1] /* w-e pixel resolution */
adfGeoTransform[2] /* rotation, 0 if image is "north up" */
adfGeoTransform[3] /* top left y */
adfGeoTransform[4] /* rotation, 0 if image is "north up" */
adfGeoTransform[5] /* n-s pixel resolution */

坐标转换

常规的WKT格式。

__author__ = 'He XK'

from osgeo import gdal, osr
from osgeo.gdalconst import *

ds = gdal.Open('I:\\MasterLife\\资源与环境遥感\\实验作业一\\caijian2.tif')
sr = ds.GetProjection()
print(sr)
# 声明一个osr的对象
osr_obj = osr.SpatialReference()
# 将获取的空间参考系导入到osr对象中
# 此时 osr对象也就具备了投影的所有信息
osr_obj.ImportFromWkt(sr)
# 常规的wkt格式
print(osr_obj)

接上代码。

osr_obj.MorphToESRI()将wkt格式转化成ESRI的格式。

输出结果会有一点变化。

osr_obj.MorphToESRI()
print(osr_obj)

自动识别EPSG。

# 对于WGS84
print(osr_obj.AutoIdentifyEPSG())  # WGS84的排序是0

# 对于Beijing 1954 
print(sr2.AutoIdentifyEPSG())  # 7

判断两个SR对象是否相同。

0是不相同。

print(sr2.IsSame(sr))  # 0

导出成米单位的坐标系统。

因为osr_obj是遥感影像已有坐标系,所以具备经纬度信息,自定义不确定到具体带的没有经纬度信息。

print(osr_obj.ExportToMICoordSys()) 
 # Earth Projection 8, 104, "m", 117, 0, 0.9996, 500000, 0

导出成PCI的格式,我也不知道PCI是什么格式。

print(osr_obj.ExportToPCI())
  # ['UTM    50   E012', 'METRE', (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)]

还有其他的一些导出格式。

ExportToWkt()
ExportToPrettyWkt()
ExportToProj4()
ExportToPCI()
ExportToUSGS()
ExportToXML()

矢量数据和栅格数据获取空间参考系的方法

矢量数据:

layer.GetSpatialRef()

矢量数据获取的空间坐标系是OSR对象。

栅格数据:

projection = dataset.GetProjection() # 或者
projection = dataset.GetProjectionRef()

geotransform = dataset.GetGeoTransform()

注意,以上栅格数据获取的投影坐标系信息,都不是OSR对象。

地理坐标系和投影坐标系之间的坐标转换

相当于之前使用过的重投影。

我们可以创建一个新的坐标系统,对某一个SHP文件进行重投影。

下面我们进行一个对shp文件重投影的实例。

# -*- coding: utf-8 -*-
# 学习时间: 2022/11/29 16:47

__author__ = 'He XK'

import os

from osgeo import osr, ogr, gdal

gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES")
gdal.SetConfigOption("SHAPE_ENCODING", "UTF8")

driver = ogr.GetDriverByName('ESRI SHAPEFILE')

origin_path = 'shp/province_1.shp'
output_path = 'shp/demo32_reproject.shp'
dataset = driver.Open(origin_path)
layer = dataset.GetLayer(0)
origin_ref = layer.GetSpatialRef()  # WGS84
# 定义新的投影
sr = osr.SpatialReference()
# sr.SetWellKnownGeogCS('EPSG:4610')
# sr.SetProjCS('xian 80')
# sr.SetUTM(19, True)
sr.ImportFromEPSG(3857)

transform = osr.CoordinateTransformation(origin_ref, sr)

if os.path.exists(output_path):
    driver.DeleteDataSource(output_path)
else:
    print('THIS SHP IS NOT EXIST!')

output_ds = driver.CreateDataSource(output_path)
output_layer = output_ds.CreateLayer('repro', srs=sr, geom_type=ogr.wkbPolygon)
output_feature_defn = output_layer.GetLayerDefn()
# 创建字段
output_field_def = ogr.FieldDefn('Name', ogr.OFTString)
output_field_def.SetWidth(10)
output_layer.CreateField(output_field_def)

layer.ResetReading()
i = 0
while i < layer.GetFeatureCount():
    feature = layer.GetFeature(i)
    i += 1
    geom = feature.GetGeometryRef()
    output_geom = geom.Transform(transform)
    output_feature = ogr.Feature(output_feature_defn)
    output_feature.SetGeometry(geom)
    output_feature.SetField('Name', feature.GetField('Name'))
    output_layer.CreateFeature(output_feature)

output_ds.Release()
dataset.Release()
put_feature)

output_ds.Release()
dataset.Release()

其中只能对geometry进行重投影。

那么我们就要获取到geometry然后投影,之后创建新要素挂载到新图层。

从QGIS上并不能直接看到不同投影的变化,可能是因为QGIS自己进行了重投影,但是查看坐标系可以发现投影坐标系。

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值