GPS网的基线计算以及平差处理(使用Python绘制误差椭圆,C++处理数据并输出Qxx矩阵)

这篇具有很好参考价值的文章主要介绍了GPS网的基线计算以及平差处理(使用Python绘制误差椭圆,C++处理数据并输出Qxx矩阵)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

题目如下:

  如下图所示为一简单GPS网,用两台GPS接收机观测,测得5条基线向量,每一条基线向量中三个坐标差观测值相关,由于只用两台GPS接收机观测,所以各观测基线向量互相独立。观测基线向量信息见表1。假定1号点为起算点坐标信息表2。

GPS网的基线计算以及平差处理(使用Python绘制误差椭圆,C++处理数据并输出Qxx矩阵)

 表1 GPS网平差观测数据及已知方差阵

GPS网的基线计算以及平差处理(使用Python绘制误差椭圆,C++处理数据并输出Qxx矩阵)

表2 GPS网平差起算数据

点号

X

Y

Z

LC01

-1974638.7340

4590014.8190

3953144.9235

要求:1)基于Matlab或其他编程语言(如C++等)编程实现该GPS网间接平差过程通用程序,包括误差方程、法方程的组成与解算。得出平差后各基线向量观测值的平差值及各待定点的坐标平差值;评定各待定点坐标平差值的精度,绘制其误差椭圆。给出程序设计思路、流程图、程序代码和计算结果。

基本原理

1.间接平差方法

  间接平差法是通过选定t个与观测值有一定关系的独立未知量作为参数,将每个观测值都分别表达成这t个参数的函数,建立函数模型,按最小二乘原理,用求函数极值的方法解出参数的最或然值,从而求得各观测值的平差值。

GPS网的基线计算以及平差处理(使用Python绘制误差椭圆,C++处理数据并输出Qxx矩阵)

GPS网的基线计算以及平差处理(使用Python绘制误差椭圆,C++处理数据并输出Qxx矩阵)

2.条件平差原理

GPS网的基线计算以及平差处理(使用Python绘制误差椭圆,C++处理数据并输出Qxx矩阵)

GPS网的基线计算以及平差处理(使用Python绘制误差椭圆,C++处理数据并输出Qxx矩阵)

程序实现:

1.数据文件准备:

  数据文件包括四个部分:文件头,已知点数据、基线数据和闭合环的序号(条件平差)

  首先,文件头只有一行,并以空格或制表符隔开,包括已知点数量、未知点数量、基线数量。然后是已知点数据行数与头文件中已知点数量相同,每一行存储一个点的点名,X坐标、Y坐标和Z坐标,以空格或制表符隔开。最后是基线数据,其行数与头文件中基线数量相同,包含起点点名、终点点名、X坐标差、Y坐标差、Z坐标差和基线方差阵,以空格或制表符隔开。

  间接平差文件结构设计如图: 

 GPS网的基线计算以及平差处理(使用Python绘制误差椭圆,C++处理数据并输出Qxx矩阵)

2.程序设计结构(C++)

GPS网的基线计算以及平差处理(使用Python绘制误差椭圆,C++处理数据并输出Qxx矩阵)

 程序运行流程图

3.代码块讲解

 1)新建了一个名为GPSnet.cpp的文件,其中包含Points结构体,GPSline结构体和一个GPSnet类,来存储GPS网相关数据和相关属性。

#include<iostream>
#include<fstream>
#include<string>
#include <map>
#include <Eigen/Dense>
using std::string;
using namespace std;
using namespace::Eigen;//引入Eigen 使用Eigen命名空间
struct Point
{
	string pointName;//点名
	int pointNum = -1;//点号
	double x = 0, y = 0, z = 0;//点的xyz坐标
	bool known = false;//该点是否已知坐标或者近似坐标,先赋值为false为未知点
};
struct GPSline
{
	//基线结构体,包含起点、终点和基线的xyz测量坐标差
	Point begin;
	Point end;
	double dx;
	double dy;
	double dz;
};

在GPSnet中存储了相应的代码进行运算,其中生成P阵的代码为

