/// <summary>以回溯的方式寻找对应线段</summary>
        /// <param name="frcpl">大比例尺线状要素</param>
        /// <param name="tocpl">小比例尺线状要素</param>
        /// <param name="CFrEdgeLt">大比例尺线段</param>
        ///  <param name="CToEdgeLt">小比例尺线段</param>
        /// <param name="frlastcpllt">大比例尺终点线段(只有一个点)</param>
        /// <param name="tolastcpllt">小比例尺终点线段(只有一个点)</param>
        /// <returns>对应线段数组</returns>
        public C5.LinkedList <CCorrespondSegment> FindCorrespondSegmentLk(CTable[,] T, CPolyline frcpl, CPolyline tocpl, List <CPolyline> CFrEdgeLt, List <CPolyline> CToEdgeLt)
        {
            C5.LinkedList <CCorrespondSegment> CorrespondSegmentLk = new C5.LinkedList <CCorrespondSegment>();
            int i = CFrEdgeLt.Count;
            int j = CToEdgeLt.Count;

            while (i >= 0 && j >= 0)
            {
                CPolyline frcplw = new CPolyline();
                CPolyline tocplw = new CPolyline();
                if (i == 0 && j == 0)
                {
                    break;
                }
                else  //其它行列的情况
                {
                    frcplw = frcpl.GetSubPolyline(CFrEdgeLt[i - T[i, j].intBackK].cptlt[0], CFrEdgeLt[i - 1].cptlt[1]);
                    tocplw = CToEdgeLt[j - 1];
                    i      = i - T[i, j].intBackK;
                    j      = j - 1;
                }

                CCorrespondSegment pCorrespondSegment = new CCorrespondSegment();
                pCorrespondSegment = new CCorrespondSegment(frcplw, tocplw);
                CorrespondSegmentLk.Insert(0, pCorrespondSegment);
            }

            return(CorrespondSegmentLk);
        }
        /// <summary>
        /// 提取对应线段
        /// </summary>
        /// <param name="frcpl">大比例尺线状要素</param>
        /// <param name="tocpl">小比例尺线状要素</param>
        /// <param name="pCorrespondBendLt">对应弯曲列表</param>
        /// <returns>对应线段</returns>
        /// <remarks></remarks>
        public static SCG.LinkedList <CCorrSegment> DetectCorrespondSegment(CPolyline frcpl, CPolyline tocpl, List <CCorrespondBend> pCorrespondBendLt)
        {
            //提取对应弯曲的首尾点为对应特征点
            SortedList <double, CCorrCpts> pCorrespondingCptSlt = new SortedList <double, CCorrCpts>(new CCmpDbl());

            CCorrCpts pStartCorrespondingCpt0 = new CCorrCpts(frcpl.CptLt[0], tocpl.CptLt[0]);                                         //第一对对应特征点
            CCorrCpts pEndCorrespondingCpt0   = new CCorrCpts(frcpl.CptLt[frcpl.CptLt.Count - 1], tocpl.CptLt[tocpl.CptLt.Count - 1]); //第二对对应特征点

            pCorrespondingCptSlt.Add(0, pStartCorrespondingCpt0);
            pCorrespondingCptSlt.Add(1, pEndCorrespondingCpt0);

            //其它对应特征点
            for (int i = 0; i < pCorrespondBendLt.Count; i++)
            {
                CCorrCpts pStartCorrespondingCpt = new CCorrCpts(pCorrespondBendLt[i].CFromBend.CptLt[0], pCorrespondBendLt[i].CToBend.CptLt[0]);
                CCorrCpts pEndCorrespondingCpt   = new CCorrCpts(
                    pCorrespondBendLt[i].CFromBend.CptLt[pCorrespondBendLt[i].CFromBend.CptLt.Count - 1],
                    pCorrespondBendLt[i].CToBend.CptLt[pCorrespondBendLt[i].CToBend.CptLt.Count - 1]);

                pCorrespondingCptSlt.Add(pCorrespondBendLt[i].CFromBend.dblStartRL, pStartCorrespondingCpt);
                pCorrespondingCptSlt.Add(pCorrespondBendLt[i].CFromBend.dblEndRL, pEndCorrespondingCpt);
            }


            //查找并删除重复对应特征点
            for (int i = pCorrespondingCptSlt.Count - 1; i > 0; i--)
            {
                CPoint frcpt2 = pCorrespondingCptSlt.Values[i].FrCpt;
                CPoint tocpt2 = pCorrespondingCptSlt.Values[i].ToCpt;
                CPoint frcpt1 = pCorrespondingCptSlt.Values[i - 1].FrCpt;
                CPoint tocpt1 = pCorrespondingCptSlt.Values[i - 1].ToCpt;
                if (frcpt1.Equals2D(frcpt2) && tocpt1.Equals2D(tocpt2))
                {
                    pCorrespondingCptSlt.RemoveAt(i);
                }
            }

            //以对应特征点为断点分割原始线段,得到对应线段
            SCG.LinkedList <CCorrSegment> pCorrespondSegmentLk = new SCG.LinkedList <CCorrSegment>();

            //中间的对应线段
            for (int i = 0; i < pCorrespondingCptSlt.Count - 1; i++)
            {
                CPolyline frSegment = frcpl.GetSubPolyline(pCorrespondingCptSlt.Values[i].FrCpt, pCorrespondingCptSlt.Values[i + 1].FrCpt);
                CPolyline toSegment = tocpl.GetSubPolyline(pCorrespondingCptSlt.Values[i].ToCpt, pCorrespondingCptSlt.Values[i + 1].ToCpt);
                pCorrespondSegmentLk.AddLast(new CCorrSegment(frSegment, toSegment));
            }

            return(pCorrespondSegmentLk);
        }
