高斯正反算—投影坐标转大地坐标、大地坐标转投影坐标(附有完整代码及测试结果)

简介: 高斯正反算—投影坐标转大地坐标、大地坐标转投影坐标(附有完整代码及测试结果)

 本文意在介绍高斯正反算的基本原理和代码实现!针对高斯正反算网上给出的方法很多,但是我试了之后发现多少都有些问题:或公式原理问题、或精度问题!


       通过查找资料对其进行了总结与测试!原理!代码!测试结果!本文都一一给出,此外本文还对常见坐标系:北京54、西安80、WGS84、CGCS2000等坐标系的高斯转换都做出了实现并使用 QT 进行封装可视化!


       对比公式和代码实现可快速理解高斯正反算!


       精度可达 0.0001!堪称最全公式原理总结!


       坐标转换整套流程包括:像素坐标转投影坐标、投影坐标转大地坐标、大地坐标转空间直角坐标、七参数转换、空间直角坐标转大地坐标、大地坐标转投影坐标、投影坐标转像素坐标; 本人均已实现,且每一个环节都已经过测试、如有需要欢迎在下方留言评论!!!


一、常用椭球参数


北京54坐标系

西安80坐标系

WGS坐标系

CGC2000坐标系

a

6378245.0000000000

6378140.0000000000

6378137.0000000000

6378137.0000000000

b

6356863.0187730473

6356755.2881575287

6356752.3142

6356752.314

f

1/298.3

1/298.257

1/298.257223563

1/298.257222101

c

6399698.9017827110

6399596.6519880105

6399593.6258

6399593.6259

e1

0.006693421622966

0.006694384999588

0.00669437999013

0.00669438002290

e2

0.006738525414683

0.006739501819473

0.00673949674227

0.00673949677548

67e22ae233b34f19ace3889620988c56.png


二、高斯正反算原理


1、高斯正算(大地坐标转投影坐标)


a87a0b19ade44bb1aa9da7547feb8927.png

408442ead7554277937e47593a468fba.png


2、高斯反算(投影坐标转大地坐标)


d89a632471a2407daf815a50d472c0d2.png

8008c498d56b44ad8460f0e536867e32.png

4abda227c4764ed881b2260d8d14c333.png


三、高斯正反算代码实现