//读取基线数据,并计算出权阵P
	for (int i = 0; i < observation_num; i++)
	{
		ifs >> lines[i].begin.pointName >> lines[i].end.pointName
			>> lines[i].dx >> lines[i].dy >> lines[i].dz;
		lines[i].begin.known = false;
		lines[i].end.known = false;
		ifs >> P(i * 3 + 0, i * 3 + 0) >> P(i * 3 + 0, i * 3 + 1) >> P(i * 3 + 0, i * 3 + 2)
			>> P(i * 3 + 1, i * 3 + 0) >> P(i * 3 + 1, i * 3 + 1) >> P(i * 3 + 1, i * 3 + 2)
			>> P(i * 3 + 2, i * 3 + 0) >> P(i * 3 + 2, i * 3 + 1) >> P(i * 3 + 2, i * 3 + 2);
	}

生成B阵的代码为:

//计算每个点的近似坐标
	while (true)
	{
		//循环结束标志,初值为true,若该次循环没有计算近似坐标,循环结束
		bool success = true;
		for (int i = 0; i < observation_num; i++)
		{
			//第一种情况:起点坐标已知,终点未知,则终点坐标=起点坐标+(deltax,deltay,deltaz)
			if (lines[i].begin.known == true && lines[i].end.known == false)
			{
				lines[i].end.x = lines[i].begin.x + lines[i].dx;//赋值
				lines[i].end.y = lines[i].begin.y + lines[i].dy;
				lines[i].end.z = lines[i].begin.z + lines[i].dz;
				//为GPS网络中,所有与该终点名称相同的点赋值
				for (int j = 0; j < observation_num; j++)
				{
					if (lines[j].end.pointName == lines[i].end.pointName)
					{
						lines[j].end.known = true;//赋为已知点
						lines[j].end.pointNum = lines[i].end.pointNum;//赋值点号
						lines[j].end.x = lines[i].end.x;
						lines[j].end.y = lines[i].end.y;
						lines[j].end.z = lines[i].end.z;
					}
					if (lines[j].begin.pointName == lines[i].end.pointName)
					{
						lines[j].begin.known = true;
						lines[j].begin.pointNum = lines[i].end.pointNum;
						lines[j].begin.x = lines[i].end.x;
						lines[j].begin.y = lines[i].end.y;
						lines[j].begin.z = lines[i].end.z;
					}

				}
				lines[i].end.known = true;//判断其是否已经接受过处理
				success = false;
			}
			//第二种情况:起点坐标未知,终点已知,计算相关的近似坐标,两个过程相似,复制粘贴后进行相关整理
			if (lines[i].begin.known == false && lines[i].end.known == true)
			{
				//为起点坐标赋值
				lines[i].begin.x = lines[i].end.x - lines[i].dx;
				lines[i].begin.y = lines[i].end.y - lines[i].dy;
				lines[i].begin.z = lines[i].end.z - lines[i].dz;
				//为GPS网络中,所有与该起点名称相同的点赋值
				for (int j = 0; j < observation_num; j++)
				{
					if (lines[j].begin.pointName == lines[i].begin.pointName)
					{
						lines[j].begin.known = true;
						lines[j].begin.pointNum = lines[i].begin.pointNum;
						lines[j].begin.x = lines[i].begin.x;
						lines[j].begin.y = lines[i].begin.y;
						lines[j].begin.z = lines[i].begin.z;//与上述内容类似
					}
					if (lines[j].end.pointName == lines[i].begin.pointName)
					{
						lines[j].end.known = true;
						lines[j].end.pointNum = lines[i].begin.pointNum;
						lines[j].end.x = lines[i].begin.x;
						lines[j].end.y = lines[i].begin.y;
						lines[j].end.z = lines[i].begin.z;
					}
				}
				lines[i].begin.known = true;
				success = false;
			}
		}
		if (success == true)
			break;//当以上过程结束,将会结束循环
	}

	//计算b、l矩阵
	for (int i = 0; i < observation_num; i++)
	{
		int beginIndex = lines[i].begin.pointNum - (known_point_num - 1) - 1;//设置开始点号的index
		int endIndex = lines[i].end.pointNum - (known_point_num - 1) - 1;//设置结束点好的index
		if (beginIndex >= 0)//当其发现起始点index为正数时,给矩阵相关元素赋值-1
		{
			B(3 * i + 0, 3 * beginIndex + 0) = -1;
			B(3 * i + 1, 3 * beginIndex + 1) = -1;
			B(3 * i + 2, 3 * beginIndex + 2) = -1;
		}
		if (endIndex >= 0)//当其发现终点index为正数时,给矩阵相关元素赋值1
		
		{
			B(3 * i + 0, 3 * endIndex + 0) = 1;
			B(3 * i + 1, 3 * endIndex + 1) = 1;
			B(3 * i + 2, 3 * endIndex + 2) = 1;
		}
		l(3 * i + 0, 0) = lines[i].dx - (lines[i].end.x - lines[i].begin.x);//给l赋值,组成l阵
		l(3 * i + 1, 0) = lines[i].dy - (lines[i].end.y - lines[i].begin.y);//观测值减去近似坐标的值为l阵
		l(3 * i + 2, 0) = lines[i].dz - (lines[i].end.z - lines[i].begin.z);
	}
	x = (B.transpose() * P * B).inverse() * B.transpose() * P * l;
	v = B * x - l;
}

