使用GDAL进行坐标转换

news2025/7/19 21:47:46

1、地理坐标系与投影坐标系

空间参考中主要包含大地水准面、地球椭球体、投影坐标系等几部分内容。地图投影就是把地球表面的任意点,利用一定数学法则,转换到地图平面上的理论和方法,一般有两种坐标系来进行表示,分别是地理坐标系和投影坐标系。如下图所示,描述了地理坐标系与投影坐标系之间的关系。

图1 地理坐标与投影坐标关系

地理坐标系即球体坐标,投影坐标即投影后的平面坐标;常见的地理坐标GPS坐标,常见的投影坐标墨卡托投影。

常用的坐标系为地理坐标系(Geograpic Coordinate System,简称GCS)和投影坐标系(Projected Coordinate System,简称PCS)。

1.1、地理坐标系统

地理坐标系统(GCS)用一个三维的球面来确定地物在地球上的位置,地面点的地理坐标有经度、纬度、高程构成。地理坐标系统与选择的地球椭球体和大地基准面有关。椭球体定义了地球的形状,而大地基准面确定了椭球体的中心。

  地理坐标系 (GCS) 使用三维球面来定义地球上的位置。GCS中的重要参数包括角度测量单位、本初子午线和基准面(基于旋转椭球体)。地理坐标系统中用经纬度来确定球面上的点位,经度和纬度是从地心到地球表面上某点的测量角。球面系统中的水平线是等纬度线或纬线,垂直线是等经度线或经线。这些线包络着地球,构成了一个称为经纬网的格网化网络。

GCS中经度和纬度值以十进制度为单位或以度、分和秒 (DMS) 为单位进行测量。纬度值相对于赤道进行测量,其范围是 -90°(南极点)到 +90°(北极点)。经度值相对于本初子午线进行测量。其范围是 -180°(向西行进时)到 180°(向东行进时)。

1.2、投影坐标系统

投影坐标系统是根据某种映射关系,将地理坐标系统中由经纬度确定的三维球面坐标投影到二维的平面上所使用的坐标系统。在该坐标系统中,点的位置是由(x,y,z)坐标来确定的。由于投影坐标是将球面展会在平面上,因此不可避免会产生变形。这些变形包括3种:长度变形、角度变形以及面积变形。通常情况下投影转换都是在保证某种特性不变的情况下牺牲其他属性。根据变形的性质可分为等角投影、等面积投影等。

我国的基本比例尺地形图(1:5千,1:1万,1:2.5万,1:10万,1:25万,1:50万,1:100万)中,大于或等于1:50万均采用高斯-克吕格投影(Gauss_Kruger),又叫横轴墨卡托投影(Transverse Mercator);1:100万的地形图采用正轴等角圆锥投影,又叫兰勃特投影(Lambert Conformal Conic);海上小于50万的地形图多用正轴等角圆柱投影,又叫墨卡托投影(Mercator)。在开发GIS系统中应该采用与我国基本比例尺地形图系列一致的地图投影系统。

2、坐标系转换

根据参考文章,封装成一个类使用。

import numpy as np
from osgeo import gdal, osr

