使用GDAL进行影像投影坐标、地理坐标、图上坐标的转换

2019-01-22 10:43:31 浏览数 (2)

我使用GDAL库写了四个函数分别进行投影坐标与地理坐标(经纬度)之间的转换,投影坐标和图上坐标(行列号)之间的转换。有需要的朋友可以参考。 直接上代码吧,因为代码很简单(Python版本)。

代码语言:javascript复制
# -*- encoding: utf-8 -*-

from osgeo import gdal
from osgeo import osr
import numpy as np

def getSRSPair(dataset):
    '''
    获得给定数据的投影参考系和地理参考系
    :param dataset: GDAL地理数据
    :return: 投影参考系和地理参考系
    '''
    prosrs = osr.SpatialReference()
    prosrs.ImportFromWkt(dataset.GetProjection())
    geosrs = prosrs.CloneGeogCS()
    return prosrs, geosrs

def geo2lonlat(dataset, x, y):
    '''
    将投影坐标转为经纬度坐标(具体的投影坐标系由给定数据确定)
    :param dataset: GDAL地理数据
    :param x: 投影坐标x
    :param y: 投影坐标y
    :return: 投影坐标(x, y)对应的经纬度坐标(lon, lat)
    '''
    prosrs, geosrs = getSRSPair(dataset)
    ct = osr.CoordinateTransformation(prosrs, geosrs)
    coords = ct.TransformPoint(x, y)
    return coords[:2]


def lonlat2geo(dataset, lon, lat):
    '''
    将经纬度坐标转为投影坐标(具体的投影坐标系由给定数据确定)
    :param dataset: GDAL地理数据
    :param lon: 地理坐标lon经度
    :param lat: 地理坐标lat纬度
    :return: 经纬度坐标(lon, lat)对应的投影坐标
    '''
    prosrs, geosrs = getSRSPair(dataset)
    ct = osr.CoordinateTransformation(geosrs, prosrs)
    coords = ct.TransformPoint(lon, lat)
    return coords[:2]

def imagexy2geo(dataset, row, col):
    '''
    根据GDAL的六参数模型将影像图上坐标(行列号)转为投影坐标或地理坐标(根据具体数据的坐标系统转换)
    :param dataset: GDAL地理数据
    :param row: 像素的行号
    :param col: 像素的列号
    :return: 行列号(row, col)对应的投影坐标或地理坐标(x, y)
    '''
    trans = dataset.GetGeoTransform()
    px = trans[0]   col * trans[1]   row * trans[2]
    py = trans[3]   col * trans[4]   row * trans[5]
    return px, py


def geo2imagexy(dataset, x, y):
    '''
    根据GDAL的六 参数模型将给定的投影或地理坐标转为影像图上坐标(行列号)
    :param dataset: GDAL地理数据
    :param x: 投影或地理坐标x
    :param y: 投影或地理坐标y
    :return: 影坐标或地理坐标(x, y)对应的影像图上行列号(row, col)
    '''
    trans = dataset.GetGeoTransform()
    a = np.array([[trans[1], trans[2]], [trans[4], trans[5]]])
    b = np.array([x - trans[0], y - trans[3]])
    return np.linalg.solve(a, b)  # 使用numpy的linalg.solve进行二元一次方程的求解


if __name__ == '__main__':
    gdal.AllRegister()
    dataset = gdal.Open(r"F:2016DataGreat KhinganDEMProjectionstrm_6102_UTM.tif")
    print('数据投影:')
    print(dataset.GetProjection())
    print('数据的大小(行,列):')
    print('(%s %s)' % (dataset.RasterYSize, dataset.RasterXSize))

    x = 464201
    y = 5818760
    lon = 122.47242
    lat = 52.51778
    row = 2399
    col = 3751

    print('投影坐标 -> 经纬度:')
    coords = geo2lonlat(dataset, x, y)
    print('(%s, %s)->(%s, %s)' % (x, y, coords[0], coords[1]))
    print('经纬度 -> 投影坐标:')
    coords = lonlat2geo(dataset, lon, lat)
    print('(%s, %s)->(%s, %s)' % (lon, lat, coords[0], coords[1]))

    print('图上坐标 -> 投影坐标:')
    coords = imagexy2geo(dataset, row, col)
    print('(%s, %s)->(%s, %s)' % (row, col, coords[0], coords[1]))
    print('投影坐标 -> 图上坐标:')
    coords = geo2imagexy(dataset, x, y)
    print('(%s, %s)->(%s, %s)' % (x, y, coords[0], coords[1]))

输出结果:

代码语言:javascript复制
数据投影:
PROJCS["WGS_1984_UTM_Zone_51N",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",123],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","32651"]]
数据的大小(行,列):
(7503 4799)
投影坐标 -> 经纬度:
(464201, 5818760)->(122.472422555, 52.5177753994)
经纬度 -> 投影坐标:
(122.47242, 52.51778)->(464200.830381, 5818760.513)
图上坐标 -> 投影坐标:
(2399, 3751)->(464163.754715, 5818797.73095)
投影坐标 -> 图上坐标:
(464201, 5818760)->(2399.49875769, 3751.50526134)

注:关于投影坐标和图上坐标转换的六参数模型可以参考我的另外一篇博文:经纬度坐标和投影坐标的转换,其实质就是一个仿射变换。

我们可以使用GDAL库自带的命令行工具(gdallocationinfo)进行检测:

其中参数-geoloc表示的后面给定坐标是投影坐标,-wgs84表示是WGS84参考系下的地理坐标(经纬度)。其输出是对应的图上坐标(行列号)。 具体参数可以使用gdallocationinfo –help查看。

0 人点赞