输出控制台函数为:

//输出解算结果到控制台
void GPSnet::print()
{
	MatrixXd Qxx = (B.transpose() * P * B).inverse();
	cout << "*******************平差结果*******************" << endl;
	cout << "P:" << endl << P << endl;
	cout << "B:" << endl << B << endl;
	cout << "l:" << endl << l << endl;
	cout << "x:" << endl << x << endl;
	cout << "v:" << endl << v << endl;
	cout << "观测值平差值"<<endl;
	for (int i = 0; i < observation_num; i++)
	{
		cout  << lines[i].dx + v(i * 3 + 0, 0) <<endl<<  lines[i].dy + v(i * 3 + 1, 0)<<endl << lines[i].dz + v(i * 3 + 2, 0) << endl;
	}
	cout << "\n\n\n*******************精度评定*******************" << endl;
	cout << "Qxx:" << endl << (B.transpose() * P * B).inverse() << endl;
	cout << "单位权中误差:" <<endl<< sqrt((v.transpose() * P * v)(0, 0) / 3)<< "m"<<endl<< sqrt((v.transpose() * P * v)(0, 0) / 3)*100<<"cm";

}

将Nbb阵放入文件方法代码如下:

void GPSnet::calculation() {
	ofstream ofs1;//新建文件输出流
	ofs1.open("./Qxx&sigma output.txt", ios::out);
	MatrixXd Qxx = (B.transpose() * P * B).inverse();//计算Qxx阵,方便元素取出
	double sigma = sqrt((v.transpose() * P * v)(0, 0) / 3);//单位权中误差获取
	ofs1 << nuknown_point_num << endl ;//取出未知点
	ofs1 << sigma << endl;//取出单位权中误差
	for (int i = 0; i < 3 * nuknown_point_num; i++) {
		for (int j = 0; j < 3 * nuknown_point_num; j++) {
			if (j != 3 * nuknown_point_num - 1) {
				ofs1 << Qxx(i, j) << " ";//取出所有元素,以方阵的形式取出,并写入到文件中,在main.py处绘制误差椭圆
			}
			else {
				ofs1 << Qxx(i, j) << endl;//取出元素
			}
			
		}

	}
	
}

完整代码如下:

//作者:Henry Yang 
//山东科技大学
//测量平差课程设计之GPS网平差通用程序
//ver1.0.1
#include<iostream>
#include<fstream>
#include<string>
#include <map>
#include <Eigen/Dense>
using std::string;
using namespace std;
using namespace::Eigen;//引入Eigen 使用Eigen命名空间
struct Point
{
	string pointName;//点名
	int pointNum = -1;//点号
	double x = 0, y = 0, z = 0;//点的xyz坐标
	bool known = false;//该点是否已知坐标或者近似坐标,先赋值为false为未知点
};
struct GPSline
{
	//基线结构体,包含起点、终点和基线的xyz测量坐标差
	Point begin;
	Point end;
	double dx;
	double dy;
	double dz;
};

