GDAL中的地理坐标系、投影坐标系及其相互转换

目录

地理坐标系

国内常用地理坐标系

投影坐标系

国内常用投影坐标系(不推荐使用)

坐标转换

地理坐标转为投影坐标

投影坐标转为地理坐标


地理坐标系

原理参考这篇文章:
地理坐标系与投影坐标系区别与联系
https://yunxingluoyun.blog.csdn.net/article/details/123970678

国内常用地理坐标系

#include <cstdio>
#include "gdal_priv.h"
#include <iostream>

int main()
{
	OGRSpatialReference oSRS1;
	oSRS1.SetGeogCS("自定义地理坐标系",// 定义地理坐标系名称
		"WGS_1984",// 基准面
		"WGS84 椭球",// 椭球体名称
		SRS_WGS84_SEMIMAJOR, SRS_WGS84_INVFLATTENING,// WGS84椭球体的长半轴,WGS84椭球体扁率的倒数
		"Greenwich", 0.0,// 格林尼治子午线
		"degree", 0.0174532925199433);// 角度度量单位
	char* WGS84_WTK = NULL;
	oSRS1.exportToPrettyWkt(&WGS84_WTK);// 以规整的WTK格式输出地理坐标系的信息
	std::cout << WGS84_WTK << std::endl;
	// CGCS2000
	OGRSpatialReference oSRS2;
	oSRS2.SetWellKnownGeogCS("EPSG:4490");
	char* CGCS2000_WTK = NULL;
	oSRS2.exportToPrettyWkt(&CGCS2000_WTK);
	std::cout << CGCS2000_WTK << std::endl;
	// Beijing_1954
	OGRSpatialReference oSRS3;
	oSRS3.SetWellKnownGeogCS("EPSG:4214");
	char* Beijing_1954_WTK = NULL;
	oSRS3.exportToPrettyWkt(&Beijing_1954_WTK);
	std::cout << Beijing_1954_WTK << std::endl;
	// Xian_1980
	OGRSpatialReference oSRS4;
	oSRS4.SetWellKnownGeogCS("EPSG:4610");
	char* Xian_1980_WTK = NULL;
	oSRS4.exportToPrettyWkt(&Xian_1980_WTK);
	std::cout << Xian_1980_WTK << std::endl;

}

结果:

GEOGCS["自定义地理坐标系",
    DATUM["WGS_1984",
        SPHEROID["WGS84 椭球",6378137,298.257223563]],
    PRIMEM["Greenwich",0],
    UNIT["degree",0.0174532925199433,
        AUTHORITY["EPSG","9122"]],
    AXIS["Latitude",NORTH],
    AXIS["Longitude",EAST]]
    
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["degree",0.0174532925199433,
        AUTHORITY["EPSG","9122"]],
    AXIS["Latitude",NORTH],
    AXIS["Longitude",EAST],
    AUTHORITY["EPSG","4490"]]
    
GEOGCS["Beijing 1954",
    DATUM["Beijing_1954",
        SPHEROID["Krassowsky 1940",6378245,298.3,
            AUTHORITY["EPSG","7024"]],
        AUTHORITY["EPSG","6214"]],
    PRIMEM["Greenwich",0,
        AUTHORITY["EPSG","8901"]],
    UNIT["degree",0.0174532925199433,
        AUTHORITY["EPSG","9122"]],
    AXIS["Latitude",NORTH],
    AXIS["Longitude",EAST],
    AUTHORITY["EPSG","4214"]]
   
GEOGCS["Xian 1980",
    DATUM["Xian_1980",
        SPHEROID["IAG 1975",6378140,298.257,
            AUTHORITY["EPSG","7049"]],
        AUTHORITY["EPSG","6610"]],
    PRIMEM["Greenwich",0,
        AUTHORITY["EPSG","8901"]],
    UNIT["degree",0.0174532925199433,
        AUTHORITY["EPSG","9122"]],
    AXIS["Latitude",NORTH],
    AXIS["Longitude",EAST],
    AUTHORITY["EPSG","4610"]]

投影坐标系

