/// <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); }
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); }