//GPS网类
class GPSnet
{
private:

	GPSline* lines;	//基线数组,存储每一条基线信息
	Point* knownPoints;//已知点数组,存储已知点信息
	map<string, int>dic;//字典,key为点名,value为点号
	MatrixXd B;//系数矩阵
	MatrixXd l;//l
	MatrixXd P;//权阵P
	MatrixXd v;//改正数矩阵v
	MatrixXd x;//改正数矩阵x
	int known_point_num, nuknown_point_num, observation_num;//已知点数目、未知点数目、基线数目


public:

	GPSnet();
	void loadData(string filePath);//计算主体函数
	void print();//控制台输出相关信息
	void calculation();//输出未知点数目,单位权中误差,Qxx阵
	~GPSnet();//析构函数

};
//空白构造
GPSnet::GPSnet()
{

}
void GPSnet::loadData(string filePath)
{
	//读取数据文件
	ifstream ifs(filePath);
	//读取已知点数目、未知点数目、基线数目
	ifs >> known_point_num >> nuknown_point_num >> observation_num;
	//初始化类的属性
	lines = new GPSline[observation_num];
	knownPoints = new Point[known_point_num];
	B = MatrixXd::Zero(observation_num * 3, nuknown_point_num * 3);//初始化B阵
	l = MatrixXd::Random(observation_num * 3, 1);//初始化l阵
	P = MatrixXd::Zero(observation_num * 3, observation_num * 3);//初始化P阵
	//读取已知点信息到knownPoints数组和dic字典
	for (int i = 0; i < known_point_num; i++)
	{
		ifs >> knownPoints[i].pointName >> knownPoints[i].x >> knownPoints[i].y >> knownPoints[i].z;
		knownPoints[i].known = true;
		knownPoints[i].pointNum = i;
		dic[knownPoints[i].pointName] = i;
	}
	//读取基线数据,并计算出权阵P
	for (int i = 0; i < observation_num; i++)
	{
		ifs >> lines[i].begin.pointName >> lines[i].end.pointName
			>> lines[i].dx >> lines[i].dy >> lines[i].dz;
		lines[i].begin.known = false;
		lines[i].end.known = false;
		ifs >> P(i * 3 + 0, i * 3 + 0) >> P(i * 3 + 0, i * 3 + 1) >> P(i * 3 + 0, i * 3 + 2)
			>> P(i * 3 + 1, i * 3 + 0) >> P(i * 3 + 1, i * 3 + 1) >> P(i * 3 + 1, i * 3 + 2)
			>> P(i * 3 + 2, i * 3 + 0) >> P(i * 3 + 2, i * 3 + 1) >> P(i * 3 + 2, i * 3 + 2);
	}
	P = P.inverse();





	//向基线数组填入已知点数据
	for (int i = 0; i < observation_num; i++)
	{
		if (!(dic.find(lines[i].begin.pointName) == dic.end()))
		{
			lines[i].begin.known = true;//设置线的起始点属性为已知点
			for (int j = 0; j < known_point_num; j++)
			{
				if (knownPoints[j].pointName == lines[i].begin.pointName)
				{
					lines[i].begin.x = knownPoints[j].x;
					lines[i].begin.y = knownPoints[j].y;
					lines[i].begin.z = knownPoints[j].z;
				}
			}
		}
		if (!(dic.find(lines[i].end.pointName) == dic.end()))
		{
			lines[i].end.known = true;//设置线的终点属性为已知点
			for (int j = 0; j < known_point_num; j++)
			{
				if (knownPoints[j].pointName == lines[i].end.pointName)
				{
					lines[i].end.x = knownPoints[j].x;
					lines[i].end.y = knownPoints[j].y;
					lines[i].end.z = knownPoints[j].z;
				}
			}
		}
	}
	//然后为已知点、未知点编号,按数字由小到大,已知点在前,未知点在后
	int sortedNum = known_point_num - 1;
	for (int i = 0; i < observation_num; i++)
	{
		if (!(dic.find(lines[i].begin.pointName) == dic.end()))//当在dic中能够找到起始点的时候
			lines[i].begin.pointNum = dic[lines[i].begin.pointName];//将点号赋值给begin、否则重新赋给新的值
		else
		{
			dic[lines[i].begin.pointName] = sortedNum + 1;
			sortedNum++;
			for (int i = 0; i < observation_num; i++)
			{
				if (!(dic.find(lines[i].begin.pointName) == dic.end()))//当能在dic中能够找到相关点之后,给其赋值
					lines[i].begin.pointNum = dic[lines[i].begin.pointName];
				if (!(dic.find(lines[i].end.pointName) == dic.end()))
					lines[i].end.pointNum = dic[lines[i].end.pointName];
			}
		}
		if (!(dic.find(lines[i].end.pointName) == dic.end()))//当在dic中能够找到未知点的时候
			lines[i].end.pointNum = dic[lines[i].end.pointName];//将点号码赋值给end,否则重新赋值
		else
		{
			dic[lines[i].end.pointName] = sortedNum + 1;
			sortedNum++;
			for (int i = 0; i < observation_num; i++)
			{
				if (!(dic.find(lines[i].begin.pointName) == dic.end()))
					lines[i].begin.pointNum = dic[lines[i].begin.pointName];
				if (!(dic.find(lines[i].end.pointName) == dic.end()))
					lines[i].end.pointNum = dic[lines[i].end.pointName];
			}
		}
	}



	//计算每个点的近似坐标
	while (true)
	{
		//循环结束标志,初值为true,若该次循环没有计算近似坐标,循环结束
		bool success = true;
		for (int i = 0; i < observation_num; i++)
		{
			//第一种情况:起点坐标已知,终点未知,则终点坐标=起点坐标+(deltax,deltay,deltaz)
			if (lines[i].begin.known == true && lines[i].end.known == false)
			{
				lines[i].end.x = lines[i].begin.x + lines[i].dx;//赋值
				lines[i].end.y = lines[i].begin.y + lines[i].dy;
				lines[i].end.z = lines[i].begin.z + lines[i].dz;
				//为GPS网络中,所有与该终点名称相同的点赋值
				for (int j = 0; j < observation_num; j++)
				{
					if (lines[j].end.pointName == lines[i].end.pointName)
					{
						lines[j].end.known = true;//赋为已知点
						lines[j].end.pointNum = lines[i].end.pointNum;//赋值点号
						lines[j].end.x = lines[i].end.x;
						lines[j].end.y = lines[i].end.y;
						lines[j].end.z = lines[i].end.z;
					}
					if (lines[j].begin.pointName == lines[i].end.pointName)
					{
						lines[j].begin.known = true;
						lines[j].begin.pointNum = lines[i].end.pointNum;
						lines[j].begin.x = lines[i].end.x;
						lines[j].begin.y = lines[i].end.y;
						lines[j].begin.z = lines[i].end.z;
					}

				}
				lines[i].end.known = true;//判断其是否已经接受过处理
				success = false;
			}
			//第二种情况:起点坐标未知,终点已知,计算相关的近似坐标,两个过程相似,复制粘贴后进行相关整理
			if (lines[i].begin.known == false && lines[i].end.known == true)
			{
				//为起点坐标赋值
				lines[i].begin.x = lines[i].end.x - lines[i].dx;
				lines[i].begin.y = lines[i].end.y - lines[i].dy;
				lines[i].begin.z = lines[i].end.z - lines[i].dz;
				//为GPS网络中,所有与该起点名称相同的点赋值
				for (int j = 0; j < observation_num; j++)
				{
					if (lines[j].begin.pointName == lines[i].begin.pointName)
					{
						lines[j].begin.known = true;
						lines[j].begin.pointNum = lines[i].begin.pointNum;
						lines[j].begin.x = lines[i].begin.x;
						lines[j].begin.y = lines[i].begin.y;
						lines[j].begin.z = lines[i].begin.z;//与上述内容类似
					}
					if (lines[j].end.pointName == lines[i].begin.pointName)
					{
						lines[j].end.known = true;
						lines[j].end.pointNum = lines[i].begin.pointNum;
						lines[j].end.x = lines[i].begin.x;
						lines[j].end.y = lines[i].begin.y;
						lines[j].end.z = lines[i].begin.z;
					}
				}
				lines[i].begin.known = true;
				success = false;
			}
		}
		if (success == true)
			break;//当以上过程结束,将会结束循环
	}

	//计算b、l矩阵
	for (int i = 0; i < observation_num; i++)
	{
		int beginIndex = lines[i].begin.pointNum - (known_point_num - 1) - 1;//设置开始点号的index
		int endIndex = lines[i].end.pointNum - (known_point_num - 1) - 1;//设置结束点好的index
		if (beginIndex >= 0)//当其发现起始点index为正数时,给矩阵相关元素赋值-1
		{
			B(3 * i + 0, 3 * beginIndex + 0) = -1;
			B(3 * i + 1, 3 * beginIndex + 1) = -1;
			B(3 * i + 2, 3 * beginIndex + 2) = -1;
		}
		if (endIndex >= 0)//当其发现终点index为正数时,给矩阵相关元素赋值1
		
		{
			B(3 * i + 0, 3 * endIndex + 0) = 1;
			B(3 * i + 1, 3 * endIndex + 1) = 1;
			B(3 * i + 2, 3 * endIndex + 2) = 1;
		}
		l(3 * i + 0, 0) = lines[i].dx - (lines[i].end.x - lines[i].begin.x);//给l赋值,组成l阵
		l(3 * i + 1, 0) = lines[i].dy - (lines[i].end.y - lines[i].begin.y);//观测值减去近似坐标的值为l阵
		l(3 * i + 2, 0) = lines[i].dz - (lines[i].end.z - lines[i].begin.z);
	}
	x = (B.transpose() * P * B).inverse() * B.transpose() * P * l;
	v = B * x - l;
}