设置横轴墨卡托投影的函数SetTM()有六个参数:

国内常用投影坐标系(不推荐使用)

推荐使用例3中的方式使用坐标系,EPSG请查看网址:

EPSG.io: Coordinate Systems Worldwide
注意:这种方式定义的坐标轴与例3相反,如果使用这样方法,后面的poCT->Transform(1, &x, &y)影改为poCT->Transform(1, &y, &x)。

#include <cstdio>
#include "gdal_priv.h"
#include <iostream>

int main()
{
	OGRSpatialReference oSRS1;
	oSRS1.SetProjCS("UTM 17(WGS84) in northern hemisphere.");// 设置投影坐标系名称
	oSRS1.SetWellKnownGeogCS("EPSG:4326");// 设置地理坐标系
	oSRS1.SetUTM(17, TRUE);//设置UTM投影的投影参数
	char* UTM17_WTK = NULL;
	oSRS1.exportToPrettyWkt(&UTM17_WTK);
	std::cout << UTM17_WTK << std::endl;

	OGRSpatialReference oSRS2;
	oSRS2.SetProjCS("CGCS2000 / Gauss-Kruger CM 117E");
	oSRS2.SetWellKnownGeogCS("EPSG:4490");
	oSRS2.SetTM(0,117,1,500000,0);//起始纬度,中央经线,比例因子,东偏移量,北偏移量
	char* CGCS2000_GK_117E_WTK = NULL;
	oSRS2.exportToPrettyWkt(&CGCS2000_GK_117E_WTK);
	std::cout << "CGCS2000 / Gauss-Kruger CM 117E" << std::endl;
	std::cout <<"是否为投影坐标系:" << oSRS2.IsProjected() << std::endl;
	std::cout << CGCS2000_GK_117E_WTK << std::endl;

	OGRSpatialReference oSRS3;
	oSRS3.SetProjCS("CGCS2000 3 Degree GK Zone 39");
	oSRS3.SetWellKnownGeogCS("EPSG:4490");
	oSRS3.SetTM(0, 117, 1, 39500000, 0);//起始纬度,中央经线,比例因子,东偏移量,北偏移量
	char* CGCS2000_GK_Zone39_WTK = NULL;
	oSRS3.exportToPrettyWkt(&CGCS2000_GK_Zone39_WTK);
	std::cout << "CGCS2000 3 Degree GK Zone 39" << std::endl;
	std::cout << "是否为投影坐标系:" << oSRS3.IsProjected() << std::endl;
	std::cout << CGCS2000_GK_Zone39_WTK << std::endl;

	OGRSpatialReference oSRS4;
	oSRS4.SetProjCS("Beijing 1954 3 Degree GK CM 117E");
	oSRS4.SetWellKnownGeogCS("EPSG:4214");
	oSRS4.SetTM(0, 117, 1, 500000, 0);//起始纬度,中央经线,比例因子,东偏移量,北偏移量
	char* Beijing1954_GK_117E_WTK = NULL;
	oSRS4.exportToPrettyWkt(&Beijing1954_GK_117E_WTK);
	std::cout << "Beijing 1954 3 Degree GK CM 117E" << std::endl;
	std::cout << "是否为投影坐标系:" << oSRS4.IsProjected() << std::endl;
	std::cout << Beijing1954_GK_117E_WTK << std::endl;

	OGRSpatialReference oSRS5;
	oSRS5.SetProjCS("Xian 1980 3 Degree GK Zone 39");
	oSRS5.SetWellKnownGeogCS("EPSG:4610");
	oSRS5.SetTM(0, 117, 1, 39500000, 0);//起始纬度,中央经线,比例因子,东偏移量,北偏移量
	char* Xian_1980_GK_Zone39_WTK = NULL;
	oSRS5.exportToPrettyWkt(&Xian_1980_GK_Zone39_WTK);
	std::cout << "Xian 1980 3 Degree GK Zone 39" << std::endl;
	std::cout << "是否为投影坐标系:" << oSRS5.IsProjected() << std::endl;
	std::cout << Xian_1980_GK_Zone39_WTK << std::endl;
}

 结果:

PROJCS["UTM 17(WGS84) in northern hemisphere.",
    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"]],
        AUTHORITY["EPSG","4326"]],
    PROJECTION["Transverse_Mercator"],
    PARAMETER["latitude_of_origin",0],
    PARAMETER["central_meridian",-81],
    PARAMETER["scale_factor",0.9996],
    PARAMETER["false_easting",500000],
    PARAMETER["false_northing",0],
    UNIT["metre",1,
        AUTHORITY["EPSG","9001"]],
    AXIS["Easting",EAST],
    AXIS["Northing",NORTH]]
    
CGCS2000 / Gauss-Kruger CM 117E
是否为投影坐标系:1
PROJCS["CGCS2000 / Gauss-Kruger CM 117E",
    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["degree",0.0174532925199433,
            AUTHORITY["EPSG","9122"]],
        AUTHORITY["EPSG","4490"]],
    PROJECTION["Transverse_Mercator"],
    PARAMETER["latitude_of_origin",0],
    PARAMETER["central_meridian",117],
    PARAMETER["scale_factor",1],
    PARAMETER["false_easting",500000],
    PARAMETER["false_northing",0],
    UNIT["metre",1,
        AUTHORITY["EPSG","9001"]],
    AXIS["Easting",EAST],
    AXIS["Northing",NORTH]]
    
CGCS2000 3 Degree GK Zone 39
是否为投影坐标系:1
PROJCS["CGCS2000 3 Degree GK Zone 39",
    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["degree",0.0174532925199433,
            AUTHORITY["EPSG","9122"]],
        AUTHORITY["EPSG","4490"]],
    PROJECTION["Transverse_Mercator"],
    PARAMETER["latitude_of_origin",0],
    PARAMETER["central_meridian",117],
    PARAMETER["scale_factor",1],
    PARAMETER["false_easting",39500000],
    PARAMETER["false_northing",0],
    UNIT["metre",1,
        AUTHORITY["EPSG","9001"]],
    AXIS["Easting",EAST],
    AXIS["Northing",NORTH]]
    
Beijing 1954 3 Degree GK CM 117E
是否为投影坐标系:1
PROJCS["Beijing 1954 3 Degree GK CM 117E",
    GEOGCS["Beijing 1954",
        DATUM["Beijing_1954",
            SPHEROID["Krassowsky 1940",6378245,298.3,
                AUTHORITY["EPSG","7024"]],
            AUTHORITY["EPSG","6214"]],
        PRIMEM["Greenwich",0,
            AUTHORITY["EPSG","8901"]],
        UNIT["degree",0.0174532925199433,
            AUTHORITY["EPSG","9122"]],
        AUTHORITY["EPSG","4214"]],
    PROJECTION["Transverse_Mercator"],
    PARAMETER["latitude_of_origin",0],
    PARAMETER["central_meridian",117],
    PARAMETER["scale_factor",1],
    PARAMETER["false_easting",500000],
    PARAMETER["false_northing",0],
    UNIT["metre",1,
        AUTHORITY["EPSG","9001"]],
    AXIS["Easting",EAST],
    AXIS["Northing",NORTH]]
    
Xian 1980 3 Degree GK Zone 39
是否为投影坐标系:1
PROJCS["Xian 1980 3 Degree GK Zone 39",
    GEOGCS["Xian 1980",
        DATUM["Xian_1980",
            SPHEROID["IAG 1975",6378140,298.257,
                AUTHORITY["EPSG","7049"]],
            AUTHORITY["EPSG","6610"]],
        PRIMEM["Greenwich",0,
            AUTHORITY["EPSG","8901"]],
        UNIT["degree",0.0174532925199433,
            AUTHORITY["EPSG","9122"]],
        AUTHORITY["EPSG","4610"]],
    PROJECTION["Transverse_Mercator"],
    PARAMETER["latitude_of_origin",0],
    PARAMETER["central_meridian",117],
    PARAMETER["scale_factor",1],
    PARAMETER["false_easting",39500000],
    PARAMETER["false_northing",0],
    UNIT["metre",1,
        AUTHORITY["EPSG","9001"]],
    AXIS["Easting",EAST],
    AXIS["Northing",NORTH]]

