一、SpatialData
/// <summary>
/// 单像片数据类
/// </summary>
class PhotoData
{
/// <summary>
/// 像片内外方位元素
/// </summary>
// 内方位元素
public double f;
public double x;
public double y;
// 外方位线元素
public double Xs;
public double Ys;
public double Zs;
// 外方位角元素
public double p;
public double w;
public double k;
//旋转矩阵元素
public double a1, a2, a3, b1, b2, b3, c1, c2, c3;
// 像空间辅助坐标(u,v,w)
public double u, v, w_;
}
/// <summary>
/// 输出数据类
/// </summary>
class OutData
{
// 摄影测量基线分量
public double Bu, Bv, Bw;
// 投影系数
public double N1, N2;
// 地面坐标
public double X, Y, Z;
}
二、AuxCalcul
/// <summary>
/// 辅助方法
/// </summary>
class AuxCalcul
{
/// <summary>
/// 角度转弧度公式
/// </summary>
/// <param name="dms">角度值</param>
/// <returns></returns>
public static double DMS2Rad(double dms)
{
double rad = dms * Math.PI / 180;
return rad;
}
}
三、Spintersec
class Spintersec
{
/// <summary>
/// 计算旋转矩阵元素
/// </summary>
/// <param name="phtodata"></param>
public static void RotaMatirx(PhotoData photo)
{
// 角度值
double p = photo.p;
double w = photo.w;
double k = photo.k;
double cos_p = Math.Cos(p);
double sin_p = Math.Sin(p);
double cos_w = Math.Cos(w);
double sin_w = Math.Sin(w);
double cos_k = Math.Cos(k);
double sin_k = Math.Sin(k);
// 算法实现
photo.a1 = cos_p * cos_k - cos_p * sin_w * sin_k;
photo.a2 = -cos_p * sin_k - sin_p * sin_w * sin_k;
photo.a3 = -sin_p * cos_w;
photo.b1 = cos_w * sin_k;
photo.b2 = cos_w * cos_k;
photo.b3 = -sin_w;
photo.c1 = sin_p * cos_k + cos_p * sin_w * sin_k;
photo.c2 = -sin_w * cos_k + cos_p * sin_w * sin_k;
photo.c3 = cos_p * cos_w;
}
/// <summary>
/// 计算像空间辅助坐标
/// </summary>
/// <param name="phtodata"></param>
public static void Auxcoord(PhotoData phtodata)
{
phtodata.u = phtodata.a1 * phtodata.x + phtodata.a2 * phtodata.y + phtodata.a3 * (-phtodata.f);
phtodata.v = phtodata.b1 * phtodata.x + phtodata.b2 * phtodata.y + phtodata.b3 * (-phtodata.f);
phtodata.w_ = phtodata.c1 * phtodata.x + phtodata.c2 * phtodata.y + phtodata.c3 * (-phtodata.f);
}
/// <summary>
/// 计算摄影基线分量
/// </summary>
/// <param name="photo1"></param>
/// <param name="photo2"></param>
/// <param name="outData"></param>
public static void PhotoBaseline(PhotoData photo1,PhotoData photo2,OutData outData)
{
outData.Bu = photo2.Xs - photo1.Xs;
outData.Bv = photo1.Ys - photo2.Ys;
outData.Bw = photo1.Zs - photo2.Zs;
}
/// <summary>
/// 计算投影系数
/// </summary>
/// <param name="photo1"></param>
/// <param name="photo2"></param>
/// <param name="outData"></param>
public static void ProjectConf(PhotoData photo1,PhotoData photo2,OutData outData)
{
outData.N1 = (outData.Bu * photo2.w_ - outData.Bw * photo2.u) / (photo1.u*photo2.w_ -photo2.u*photo1.w_);
outData.N2 = (outData.Bu * photo1.w_ - outData.Bw * photo1.u) / (photo1.u * photo2.w_ - photo2.u * photo1.w_);
}
/// <summary>
/// 计算地理坐标XYZ
/// </summary>
/// <param name="photo1"></param>
/// <param name="photo2"></param>
/// <param name="outData"></param>
public static void GeoXYz(PhotoData photo1, PhotoData photo2, OutData outData)
{
outData.X = photo1.Xs + outData.N1 * photo1.u;
outData.Y = 0.5 * ((photo1.Ys + outData.N1 * photo1.v) + (photo2.Ys + outData.N2 * photo2.v));
outData.Z = photo1.Zs + outData.N1 * photo1.w_;
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/74d652cc520386ae9b14dc97f91846da.png)
四、Form
public partial class Form1 : Form
{
// 声明变量
PhotoData photo1 = new PhotoData();
PhotoData photo2 = new PhotoData();
OutData outData = new OutData();
bool is_Read = false;
// 主函数
public Form1()
{
InitializeComponent();
}
/// <summary>
/// 打开数据文件并获取像片内方位元素
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void 打开文件ToolStripMenuItem_Click(object sender, EventArgs e)
{
// 临时存储变量
string SpData = null;
// 打开文件选择器
OpenFileDialog op = new OpenFileDialog();
op.Filter = "txt|*.txt";
op.ShowDialog();
// 读取文件
using (StreamReader reader = new StreamReader(op.FileName))
{
SpData = reader.ReadToEnd();
}
// 处理读取数据
string[] temp = SpData.Split(new char[] { ' ', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
// 像片1
photo1.Xs = double.Parse(temp[0].Trim());textBox_xs1.Text = temp[0].Trim();
photo1.Ys = double.Parse(temp[1].Trim());textBox_ys1.Text = temp[1].Trim();
photo1.Zs = double.Parse(temp[2].Trim());textBox_zs1.Text = temp[2].Trim(); // 外方位线元素
photo1.p = AuxCalcul.DMS2Rad( double.Parse(temp[3].Trim()));textBox_p1.Text = temp[3].Trim();
photo1.w = AuxCalcul.DMS2Rad(double.Parse(temp[4].Trim())); textBox_w1.Text = temp[4].Trim();
photo1.k = AuxCalcul.DMS2Rad(double.Parse(temp[5].Trim())); textBox_k1.Text = temp[5].Trim();//外方位角元素
photo1.x = double.Parse(temp[6].Trim()); textBox_x1.Text = temp[6].Trim();
photo1.y = double.Parse(temp[7].Trim()); textBox_y1.Text = temp[7].Trim();
photo1.f = double.Parse(temp[8].Trim()); textBox_f1.Text = temp[8].Trim();// 内方位元素
// 像片2
photo2.Xs = double.Parse(temp[9].Trim()); textBox_xs2.Text = temp[9].Trim();
photo2.Ys = double.Parse(temp[10].Trim()); textBox_ys2.Text = temp[10].Trim();
photo2.Zs = double.Parse(temp[11].Trim()); textBox_zs2.Text = temp[11].Trim();// 外方位线元素
photo2.p = AuxCalcul.DMS2Rad(double.Parse(temp[12].Trim())); textBox_p2.Text = temp[12].Trim();
photo2.w = AuxCalcul.DMS2Rad(double.Parse(temp[13].Trim())); textBox_w2.Text = temp[13].Trim();
photo2.k = AuxCalcul.DMS2Rad(double.Parse(temp[14].Trim())); textBox_k2.Text = temp[14].Trim();//外方位角元素
photo2.x = double.Parse(temp[15].Trim()); textBox_x2.Text = temp[15].Trim();
photo2.y = double.Parse(temp[16].Trim()); textBox_y2.Text = temp[16].Trim();
photo2.f = double.Parse(temp[17].Trim()); textBox_f2.Text = temp[17].Trim(); // 内方位元素
// 修改状态栏提示
toolStripStatusLabel2.Text = "文件读取成功!请核对~";
// isread
is_Read = true;
}
private void 开始计算ToolStripMenuItem_Click(object sender, EventArgs e)
{
if (is_Read == true)
{
// 计算旋转矩阵参数
Spintersec.RotaMatirx(photo1); Spintersec.RotaMatirx(photo2);
// 计算空间辅助坐标
Spintersec.Auxcoord(photo1); Spintersec.Auxcoord(photo2);
textBox_u1.Text = photo1.u.ToString(); textBox_v1.Text = photo1.v.ToString(); textBox_w_1.Text = photo1.w_.ToString();
textBox_u2.Text = photo2.u.ToString(); textBox_v2.Text = photo2.v.ToString(); textBox_w_2.Text = photo2.w_.ToString();
// 计算 摄影基线分量
Spintersec.PhotoBaseline(photo1, photo2, outData);
// 计算投影系数
Spintersec.ProjectConf(photo1, photo2, outData);
textBox_N1.Text = outData.N1.ToString(); textBox_N2.Text = outData.N2.ToString();
// 计算地面坐标
Spintersec.GeoXYz(photo1, photo2, outData);
textBox_X.Text = outData.X.ToString();
textBox_Y.Text = outData.Y.ToString();
textBox_Z.Text = outData.Z.ToString();
// 修改状态栏提示
toolStripStatusLabel2.Text = "数据计算成功!请核对~";
}
else
{
MessageBox.Show("请先打开文件!");
}
is_Read = false;
}
private void 退出程序ToolStripMenuItem_Click(object sender, EventArgs e)
{
System.Environment.Exit(0);
}
}