//输出解算结果到控制台
void GPSnet::print()
{
	MatrixXd Qxx = (B.transpose() * P * B).inverse();
	cout << "*******************平差结果*******************" << endl;
	cout << "P:" << endl << P << endl;
	cout << "B:" << endl << B << endl;
	cout << "l:" << endl << l << endl;
	cout << "x:" << endl << x << endl;
	cout << "v:" << endl << v << endl;
	cout << "观测值平差值"<<endl;
	for (int i = 0; i < observation_num; i++)
	{
		cout  << lines[i].dx + v(i * 3 + 0, 0) <<endl<<  lines[i].dy + v(i * 3 + 1, 0)<<endl << lines[i].dz + v(i * 3 + 2, 0) << endl;
	}
	cout << "\n\n\n*******************精度评定*******************" << endl;
	cout << "Qxx:" << endl << (B.transpose() * P * B).inverse() << endl;
	cout << "单位权中误差:" <<endl<< sqrt((v.transpose() * P * v)(0, 0) / 3)<< "m"<<endl<< sqrt((v.transpose() * P * v)(0, 0) / 3)*100<<"cm";

}
void GPSnet::calculation() {
	ofstream ofs1;//新建文件输出流
	ofs1.open("./Qxx&sigma output.txt", ios::out);
	MatrixXd Qxx = (B.transpose() * P * B).inverse();//计算Qxx阵,方便元素取出
	double sigma = sqrt((v.transpose() * P * v)(0, 0) / 3);//单位权中误差获取
	ofs1 << nuknown_point_num << endl ;//取出未知点
	ofs1 << sigma << endl;//取出单位权中误差
	for (int i = 0; i < 3 * nuknown_point_num; i++) {
		for (int j = 0; j < 3 * nuknown_point_num; j++) {
			if (j != 3 * nuknown_point_num - 1) {
				ofs1 << Qxx(i, j) << " ";//取出所有元素,以方阵的形式取出,并写入到文件中,在main.py处绘制误差椭圆
			}
			else {
				ofs1 << Qxx(i, j) << endl;//取出元素
			}
			
		}

	}
	
}