坐标转换

地理坐标转为投影坐标

#include <cstdio>
#include "gdal_priv.h"

int main()
{
    OGRSpatialReference oSourceSRS, oTargetSRS;
    OGRCoordinateTransformation* poCT;
    oSourceSRS.importFromEPSG(4610); // 地理坐标系:Xian 1980
    oTargetSRS.importFromEPSG(2383); // 投影坐标系:Xian 1980 / 3-degree Gauss-Kruger CM 114E
    
    char* Xian_1980 = NULL;
    oSourceSRS.exportToPrettyWkt(&Xian_1980);
    char* Xian_1980_GK_114E_WTK = NULL;
    oTargetSRS.exportToPrettyWkt(&Xian_1980_GK_114E_WTK);
    printf("%s,%s\n", "oSourceSRS:\n", Xian_1980);
    printf("%s,%s\n", "oTargetSRS:\n", Xian_1980_GK_114E_WTK);


    poCT = OGRCreateCoordinateTransformation(&oSourceSRS, &oTargetSRS);
    double x, y;
    x = 38.8; //纬度
    y = 113.6; //经度
    printf("经纬度坐标:%.9lf	%.9lf", x, y);
    if (poCT == NULL || !poCT->Transform(1, &x, &y))
    {
        printf("Transformation failed.\n");
    }
    else
    {
        printf("\n平面坐标:%.9lf	%.9lf", x, y);
    }
    
}

 结果:

oSourceSRS:
,GEOGCS["Xian 1980",
    DATUM["Xian_1980",
        SPHEROID["IAG 1975",6378140,298.257,
            AUTHORITY["EPSG","7049"]],
        AUTHORITY["EPSG","6610"]],
    PRIMEM["Greenwich",0,
        AUTHORITY["EPSG","8901"]],
    UNIT["degree",0.0174532925199433,
        AUTHORITY["EPSG","9122"]],
    AXIS["Latitude",NORTH],
    AXIS["Longitude",EAST],
    AUTHORITY["EPSG","4610"]]
