源项目地址:高斯投影: Gaussian_projection_coordinates (gitee.com)
git clone:
git clone git@gitee.com:yitian00/gaussian-projection.git
擅长或喜欢c++qt编程的可以前往:
主窗口
正算窗口
算法
子午线弧长公式:
代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Gaussian_projection_coordinates
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text != string.Empty && textBox2.Text != string.Empty&& textBox3.Text != string.Empty &&
textBox4.Text != string.Empty && textBox5.Text != string.Empty && textBox6.Text != string.Empty &&
textBox7.Text != string.Empty )
{
double a = 0, b = 0, e_2 = 0, e_dot_2 = 0, rou = 206264.806247096355;
int pp = 0;
if (radioButton1.Checked)
{
a = 6378245;//椭圆长半轴
b = 6356863.0187730473;//椭圆短半轴
e_2 = 0.006693421622966;//椭圆第一偏心率e^2
e_dot_2 = 0.006738525414683;//椭圆第二偏心率e'^2
pp = 1;
}
else if (radioButton2.Checked)//
{
a = 6378140;//椭圆长半轴
b = 6356755.2881575287;//椭圆短半轴
e_2 = 0.006694384999588;//椭圆第一偏心率e^2
e_dot_2 = 0.006739501819473;//椭圆第二偏心率e'^2
pp = 1;
}
else if (radioButton3.Checked)//
{
a = 6378137;//椭圆长半轴
b = 6356752.3142;//椭圆短半轴
e_2 = 0.00669437999013;//椭圆第一偏心率e^2
e_dot_2 = 0.00673949674227;//椭圆第二偏心率e'^2
pp = 1;
}
else if (radioButton4.Checked)//
{
a = 6378137;//椭圆长半轴
b = 6356752.3141;//椭圆短半轴
e_2 = 0.00669438002290;//椭圆第一偏心率e^2
e_dot_2 = 0.00673949677548;//椭圆第二偏心率e'^2
pp = 1;
}
else if (pp == 0)
{
MessageBox.Show("请选择椭球体", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
double c = a * a / b;
//转化为弧度制
double B = (Convert.ToDouble(textBox1.Text) + Convert.ToDouble(textBox2.Text) / 60 + Convert.ToDouble(textBox3.Text) / 3600) / 180 * Math.PI;
double L = (Convert.ToDouble(textBox4.Text) + Convert.ToDouble(textBox5.Text) / 60 + Convert.ToDouble(textBox6.Text) / 3600) / 180 * Math.PI;
double L0 = (Convert.ToDouble(textBox7.Text)) / 180 * Math.PI;
double W = Math.Sqrt(1 - e_2 * Math.Sin(B) * Math.Sin(B));
double V = Math.Sqrt(1 + e_dot_2 * Math.Cos(B) * Math.Cos(B));
double M = a * (1 - e_2) / (W * W * W);//子午圈曲率半径
double N = a / W;//卯酉圈曲率半径
double t= Math.Tan(B), n = e_dot_2 * Math.Cos(B) * Math.Cos(B);
double l = (L - L0) * rou;//单位弧度秒
//计算子午圈弧长
double A1 = 1 + 3 / 4 * e_2 + 45 / 64 * e_2 * e_2 + 175 / 256 * Math.Pow(e_2, 3) + 11025 / 16384 * Math.Pow(e_2, 4) + 43659 / 65536 * Math.Pow(e_2, 5);
double A2= 3 / 4 * e_2 + 15 / 16* e_2 * e_2 + 525/512 * Math.Pow(e_2, 3) + 2205/2048 * Math.Pow(e_2, 4) +72765/65536 * Math.Pow(e_2, 5);
double A3= 15 / 64 * e_2 * e_2 + 105/256 * Math.Pow(e_2, 3) + 2205 /4096 * Math.Pow(e_2, 4) + 10395/16384 * Math.Pow(e_2, 5);
double A4= 35/512 * Math.Pow(e_2, 3) + 315/2048 * Math.Pow(e_2, 4) + 31185/131072 * Math.Pow(e_2, 5);
double A5 = 315 / 16384 * Math.Pow(e_2, 4) + 3465 / 65536 * Math.Pow(e_2, 5);
double A6 = 693 / 131072 * Math.Pow(e_2, 5);
double a0 = A1 * a * (1 - e_2), a2 = -A2 / 2 * a * (1 - e_2), a4 = A3 / 4 * a * (1 - e_2), a6 = -A4 * a / 6 * (1 - e_2), a8 = A5 * a / 8 * (1 - e_2), a10 = -A6 * a / 10 * (1 - e_2);
double X = a0*B+a2*Math.Sin(2*B)+ a4 * Math.Sin(4* B)+ a6* Math.Sin(6 * B)+ a8 * Math.Sin(8 * B)+a10*Math.Sin(10*B);
double x = X + N * Math.Sin(B) * Math.Cos(B) * l * l / 2 / rou / rou +
N / 24 * Math.Sin(B) * Math.Pow(Math.Cos(B), 3) * (5 - t * t + 9 * n * n+4*Math.Pow(n,4)) * Math.Pow(l, 4) / Math.Pow(rou, 4)+
N*Math.Sin(B)*Math.Pow(Math.Cos(B),5)*(61-58*t*t+Math.Pow(t,4))*Math.Pow(l,6)/720/Math.Pow(rou,6) ;
double y = N * Math.Cos(B) * l / rou + N * Math.Pow(Math.Cos(B), 3) * (1 - t * t + n * n) * Math.Pow(l, 3) / 6 / Math.Pow(rou, 3)
+ N * Math.Pow(Math.Cos(B), 5) * (5 - 18 * t * t + Math.Pow(t, 4)) * Math.Pow(l, 5) / 120 / Math.Pow(rou, 5);
double gamma = Math.Sin(B) * l/rou + Math.Sin(B) * Math.Cos(B) * Math.Cos(B) * Math.Pow(l/rou, 3) / 3 * (1 + 3 * n * n + 2 * Math.Pow(n, 4)) +
Math.Sin(B) * Math.Pow(Math.Cos(B), 4) * Math.Pow(l/rou, 5) / 15 * (2 - t * t);//弧度制
gamma = gamma * 180 / Math.PI;//角度制
//打印
textBox8.Text = Convert.ToString(x);
textBox9.Text = Convert.ToString(y);
//子午线收敛角
textBox10.Text = Convert.ToString((int)(gamma));
textBox11.Text = Convert.ToString((int)((gamma -(int)(gamma)) * 60));
textBox12.Text = Convert.ToString(((gamma - (int)(gamma)) * 60 - (int)((gamma - (int)(gamma)) * 60)) * 60);
}
else
{
MessageBox.Show("请输入完整参数", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void button2_Click(object sender, EventArgs e)
{
textBox1.Text = string.Empty;
textBox2.Text = string.Empty;
textBox3.Text = string.Empty;
textBox4.Text = string.Empty;
textBox5.Text = string.Empty;
textBox6.Text = string.Empty;
textBox7.Text = string.Empty;
textBox8.Text = string.Empty;
textBox9.Text = string.Empty;
textBox10.Text = string.Empty;
textBox11.Text = string.Empty;
textBox12.Text = string.Empty;
}
}
}
反算及换带窗口
反算算法:
子午线弧长反算公式:
领带换算算法
代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Gaussian_projection_coordinates
{
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
}
//反算
private void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text != string.Empty && textBox2.Text != string.Empty && textBox3.Text != string.Empty)
{
double a = 0, b = 0, e_2 = 0, e_dot_2 = 0, rou = 206264.806247096355;
int pp = 0;
if (radioButton1.Checked)
{
a = 6378245;//椭圆长半轴
b = 6356863.0187730473;//椭圆短半轴
e_2 = 0.006693421622966;//椭圆第一偏心率e^2
e_dot_2 = 0.006738525414683;//椭圆第二偏心率e'^2
pp = 1;
}
else if (radioButton2.Checked)//
{
a = 6378140;//椭圆长半轴
b = 6356755.2881575287;//椭圆短半轴
e_2 = 0.006694384999588;//椭圆第一偏心率e^2
e_dot_2 = 0.006739501819473;//椭圆第二偏心率e'^2
pp = 1;
}
else if (radioButton3.Checked)//
{
a = 6378137;//椭圆长半轴
b = 6356752.3142;//椭圆短半轴
e_2 = 0.00669437999013;//椭圆第一偏心率e^2
e_dot_2 = 0.00673949674227;//椭圆第二偏心率e'^2
pp = 1;
}
else if (radioButton4.Checked)//
{
a = 6378137;//椭圆长半轴
b = 6356752.3141;//椭圆短半轴
e_2 = 0.00669438002290;//椭圆第一偏心率e^2
e_dot_2 = 0.00673949677548;//椭圆第二偏心率e'^2
pp = 1;
}
else if (pp == 0)
{
MessageBox.Show("请选择椭球体", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
double c = a * a / b;
//转化为弧度制
double x = Convert.ToDouble(textBox1.Text);
double y = Convert.ToDouble(textBox2.Text);
double L0 = Convert.ToDouble(textBox3.Text);
//子午线弧长求大地纬度(迭代法)
double Bf = x /111134.8611,cha;//单位度
double F = -16036.4803 * Math.Sin(2 * Bf/180*Math.PI) + 16.8281 * Math.Sin(4 * Bf / 180 * Math.PI) - 0.022 * Math.Sin(6 * Bf / 180 * Math.PI);
do
{
cha = Bf;
F = -16036.4803 * Math.Sin(2 * Bf / 180 * Math.PI) + 16.8281 * Math.Sin(4 * Bf / 180 * Math.PI) - 0.022 * Math.Sin(6 * Bf / 180 * Math.PI);
Bf = (x - F) /111134.8611;
} while (Math.Abs(cha - Bf) > 1e-8);
Bf = Bf / 180 * Math.PI;//单位弧度
double Wf = Math.Sqrt(1 - e_2 * Math.Sin(Bf) * Math.Sin(Bf));
double Vf = Math.Sqrt(1 + e_dot_2 * Math.Cos(Bf) * Math.Cos(Bf));
double Mf = a * (1 - e_2) / (Wf * Wf * Wf);
double Nf = a / Wf;
double tf = Math.Tan(Bf), nf = e_dot_2 * Math.Cos(Bf) * Math.Cos(Bf);
double gamma = rou * y * tf / Nf - rou * y * y * y * tf / 3 / Math.Pow(Nf, 3) * (1 + tf * tf - nf * nf) +
rou * Math.Pow(y, 5) * tf / 15 / Math.Pow(Nf, 5) * (2 + 5 * tf * tf + 3 * Math.Pow(tf, 4));//单位弧度秒
gamma = gamma * 180 / Math.PI/rou;//单位度
double B = Bf - tf * y * y / 2 / Mf / Math.Pow(Nf, 3) + tf * (5 + 3 * tf * tf + nf * nf - 9 * nf * nf * tf * tf) * Math.Pow(y, 4) / 24 / Mf / Math.Pow(Nf, 3) -
tf * (61 + 90 * tf * tf + 45 * Math.Pow(tf, 4)) * Math.Pow(y, 6) / 720 / Mf / Math.Pow(Nf, 5);
double l = y / Nf / Math.Cos(Bf) - (1 + 2 * tf * tf + nf * nf) * Math.Pow(y, 3) / 6 / Math.Cos(Bf) / Math.Pow(Nf, 3) +
(5 + 28 * tf * tf + 24 * Math.Pow(tf, 4) + 6 * nf * nf + 8 * tf * tf * nf * nf) * Math.Pow(y, 5) / 120 / Math.Cos(Bf) / Math.Pow(Nf, 5);
double L = l*180/Math.PI + L0;//单位度
B = B * 180 / Math.PI ;
//打印纬度
textBox9.Text = Convert.ToString(Math.Floor(B));
textBox8.Text = Convert.ToString(Math.Floor((B - Math.Floor(B)) * 60));
textBox7.Text = Convert.ToString(((B - Math.Floor(B)) * 60 - Math.Floor((B - Math.Floor(B)) * 60)) * 60);
//打印经度
textBox4.Text = Convert.ToString(Math.Floor(L));
textBox5.Text = Convert.ToString(Math.Floor((L- Math.Floor(L)) * 60));
textBox6.Text = Convert.ToString(((L - Math.Floor(L)) * 60 - Math.Floor((L - Math.Floor(L)) * 60)) * 60);
//打印子午线收敛角
textBox10.Text = Convert.ToString((int)(gamma));
textBox11.Text = Convert.ToString((int)((gamma - (int)(gamma)) * 60));
textBox12.Text = Convert.ToString(((gamma - (int)(gamma)) * 60 - (int)((gamma - (int)(gamma)) * 60)) * 60);
}
else
{
MessageBox.Show("请输入完整参数", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void button2_Click(object sender, EventArgs e)
{
textBox1.Text = string.Empty;
textBox2.Text = string.Empty;
textBox3.Text = string.Empty;
textBox4.Text = string.Empty;
textBox5.Text = string.Empty;
textBox6.Text = string.Empty;
textBox7.Text = string.Empty;
textBox8.Text = string.Empty;
textBox9.Text = string.Empty;
}
//换带
private void button3_Click(object sender, EventArgs e)
{
if (textBox1.Text != string.Empty && textBox2.Text != string.Empty && textBox3.Text != string.Empty && textBox13.Text != string.Empty)
{
double a = 0, b = 0, e_2 = 0, e_dot_2 = 0, rou = 206264.806247096355;
int pp = 0;
if (radioButton1.Checked)
{
a = 6378245;//椭圆长半轴
b = 6356863.0187730473;//椭圆短半轴
e_2 = 0.006693421622966;//椭圆第一偏心率e^2
e_dot_2 = 0.006738525414683;//椭圆第二偏心率e'^2
pp = 1;
}
else if (radioButton2.Checked)//
{
a = 6378140;//椭圆长半轴
b = 6356755.2881575287;//椭圆短半轴
e_2 = 0.006694384999588;//椭圆第一偏心率e^2
e_dot_2 = 0.006739501819473;//椭圆第二偏心率e'^2
pp = 1;
}
else if (radioButton3.Checked)//
{
a = 6378137;//椭圆长半轴
b = 6356752.3142;//椭圆短半轴
e_2 = 0.00669437999013;//椭圆第一偏心率e^2
e_dot_2 = 0.00673949674227;//椭圆第二偏心率e'^2
pp = 1;
}
else if (radioButton4.Checked)//
{
a = 6378137;//椭圆长半轴
b = 6356752.3141;//椭圆短半轴
e_2 = 0.00669438002290;//椭圆第一偏心率e^2
e_dot_2 = 0.00673949677548;//椭圆第二偏心率e'^2
pp = 1;
}
else if (pp == 0)
{
MessageBox.Show("请选择椭球体", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
double c = a * a / b;
//转化为弧度制
double x = Convert.ToDouble(textBox1.Text);
double y = Convert.ToDouble(textBox2.Text);
double L0 = Convert.ToDouble(textBox3.Text);
//子午线弧长求大地纬度(迭代法)
double Bf = x / 111134.8611, cha;//单位度
double F = -16036.4803 * Math.Sin(2 * Bf / 180 * Math.PI) + 16.8281 * Math.Sin(4 * Bf / 180 * Math.PI) - 0.022 * Math.Sin(6 * Bf / 180 * Math.PI);
do
{
cha = Bf;
F = -16036.4803 * Math.Sin(2 * Bf / 180 * Math.PI) + 16.8281 * Math.Sin(4 * Bf / 180 * Math.PI) - 0.022 * Math.Sin(6 * Bf / 180 * Math.PI);
Bf = (x - F) / 111134.8611;
} while (Math.Abs(cha - Bf) > 1e-8);
Bf = Bf / 180 * Math.PI;//单位弧度
double Wf = Math.Sqrt(1 - e_2 * Math.Sin(Bf) * Math.Sin(Bf));
double Vf = Math.Sqrt(1 + e_dot_2 * Math.Cos(Bf) * Math.Cos(Bf));
double Mf = a * (1 - e_2) / (Wf * Wf * Wf);
double Nf = a / Wf;
double tf = Math.Tan(Bf), nf = e_dot_2 * Math.Cos(Bf) * Math.Cos(Bf);
double gamma = rou * y * tf / Nf - rou * y * y * y * tf / 3 / Math.Pow(Nf, 3) * (1 + tf * tf - nf * nf) +
rou * Math.Pow(y, 5) * tf / 15 / Math.Pow(Nf, 5) * (2 + 5 * tf * tf + 3 * Math.Pow(tf, 4));//单位弧度秒
gamma = gamma * 180 / Math.PI / rou;//单位度
double B = Bf - tf * y * y / 2 / Mf / Math.Pow(Nf, 3) + tf * (5 + 3 * tf * tf + nf * nf - 9 * nf * nf * tf * tf) * Math.Pow(y, 4) / 24 / Mf / Math.Pow(Nf, 3) -
tf * (61 + 90 * tf * tf + 45 * Math.Pow(tf, 4)) * Math.Pow(y, 6) / 720 / Mf / Math.Pow(Nf, 5);
double l = y / Nf / Math.Cos(Bf) - (1 + 2 * tf * tf + nf * nf) * Math.Pow(y, 3) / 6 / Math.Cos(Bf) / Math.Pow(Nf, 3) +
(5 + 28 * tf * tf + 24 * Math.Pow(tf, 4) + 6 * nf * nf + 8 * tf * tf * nf * nf) * Math.Pow(y, 5) / 120 / Math.Cos(Bf) / Math.Pow(Nf, 5);
double L = l * 180 / Math.PI + L0;//单位度
B = B * 180 / Math.PI;
//打印纬度
textBox9.Text = Convert.ToString(Math.Floor(B));
textBox8.Text = Convert.ToString(Math.Floor((B - Math.Floor(B)) * 60));
textBox7.Text = Convert.ToString(((B - Math.Floor(B)) * 60 - Math.Floor((B - Math.Floor(B)) * 60)) * 60);
//打印经度
textBox4.Text = Convert.ToString(Math.Floor(L));
textBox5.Text = Convert.ToString(Math.Floor((L - Math.Floor(L)) * 60));
textBox6.Text = Convert.ToString(((L - Math.Floor(L)) * 60 - Math.Floor((L - Math.Floor(L)) * 60)) * 60);
//打印子午线收敛角
textBox10.Text = Convert.ToString((int)(gamma));
textBox11.Text = Convert.ToString((int)((gamma - (int)(gamma)) * 60));
textBox12.Text = Convert.ToString(((gamma - (int)(gamma)) * 60 - (int)((gamma - (int)(gamma)) * 60)) * 60);
//求新坐标的x,y
//转化为弧度制
B = B/ 180 * Math.PI;
L = L / 180 * Math.PI;
L0 = (Convert.ToDouble(textBox13.Text)) / 180 * Math.PI;
double W = Math.Sqrt(1 - e_2 * Math.Sin(B) * Math.Sin(B));
double V = Math.Sqrt(1 + e_dot_2 * Math.Cos(B) * Math.Cos(B));
double M = a * (1 - e_2) / (W * W * W);//子午圈曲率半径
double N = a / W;//卯酉圈曲率半径
double t = Math.Tan(B), n = e_dot_2 * Math.Cos(B) * Math.Cos(B);
l = (L - L0) * rou;//单位弧度秒
//计算子午圈弧长
double A1 = 1 + 3 / 4 * e_2 + 45 / 64 * e_2 * e_2 + 175 / 256 * Math.Pow(e_2, 3) + 11025 / 16384 * Math.Pow(e_2, 4) + 43659 / 65536 * Math.Pow(e_2, 5);
double A2 = 3 / 4 * e_2 + 15 / 16 * e_2 * e_2 + 525 / 512 * Math.Pow(e_2, 3) + 2205 / 2048 * Math.Pow(e_2, 4) + 72765 / 65536 * Math.Pow(e_2, 5);
double A3 = 15 / 64 * e_2 * e_2 + 105 / 256 * Math.Pow(e_2, 3) + 2205 / 4096 * Math.Pow(e_2, 4) + 10395 / 16384 * Math.Pow(e_2, 5);
double A4 = 35 / 512 * Math.Pow(e_2, 3) + 315 / 2048 * Math.Pow(e_2, 4) + 31185 / 131072 * Math.Pow(e_2, 5);
double A5 = 315 / 16384 * Math.Pow(e_2, 4) + 3465 / 65536 * Math.Pow(e_2, 5);
double A6 = 693 / 131072 * Math.Pow(e_2, 5);
double a0 = A1 * a * (1 - e_2), a2 = -A2 / 2 * a * (1 - e_2), a4 = A3 / 4 * a * (1 - e_2), a6 = -A4 * a / 6 * (1 - e_2), a8 = A5 * a / 8 * (1 - e_2), a10 = -A6 * a / 10 * (1 - e_2);
double X = a0 * B + a2 * Math.Sin(2 * B) + a4 * Math.Sin(4 * B) + a6 * Math.Sin(6 * B) + a8 * Math.Sin(8 * B) + a10 * Math.Sin(10 * B);
x = X + N * Math.Sin(B) * Math.Cos(B) * l * l / 2 / rou / rou +
N / 24 * Math.Sin(B) * Math.Pow(Math.Cos(B), 3) * (5 - t * t + 9 * n * n + 4 * Math.Pow(n, 4)) * Math.Pow(l, 4) / Math.Pow(rou, 4) +
N * Math.Sin(B) * Math.Pow(Math.Cos(B), 5) * (61 - 58 * t * t + Math.Pow(t, 4)) * Math.Pow(l, 6) / 720 / Math.Pow(rou, 6);
y = N * Math.Cos(B) * l / rou + N * Math.Pow(Math.Cos(B), 3) * (1 - t * t + n * n) * Math.Pow(l, 3) / 6 / Math.Pow(rou, 3)
+ N * Math.Pow(Math.Cos(B), 5) * (5 - 18 * t * t + Math.Pow(t, 4)) * Math.Pow(l, 5) / 120 / Math.Pow(rou, 5);
gamma = Math.Sin(B) * l / rou + Math.Sin(B) * Math.Cos(B) * Math.Cos(B) * Math.Pow(l / rou, 3) / 3 * (1 + 3 * n * n + 2 * Math.Pow(n, 4)) +
Math.Sin(B) * Math.Pow(Math.Cos(B), 4) * Math.Pow(l / rou, 5) / 15 * (2 - t * t);//弧度制
gamma = gamma * 180 / Math.PI ;//单位度
//打印新坐标
textBox15.Text = Convert.ToString(x);
textBox14.Text = Convert.ToString(y);
//打印新子午线收敛角
textBox18.Text = Convert.ToString( (int) gamma);
textBox17.Text = Convert.ToString((int)((gamma - (int)(gamma)) * 60));
textBox16.Text = Convert.ToString(((gamma - (int)(gamma)) * 60 - (int)((gamma - (int)(gamma)) * 60)) * 60);
}
else
{
MessageBox.Show("请输入完整参数", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}