GPSnet::~GPSnet()
{
	delete[] lines;
	delete[] knownPoints;
}
extern "C" {//计划将其转化为.so文件方便Python调用,失败。
	int main() {
		//调用类
		GPSnet net;                          //创建GPSnet对象
		net.loadData("./data1.txt");    //导入数据文件
		net.print();                         //控制台输出解算结果
		net.calculation();                   //输出相应文件
		return 0;
	}
}

绘制误差椭圆(Python实现)

  该程序使用C++生成的结果,绘制误差椭圆,使用numpy和matplotlib,绘制相关图。

import math

from matplotlib.patches import Ellipse
import matplotlib.pyplot as plt
import numpy as np

file = open("GPSnet\\test\\Qxx&sigma output.txt", "r")# 读取权阵和单位权中误差
unknown_points_num = int(file.readline())
sigma = float(file.readline())#获得单位权中误差
Qxx = []
for i in range(0, 3 * unknown_points_num):
  arr = []
  arr = file.readline().split(" ")
  arr1 = [x.strip() for x in arr if x.strip() != '\n']  # 去掉读取中产生的换行符
  arr2 = [float(x) for x in arr1]
  Qxx.append(arr2)
MatQxx = np.mat(Qxx)  # 生成矩阵
j = 0
for i in range(0, unknown_points_num):
  cut = np.zeros((3, 3))
  cut = MatQxx[i + j:i + j + 2, i + j:i + j + 2]#将矩阵分块
  j = j + 2
  Qxx = float(cut[0, 0])#矩阵重新赋值
  Qyy = float(cut[1, 1])
  Qxy = float(cut[0, 1])
  fi = math.atan(2 * Qxy / (Qxx - Qyy)) / 2
  E = 0.5 * pow(sigma, 2) * (Qxx + Qyy + math.sqrt(pow(Qxx - Qyy, 2) + 4 * pow(Qxy, 2)))#计算最大最小值
  F = 0.5 * pow(sigma, 2) * (Qxx + Qyy + math.sqrt(pow(Qxx - Qyy, 2) - 4 * pow(Qxy, 2)))
  fig = plt.figure()#创建plt对象
  ax = fig.add_subplot(111)
  print(math.degrees(fi))
  ell1 = Ellipse(xy=(0.0, 0.0), width=2 * math.sqrt(E), height=2 * math.sqrt(F), angle=math.degrees(fi),color="blue")#绘制椭圆 长半轴 短半轴设置,设置偏移角度,换算成角度值(degrees)
  ax.add_patch(ell1)#在图中添加椭圆对象
  x, y = 0, 0#设置坐标轴坐标
  ax.plot(x, y, 'ro')
  plt.savefig("{}.jpg".format(i))#存储到根目录中