oTargetSRS:
,PROJCS["Xian 1980 / 3-degree Gauss-Kruger CM 114E",
    GEOGCS["Xian 1980",
        DATUM["Xian_1980",
            SPHEROID["IAG 1975",6378140,298.257,
                AUTHORITY["EPSG","7049"]],
            AUTHORITY["EPSG","6610"]],
        PRIMEM["Greenwich",0,
            AUTHORITY["EPSG","8901"]],
        UNIT["degree",0.0174532925199433,
            AUTHORITY["EPSG","9122"]],
        AUTHORITY["EPSG","4610"]],
    PROJECTION["Transverse_Mercator"],
    PARAMETER["latitude_of_origin",0],
    PARAMETER["central_meridian",114],
    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","2383"]]
经纬度坐标:38.800000000        113.600000000
平面坐标:4296379.277209882     465252.023887851

投影坐标转为地理坐标

#include <cstdio>
#include "gdal_priv.h"

int main()
{
    OGRSpatialReference oSourceSRS, oTargetSRS;
    OGRCoordinateTransformation* poCT;
    oSourceSRS.importFromEPSG(2383); // Xian 1980 / 3-degree Gauss-Kruger CM 114E
    oTargetSRS.importFromEPSG(4610); // Xian 1980 

    char* Xian_1980_GK_114E_WTK = NULL;
    oSourceSRS.exportToPrettyWkt(&Xian_1980_GK_114E_WTK);
    char* Xian_1980 = NULL;
    oTargetSRS.exportToPrettyWkt(&Xian_1980);

    printf("%s,%s\n", "oSourceSRS:\n", Xian_1980);
    printf("%s,%s\n", "oTargetSRS:\n", Xian_1980_GK_114E_WTK);


    poCT = OGRCreateCoordinateTransformation(&oSourceSRS, &oTargetSRS);
    double x, y;  
    x = 4296379.277209882; //纬度
    y = 465252.023887851; //经度
    printf("\n平面坐标:%.9lf	%.9lf", x, y);
    
    if (poCT == NULL || !poCT->Transform(1, &x, &y))
    {
        printf("Transformation failed.\n");
    }
    else
    {
        printf("\n经纬度坐标:%.9lf  %.9lf", x, y);
    }
    
}

结果:

oSourceSRS:
,GEOGCS["Xian 1980",
    DATUM["Xian_1980",
        SPHEROID["IAG 1975",6378140,298.257,
            AUTHORITY["EPSG","7049"]],
        AUTHORITY["EPSG","6610"]],
    PRIMEM["Greenwich",0,
        AUTHORITY["EPSG","8901"]],
    UNIT["degree",0.0174532925199433,
        AUTHORITY["EPSG","9122"]],
    AXIS["Latitude",NORTH],
    AXIS["Longitude",EAST],
    AUTHORITY["EPSG","4610"]]
oTargetSRS:
,PROJCS["Xian 1980 / 3-degree Gauss-Kruger CM 114E",
    GEOGCS["Xian 1980",
        DATUM["Xian_1980",
            SPHEROID["IAG 1975",6378140,298.257,
                AUTHORITY["EPSG","7049"]],
            AUTHORITY["EPSG","6610"]],
        PRIMEM["Greenwich",0,
            AUTHORITY["EPSG","8901"]],
        UNIT["degree",0.0174532925199433,
            AUTHORITY["EPSG","9122"]],
        AUTHORITY["EPSG","4610"]],
    PROJECTION["Transverse_Mercator"],
    PARAMETER["latitude_of_origin",0],
    PARAMETER["central_meridian",114],
    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","2383"]]

平面坐标:4296379.277209882     465252.023887851
经纬度坐标:38.800000000  113.600000000

参考资料:

《GDAL源码剖析与开发指南》
ogr_srs_api.h:空间参考系C api — GDAL 文档

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
GDAL ,可以通过 `osr` 模块的 `SpatialReference` 和 `CoordinateTransformation` 类来实现地理坐标与投影坐标的转换。下面是一个简单的例子: ```python from osgeo import gdal, osr # 定义源影像和目标影像的文件路径 src_file = 'input.tif' dst_file = 'output.tif' # 定义目标投影 dst_proj = 'EPSG:32650' # 例如,设置目标坐标系为 WGS84 UTM Zone 50N # 打开源影像文件 src_ds = gdal.Open(src_file) # 获取源影像的地理信息和投影信息 src_geo = src_ds.GetGeoTransform() src_proj = osr.SpatialReference() src_proj.ImportFromWkt(src_ds.GetProjection()) # 定义目标投影 dst_proj = osr.SpatialReference() dst_proj.SetFromUserInput(dst_proj) # 创建坐标转换对象 coord_trans = osr.CoordinateTransformation(src_proj, dst_proj) # 计算转换后的坐标 x, y, _ = coord_trans.TransformPoint(src_geo[0], src_geo[3]) # 输出转换后的坐标 print('X: {}'.format(x)) print('Y: {}'.format(y)) # 关闭影像文件 src_ds = None ``` 在上面的例子,我们打开了一个名为 `input.tif` 的影像文件,并获取了其地理信息和投影信息。然后,我们定义了一个名为 `dst_proj` 的目标投影,创建了一个名为 `coord_trans` 的坐标转换对象,并使用 `coord_trans.TransformPoint` 方法计算了转换后的坐标。最后,我们输出了转换后的坐标,并关闭了影像文件。 需要注意的是,在上面的例子,我们使用了 `osr.SpatialReference.SetFromUserInput` 方法来设置目标投影,该方法可以根据用户输入的字符串自动识别投影坐标系。如果你已经知道目标投影的 EPSG 代码或 WKT 字符串,也可以使用 `osr.SpatialReference.ImportFromEPSG` 或 `osr.SpatialReference.ImportFromWkt` 方法来设置目标投影

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值