/// <summary> /// 提取观测量的权逆阵。是否只提取对角阵?? /// </summary> /// <param name="fileA"></param> /// <param name="fileB"></param> /// <returns></returns> public static double[][] GetCovaMatrixOfObs(SinexFile fileA, SinexFile fileB) { int paramCountA = fileA.EstimateParamCount; int row = paramCountA + fileB.EstimateParamCount; double[][] array = MatrixUtil.Create(row); //fileA直接设置。 //这里应该定权! SinexStatistic statisticA = fileA.GetStatistic(); SinexStatistic statisticB = fileB.GetStatistic(); SinexStatistic statisticNew = SinexStatistic.Merge(statisticA, statisticB); double varFactorA = statisticNew.VarianceOfUnitWeight / statisticA.VarianceOfUnitWeight; double varFactorB = statisticNew.VarianceOfUnitWeight / statisticB.VarianceOfUnitWeight; double[][] matrixA = fileA.GetEstimateCovaMatrix(); double[][] matrixB = fileB.GetEstimateCovaMatrix(); MatrixUtil.Multiply(matrixA, varFactorA); MatrixUtil.Multiply(matrixB, varFactorB); MatrixUtil.SetSubMatrix(array, matrixA); MatrixUtil.SetSubMatrix(array, matrixB, paramCountA, paramCountA); return(array); }
private void Read() { string pathA = this.textBox_PathA.Text; if (!File.Exists(pathA)) { FormUtil.ShowFileNotExistBox(pathA); return; } string pathB = this.textBox_PathB.Text; if (!File.Exists(pathB)) { FormUtil.ShowFileNotExistBox(pathB); return; } fileA = SinexReader.Read(pathA); this.textBox_sinexA.Text = fileA.ToString(); List <SinexSiteDetail> listA = fileA.GetSinexSites(); this.bindingSourceA.DataSource = listA; fileB = SinexReader.Read(pathB); this.textBox_sinexB.Text = fileB.ToString(); List <SinexSiteDetail> listB = fileB.GetSinexSites(); this.bindingSourceB.DataSource = listB; this.bindingSourceC.DataSource = SinexSiteDetail.Compare(listA, listB); }
/// <summary> /// 从 Sinex 文件中提取 XYZ 坐标。 /// </summary> /// <param name="Site"></param> /// <param name="path"></param> /// <returns></returns> public static List <XYZ> GetEstXYZ(string[] Site, string path = "D:\\Test\\igs13p17212.SNX") { SinexFile pubSinexFile = SinexReader.Read(path); List <string> pubSiteCode = pubSinexFile.GetSiteCods(); double[] pubAllEst = pubSinexFile.GetEstimateVector(); int m = Site.Length; List <XYZ> pubXYZ = new List <XYZ>(); for (int i = 0; i < m; i++) { string item = Site[i]; for (int j = 0; j < pubSiteCode.Count; j++) { if (pubSiteCode[j].ToUpper() == item.ToUpper()) { XYZ xyz = new XYZ(); xyz.Site = item; xyz.X = pubAllEst[3 * j + 0]; xyz.Y = pubAllEst[3 * j + 1]; xyz.Z = pubAllEst[3 * j + 2]; pubXYZ.Add(xyz); } } } return(pubXYZ); }
private void button_merge_Click(object sender, EventArgs e) { SinexFile fileMerged = null; foreach (var item in this.textBox_pathes.Lines) { SinexFile file = SinexReader.Read(item); if (fileMerged == null) { fileMerged = file; } else { fileMerged = SinexMerger.Merge(fileMerged, file, this.checkBox_eraseNonCoord.Checked); } } if (checkBox_showresult.Checked) { this.textBox_result.Text = fileMerged.ToString(); } File.WriteAllText(this.textBox_savepath.Text, fileMerged.ToString()); Geo.Utils.FormUtil.ShowIfOpenDirMessageBox(this.textBox_savepath.Text); }
public SinexSubNetsUnion(SinexFile fileA, SinexFile fileB) { this.fileA = fileA; this.fileB = fileB; double[][] apriori = Adjust(fileA, fileB); BuildResultSinex(fileA, fileB, apriori); }
/// <summary> /// 坐标解析 /// </summary> /// <param name="path"></param> /// <returns></returns> public static List <NamedXyz> GetCoords(string path) { try { string extension = Path.GetExtension(path).ToLower(); switch (extension) { case ".snx": SinexFile fileA = SinexReader.Read(path, true); return(fileA.GetSiteEstimatedCoords()); case ".xls": return(NamedXyz.ReadNamedXyz(path)); case ".txt": return(NamedXyz.ReadNamedXyztxt(path)); case ".org": GamitOrgFileService service = new GamitOrgFileService(path); return(service.GetNamedXyzs()); case ".rep": var p = new PinnacleRepFileService(path); return(p.GetNamedXyzs()); case ".pos": //"Rtklib 结果|*.pos { var pp = Gnsser.Interoperation.RtkpostResult.Load(path); return(pp.GetNamedXyzs()); } case ".clk": case ".clk_30s": case ".clk_05s": ClockFileHeader a = ClockFileReader.ReadHeader(path); List <NamedXyz> results = new List <NamedXyz>(); foreach (var item in a.ClockSolnStations) { NamedXyz bb = new NamedXyz(); bb.Name = item.Name; bb.Value = item.XYZ; results.Add(bb); } return(results); default: break; } return(new List <NamedXyz>()); }catch (Exception ex) { new Log(ex.Message).Error(ex.Message + ", 解析出错!"); return(new List <NamedXyz>()); } }
private void button_read_Click(object sender, EventArgs e) { string path = this.textBox_Path.Text; if (!File.Exists(path)) { FormUtil.ShowFileNotExistBox(path); return; } file = SinexReader.Read(path, this.checkBox_notReadMatix.Checked); ShowFile(); }
private void button_merge_Click(object sender, EventArgs e) { SinexFile a = SinexReader.ParseText(this.textBox_A.Text); SinexFile b = SinexReader.ParseText(this.textBox_B.Text); SinexFile c = SinexMerger.Merge(a, b); if (checkBox_show.Checked) { this.textBox_C.Text = c.ToString(); } File.WriteAllText(this.textBox_mergePath.Text, c.ToString()); Geo.Utils.FormUtil.ShowIfOpenDirMessageBox(this.textBox_mergePath.Text); }
/// <summary> /// 根据两个Sinex文件,提取系数阵。就是参数平差的参数系数阵。 /// Get coe Of Params Matrix Of Params /// </summary> /// <param name="fileA"></param> /// <param name="fileB"></param> /// <returns></returns> public static double[][] GetCoeffMatrixOfParams(SinexFile fileA, SinexFile fileB) { List <string> paramCodes = SinexFile.GetDistinctSiteCodes(fileA, fileB); List <string> codesA = fileA.GetSiteCods(); List <string> codesB = fileB.GetSiteCods(); List <int> sameParamIndexesInB = new List <int>();//B文件中具有相同测站的代码的索引号。 for (int i = 0; i < codesB.Count; i++) { if (codesA.Contains(codesB[i])) { sameParamIndexesInB.Add(i); } } int paramCountA = fileA.EstimateParamCount; //文件A的参数,一个测站有三个参数X,Y,Z int row = paramCountA + fileB.EstimateParamCount; //观测数量包含A和B int col = paramCodes.Count * 3; //新参数数量(除去了A,B共有参数) double[][] array = MatrixUtil.Create(row, col); int indentCount = 0;//有多少参数相同,则缩进多少位置 for (int i = 0; i < paramCountA; i++) { array[i][i] = 1; //先A } for (int i = paramCountA; i < row; i++) //再B { int siteIndexInB = (i - paramCountA) / 3; //测站名在B中的索引 if (sameParamIndexesInB.Contains(siteIndexInB)) { int colInA = codesA.IndexOf(codesB[siteIndexInB]) * 3;//在A中的索引 array[i][colInA] = 1; array[++i][colInA + 1] = 1; array[++i][colInA + 2] = 1; indentCount += 3;//一个测站缩进三单位 } else { array[i][i - indentCount] = 1; } } return(array); }
private void button_extractcoords_Click(object sender, EventArgs e) { sinexfile = SinexReader.Read(textBox_sinexFile.Text); List <string> sites = sinexfile.GetSiteCods(); double[] CoordArray = sinexfile.GetEstimateVector(); sitecood = new Dictionary <string, xyzblh>(); for (int i = 0; i < sites.Count; i++) { string tmpsite = sites[i]; XYZ tmpxyz = new XYZ(CoordArray[3 * i + 0], CoordArray[3 * i + 1], CoordArray[3 * i + 2]); GeoCoord tmplonlat = CoordTransformer.XyzToGeoCoord(tmpxyz, Ellipsoid.WGS84); if (!sitecood.Keys.Contains(tmpsite)) { sitecood.Add(tmpsite, new xyzblh()); sitecood[tmpsite].truexyz = tmpxyz; sitecood[tmpsite].lon = tmplonlat.Lon; sitecood[tmpsite].lat = tmplonlat.Lat; } } SavePath = this.textBox_uotputpath.Text + "\\sinexcoord" + ".txt"; //"C:\\Users\\lilinyang\\Desktop\\sinexcoord" + ".txt"; FileInfo aFile = new FileInfo(SavePath); StreamWriter SW = aFile.CreateText(); System.Globalization.NumberFormatInfo GN = new System.Globalization.CultureInfo("zh-CN", false).NumberFormat; GN.NumberDecimalDigits = 6; foreach (var item in sitecood) { SW.Write(item.Key.ToString()); SW.Write(" "); SW.Write(item.Value.truexyz.X.ToString()); SW.Write(" "); SW.Write(item.Value.truexyz.Y.ToString()); SW.Write(" "); SW.Write(item.Value.truexyz.Z.ToString()); SW.Write(" "); SW.Write(item.Value.lon.ToString()); SW.Write(" "); SW.Write(item.Value.lat.ToString()); SW.Write("\n"); } SW.Close(); }
private void Read() { string[] filePathes = this.textBox_Path.Lines; List <SinexFile> sinexFiles = SinexReader.Read(filePathes); current = null; foreach (var item in sinexFiles) { if (current == null) { current = item; } else { SinexSubNetsUnion just = new SinexSubNetsUnion(current, item); current = just.ResultSinexFile; } } this.textBox_info.Text = current.ToString(); }
/// <summary> /// 依据输入和平差信息,构建平差结果Sinex文件 /// </summary> /// <param name="fileA"></param> /// <param name="fileB"></param> /// <param name="apriori"></param> private void BuildResultSinex(SinexFile fileA, SinexFile fileB, double[][] apriori) { //统计信息 SinexStatistic stat = SinexStatistic.Merge(fileA.GetStatistic(), fileB.GetStatistic()); stat.NumberOfDegreesOfFreedom = p.Freedom; stat.NumberOfObservations = p.ObsMatrix.Observation.Count; stat.NumberOfUnknown = p.ParamCount; stat.VarianceOfUnitWeight = p.VarianceOfUnitWeight; result.SolutionStattisticsBlock.Items = stat.GetSolutionStatistics(); //先验值 result.SolutionAprioriBlock.Items.AddRange(fileA.SolutionAprioriBlock.Items); foreach (var item in fileB.SolutionAprioriBlock.Items) { if (!result.SolutionAprioriBlock.Items.Contains(item)) { result.SolutionAprioriBlock.Items.Add(item); } } //测站估值 result.SolutionEstimateBlock.Items.AddRange(fileA.SolutionEstimateBlock.Items); foreach (var item in fileB.SolutionEstimateBlock.Items) { if (!result.SolutionEstimateBlock.Items.Contains(item)) { result.SolutionEstimateBlock.Items.Add(item); } } int i = 0; foreach (var item in result.SolutionEstimateBlock.Items) { item.ParameterValue = apriori[i][0]; item.StdDev = p.CovaOfEstimatedParam[i, i]; i++; } //矩阵 result.SolutionMatrixEstimateCova.Items = SinexMatrixConvertor.GetMatrixLines(p.CovaOfEstimatedParam.Array); }
/// <summary> /// 构建参数平差观测方程,并进行平差计算。 /// </summary> /// <param name="fileA"></param> /// <param name="fileB"></param> /// <returns></returns> private double[][] Adjust(SinexFile fileA, SinexFile fileB) { //检查一下是否只包含坐标,如否,则清理。 if (!fileA.IsOnlyEstimateCoordValue) { fileA.CleanNonCoordSolutionValue(); } if (!fileB.IsOnlyEstimateCoordValue) { fileB.CleanNonCoordSolutionValue(); } double[][] A = SinexSubNetsUnion.GetCoeffMatrixOfParams(fileA, fileB); double[][] Q = SinexSubNetsUnion.GetCovaMatrixOfObs(fileA, fileB); double[][] obsMinusApriori = SinexSubNetsUnion.GetObsMinusApriori(fileA, fileB); var pa = new ParamAdjuster(); p = pa.Run(new AdjustObsMatrix(A, obsMinusApriori, Q)); double[][] apriori = GetApriori(fileA, fileB); //MatrixUtil.SaveToText(A, @"C:\A.txt"); //MatrixUtil.SaveToText(Q, @"C:\Q.txt"); //MatrixUtil.SaveToText(obsMinusApriori, @"C:\l.txt"); //MatrixUtil.SaveToText(apriori, @"C:\D.txt"); xyzs = GetXyzs(MatrixUtil.GetPlus(p.Estimated.OneDimArray, apriori)); geoCoords = new List <GeoCoord>(); foreach (var item in xyzs) { geoCoords.Add(CoordTransformer.XyzToGeoCoord(item)); } result = SinexMerger.EmergeBasic(fileA, fileB); return(apriori); }
/// <summary> /// 未知参数的先验值。是一个列向量. /// </summary> /// <param name="fileA"></param> /// <param name="fileB"></param> /// <returns></returns> public static double[][] GetApriori(SinexFile fileA, SinexFile fileB) { int row = SinexFile.GetDistinctSiteCodes(fileA, fileB).Count * 3; double[][] array = MatrixUtil.Create(row, 1); int j = 0; foreach (var item in fileA.SolutionAprioriBlock.Items) { array[j++][0] = item.ParameterValue; } List <string> sames = SinexFile.GetSameSiteCodes(fileA, fileB); foreach (var item in fileB.SolutionAprioriBlock.Items) { if (!sames.Contains(item.SiteCode)) { array[j++][0] = item.ParameterValue; } } return(array); }
/// <summary> /// 获取矩阵l,为观测值减去先验值,是一个列向量。 /// </summary> /// <param name="fileA"></param> /// <param name="fileB"></param> /// <returns></returns> public static double[][] GetObsMinusApriori(SinexFile fileA, SinexFile fileB) { int paraCountA = fileA.EstimateParamCount; int row = paraCountA + fileB.EstimateParamCount; double[][] array = MatrixUtil.Create(row, 1); double[] estiamtedA = fileA.GetEstimateVector(); double[] aprioriA = fileA.GetAprioriVector(); double[] estiamtedB = fileB.GetEstimateVector(); double[] aprioriB = fileB.GetAprioriVector(); for (int i = 0; i < paraCountA; i++) { array[i][0] = estiamtedA[i] - aprioriA[i]; } for (int i = paraCountA; i < paraCountA + estiamtedB.Length; i++) { array[i][0] = estiamtedB[i - paraCountA] - aprioriB[i - paraCountA]; } return(array); }
/// <summary> /// 读取基线向量观测文件和SNX文件,获取基线相关信息 /// </summary> private void Int() { List <string> allKnownPointName = new System.Collections.Generic.List <string>(); //所指定的已知点,但这些已知点可能SNX文件中没有,不是全部采用 KnownPointName = new System.Collections.Generic.List <string>(); //实际采用的已知点,根据SNX文件读取坐标值 KonwnPointsXyz = new System.Collections.Generic.Dictionary <string, XYZ>(); CommonPointName = new System.Collections.Generic.List <string>(); CommonPointsXyz = new System.Collections.Generic.Dictionary <string, XYZ>(); AllPointsApproXyz = new System.Collections.Generic.Dictionary <string, XYZ>(); //所有点的坐标,已知点为真值,未知的为近似值 AllPointName = new System.Collections.Generic.List <string>(); BaselineInfo = new System.Collections.Generic.Dictionary <string, XYZ>(); //存放观测值基线残差信息 BaselineInverseOfWegihtInfo = new System.Collections.Generic.Dictionary <string, SymmetricMatrix>(); //存放观测值的协方差阵 var coordNamePath = this.fileOpenControl2_KnownPointName.FilePath; StreamReader sr = new StreamReader(coordNamePath); string strLine = sr.ReadLine(); while ((strLine) != null && strLine != "") { string[] names = strLine.Split(new char[] { ' ', ',', ';', '\t' }); foreach (var item in names) { if (!allKnownPointName.Contains(item)) { allKnownPointName.Add(item.ToUpper()); } } strLine = sr.ReadLine(); } sr.Close(); var coordPath = this.fileOpenControl1.FilePath; if (coordPath == null || !Path.GetExtension(coordPath).Contains(".snx")) { throw new Exception("请指定坐标基准文件SNX"); } SinexFile SinexFile = new Data.Sinex.SinexFile(coordPath); SinexFile fileA = SinexReader.Read(coordPath, true); List <NamedXyz> listSnx = fileA.GetSiteEstimatedCoords(); Dictionary <string, XYZ> SnxXyz = new System.Collections.Generic.Dictionary <string, XYZ>();//snx文件的坐标值 // var colName = SinexFile.GetSinexSites(); foreach (var item in listSnx) { SnxXyz.Add(item.Name.ToUpper().Trim(), item.Value); } foreach (var item in allKnownPointName) { if (SnxXyz.ContainsKey(item)) { KonwnPointsXyz.Add(item, SnxXyz[item]); KnownPointName.Add(item); } } var baselinefiles = this.fileOpenControl2baselinefiles.FilePathes; foreach (var path in baselinefiles) { using (StreamReader reader = new StreamReader(new FileStream(path, FileMode.Open))) { int nameIndex = -1; int detXIndex = -1; int detYIndex = -1; int detZIndex = -1; int QxxIndex = -1; int QxyIndex = -1; int QyyIndex = -1; int QxzIndex = -1; int QyzIndex = -1; int QzzIndex = -1; int RefApproXIndex = -1; int RefApproYIndex = -1; int RefApproZIndex = -1; int RovApproXIndex = -1; int RovApproYIndex = -1; int RovApproZIndex = -1; string line = reader.ReadLine(); //第一行为头部 string[] titles = StringUtil.SplitByTab(line); int i = 0; foreach (var item in titles) { var title = item.ToLower(); if (title.Contains("name") && nameIndex == -1) { nameIndex = i; } else if (title.Contains("estvectorx") && detXIndex == -1) { detXIndex = i; } else if (title.Contains("estvectory") && detYIndex == -1) { detYIndex = i; } else if (title.Contains("estvectorz") && detZIndex == -1) { detZIndex = i; } else if (title.Contains("qxx") && QxxIndex == -1) { QxxIndex = i; } else if (title.Contains("qxy") && QxyIndex == -1) { QxyIndex = i; } else if (title.Contains("qyy") && QyyIndex == -1) { QyyIndex = i; } else if (title.Contains("qxz") && QxzIndex == -1) { QxzIndex = i; } else if (title.Contains("qyz") && QyzIndex == -1) { QyzIndex = i; } else if (title.Contains("qzz") && QzzIndex == -1) { QzzIndex = i; } else if (title.Contains("refapprox") && RefApproXIndex == -1) { RefApproXIndex = i; } else if (title.Contains("refapproy") && RefApproYIndex == -1) { RefApproYIndex = i; } else if (title.Contains("refapproz") && RefApproZIndex == -1) { RefApproZIndex = i; } else if (title.Contains("rovapprox") && RovApproXIndex == -1) { RovApproXIndex = i; } else if (title.Contains("rovapproy") && RovApproYIndex == -1) { RovApproYIndex = i; } else if (title.Contains("rovapproz") && RovApproZIndex == -1) { RovApproZIndex = i; } i++; } while ((line = reader.ReadLine()) != null) { if (String.IsNullOrWhiteSpace(line)) { continue; } string[] values = StringUtil.SplitByTab(line); string baselineName = values[nameIndex]; string[] Names = baselineName.Split('-'); string RefName = Names[0].Substring(0, 4).ToUpper(); string RovName = Names[1].Substring(0, 4).ToUpper(); XYZ baselineValue = new XYZ(double.Parse(values[detXIndex]), double.Parse(values[detYIndex]), double.Parse(values[detZIndex])); double[] qx = new double[6] { double.Parse(values[QxxIndex]) + 10e-10, double.Parse(values[QxyIndex]), double.Parse(values[QyyIndex]) + 10e-10, double.Parse(values[QxzIndex]), double.Parse(values[QyzIndex]), double.Parse(values[QzzIndex]) + 10e-10 }; SymmetricMatrix Q = new SymmetricMatrix(qx); XYZ RefApproXYZ = new XYZ(double.Parse(values[RefApproXIndex]), double.Parse(values[RefApproYIndex]), double.Parse(values[RefApproZIndex])); XYZ RovApproXYZ = new XYZ(double.Parse(values[RovApproXIndex]), double.Parse(values[RovApproYIndex]), double.Parse(values[RovApproZIndex])); //观测值常数项l=L(基线向量)-(流动站近似坐标-基准站近似坐标) //参考站 if (RefName == "SHAO" && RovName == "ZJZS") { // } if (SnxXyz.ContainsKey(RefName)) { if (!CommonPointsXyz.ContainsKey(RefName)) { CommonPointsXyz.Add(RefName, SnxXyz[RefName]); } //if (!AllPointsApproXyz.ContainsKey(RefName)) { AllPointsApproXyz.Add(RefName, RefApproXYZ); } if (!AllPointsApproXyz.ContainsKey(RefName)) { AllPointsApproXyz.Add(RefName, RefApproXYZ);// SnxXyz[RefName]); AllPointName.Add(RefName); } if ((CommonPointsXyz[RefName] - AllPointsApproXyz[RefName]).Length > 1.0) //暂时防止同名点情况 { CommonPointsXyz.Remove(RefName); AllPointsApproXyz[RefName] = RefApproXYZ; baselineValue += AllPointsApproXyz[RefName]; } else { baselineValue += CommonPointsXyz[RefName];//基线观测值减去基线近似值 // baselineValue += AllPointsApproXyz[RefName]; } } else { if (!AllPointsApproXyz.ContainsKey(RefName)) { AllPointsApproXyz.Add(RefName, RefApproXYZ); AllPointName.Add(RefName); } baselineValue += AllPointsApproXyz[RefName];//基线观测值减去基线近似值 } //流动站 if (SnxXyz.ContainsKey(RovName)) { if (!CommonPointsXyz.ContainsKey(RovName)) { CommonPointsXyz.Add(RovName, SnxXyz[RovName]); } //if (!AllPointsApproXyz.ContainsKey(RovName)) { AllPointsApproXyz.Add(RovName, RovApproXYZ); } if (!AllPointsApproXyz.ContainsKey(RovName)) { AllPointsApproXyz.Add(RovName, RovApproXYZ);// SnxXyz[RovName]); AllPointName.Add(RovName); } if ((CommonPointsXyz[RovName] - AllPointsApproXyz[RovName]).Length > 1.0) //暂时防止同名点情况 { CommonPointsXyz.Remove(RovName); AllPointsApproXyz[RovName] = RovApproXYZ; baselineValue -= AllPointsApproXyz[RovName]; } else { baselineValue -= CommonPointsXyz[RovName]; // baselineValue -= AllPointsApproXyz[RovName]; } } else { if (!AllPointsApproXyz.ContainsKey(RovName)) { AllPointsApproXyz.Add(RovName, RovApproXYZ); AllPointName.Add(RovName); } baselineValue -= AllPointsApproXyz[RovName]; //基线观测值减去基线近似值 } //// //基线观测值减去基线近似值 ////// baselineValue -= (AllPointsApproXyz[RovName] - AllPointsApproXyz[RefName]); //不同基线文件中可能存在同名基线,需根据基线文件再唯一标示 BaselineInfo.Add(RefName + "-" + RovName + "-" + Path.GetFileName(path), baselineValue); BaselineInverseOfWegihtInfo.Add(RefName + "-" + RovName + "-" + Path.GetFileName(path), Q); } } //当前基线文件遍历完 } //所有基线文件遍历完 //已知点的向量 foreach (var item in KonwnPointsXyz) { if (!AllPointsApproXyz.ContainsKey(item.Key)) { AllPointsApproXyz.Add(item.Key, item.Value); AllPointName.Add(item.Key); } string knownName = null; double length = 10e14; foreach (var com in CommonPointsXyz) { if (com.Key != item.Key) { double tmp = (com.Value - item.Value).Length; if (tmp < length) { length = tmp; knownName = com.Key; } } } XYZ baseline = (CommonPointsXyz[knownName] - KonwnPointsXyz[item.Key]) - (AllPointsApproXyz[knownName] - AllPointsApproXyz[item.Key]); //不同基线文件中可能存在同名基线,需根据基线文件再唯一标示 BaselineInfo.Add(item.Key + "-" + knownName + "-" + "基准基线", baseline); SymmetricMatrix Q = new SymmetricMatrix(3, 0); Q[0, 0] = Q[1, 1] = Q[2, 2] = 10e-10; BaselineInverseOfWegihtInfo.Add(item.Key + "-" + knownName + "-" + "基准基线", Q); } ////关系后续矩阵方程建立的编号,得小心改 //foreach (var key in AllPointsApproXyz) //{ // AllPointName.Add(key.Key); //} }
private void button_PppBestBaseline_Click(object sender, EventArgs e) { //---------------------------------------------------数据读取//--------------------------------------------------- //读取PPP结果 string[] pppfilePathes = this.textBox_PathesOfPppFile.Lines; List <SinexFile> pppsinexFiles = SinexFile.Read(pppfilePathes); List <string> strSite = new List <string>(); int m = pppfilePathes.Length; double[][] pppXyz = new double[m * 3][]; int count = 0; foreach (var file in pppsinexFiles) { List <SinexSiteDetail> sites = file.GetSinexSites(); foreach (var item2 in sites) { if (!strSite.Contains(item2.Name.ToUpper())) { strSite.Add(item2.Name.ToUpper()); } else { throw new Exception("测站信息重复!"); } } double[][] xyz = file.GetEstimateMatrix(); double[][] xyzCov = file.GetEstimateCovaMatrix(); double std = file.GetStatistic().VarianceFactor; pppXyz[3 * count + 0] = new double[1]; pppXyz[3 * count + 0][0] = xyz[0][0]; pppXyz[3 * count + 1] = new double[1]; pppXyz[3 * count + 1][0] = xyz[1][0]; pppXyz[3 * count + 2] = new double[1]; pppXyz[3 * count + 2][0] = xyz[2][0]; count += 1; } List <Delaunay.deXYZ> ListXyz = new List <Delaunay.deXYZ>(); for (int i = 0; i < strSite.Count; i++) { Delaunay.deXYZ xyz = new Delaunay.deXYZ(); xyz.X = pppXyz[3 * i + 0][0]; xyz.Y = pppXyz[3 * i + 1][0]; xyz.Z = pppXyz[3 * i + 2][0]; ListXyz.Add(xyz); } Delaunay delaunay = new Delaunay(ListXyz); MiniSpanTreeKruskal MiniSpanTreeKruskal = new Cygeo.Adjustment.EMST.MiniSpanTreeKruskal(delaunay); List <string> BenDir = new List <string>(); List <string> EndDir = new List <string>(); List <double> LengthBaseline = new List <double>(); foreach (var item in MiniSpanTreeKruskal.min_ed) { BenDir.Add(strSite[item.vs]); //起点 EndDir.Add(strSite[item.ve]); //终点 LengthBaseline.Add(item.weight); } //---------------------------------------------------------结果输出-------------------------------------------- StringBuilder sb = new StringBuilder(); sb.AppendLine("最短基线及其长度"); for (int i = 0; i < strSite.Count; i++) { sb.AppendLine(strSite[i]); } for (int i = 0; i < BenDir.Count; i++) { sb.AppendLine(BenDir[i] + "-" + EndDir[i] + " " + LengthBaseline[i].ToString()); } this.textBox_info.Text = sb.ToString(); //----------------------------------------------------地图准备//---------------------------------------------------- points.Clear(); //GeoCoord c1 = CoordTransformer.XyzToGeoCoord(aprioriA); //GeoCoord c2 = CoordTransformer.XyzToGeoCoord(aprioriB); //GeoCoord c3 = CoordTransformer.XyzToGeoCoord(estA); //GeoCoord c4 = CoordTransformer.XyzToGeoCoord(estB); //points.Add(new AnyInfo.Geometries.Point(c1.Lon, c1.Lat, "aprA")); //points.Add(new AnyInfo.Geometries.Point(c2.Lon, c2.Lat, "aprB")); //points.Add(new AnyInfo.Geometries.Point(c3.Lon, c3.Lat, "estA")); //points.Add(new AnyInfo.Geometries.Point(c4.Lon, c4.Lat, "estB")); }
/// <summary> /// 单点定位结果转化为Sinex文件 /// </summary> /// <returns></returns> public static SinexFile Build(SingleSiteGnssResult result) { SinexFile sinex = new SinexFile("Gnsser"); sinex.SolutionEpochBlock.Items.Add(new SolutionEpoch() { DateStart = result.ReceiverTime, DateEnd = result.ReceiverTime, DateMean = result.ReceiverTime, ObservationCode = "P", PointCode = "A", SiteCode = result.SiteInfo.SiteName, SolutionID = "0001" }); SinexStatistic stat = new SinexStatistic() { NumberOfUnknown = result.ResultMatrix.ParamCount, NumberOfObservations = result.ResultMatrix.ObsMatrix.Observation.Count, VarianceOfUnitWeight = result.ResultMatrix.VarianceOfUnitWeight, NumberOfDegreesOfFreedom = result.ResultMatrix.Freedom }; sinex.SolutionStattisticsBlock.Items = stat.GetSolutionStatistics(); GeoCoord approxGeo = CoordTransformer.XyzToGeoCoord(result.ApproxXyz); sinex.SiteIdBlock.Items.Add(new SiteId() { SiteCode = result.SiteInfo.SiteName, PointCode = "A", UniqueMonumentId = result.SiteInfo.MarkerNumber, ApproximateHeight = approxGeo.Height, ApproximateLatitude = approxGeo.Lat, ApproximateLongitude = approxGeo.Lon, ObservationCode = "P", GeoCoord = result.GeoCoord, StationDescription = "Single Point" }); int index = 0; sinex.SolutionEstimateBlock.Items.AddRange(new SolutionValue[] { new SolutionValue() { Index = 1 + index++, ParameterType = "STAX", ParameterValue = result.EstimatedXyz.X, SiteCode = result.SiteInfo.SiteName, RefEpoch = result.ReceiverTime, PointCode = "A", ParameterUnits = "m", ConstraintCode = "2", StdDev = Math.Sqrt(result.ResultMatrix.CovaOfEstimatedParam[index - 1, index - 1]), SolutionID = "0001" }, new SolutionValue() { Index = 1 + index++, ParameterType = "STAY", ParameterValue = result.EstimatedXyz.Y, SiteCode = result.SiteInfo.SiteName, RefEpoch = result.ReceiverTime, PointCode = "A", ParameterUnits = "m", ConstraintCode = "2", StdDev = Math.Sqrt(result.ResultMatrix.CovaOfEstimatedParam[index - 1, index - 1]), SolutionID = "0001" }, new SolutionValue() { Index = 1 + index++, ParameterType = "STAZ", ParameterValue = result.EstimatedXyz.Z, SiteCode = result.SiteInfo.SiteName, RefEpoch = result.ReceiverTime, PointCode = "A", ParameterUnits = "m", ConstraintCode = "2", StdDev = Math.Sqrt(result.ResultMatrix.CovaOfEstimatedParam[index - 1, index - 1]), SolutionID = "0001" }, new SolutionValue() { Index = 1 + index++, ParameterType = "RBIAS", ParameterValue = result.RcvClkErrDistance, SiteCode = result.SiteInfo.SiteName, RefEpoch = result.ReceiverTime, PointCode = "A", ParameterUnits = "m", ConstraintCode = "2", StdDev = Math.Sqrt(result.ResultMatrix.CovaOfEstimatedParam[index - 1, index - 1]), SolutionID = "0001" } }); // sinex. sinex.SolutionMatrixEstimateCova.Items = SinexMatrixConvertor.GetMatrixLines(result.ResultMatrix.CovaOfEstimatedParam.Array); return(sinex); }
/// <summary> /// 基于 Sinex 文件的分区平差。 /// </summary> /// <param name="files">具有公共参数的分区</param> public SinexBlockAdjust(params SinexFile[] files) { if (files.Length <= 1) { throw new ArgumentException("输入的SINEX文件数量不可少于2!"); } this.files = files; //检查一下是否只包含坐标,如否,则清理。 foreach (var item in files) { if (!item.IsOnlyEstimateCoordValue) { item.CleanNonCoordSolutionValue(); } } //提取公共测站名称 List <string> sameSites = null; new List <string>(); foreach (var item in files) { if (sameSites == null) { sameSites = new List <string>(); sameSites.AddRange(item.GetSiteCods()); } else { sameSites = SinexFile.GetSameSiteCodes(item, sameSites); } } if (sameSites.Count == 0) { throw new ArgumentException("分区没有公共点,不可执行分区平差!"); } //计算统一单位权中误差 double commonVarFactor = GetVarianceFactor(files); //组建分区 DateTime from = DateTime.Now; List <BlockAdjustItem> items = new List <BlockAdjustItem>(); foreach (var file in files) { //获取公共参数所在的编号,都转化为X,Y,Z分别的参数 List <int> commonParamIndexes = file.GetParamIndexes(sameSites); //公共参数的索引 List <int> blockParamIndexes = file.GetParamIndexesExcept(sameSites); //区内参数的索引 List <int> newIndexes = new List <int>(blockParamIndexes); //新索引顺序 newIndexes.AddRange(commonParamIndexes); int blockParamCount = blockParamIndexes.Count; int obsCount = file.EstimateParamCount; int commonParamCount = commonParamIndexes.Count; //分区内参数系数阵 obsCount x paramCount double[][] coeffA = MatrixUtil.Create(obsCount, blockParamCount); for (int i = 0; i < blockParamCount; i++) { coeffA[i][i] = 1.0; } //观测值 obsCount x 1 double[][] obs = MatrixUtil.Create(obsCount, 1); for (int i = 0; i < obsCount; i++) { if (i < blockParamCount)//区内参数 { obs[i][0] = file.SolutionEstimateBlock.Items[blockParamIndexes[i]].ParameterValue; } else//公共参数 { obs[i][0] = file.SolutionEstimateBlock.Items[commonParamIndexes[i - blockParamCount]].ParameterValue; } } //观测值权逆阵 obsCount x obsCount //注意:此处应该统一化权阵 double[][] inverseOfObs = null; if (file.HasEstimateCovaMatrix) { inverseOfObs = file.GetEstimateCovaMatrix(); MatrixUtil.SymmetricExchange(inverseOfObs, newIndexes); MatrixUtil.Multiply(inverseOfObs, commonVarFactor / file.GetStatistic().VarianceOfUnitWeight); } //else if (file.HasNormalEquationMatrix && file.HasNormalEquationVectorMatrix) //{ // //方法待验证 // double[][] normal = file.GetNormalEquationMatrix(); // double[] righHand = file.GetNormalEquationVector(); // Geo.Algorithm.Matrix n = new Geo.Algorithm.Matrix(normal); // Geo.Algorithm.Matrix u = new Geo.Algorithm.Matrix(MatrixUtil.Create( righHand)); // inverseOfObs = n.Inverse.Array; // double lTpl = file.GetStatistic().WeightedSqureSumOfOMinusC; // double vTpv = lTpl - (u.Transpose() * n * u)[0,0]; // double varFactor = vTpv / file.GetStatistic().NumberOfDegreesOfFreedom; // MatrixUtil.Multiply(inverseOfObs, varFactor); // MatrixUtil.SymmetricExchange(inverseOfObs, newIndexes); // MatrixUtil.Multiply(inverseOfObs, commonVarFactor / file.GetStatistic().VarianceOfUnitWeight); //} else//去相关 { inverseOfObs = MatrixUtil.Create(obsCount); for (int i = 0; i < obsCount; i++) { if (i < blockParamCount)//区内参数 { inverseOfObs[i][i] = Math.Pow(file.SolutionEstimateBlock.Items[blockParamIndexes[i]].StdDev, 2); } else//公共参数 { inverseOfObs[i][i] = Math.Pow(file.SolutionEstimateBlock.Items[commonParamIndexes[i - blockParamCount]].StdDev, 2); } } MatrixUtil.Multiply(inverseOfObs, commonVarFactor / file.GetStatistic().VarianceOfUnitWeight); } //分区内对公共参数的系数阵 obsCount x commonParamCount double[][] coeffB = MatrixUtil.Create(obsCount, commonParamCount); for (int i = blockParamCount; i < obsCount; i++) { coeffB[i][i - blockParamCount] = 1; } BlockAdjustItem item = new BlockAdjustItem(coeffA, obs, inverseOfObs, coeffB); items.Add(item); } ba = new BlockAdjustment(items.ToArray(), false); //创建结果SINEX文件,文件只包含公共参数的内容 ResultSinexFile = new SinexFile("Gnsser"); //测站名称 int commonSiteCount = ba.CommonParamCount / 3; List <SiteId> siteIds = new List <SiteId>(); for (int i = 0; i < commonSiteCount; i++) { siteIds.Add(files[0].GetSiteId(sameSites[i])); } ResultSinexFile.SiteIdBlock = SinexFactory.CreateSiteIdBlock(siteIds); //统计信息 SinexStatistic statistic = new SinexStatistic() { NumberOfUnknown = ba.CommonParamCount, NumberOfDegreesOfFreedom = ba.Freedom, VarianceOfUnitWeight = ba.VarianceOfUnitWeight, SquareSumOfResidualsVTPV = ba.SquareSumOfResidualsVTPV, NumberOfObservations = ba.ObsCount }; ResultSinexFile.SolutionStattisticsBlock = SinexFactory.CreateSolutionStattisticsBlock(statistic.GetSolutionStatistics()); //估值 List <SolutionValue> estList = new List <SolutionValue>(); Time refEchop = files[0].SolutionEstimateBlock.Items[0].RefEpoch; for (int i = 0; i < commonSiteCount; i++) { int paramIndex = i * 3; SolutionValue svX = new SolutionValue(paramIndex + 1, siteIds[i].SiteCode, "STAX", ba.CommonParams[paramIndex + 0][0], refEchop, ba.CommonParamRmsVector[paramIndex + 0]); SolutionValue svY = new SolutionValue(paramIndex + 2, siteIds[i].SiteCode, "STAY", ba.CommonParams[paramIndex + 1][0], refEchop, ba.CommonParamRmsVector[paramIndex + 1]); SolutionValue svZ = new SolutionValue(paramIndex + 3, siteIds[i].SiteCode, "STAZ", ba.CommonParams[paramIndex + 2][0], refEchop, ba.CommonParamRmsVector[paramIndex + 2]); estList.AddRange(new SolutionValue[] { svX, svY, svZ }); } ResultSinexFile.SolutionEstimateBlock = SinexFactory.CreateSolutionEstimateBlock(estList); //协方差 ResultSinexFile.SolutionMatrixEstimateCova = SinexFactory.CreateSolutionMatrixEstimateCova(ba.CovaOfCommonParams); this.TimeSpan = DateTime.Now - from; }