得到结果如下:

GPS网的基线计算以及平差处理(使用Python绘制误差椭圆,C++处理数据并输出Qxx矩阵)GPS网的基线计算以及平差处理(使用Python绘制误差椭圆,C++处理数据并输出Qxx矩阵)

学习不易,如有转载,请与作者联系。文章来源地址https://www.toymoban.com/news/detail-437718.html

到了这里,关于GPS网的基线计算以及平差处理(使用Python绘制误差椭圆,C++处理数据并输出Qxx矩阵)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 使用TransBigData快速高效地处理、分析、挖掘出租车GPS数据

    TransBigData是一个为交通时空大数据处理、分析和可视化而开发的Python包。TransBigData为处理常见的交通时空大数据(如出租车GPS数据、共享单车数据和公交车GPS数据等)提供了快速而简洁的方法。TransBigData为交通时空大数据分析的各个阶段提供了多种处理方法,代码简洁、高效、

    2024年02月14日
    浏览(49)
  • 解放计算力:使用并行处理提升python for循环速度

    Python 是一门功能强大的编程语言,但在处理大规模数据或复杂计算任务时,性能可能成为一个瓶颈。幸运的是,Python 提供了多种方法来提升性能,其中之一是利用并行处理来加速循环操作。本文将介绍如何使用并行处理技术来优化 for 循环,从而提高 Python 程序的执行速度。

    2024年02月10日
    浏览(50)
  • 网络基础静态综合实验,使用eNSP模拟给公司内网配置IP,路由。并连接到外网的以及服务端与客户端的远程登录和通信的综合实验。

    实验拓扑及要求图 实验给出网段为192.168.1.0/24,基于此网段进行IP规划。 一、看到拓扑中有6段骨干网段,以及需要配置8段环回地址的网段,将192.168.1.0/24先分为8个子网段,其中192.168.1.00000000/27用于配置骨干网段IP。 192.168.1.00100000/27    192.168.1.01000000/27   192.168.1.01100000/27  

    2024年02月20日
    浏览(42)
  • 金浪路由器上不了网的原因以及解决办法

        一、首先检查是否存在连接故障,进入与路由器相连的电脑的设备管理器,检查是否已经正确安装了电脑网卡,如果发现有故障,尝试重新安装网卡,主要是查看是否是网卡驱动装错了,这种情况不多,但也不容易被发现,可以从官网上下载对应的驱动重新装一遍,以确

    2024年02月05日
    浏览(49)
  • 单片机处理GPS模块信息

    1.GPS信息获取(串口中断执行) 2.由经纬度计算两点距离 理论说明 已知两点经纬度计算距离的具体例子球是一个近乎标准的椭球体,它的赤道半径为6378.140千米,极半径为 6356.755千米,平均半径6371.004千米。如果我们假设地球是一个完美的球体,那么它的半径就是地球的平均半径

    2024年01月22日
    浏览(34)
  • 手机无线网络连接上但上不了网的原因以及解决方法汇总

    昨天在家里设置无线网,明明手机连上了但是就是不能上网,今天小编就为大家带来手机无线网络连接上但上不了网的原因以及解决方法汇总,需要的朋友可以一起看看?此篇教程从IP设置方面帮你解决这个问题。前提是您有无线网的正确密码,且宽带没有欠费。 手机无线网

    2024年02月08日
    浏览(46)
  • STM32基于HAL解析GPS经度纬度以及时间

    第一步:打开CubeMX工具: 第二步:创建一个工程:搜索一下需要的芯片。  第三步:配置调试器 第四步:配置时钟 第五步: 配置时钟树,在下图所示出输入,点击回车即可。  第六步:配置串口  第七步: 第二部分: 代码编写 第一步:定义一个用于存放经度纬度的缓存

    2024年04月08日
    浏览(66)
  • 计算机颜色学---CIE 色度图以及饱和度处理

    了解颜色相关理论与成像知识,对于深入了解视觉相关算法与ISP算法而言十分重要,了解颜色理论,离不开CIE色度图; CIE 1931 Yxy色度图。外形形似马蹄,所以也叫“马蹄图”; 在色度图中,x,y为横纵坐标,其中,横坐标的定义是: x = X X + Y + Z x=frac{X}{X+Y+Z} x = X + Y + Z X ​

    2024年02月09日
    浏览(44)
  • transbigdata 笔记:官方文档案例1(出租车GPS数据处理)

    官方文档中给定的出租车数据在transbigdata/docs/source/gallery/data/TaxiData-Sample.csv at main · ni1o1/transbigdata (github.com)     transbigdata笔记:数据预处理-CSDN博客 transbigdata笔记:数据预处理-CSDN博客 异常记录点,指的是记录点前后的出租车状态(有乘客/无乘客)和自己的出租车状态不一

    2024年01月21日
    浏览(50)
  • 全国大数据与计算智能挑战赛:面向低资源的命名实体识别基线方案,排名13/64,组织单位:(大数据与决策实验室)

    NLP专栏简介:数据增强、智能标注、意图识别算法|多分类算法、文本信息抽取、多模态信息抽取、可解释性分析、性能调优、模型压缩算法等 专栏详细介绍:NLP专栏简介:数据增强、智能标注、意图识别算法|多分类算法、文本信息抽取、多模态信息抽取、可解释性分析、性

    2024年02月13日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包