#include<iostream>
#include<cmath>
#include "stdio.h"
#define pi 3.141592653589793238463
#define p0 206264.8062470963551564
//wgs84参考椭球
const double e = 0.00669438002290;
const double e1 = 0.00673949677548;
const double b = 6356752.3141;
const double a = 6378137.0;
using namespace std;
//大地坐标转投影坐标
void DadiPoint2ProjectPoint(double B, double L)
{
    //把度转化为弧度
    B = B * pi / 180;
    L = L * pi / 180;
    double N, t, n, c, V, Xz, m1, m2, m3, m4, m5, m6, a0, a2, a4, a6, a8, M0, M2, M4, M6, M8, x0, y0, l;
    int L_num;
    double L_center;
    //中央子午线经度,6°带
    L_num = (int)(L * 180 / pi / 6.0) + 1;
    L_center = 6 * L_num - 3;
    //中央子午线经度,3°带
    //L_num = (int)(L * 180 / pi / 3.0 + 0.5);
    //L_center = 3 * L_num;         
    l = (L / pi * 180 - L_center) * 3600; //求带号、中央经线、经差
    M0 = a * (1 - e);
    M2 = 3.0 / 2.0 * e * M0;
    M4 = 5.0 / 4.0 * e * M2;
    M6 = 7.0 / 6.0 * e * M4;
    M8 = 9.0 / 8.0 * e * M6;
    a0 = M0 + M2 / 2.0 + 3.0 / 8.0 * M4 + 5.0 / 16.0 * M6 + 35.0 / 128.0 * M8;
    a2 = M2 / 2.0 + M4 / 2 + 15.0 / 32.0 * M6 + 7.0 / 16.0 * M8;
    a4 = M4 / 8.0 + 3.0 / 16.0 * M6 + 7.0 / 32.0 * M8;
    a6 = M6 / 32.0 + M8 / 16.0;
    a8 = M8 / 128.0;
    Xz = a0 * B - a2 / 2.0 * sin(2 * B) + a4 / 4.0 * sin(4 * B) - a6 / 6.0 * sin(6 * B) + a8 / 8.0 * sin(8 * B);  //计算子午线弧长
    c = a * a / b;
    V = sqrt(1 + e1 * cos(B) * cos(B));
    N = c / V;
    t = tan(B);
    n = e1 * cos(B) * cos(B);
    m1 = N * cos(B);
    m2 = N / 2.0 * sin(B) * cos(B);
    m3 = N / 6.0 * pow(cos(B), 3) * (1 - t * t + n);
    m4 = N / 24.0 * sin(B) * pow(cos(B), 3) * (5 - t * t + 9 * n);
    m5 = N / 120.0 * pow(cos(B), 5) * (5 - 18 * t * t + pow(t, 4) + 14 * n - 58 * n * t * t);
    m6 = N / 720.0 * sin(B) * pow(cos(B), 5) * (61 - 58 * t * t + pow(t, 4));
    x0 = Xz + m2 * l * l / pow(p0, 2) + m4 * pow(l, 4) / pow(p0, 4) + m6 * pow(l, 6) / pow(p0, 6);
    y0 = m1 * l / p0 + m3 * pow(l, 3) / pow(p0, 3) + m5 * pow(l, 5) / pow(p0, 5);   //计算x y坐标
    double x = x0;
    //double y = y0 + 500000 + 1000000 * L_num;    //化为国家统一坐标
    double y = y0 + 500000;     //化为国家统一坐标
    cout << "方法一 x=" << x << endl;
    cout << "方法一 y=" << y << endl;
}
//投影坐标转大地坐标
void ProjectPoint2DadiPoint(double x, double y, double l0)
{
    //l0为中央经度
    double Bf, B0, FBf, M, N, V, t, n, c, y1, n1, n2, n3, n4, n5, n6, a0, a2, a4, a6, M0, M2, M4, M6, M8, l;
    int L_num, L_center;
    L_num = (int)(x / 1000000.0);
    y1 = y - 500000;
    //y1 = y - 500000 - L_num * 1000000;
    //L_center = ((L_num + 1) * 6 - 3)*pi*180;    //中央子午线经度,6°带
    //cout<<"L_center="<<L_center<<endl;
    //L_center = L_num * 3;     //中央子午线经度,3°带
    M0 = a * (1 - e);
    M2 = 3.0 / 2.0 * e * M0;
    M4 = 5.0 / 4.0 * e * M2;
    M6 = 7.0 / 6.0 * e * M4;
    M8 = 9.0 / 8.0 * e * M6;
    a0 = M0 + M2 / 2.0 + 3.0 / 8.0 * M4 + 5.0 / 16.0 * M6 + 35.0 / 128.0 * M8;
    a2 = M2 / 2.0 + M4 / 2 + 15.0 / 32.0 * M6 + 7.0 / 16.0 * M8;
    a4 = M4 / 8.0 + 3.0 / 16.0 * M6 + 7.0 / 32.0 * M8;
    a6 = M6 / 32.0 + M8 / 16.0;
    cout << "a0=" << a0 << endl;
    cout << "a2=" << a2 << endl;
    cout << "a4=" << a4 << endl;
    cout << "a6=" << a6 << endl;
    Bf = x / a0;
    B0 = Bf;
    cout<<"B0="<<B0<<endl;
     cout<<"sin(2 * B0)="<<sin(2 * B0)/2<<endl;
    while ((fabs(Bf - B0) > 0.0000001) || (B0 == Bf))
    {
        B0 = Bf;
        FBf = -a2 / 2.0 * sin(2 * B0) + a4 / 4.0 * sin(4 * B0) - a6 / 6.0 * sin(6 * B0);
        Bf = (x - FBf) / a0;
    }    //迭代求数值为x坐标的子午线弧长对应的底点纬度
    cout<<"Bf="<<Bf<<endl;
    t = tan(Bf);                            //一样
    c = a * a / b;
    V = sqrt(1 + e1 * cos(Bf) * cos(Bf));   //一样
    N = c / V;                              //一样
    M = c / pow(V, 3);                      //一样
    n = e1 * cos(Bf) * cos(Bf);             //一样(为n的平方)
    n1 = 1 / (N * cos(Bf));
    n2 = -t / (2.0 * M * N);
    n3 = -(1 + 2 * t * t + n) / (6.0 * pow(N, 3) * cos(Bf));
    n4 = t * (5 + 3 * t * t + n - 9 * n * t * t) / (24.0 * M * pow(N, 3));
    n5 = (5 + 28 * t * t + 24 * pow(t, 4) + 6 * n + 8 * n * t * t) / (120.0 * pow(N, 5) * cos(Bf));
    n6 = -t * (61 + 90 * t * t + 45 * pow(t, 4)) / (720.0 * M * pow(N, 5));
    //秒
    double B = (Bf + n2 * y1 * y1 + n4 * pow(y1, 4) + n6 * pow(y1, 6)) / pi * 180;
    double L0=l0;
    l = n1 * y1 + n3 * pow(y1, 3) + n5 * pow(y1, 5);
    //double L = L_center + l / pi * 180;    //反算得大地经纬度
    double L = L0 + l / pi * 180;    //反算得大地经纬度
    cout << "方法一 B=" << B << endl;
    cout << "方法一 L=" << L << endl;
}

