Пример #1
0
        /// <summary>
        /// 生产平差器
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static MatrixAdjuster Create(AdjustmentType type)
        {
            MatrixAdjuster Adjustment = null;

            switch (type)
            {
            case AdjustmentType.参数平差:
                Adjustment = new ParamAdjuster();
                break;

            case AdjustmentType.条件平差:
                Adjustment = new ConditionalAdjuster();
                break;

            case AdjustmentType.具有参数的条件平差:
                Adjustment = new ConditionalAdjusterWithParam();
                break;

            case AdjustmentType.具有条件的参数平差:
                Adjustment = new ParamAdjusterWithCondition();
                break;

            case AdjustmentType.卡尔曼滤波:
                Adjustment = new SimpleKalmanFilter();
                // Adjustment = new KalmanFilter();
                break;

            case AdjustmentType.均方根滤波:
                Adjustment = new SquareRootInformationFilter();
                break;

            case AdjustmentType.序贯平差:
                Adjustment = new SequentialAdjuster();
                break;

            case AdjustmentType.参数加权平差:
                Adjustment = new WeightedParamAdjuster();
                break;

            case AdjustmentType.递归最小二乘:
                Adjustment = new RecursiveAdjuster();
                break;

            case AdjustmentType.单期递归最小二乘:
                Adjustment = new SingleRecursiveAdjuster();
                break;

            default:
                //Adjustment = new ParamAdjuster();
                break;
            }
            if (Adjustment == null)
            {
                throw new Exception("尚未实现 " + type);
            }

            return(Adjustment);
        }
Пример #2
0
        /// <summary>
        /// 参数估计
        /// </summary>
        /// <returns></returns>
        public PlainXyConvertParam Estimate()
        {
            var obsVector = new Vector(ObsCount);

            //构建观测向量
            for (int i = 0; i < CoordCount; i++)
            {
                int index = 2 * i;
                var oldXy = OldOrTobeConvertingXys[i];
                var newXy = NewOrTargedXys[i];
                obsVector[index + 0] = newXy.X - oldXy.X;
                obsVector[index + 1] = newXy.Y - oldXy.Y;
            }
            //构建系数阵
            Matrix coeffOfParam = new Matrix(ObsCount, 4);

            for (int i = 0; i < CoordCount; i++)
            {
                int index = 2 * i;
                var oldXy = OldOrTobeConvertingXys[i];
                //尺度因子,
                coeffOfParam[index + 0, 0] = 1;
                coeffOfParam[index + 1, 1] = 1;
                //转换参数,弧度
                coeffOfParam[index + 0, 2] = oldXy.X;
                coeffOfParam[index + 0, 3] = oldXy.Y;
                coeffOfParam[index + 1, 2] = oldXy.Y;
                coeffOfParam[index + 1, 3] = -oldXy.X;
            }


            AdjustObsMatrix obsMatrix = new AdjustObsMatrix();

            obsMatrix.SetCoefficient(coeffOfParam).SetObservation(obsVector);
            var adjuster = new ParamAdjuster();

            this.ResultMatrix = adjuster.Run(obsMatrix);
            var ested = ResultMatrix.Estimated;

            var result = new PlainXyConvertParam(new XY(ested[0], ested[1]), ested[2] * 1e6, ested[3] * CoordConsts.RadToSecMultiplier);

            return(result);
        }
Пример #3
0
        /// <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);
        }
Пример #4
0
        /// <summary>
        /// 参数估计
        /// </summary>
        /// <returns></returns>
        public XyzFrameConvertParam Estimate()
        {
            var obsVector = new Vector(ObsCount);

            //构建观测向量
            for (int i = 0; i < CoordCount; i++)
            {
                int index = 3 * i;
                var oldXy = OldOrTobeConvertingXys[i];
                var newXy = NewOrTargedXys[i];
                obsVector[index + 0] = newXy.X - oldXy.X;
                obsVector[index + 1] = newXy.Y - oldXy.Y;
                obsVector[index + 2] = newXy.Z - oldXy.Z;
            }
            //构建系数阵
            Matrix coeffOfParam = new Matrix(ObsCount, 7);

            for (int i = 0; i < CoordCount; i++)
            {
                int index = 3 * i;
                var oldXy = OldOrTobeConvertingXys[i];
                //平移参数XYZ,0-2,单位:m
                coeffOfParam[index + 0, 0] = 1;
                coeffOfParam[index + 1, 1] = 1;
                coeffOfParam[index + 2, 2] = 1;
                //尺度参数,3,单位:ppm,求出的直接为 ppm
                double factor = 1.0;// 1e-6;
                coeffOfParam[index + 0, 3] = oldXy.X * factor;
                coeffOfParam[index + 1, 3] = oldXy.Y * factor;
                coeffOfParam[index + 2, 3] = oldXy.Z * factor;

                //旋转参数,4-6, 单位:s,需要转换为rad
                factor = 1.0;// CoordConsts.SecToRadMultiplier;
                coeffOfParam[index + 0, 5] = -oldXy.Z * factor;
                coeffOfParam[index + 0, 6] = oldXy.Y * factor;
                coeffOfParam[index + 1, 4] = oldXy.Z * factor;
                coeffOfParam[index + 1, 6] = -oldXy.X * factor;
                coeffOfParam[index + 2, 4] = -oldXy.Y * factor;
                coeffOfParam[index + 2, 5] = oldXy.X * factor;
            }
            AdjustObsMatrix obsMatrix = new AdjustObsMatrix();

            obsMatrix.SetCoefficient(coeffOfParam).SetObservation(obsVector);
            var adjuster = new ParamAdjuster();

            this.ResultMatrix = adjuster.Run(obsMatrix);
            var ested = ResultMatrix.Estimated;

            var result = new XyzFrameConvertParam(
                new XYZ(ested[0], ested[1], ested[2]),                                  //meter
                new XYZ(ested[4], ested[5], ested[6]) * CoordConsts.RadToSecMultiplier, //second
                ested[3] * 1e6                                                          //ppm
                );

            //输出精度信息
            var           RMSVector = ResultMatrix.StdOfEstimatedParam;
            StringBuilder sb        = new StringBuilder();

            sb.AppendLine("单位权中误差:" + this.ResultMatrix.StdDev.ToString("G6"));
            sb.Append("平移参数(m):" + result.Offset);
            sb.AppendLine(", 标准差:" + RMSVector[0].ToString("G6") + ", " + RMSVector[1].ToString("G6") + ", " + RMSVector[2].ToString("G6"));
            sb.Append("旋转参数(s):" + result.RotationAngleSecond);
            sb.AppendLine(", 标准差:" + RMSVector[4].ToString("G6") + ", " + RMSVector[5].ToString("G6") + ", " + RMSVector[6].ToString("G6"));
            sb.Append("尺度参数(ppm):" + result.ScaleFactorPpm.ToString("G6"));
            sb.AppendLine(", 标准差:" + RMSVector[3].ToString("G6"));

            log.Info(sb.ToString());

            return(result);
        }