class GdalTif(object):
    def __init__(self, tif_path):
        self.tif_path = tif_path
        self.dataset = self._read_tif(tif_path)

    @staticmethod
    def _read_tif(tif_path):
        """ 读取GDAL地理数据
        :param tif_path: tif图像路径
        :return: GDAL地理数据
        """

        dataset = gdal.Open(tif_path)
        if dataset is None:
            print(tif_path + " 文件无法打开")
        return dataset

    def get_geo_trans(self):
        """ 获取仿射矩阵信息
        :return: 仿射矩阵信息有六个参数,描述的是栅格行列号和地理坐标之间的关系:
            (
                0:左上角横坐标(投影坐标,经度);
                1:像元宽度,影像东西/水平方向分辨率;
                2:行旋转,如果图像北方朝上,该值为0;
                3:左上角纵坐标(投影坐标,纬度);
                4:列旋转,如果图像北方朝上,该值为0;
                5:像元高度,影像南北/垂直方向分辨率;
            )
            如果图像不含地理坐标信息,默认返回值是:(0,1,0,0,0,1)
        """

        return self.dataset.GetGeoTransform()

    def get_projection(self):
        """ 获取数据投影信息
        :return: INFO
        """

        return self.dataset.GetProjection()

    def get_srs_pair(self):
        """ 获得给定数据的投影参考系和地理参考系
        :param dataset: GDAL地理数据
        :return: 投影参考系和地理参考系
        """

        prosrs = osr.SpatialReference()
        prosrs.ImportFromWkt(self.dataset.GetProjection())
        geosrs = prosrs.CloneGeogCS()
        return prosrs, geosrs

    def imagexy2geo(self, row, col):
        """ 根据GDAL的六参数模型将影像图上坐标(行列号)转为投影坐标或地理坐标(根据具体数据的坐标系统转换)
        :param dataset: GDAL地理数据
        :param row: 像素的行号(i)
        :param col: 像素的列号(j)
        :return: 行列号(row, col)对应的投影坐标或地理坐标(x, y) - WGS84
        """

        trans = self.dataset.GetGeoTransform()
        x = trans[0] + col * trans[1] + row * trans[2]
        y = trans[3] + col * trans[4] + row * trans[5]
        return (x, y)

    def geo2imagexy(self, x, y):
        """ 根据GDAL的六 参数模型将给定的投影或地理坐标转为影像图上坐标(行列号)
        :param x: 投影或地理坐标x
        :param y: 投影或地理坐标y
        :return: 影坐标或地理坐标(x, y)对应的影像图上行列号(row, col)
        """

        trans = self.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)[::-1]  # 使用numpy的linalg.solve进行二元一次方程的求解

    def geo_to_lonlat(self, x, y):
        """ 将投影坐标转为经纬度坐标(具体的投影坐标系由给定数据确定)
        :param x: 投影坐标x
        :param y: 投影坐标y
        :return: 投影坐标(x, y)对应的经纬度坐标(lon, lat)
        """

        prosrs, geosrs = self.get_srs_pair()
        ct = osr.CoordinateTransformation(prosrs, geosrs)
        coords = ct.TransformPoint(x, y)
        return coords[:2]

    def lonlat2geo(self, lon, lat):
        """ 将经纬度坐标转为投影坐标(具体的投影坐标系由给定数据确定)
        :param dataset: GDAL地理数据
        :param lon: 地理坐标lon经度
        :param lat: 地理坐标lat纬度
        :return: 经纬度坐标(lon, lat)对应的投影坐标
        """

        prosrs, geosrs = self.get_srs_pair()
        ct = osr.CoordinateTransformation(geosrs, prosrs)
        coords = ct.TransformPoint(lon, lat)
        return coords[:2]

def main():
    tif_file = r"C:\Users\i\Desktop\dsm.tif"
    gda = GdalTif(tif_file)
    print("数据投影信息:", gda.get_projection())
    
    pt = (300, 500)
    print("pt = ", pt)

    print("图上坐标 -> 投影坐标:")
    point = gda.imagexy2geo(*pt)
    print("WGS84 point:", point)

    print("投影坐标 -> 图上坐标:")
    pt = gda.geo2imagexy(*point)
    print("pixel pt:", pt)

    print("投影坐标 -> 经纬度:")
    coord = gda.geo_to_lonlat(*point)
    print("gps coord:", coord)

    print("经纬度 -> 投影坐标:")
    point = gda.lonlat2geo(*coord)
    print("point:", point)

if __name__ == '__main__':
    main()

测试结果:

数据投影信息: PROJCS["CGCS2000 / 3-degree Gauss-Kruger CM 111E",GEOGCS["China Geodetic Coordinate System 2000",DATUM["China_2000",SPHEROID[
"CGCS2000",6378137,298.257222101,AUTHORITY["EPSG","1024"]],AUTHORITY["EPSG","1043"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["d
egree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4490"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_orig
in",0],PARAMETER["central_meridian",111],PARAMETER["scale_factor",1],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["
metre",1,AUTHORITY["EPSG","9001"]],AXIS["Northing",NORTH],AXIS["Easting",EAST],AUTHORITY["EPSG","4546"]]
pt =  (300, 500)
图上坐标 -> 投影坐标:
WGS84 point: (402657.7898284429, 2052764.045716705)
投影坐标 -> 图上坐标:
pixel pt: [300. 500.]
投影坐标 -> 经纬度:
gps coord: (3.535317397929979, 124.8387146988415)
经纬度 -> 投影坐标:
point: (402657.78982844297, 2052764.0457167062)

参考文章:

1、谈谈地理坐标和投影坐标

http://www.360doc.com/content/22/1214/01/65719465_1060178233.shtml

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/368807.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Free for photo container detection, container damage detect PaaS

集装箱箱号识别API免费,飞瞳引擎集装箱人工智能平台,可通过API二次开发或小程序拍照使用,可二次开发应用码头港区海关仓库口岸铁路场站船公司堆场,实现云端集装箱信息识别/集装箱箱况残损检测/好坏箱检验,高检测率/高实…

对话数字化经营新模式:第2届22客户节(22Day)年猪宴圆满结束!

2023年2月22日,由杭州电子商务研究院联合贰贰网络(集团)、TO B总监联盟等发起举办的“第二届客户节22Day”暨2022年度爱名奖 AM AWARDS颁奖及22年猪宴沙龙活动圆满结束。 (主持人:杜灵芝) 本次沙龙邀请到浙江工业大学管理学院程志…

windows版 redis在同意局域网下互联

项目场景: 同一局域网下各个主机互相连接同一个redis 问题描述 无法连接 原因分析: 没有放行对方的地址 解决方案: 修改配置文件 最重要的一步如下 然后把 redis.windows.conf的文件也照上面的修改一下保持一致 然后安装一下redis服务这…

腾讯在海外游戏和短视频广告领域的新增长机会

来源:猛兽财经 作者:猛兽财经 腾讯(00700)的收入在过去几个季度一直在下降,部分原因是由于新冠疫情导致的经济放缓以及中国监管机构对大型科技公司的监管收紧导致游戏行业萎缩造成的。 然而,猛兽财经认为,这些不利因素…

java 面试问题(一)

文章目录1、Iterator 怎么使用2、Iterator 和 ListIterator 有什么区别3、怎么确保一个集合不能被修改4、 队列和栈是什么5、什么是 Java 的内存模型6、Volatile 关键字的作用7、Volatile 与 Synchronized 比较8、ThreadLocal 介绍9、ThreadLocal 与 Synchronized 的区别10、哪…

十五、多路查找树

1、二叉树与B树 1.1 二叉树的问题分析 二叉树的操作效率较高,但是也存在问题,请看下面的二叉树 二叉树需要加载到内存中,如果二叉树的节点少,没有什么问题,但是如果二叉树的节点很多(比如 1 亿&#xff…

使用antlr实现一个简单的表达式解析

背景 之前在做游戏的过程中,我们经常需要解析一些公式,比如(对方攻击值-对方防御值)*2这种表达式,我们习惯于用代码写死公式,但是这种方式不够灵活,我们想要的是一种灵活的解析方式, 只需要策划输入一个任…

教师管理系统的设计与实现

技术:Java、JSP等摘要:1.1 计算机管理教师的意义近年来,随着经济的发展,教育正面向着大型化、规模化的方向发展,教师数量急剧增加,有关教师的各种信息量也成倍增长。在这种情况下用计算机可使人们从繁重的劳…

微机原理复习(周五),计算机组成原理图

1.计算机由运算器,控制器,存储器,输入设备,输出设备等5大基本部件组成。 2.冯诺依曼提出存储设计思想是:数字计算机的数制采用二进制,存储程序,程序控制。 3.计算机的基本组成框图&#xff1a…

什么是分组柱状图?

柱形图是我们做数据分析时最常用的图表类型之一,很多时候都需要制作分组展示的柱形图,以分类别的展示各种维度的数据情况。上文我已经介绍过堆叠柱状图,因此本文将分享分组柱形图的知识。 分组柱状图,又叫聚合柱状图。当使用者需要…

正点原子linux驱动篇

linux驱动开发与裸机开发的区别 裸机直接操作寄存器,有些mcu提供了库,但还是很底层 1、linux驱动开发直接操作寄存器很麻烦不现实,主要是根据linux驱动框架进行开发(就是有很多操作都是一样的,我们只需要对一个程序模…

linux安装nodejs和微信小程序自动化部署操作

一.运行环境安装 Node.js 并且版本大于 8.0基础库版本为 2.7.3 及以上开发者工具版本为 1.02.1907232 及以上安装node.js(1).下载node包官网地址:https://nodejs.org/en/download/如果英文不好的,可以看中文网站:https://nodejs.org/zh-cn/download/点击上面的进行下载,当然,也…

国产音质好的蓝牙耳机有哪些?国产音质最好的耳机排行

随着时间的推移,真无线蓝牙耳机逐渐占据耳机市场的份额,成为人们日常生活中必备的数码产品之一。蓝牙耳机品牌也多得数不胜数,哪些国产蓝牙耳机音质好?下面,我们从音质出来,来给大家介绍几款国产蓝牙耳机&a…

Quartus II 的入门级使用

好久没有用VHDL写东西了,今天需要完成一个项目,重新复习一下新建工程新建工程file-->New Project Wizard, next, 选择存放的路径名字(projecttop-level 名字要相同),next,File name名字同上,…

【一看就会】实现仿京东移动端页面滚动条布局

简单粗暴直接上代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta http-equiv"X-UA-Compatible" content"IEedge"> <meta name"viewport" content&q…

matlab simulink 模糊控制蔬菜气雾栽培营养液供给自动监控

1、内容简介略-可以交流、咨询、答疑2、内容说明模型基本数学公式参考的是硕士论文摘要&#xff1a;随着社会的发展&#xff0c;世界人口逐渐增加&#xff0c;耕地面积日益减少&#xff0c;而且人们对 优质、安全、无污染的蔬菜需求也越来越高&#xff0c;植物工厂成为蔬菜栽培…

MyBatis学习笔记(五) —— MyBatis获取参数值的两种方式

5、MyBatis获取参数值的两种方式 MyBatis获取参数值的两种方式&#xff1a;${} 和 #{} ${} 的本质就是字符串拼接&#xff0c; #{} 的本质就是占位符赋值 ${} 使用字符串拼接的方式拼接sql&#xff0c;若为字符串类型或日期类型的字段进行赋值时&#xff0c;需要手动加单引号&a…

【数据挖掘实战】——家用电器用户行为分析及事件识别

项目地址&#xff1a;Datamining_project: 数据挖掘实战项目代码 目录 一、背景和挖掘目标 1、问题背景 2、原始数据 3、挖掘目标 二、分析方法与过程 1、初步分析 2、总体流程 第一步&#xff1a;数据抽取 第二步&#xff1a;探索分析 第三步&#xff1a;数据的预处…

mysql 中关于慢查询日志

慢查询日志 慢查询日志主要用来记录执行时间超过设置的某个时长的SQL语句&#xff0c;能够帮助数据库维护人员找出执行时间比较长、执行效率比较低的SQL语句&#xff0c;并对这些SQL语句进行针对性优化。 开启慢查询 可以在 my.cnf 文件或者 my.ini 文件中配置开启慢查询日志…

数影周报:动视暴雪疑似数据泄露,数据出境安全评估申报最新进展

本周看点&#xff1a;动视暴雪疑似员工敏感信息及游戏数据泄露&#xff1b;谷歌云计算部门&#xff1a;两名员工合用一个工位&#xff1b;数据出境安全评估申报最新进展&#xff1b;TikTok Shop东南亚商城在泰国和菲律宾公布&#xff1b;智己汽车获九大金融机构50亿元贷款签约.…