说明:高斯正算中的输入为度;


四、高斯正反算结果


1、已知旧坐标系投影坐标数据


1e7dae8a6ffd4675bcc1fbca536da093.png


2、高斯反算(投影坐标转大地坐标)


085ff93cdb8e4046bbad0dbd13b0da37.png


3、高斯正算(大地坐标转投影坐标)


d82dc6c01d1b46609c00f3d529732ade.png

说明:高斯正反算经度由上述转换结果对比可知;


常见坐标系:北京54、西安80、WGS84、CGCS2000等坐标系的高斯转换都做出了实现并使用 QT 进行封装可视化:高斯正反算设计实现!!!-C++文档类资源-CSDN下载


坐标转换整套流程包括:像素坐标转投影坐标、投影坐标转大地坐标、大地坐标转空间直角坐标、七参数转换、空间直角坐标转大地坐标、大地坐标转投影坐标、投影坐标转像素坐标; 本人均已实现,且每一个环节都已经过测试、如有需要欢迎在下方留言评论!!!

相关文章
|
14天前
|
SQL JavaScript 前端开发
基于Python访问Hive的pytest测试代码实现
根据《用Java、Python来开发Hive应用》一文,建立了使用Python、来开发Hive应用的方法,产生的代码如下
45 6
基于Python访问Hive的pytest测试代码实现
|
16天前
|
测试技术 UED
软件测试的艺术:从代码到品质的探索之旅
在数字时代的浪潮中,软件已成为我们生活和工作不可或缺的一部分。然而,高质量的软件背后隐藏着一门鲜为人知的艺术——软件测试。本文将带你走进这门艺术的世界,从基础理论到实践应用,一起探索如何通过软件测试保障产品质量,提升用户体验,并最终实现从代码到品质的华丽转变。
|
9天前
|
敏捷开发 安全 测试技术
软件测试的艺术:从代码到用户体验的全方位解析
本文将深入探讨软件测试的重要性和实施策略,通过分析不同类型的测试方法和工具,展示如何有效地提升软件质量和用户满意度。我们将从单元测试、集成测试到性能测试等多个角度出发,详细解释每种测试方法的实施步骤和最佳实践。此外,文章还将讨论如何通过持续集成和自动化测试来优化测试流程,以及如何建立有效的测试团队来应对快速变化的市场需求。通过实际案例的分析,本文旨在为读者提供一套系统而实用的软件测试策略,帮助读者在软件开发过程中做出更明智的决策。
|
14天前
|
SQL JavaScript 前端开发
基于Java访问Hive的JUnit5测试代码实现
根据《用Java、Python来开发Hive应用》一文,建立了使用Java、来开发Hive应用的方法,产生的代码如下
46 6
|
15天前
|
测试技术 持续交付
软件测试的艺术:从代码到信心的旅程
探索软件测试不仅仅是发现错误的技术过程,它是一场从编码到用户信心的转化之旅。本文将带你了解如何通过创造性思维和系统方法,将软件测试变成一门艺术,确保产品质量的同时,提升用户对技术的信赖。
33 4
|
19天前
|
人工智能 计算机视觉
AI计算机视觉笔记十五:编写检测的yolov5测试代码
该文为原创文章,如需转载,请注明出处。本文作者在成功运行 `detect.py` 后,因代码难以理解而编写了一个简易测试程序,用于加载YOLOv5模型并检测图像中的对象,特别是“人”类目标。代码实现了从摄像头或图片读取帧、进行颜色转换,并利用YOLOv5进行推理,最后将检测框和置信度绘制在输出图像上,并保存为 `result.jpg`。如果缺少某些模块,可使用 `pip install` 安装。如涉及版权问题或需获取完整代码,请联系作者。
|
1天前
|
机器学习/深度学习 敏捷开发 测试技术
软件测试的艺术:从代码到用户心灵的旅程
在阅读本文之前,让我们先共同思考一个问题:“为什么即使是最小的错误,也可能对用户体验和企业声誉造成巨大的影响?” 正如我们将要探讨的,软件测试不仅是技术活动的一种,更是确保产品质量、优化用户体验和维持品牌声誉的关键步骤。本文将引导您了解软件测试的基本概念,探索其背后的艺术性,以及如何高效地实施测试策略来达到最佳的质量保证结果。
6 0
|
23天前
|
敏捷开发 安全 测试技术
软件测试的艺术:从代码到信心的旅程
在数字时代的浪潮中,软件成为我们日常生活和工作不可或缺的一部分。然而,高质量的软件背后隐藏着一群默默无闻的英雄——软件测试工程师。本文将带你一探究竟,软件测试不仅仅是找出错误的技术活动,它更是一门确保产品质量、提升用户信心的艺术。我们将从测试的重要性出发,探索不同的测试类型,深入理解测试用例的设计,并讨论如何通过持续集成和自动化测试来提高效率。无论你是软件开发者还是对软件质量感兴趣的读者,这篇文章都将为你提供新的视角和深入的洞见。
|
27天前
|
测试技术 C# 开发者
“代码守护者:详解WPF开发中的单元测试策略与实践——从选择测试框架到编写模拟对象,全方位保障你的应用程序质量”
【8月更文挑战第31天】单元测试是确保软件质量的关键实践,尤其在复杂的WPF应用中更为重要。通过为每个小模块编写独立测试用例,可以验证代码的功能正确性并在早期发现错误。本文将介绍如何在WPF项目中引入单元测试,并通过具体示例演示其实施过程。首先选择合适的测试框架如NUnit或xUnit.net,并利用Moq模拟框架隔离外部依赖。接着,通过一个简单的WPF应用程序示例,展示如何模拟`IUserRepository`接口并验证`MainViewModel`加载用户数据的正确性。这有助于确保代码质量和未来的重构与扩展。
29 0
|
27天前
|
数据库 测试技术 开发者
Play Framework的测试魔法:让代码在舞台上翩翩起舞,确保应用质量的幕后英雄!
【8月更文挑战第31天】Play Framework不仅以其高效开发与部署流程著称,还内置了强大的测试工具,提供全面的测试支持,确保应用高质量和稳定性。本文将详细介绍如何在Play Framework中进行单元测试和集成测试,涵盖`WithApplication`、`WithServer`及`WithDatabase`等类的使用方法,并通过示例代码手把手教你如何利用Play的测试框架。无论是单元测试、集成测试还是数据库操作测试,Play Framework均能轻松应对,助你提升应用质量和开发效率。
26 0