Esempio n. 3
0
        private CPolyline[,] CreateSubCpl(CPolyline cpl, int intMaxBackKforI)
        {
            List <CPoint> cptlt = cpl.CptLt;

            CPolyline[,] asubcpl = new CPolyline[cptlt.Count, intMaxBackKforI + 1];
            for (int i = 0; i < cptlt.Count; i++)
            {
                int intBack = Math.Min(i, intMaxBackKforI);
                for (int j = 0; j < intBack + 1; j++)
                {
                    asubcpl[i, j] = cpl.GetSubPolyline(cptlt[i - j], cptlt[i]);
                }
            }

            return(asubcpl);
        }
        /// <summary>创建T矩阵</summary>
        /// <param name="frcpl">大比例尺线状要素</param>
        /// <param name="tocpl">小比例尺线状要素</param>
        /// <param name="CFrEdgeLt">大比例尺线段</param>
        ///  <param name="CToEdgeLt">小比例尺线段</param>
        /// <param name="frlastcpllt">大比例尺终点线段(只有一个点)</param>
        /// <param name="tolastcpllt">小比例尺终点线段(只有一个点)</param>
        /// <param name="intMaxBackK">回溯系数</param>
        /// <returns>T矩阵</returns>
        public CTable[,] CreatT(CPolyline frcpl, CPolyline tocpl, List <CPolyline> CFrEdgeLt, List <CPolyline> CToEdgeLt, int intMaxBackK, CPoint StandardVetorCpt)
        {
            //注意:T矩阵中的序号跟原文算法中的序号是统一的,但线数组中的序号则应减1
            CTable[,] T = new CTable[frcpl.cptlt.Count, tocpl.cptlt.Count];  //线段数量为顶点数量减1

            //数组的第一行及第一列初始化
            T[0, 0] = new CTable();
            T[0, 0].dblEvaluation = 0;

            CPolyline frfirstcpl = new CPolyline(0, frcpl.cptlt[0]);  //以线状要素的第一个点作为线段

            for (int j = 1; j <= CToEdgeLt.Count; j++)
            {
                T[0, j] = new CTable();
                T[0, j].dblEvaluation = -1;
            }

            for (int i = 1; i <= CFrEdgeLt.Count; i++)
            {
                T[i, 0] = new CTable();
                T[i, 0].dblEvaluation = -1;
            }


            int intI = CFrEdgeLt.Count;
            int intJ = CToEdgeLt.Count;

            if (intJ == 1)
            {
                T[intI, intJ]          = new CTable();
                T[intI, intJ].frfrId   = 1;
                T[intI, intJ].frtoId   = intI;
                T[intI, intJ].tofrId   = intJ;
                T[intI, intJ].intBackK = intI;
                CPolyline frcpli = frcpl.GetSubPolyline(CFrEdgeLt[intI - intI].cptlt[0], CFrEdgeLt[intI - 1].cptlt[1]);
                T[intI, intJ].dblEvaluation = T[0, 0].dblEvaluation + CalTDistance(frcpli, CToEdgeLt[intJ - 1], StandardVetorCpt);
            }
            else if (intJ > 1)
            {
                //循环填满二维数组T中的各个值
                //注意:T中的序号1指定第一个元素,而各LT中(如CFrEdgeLt,tolastcpllt)的序号1则指定第二个元素
                //前提:仅存在的对应关系为每个“较小比例尺线状要素上的线段”对应一个或多个“较大比例尺线状要素上的线段”,即不存在“点对应线段”或“较大比例尺线状要素上的一个线段对应多个较小比例尺上的线段”
                for (int i = 1; i <= CFrEdgeLt.Count - 1; i++)               //计算各空格值
                {
                    //特殊情况(“较小比例尺线状要素上第一个线段”对应“较大比例尺线状要素前i个线段”):基于“前提”,“较大比例尺线状要素上的第一个线段”必需“隶属于”“某个较小比例尺线状要素上的线段”,因此该步骤不能放入接下来的循环中
                    //此处以及下面关于j的循环中,似乎忘记考虑这个情况: CFrEdgeLt.Count-i>= CToEdgeLt.Count-j
                    T[i, 1]          = new CTable();
                    T[i, 1].frfrId   = 1;
                    T[i, 1].frtoId   = i;
                    T[i, 1].tofrId   = 1;
                    T[i, 1].intBackK = i;
                    CPolyline frcpli = frcpl.GetSubPolyline(CFrEdgeLt[0].cptlt[0], CFrEdgeLt[i - 1].cptlt[1]);
                    T[i, 1].dblEvaluation = T[0, 0].dblEvaluation + CalTDistance(frcpli, CToEdgeLt[0], StandardVetorCpt);

                    //在该循环的两个条件中:
                    //    1、“j = CToEdgeLt.Count”为特殊情况,“较小比例尺线状要素上的最后一个线段”必需有相应的对应线段,因此该步骤不能放入该循环中
                    //    2、“j <= i”,基于前提,必需在j <= i时,计算 T[i, j]才有意义
                    for (int j = 2; (j <= CToEdgeLt.Count - 1 && j <= i); j++)
                    {
                        SortedDictionary <double, CTable> dblCTableSlt = new SortedDictionary <double, CTable>(new CDblDecCompare());
                        for (int k = 1; k <= intMaxBackK; k++)
                        {
                            //if语句的两个条件中:
                            //    1、(i - k >= 1):程序刚开始执行时,之前已遍历过线段数较少,可能小于intMaxBackK
                            //    2、基于“前提”,在较大比例尺线状要素上位于回溯范围之前的线段数量(i - k)必需大于较小比例尺线状要素上目标线段j之前的线段数量(j - 1)
                            //因此,限制条件应该为(i - k >= 1) && ((i - k) >=(j-1)),考虑到j>=2,因此第二个条件比第一个条件更加严格,可以省去第一个条件
                            if ((i - k) >= (j - 1))
                            {
                                CTable table5i = new CTable();
                                table5i.frfrId   = i - k + 1;
                                table5i.frtoId   = i;
                                table5i.tofrId   = j;
                                table5i.intBackK = k;
                                CPolyline frcplik = frcpl.GetSubPolyline(CFrEdgeLt[i - k].cptlt[0], CFrEdgeLt[i - 1].cptlt[1]);
                                table5i.dblEvaluation = T[i - k, j - 1].dblEvaluation + CalTDistance(frcplik, CToEdgeLt[j - 1], StandardVetorCpt);
                                dblCTableSlt.Add(table5i.dblEvaluation, table5i);
                            }
                            else
                            {
                                break;
                            }
                        }
                        T[i, j] = dblCTableSlt.ElementAt(0).Value;
                    }
                }

                //最后一个元素
                SortedDictionary <double, CTable> dblCTableSlt2 = new SortedDictionary <double, CTable>(new CDblDecCompare());
                for (int k = 1; k <= intMaxBackK; k++)
                {
                    //if语句的两个条件中:
                    //    1、(i - k >= 1):程序刚开始执行时,之前已遍历过线段数较少,可能小于intMaxBackK
                    //    2、基于“前提”,在较大比例尺线状要素上位于回溯范围之前的线段数量(i - k)必需大于较小比例尺线状要素上目标线段j之前的线段数量(j - 1)
                    //因此,限制条件应该为(i - k >= 1) && ((i - k) >=(j-1)),考虑到j>=2,因此第二个条件比第一个条件更加严格,可以省去第一个条件
                    if ((intI - k) >= (intJ - 1))
                    {
                        CTable table5i = new CTable();
                        table5i.frfrId   = intI - k + 1;
                        table5i.frtoId   = intI;
                        table5i.tofrId   = intJ;
                        table5i.intBackK = k;
                        CPolyline frcpli = frcpl.GetSubPolyline(CFrEdgeLt[intI - k].cptlt[0], CFrEdgeLt[intI - 1].cptlt[1]);
                        table5i.dblEvaluation = T[intI - k, intJ - 1].dblEvaluation + CalTDistance(frcpli, CToEdgeLt[intJ - 1], StandardVetorCpt);
                        dblCTableSlt2.Add(table5i.dblEvaluation, table5i);
                    }
                    else
                    {
                        break;
                    }
                }
                T[intI, intJ] = dblCTableSlt2.ElementAt(0).Value;
            }


            double dblTranslation = T[intI, intJ].dblEvaluation;

            return(T);
        }
        /// <summary>创建T矩阵</summary>
        /// <param name="frcpl">大比例尺线状要素</param>
        /// <param name="tocpl">小比例尺线状要素</param>
        /// <param name="CFrEdgeLt">大比例尺线段</param>
        ///  <param name="CToEdgeLt">小比例尺线段</param>
        /// <param name="frlastcpllt">大比例尺终点线段(只有一个点)</param>
        /// <param name="tolastcpllt">小比例尺终点线段(只有一个点)</param>
        /// <param name="intMaxBackK">回溯系数</param>
        /// <remarks>已释放内存</remarks>
        /// <returns>T矩阵</returns>
        public override CTable[,] CreatTable(CPolyline frcpl, CPolyline tocpl, int intMaxBackK, CPoint StandardVetorCpt, double dblSmallDis)
        {
            List <CPolyline> CFrEdgeLt = CGeometricMethods.CreateCplLt(frcpl.cptlt);
            List <CPolyline> CToEdgeLt = CGeometricMethods.CreateCplLt(tocpl.cptlt);

            int intFrPtNum = frcpl.cptlt.Count;
            int intToPtNum = tocpl.cptlt.Count;

            List <CPolyline> frlastcpllt = new List <CPolyline>(intFrPtNum - 1);
            List <CPolyline> tolastcpllt = new List <CPolyline>(intToPtNum - 1);

            //注意:T矩阵中的序号跟原文算法中的序号是统一的,但线数组中的序号则应减1
            CTable[,] T = new CTable[intFrPtNum, intToPtNum];

            //T[0,0]
            T[0, 0] = new CTable();
            T[0, 0].dblEvaluation = 0;
            LinkedList <CCorrespondCPoint> CorrCptLk0 = new LinkedList <CCorrespondCPoint>();

            CorrCptLk0.AddLast(new CCorrespondCPoint(CFrEdgeLt[0].FrCpt, CToEdgeLt[0].FrCpt));
            T[0, 0].CorrCptLk = CorrCptLk0;

            CPolyline frfirstcpl = new CPolyline(0, CFrEdgeLt[0].FrCpt);  //以线状要素的第一个点作为线段

            for (int j = 1; j < intToPtNum; j++)
            {
                T[0, j]           = new CTable();
                T[0, j].intBackK1 = 0;
                T[0, j].intBackK2 = 1;
                LinkedList <CCorrespondCPoint> CorrCptLkj;
                T[0, j].dblEvaluation = T[0, j - 1].dblEvaluation + CalDistance(frfirstcpl, CToEdgeLt[j - 1], StandardVetorCpt, dblSmallDis, frcpl, tocpl, out CorrCptLkj);
                T[0, j].CorrCptLk     = CorrCptLkj;
            }

            CPolyline tofirstcpl = new CPolyline(0, CToEdgeLt[0].FrCpt);  //以线状要素的第一个点作为线段

            for (int i = 1; i < intFrPtNum; i++)
            {
                T[i, 0]           = new CTable();
                T[i, 0].intBackK1 = 1;
                T[i, 0].intBackK2 = 0;
                LinkedList <CCorrespondCPoint> CorrCptLki;
                T[i, 0].dblEvaluation = T[i - 1, 0].dblEvaluation + CalDistance(CFrEdgeLt[i - 1], tofirstcpl, StandardVetorCpt, dblSmallDis, frcpl, tocpl, out CorrCptLki);
                T[i, 0].CorrCptLk     = CorrCptLki;
            }

            //循环填满二维数组T中的各个值
            for (int i = 0; i < CFrEdgeLt.Count; i++)//大比例尺线段终点数据准备
            {
                List <CPoint> frlastptlt = new List <CPoint>(1);
                frlastptlt.Add(CFrEdgeLt[i].ToCpt);
                frlastcpllt.Add(new CPolyline(0, frlastptlt));
            }

            for (int i = 0; i < CToEdgeLt.Count; i++)//小比例尺线段终点数据准备
            {
                List <CPoint> frlastptlt = new List <CPoint>(1);
                frlastptlt.Add(CToEdgeLt[i].ToCpt);
                tolastcpllt.Add(new CPolyline(0, frlastptlt));
            }

            //注意:T中的序号1指定第一个元素,而各LT中(如CFrEdgeLt,tolastcpllt)的序号1则指定第二个元素
            for (int i = 1; i < intFrPtNum; i++)               //计算各空格值
            {
                int intBackKforI = Math.Min(i, intMaxBackK);   //程序刚开始执行时,之前已遍历过线段数较少,可能小于intMaxBackK
                for (int j = 1; j < intToPtNum; j++)
                {
                    int           intBackKforJ = Math.Min(j, intMaxBackK); //程序刚开始执行时,之前已遍历过线段数较少,可能小于intMaxBackK
                    List <CTable> CTableLt     = new List <CTable>(intBackKforI * intBackKforJ);
                    for (int k1 = 1; k1 <= intBackKforI; k1++)
                    {
                        for (int k2 = 1; k2 <= intBackKforJ; k2++)
                        {
                            CTable tableij = new CTable();
                            tableij.intBackK1 = k1;
                            tableij.intBackK2 = k2;
                            LinkedList <CCorrespondCPoint> CorrCptLkij;
                            CPolyline frcpli = frcpl.GetSubPolyline(CFrEdgeLt[i - k1].FrCpt, CFrEdgeLt[i - 1].ToCpt);
                            CPolyline tocplj = tocpl.GetSubPolyline(CToEdgeLt[j - k2].FrCpt, CToEdgeLt[j - 1].ToCpt);
                            tableij.dblEvaluation = T[i - k1, j - k2].dblEvaluation + CalDistance(frcpli, tocplj, StandardVetorCpt, dblSmallDis, frcpl, tocpl, out CorrCptLkij);
                            tableij.CorrCptLk     = CorrCptLkij;
                            CTableLt.Add(tableij);
                        }
                    }

                    //find the minimum one
                    T[i, j] = FindMinTable(CTableLt);
                }
            }

            return(T);
        }