Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <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);
        }
Пример #3
0
        /// <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);
        }
Пример #4
0
        /// <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;
        }