/// <summary>计算切割时刻</summary> /// <param name="CBSRiverNetLt">大比例尺表达河网列</param> /// <remarks></remarks> private void CalCutTime(List <CRiverNet> CBSRiverNetLt) { SortedList <double, CRiver> dblDataSLt = new SortedList <double, CRiver>(new CCmpDbl()); //添加大比例尺表达图层中(包括各河网)的所有没有对应河流的河流 for (int i = 0; i < CBSRiverNetLt.Count; i++) { for (int j = 0; j < CBSRiverNetLt[i].CRiverLt.Count; j++) { if (CBSRiverNetLt[i].CRiverLt[j].CCorrRiver == null) //有对应河流 { dblDataSLt.Add(CBSRiverNetLt[i].CRiverLt[j].LengthSum, CBSRiverNetLt[i].CRiverLt[j]); } } } int intCount = dblDataSLt.Count; double dblInterval = (dblDataSLt.Keys[intCount - 1] - dblDataSLt.Keys[0]) / (intCount - 1); double dblDCutBound = dblDataSLt.Keys[0] - dblInterval; double dblUCutBound = dblDataSLt.Keys[intCount - 1] + dblInterval; double dblDis = dblUCutBound - dblDCutBound; for (int i = 0; i < dblDataSLt.Count; i++) { CRiver pRiver = dblDataSLt.Values[i]; pRiver.dblCutTime = (pRiver.LengthSum - dblDCutBound) / dblDis; } }
/// <summary>递归计算该河流的长度总和(该河流及其所有支流的长度之和)</summary> /// <param name="pRiver">当前河流</param> private void RecursiveCalLengthSum(CRiver pRiver) { pRiver.LengthSum = pRiver.pPolyline.Length; if (pRiver.CTributaryLt.Count > 0) { for (int i = 0; i < pRiver.CTributaryLt.Count; i++) { RecursiveCalLengthSum(pRiver.CTributaryLt[i]); //先计算该支流的长度总和,再计算当前河流的长度总和 pRiver.LengthSum = pRiver.LengthSum + pRiver.CTributaryLt[i].LengthSum; } } }
/// <summary>递归计算河流的层次和等级</summary> /// <param name="pRiver">当前河流</param> public void RecursiveCalLeverAndOrder(CRiver pRiver) { //计算层次 pRiver.dblLevel = pRiver.CMainStream.dblLevel + 1; //计算等级 for (int i = 0; i < pRiver.CTributaryLt.Count; i++) { RecursiveCalLeverAndOrder(pRiver.CTributaryLt[i]); pRiver.dblOrder = pRiver.dblOrder + pRiver.CTributaryLt[i].dblOrder; } pRiver.dblOrder = pRiver.dblOrder + 1; }
/// <summary>计算河流的层次和等级</summary> /// <param name="pMasterRiver">主干流</param> /// <remarks>主干流的层次为1,支流的层次为干流的层次+1;河流的等级为河流的所有支流数量之和再加1</remarks> public void CalLeverAndOrder(CRiver pMasterRiver) { //主河流的层次为1 pMasterRiver.dblLevel = 1; //计算等级 for (int i = 0; i < pMasterRiver.CTributaryLt.Count; i++) { RecursiveCalLeverAndOrder(pMasterRiver.CTributaryLt[i]); pMasterRiver.dblOrder = pMasterRiver.dblOrder + pMasterRiver.CTributaryLt[i].dblOrder; } pMasterRiver.dblOrder = pMasterRiver.dblOrder + 1; }
/// <summary>递归添加属于该河网的河流</summary> /// <param name="pRiverNet">河网</param> /// <param name="CurrentRiver">当前河流</param> private void RecursiveSettleRiver(ref CRiverNet pRiverNet, CRiver CurrentRiver) { if (CurrentRiver.CTributaryLt.Count == 0) { return; } for (int i = 0; i < CurrentRiver.CTributaryLt.Count; i++) { pRiverNet.CRiverLt.Add(CurrentRiver.CTributaryLt[i]); RecursiveSettleRiver(ref pRiverNet, CurrentRiver.CTributaryLt[i]); } }
/// <summary>处理上一级河流没有对应河流的情况</summary> /// <param name="pCorrespondRiverNet">对应河网数据</param> /// <param name="pBSRiver">当前大比例尺表达河流</param> /// <param name="dblMainReductionRatio">上一级河流缩减比率</param> /// <remarks>RecursiveDWNotExistCorr:RecursiveDealWithNotExistCorrepondenceRiver</remarks> private void RecursiveDWNotExistCorr(CCorrespondRiverNet pCorrespondRiverNet, CRiver pBSRiver, double dblMainReductionRatio) { CRiver pMainStream = pBSRiver.CMainStream; IPoint intersectipt = pBSRiver.pPolyline.ToPoint; double dblFromStartLength = CGeoFunc.CalDistanceFromStartPoint((IPolyline5)pMainStream, intersectipt, false); double dblCurrentReductionRatio = pMainStream.pPolyline.Length / dblFromStartLength; pBSRiver.dblReductionRatio = dblCurrentReductionRatio * dblMainReductionRatio; //pCorrespondRiverNet.CResultRiverLt.Add(pBSRiver); //处理当前河流的支流 for (int i = 0; i < pBSRiver.CTributaryLt.Count; i++) { RecursiveDWNotExistCorr(pCorrespondRiverNet, pBSRiver.CTributaryLt[i], pBSRiver.dblReductionRatio); } }
/// <summary>找到当前河流与其各支流的相交点(属于当前河流),并记录在支流河流数据中(顺便完成了支流记录从上游到下游的排序)</summary> /// <param name="pRiver">当前河流</param> /// <param name="dblVerySmall">一个非常小的值</param> /// <remarks>对于一条“其干流有对应河流”的河流,其变化(收缩、平移)时,由于其干流在不断移动,会造成脱节或相交, /// 因此要记录此处相交点,以方便后续处理</remarks> public void RecursiveFindTocpt2(CRiver pRiver, double dblVerySmall) { if (pRiver.CTributaryLt.Count == 0) { return; //如果不存在支流,则直接返回 } //数据准备 List <CRiver> pTributaryLt = new List <CRiver>(); pTributaryLt.AddRange(pRiver.CTributaryLt); //找到每条支流的终点"Tocpt",并添加到数组pTributaryTocptLt List <CPoint> pTributaryTocptLt = new List <CPoint>(); for (int i = 0; i < pTributaryLt.Count; i++) { pTributaryTocptLt.Add(pTributaryLt[i].CptLt[pTributaryLt[i].CptLt.Count - 1]); } //寻找各支流的Tocpt2 List <CRiver> pNewTributaryLt = new List <CRiver>(); for (int i = 0; i < pRiver.CptLt.Count; i++) { for (int j = pTributaryTocptLt.Count - 1; j >= 0; j--) { //为顾及“多叉路口”的情况,此处找到交点后应继续寻找(一个点可能对应多个支流),因此if中没有放入"break" if (pRiver.CptLt[i].Equals2D(pTributaryTocptLt[j])) { pTributaryLt[j].Tocpt2 = pRiver.CptLt[i]; pNewTributaryLt.Add(pTributaryLt[j]); //从上游到下游记录支流 pTributaryLt.RemoveAt(j); //为节省时间,找到即移除该河流 pTributaryTocptLt.RemoveAt(j); //为节省时间,找到"Tocpt2"即移除该点 } } } pRiver.CTributaryLt = pNewTributaryLt; //得到排好序的支流 //依次对该河流的支流进行操作 for (int i = 0; i < pRiver.CTributaryLt.Count; i++) { RecursiveFindTocpt2(pRiver.CTributaryLt[i], dblVerySmall); } }
/// <summary>依据线数据建立河网列(包括建立干支关系,添加各支流成员)</summary> /// <param name="CPlLt">线数据</param> /// <param name="pParameterThreshold">阈值参数</param> /// <returns>河网列</returns> public List <CRiverNet> BuildRiverNetLt(List <CPolyline> CPlLt, CParameterThreshold pParameterThreshold) { double dblVerySmall = CConstants.dblVerySmallCoord; //根据线数据生成河流数据 List <CRiver> CAllRiverLt = new List <CRiver>(); for (int i = 0; i < CPlLt.Count; i++) { CRiver pRiver = new CRiver(i, CPlLt[i], dblVerySmall); CAllRiverLt.Add(pRiver); } CreateRiverRelationship(ref CAllRiverLt); //创建各河流间的干支关系 List <CRiverNet> pRiverNetLt = CreateRiverNetLt(CAllRiverLt, dblVerySmall); // 创建河网 return(pRiverNetLt); }
/// <summary>依据线数据建立河网列(包括建立干支关系,添加各支流成员)</summary> /// <param name="CPlLt">线数据</param> /// <param name="pParameterThreshold">阈值参数</param> /// <returns>河网列</returns> public List <CRiverNet> BuildRiverNetLt(List <CPolyline> CPlLt, CParameterThreshold pParameterThreshold, ref long lngTime) { double dblVerySmall = CConstants.dblVerySmallCoord; double dblBuffer = pParameterThreshold.dblBuffer; //根据线数据生成河流数据 long lngStartTime = System.Environment.TickCount; List <CRiver> CAllRiverLt = new List <CRiver>(); for (int i = 0; i < CPlLt.Count; i++) { CRiver pRiver = new CRiver(i, CPlLt[i], dblBuffer, dblVerySmall); CAllRiverLt.Add(pRiver); } long lngEndTime = System.Environment.TickCount; lngTime = lngEndTime - lngStartTime; CreateRiverRelationship(ref CAllRiverLt); //创建各河流间的干支关系 List <CRiverNet> pRiverNetLt = CreateRiverNetLt(CAllRiverLt, dblVerySmall); // 创建河网 return(pRiverNetLt); }
public CPolyline(CRiver pRiver, bool blnSetPolyline = false) : this(pRiver.ID, pRiver.CptLt, blnSetPolyline) { }
public CCorrespondRiver(CRiver pCFromRiver, CRiver pCToRiver) { _CFromRiver = pCFromRiver; _CToRiver = pCToRiver; }
/// <summary>处理上一级河流有对应河流的情况</summary> /// <param name="pCorrespondRiverNet">对应河网数据</param> /// <param name="pParameterThreshold">阈值参数</param> /// <remarks>RecursiveDWExistCorr:RecursiveDealWithExistCorrepondenceRiver</remarks> private void RecursiveDWExistCorrCut(CCorrespondRiverNet pCorrespondRiverNet, CParameterThreshold pParameterThreshold, CRiver pBSRiver) { if (pBSRiver.CCorrRiver != null) { _OptMRL.DWExistCorr(pCorrespondRiverNet, pParameterThreshold, pBSRiver); //处理当前河流的支流 for (int i = 0; i < pBSRiver.CTributaryLt.Count; i++) { RecursiveDWExistCorrCut(pCorrespondRiverNet, pParameterThreshold, pBSRiver.CTributaryLt[i]); } } }
/// <summary>处理上一级河流有对应河流的情况</summary> /// <param name="pCorrespondRiverNet">对应河网数据</param> /// <param name="dblLengthSumRatio">小比例尺表达河流</param> /// <param name="pParameterThreshold">阈值参数</param> /// <remarks>DWExistCorr:DealWithExistCorrepondenceRiver /// 河流的对应特征点结果存储在它们自己的“pBSRiver.CResultPtLt中”; /// 此外pCorrespondRiverNet.CResultPtLtLt则存储了对应河网中各河流的对应特征点结果</remarks> public void DWExistCorr(CCorrespondRiverNet pCorrespondRiverNet, CParameterThreshold pParameterThreshold, CRiver pBSRiver) { //pBSRiver.CResultPtLt = new List<CPoint>(); //CRiver pSSRiver = pBSRiver.CCorrRiver; //CMPBDP OptMPBDP = new CMPBDP(); //if ((pBSRiver.CCorrTriJunctionPtLt != null) && // (pBSRiver.CCorrTriJunctionPtLt.Count != 0) && // (pBSRiver.CCorrTriJunctionPtLt.Count == pSSRiver.CCorrTriJunctionPtLt.Count)) //{ // //数据准备 // List<CPoint> pBSCorrTriJunctionPtLt = new List<CPoint>(); // pBSCorrTriJunctionPtLt.Add(pBSRiver.CptLt[0]); // pBSCorrTriJunctionPtLt.AddRange(pBSRiver.CCorrTriJunctionPtLt); // pBSCorrTriJunctionPtLt.Add(pBSRiver.CptLt[pBSRiver.CptLt.Count - 1]); // List<CPoint> pSSCorrTriJunctionPtLt = new List<CPoint>(); // pSSCorrTriJunctionPtLt.Add(pSSRiver.CptLt[0]); // pSSCorrTriJunctionPtLt.AddRange(pSSRiver.CCorrTriJunctionPtLt); // pSSCorrTriJunctionPtLt.Add(pSSRiver.CptLt[pSSRiver.CptLt.Count - 1]); // List<CPolyline> pBSsubcpllt = new List<CPolyline>(); // List<CPolyline> pSSsubcpllt = new List<CPolyline>(); // for (int i = 0; i < pBSCorrTriJunctionPtLt.Count - 1; i++) // { // CPolyline pBSsubcpl = pBSRiver.GetSubPolyline(pBSCorrTriJunctionPtLt[i], pBSCorrTriJunctionPtLt[i + 1]); // CPolyline pSSsubcpl = pSSRiver.GetSubPolyline(pSSCorrTriJunctionPtLt[i], pSSCorrTriJunctionPtLt[i + 1]); // MessageBox.Show("CMRL.cs: Row499 is needed to be improved"); // //OptMPBDP.DivideCplForDP(pBSsubcpl); // //OptMPBDP.DivideCplForDP(pSSsubcpl); // pBSsubcpllt.Add(pBSsubcpl); // pSSsubcpllt.Add(pSSsubcpl); // } // CAlgorithmsHelper pAlgorithmsHelper = new CAlgorithmsHelper(); // CParameterThreshold ParameterThreshold = new CParameterThreshold(); // //double dblSumLength = frcpl.pPolyline.Length + tocpl.pPolyline.Length; // CTranslation pTranslation = new CTranslation(); // double dblMin = double.MaxValue; // int intIndex = 0; // for (int i = 0; i < 25; i++) // { // ParameterThreshold.dblDLengthBound = pParameterThreshold.dblLengthSumRatio * (1 - 0.02 * i); // ParameterThreshold.dblULengthBound = pParameterThreshold.dblLengthSumRatio / (1 - 0.02 * i); // List<CPoint> ResultPtLt = new List<CPoint>(); // for (int j = 0; j < pBSsubcpllt.Count; j++) // { // //进行弯曲匹配,提取对应线段 // C5.LinkedList<CCorrSegment> CorrespondSegmentLk = new C5.LinkedList<CCorrSegment>(); // MessageBox.Show("CMRL.cs: Row523 is needed to be improved"); // //OptMPBDP.SubPolylineMatch(pBSsubcpllt[j], pSSsubcpllt[j], ParameterThreshold, ref CorrespondSegmentLk); // //按指定方式对对应线段进行点匹配,提取对应点 // ResultPtLt.AddRange(pAlgorithmsHelper.BuildPointCorrespondence(CorrespondSegmentLk, "Linear")); // if ((j > 0) && (i < pBSsubcpllt.Count - 1)) // { //考虑到线段相接处的顶点被两次求解对应点,最好删除一对对应点 // ResultPtLt.RemoveAt(ResultPtLt.Count - 1); // } // } // double dblTranslation = pTranslation.CalTranslation(ResultPtLt); // if (dblTranslation < dblMin) // { // intIndex = i; // dblMin = dblTranslation; // } // } // //求出最佳解 // ParameterThreshold.dblDLengthBound = pParameterThreshold.dblLengthSumRatio * (1 - 0.02 * intIndex); // ParameterThreshold.dblULengthBound = pParameterThreshold.dblLengthSumRatio / (1 - 0.02 * intIndex); // List<CPoint> pResultPtLt = new List<CPoint>(); // for (int j = 0; j < pBSsubcpllt.Count; j++) // { // //进行弯曲匹配,提取对应线段 // C5.LinkedList<CCorrSegment> CorrespondSegmentLk = new C5.LinkedList<CCorrSegment>(); // MessageBox.Show("CMRL.cs: Row551 is needed to be improved"); // //OptMPBDP.SubPolylineMatch(pBSsubcpllt[j], pSSsubcpllt[j], ParameterThreshold, ref CorrespondSegmentLk); // //按指定方式对对应线段进行点匹配,提取对应点 // pResultPtLt.AddRange(pAlgorithmsHelper.BuildPointCorrespondence(CorrespondSegmentLk, "Linear")); // if ((j > 0) && (j < pBSsubcpllt.Count - 1)) // { //考虑到线段相接处的顶点被两次求解对应点,最好删除一对对应点 // pResultPtLt.RemoveAt(pResultPtLt.Count - 1); // } // } // pBSRiver.CResultPtLt = pResultPtLt; // pCorrespondRiverNet.CResultPtLtLt.Add(pResultPtLt); //} //else //{ // CPolyline pBScpl = new CPolyline(pBSRiver); // CPolyline pSScpl = new CPolyline(pSSRiver); // MessageBox.Show("CMRL.cs: Row570 is needed to be improved"); // //pBSRiver.CResultPtLt = OptMPBDP.DWByDP(pBScpl, pSScpl, pParameterThreshold.dblLengthSumRatio, "Linear"); // pCorrespondRiverNet.CResultPtLtLt.Add(pBSRiver.CResultPtLt); //} }
/// <summary>处理上一级河流有对应河流的情况</summary> /// <param name="pCorrespondRiverNet">对应河网数据</param> /// <param name="dblLengthSumRatio">小比例尺表达河流</param> /// <param name="pParameterThreshold">阈值参数</param> /// <remarks>RecursiveDWExistCorr:RecursiveDealWithExistCorrepondenceRiver /// 注意:不管主干流存不存在对应河流,都从此处开始,因为不存在对应河流则在此函数中自动转入处理不存在对应河流的函数</remarks> public void RecursiveDWExistCorr(CCorrespondRiverNet pCorrespondRiverNet, CParameterThreshold pParameterThreshold, CRiver pBSRiver) { if (pBSRiver.CCorrRiver != null) { DWExistCorr(pCorrespondRiverNet, pParameterThreshold, pBSRiver); //处理当前河流的支流 for (int i = 0; i < pBSRiver.CTributaryLt.Count; i++) { RecursiveDWExistCorr(pCorrespondRiverNet, pParameterThreshold, pBSRiver.CTributaryLt[i]); } } else { pBSRiver.dblReductionRatio = 1; //pCorrespondRiverNet.CResultRiverLt.Add(pBSRiver); //处理当前河流的支流 for (int i = 0; i < pBSRiver.CTributaryLt.Count; i++) { RecursiveDWNotExistCorr(pCorrespondRiverNet, pBSRiver.CTributaryLt[i], 1); } } }
/// <summary>递归找到对应河流,同时记录对应支流对应交汇点</summary> /// <param name="CCorrespondRiverLt">对应河流记录列</param> /// <param name="pBSRiver">大比例尺表达河流</param> /// <param name="pSSRiver">小比例尺表达河流</param> /// <param name="pParameterThreshold">阈值参数</param> /// <remarks ></remarks> private void RecursiveFindCorrespondRiverLt(ref List <CCorrespondRiver> CCorrespondRiverLt, CRiver pBSRiver, CRiver pSSRiver, CParameterThreshold pParameterThreshold) { //建立河流对应关系 pBSRiver.CCorrRiver = pSSRiver; pSSRiver.CCorrRiver = pBSRiver; CCorrespondRiver pCorrespondRiver = new CCorrespondRiver(pSSRiver, pBSRiver); pCorrespondRiver.blnCorr = true; CCorrespondRiverLt.Add(pCorrespondRiver); //如果小比例尺表达河流分支不存在 if (pSSRiver.CTributaryLt == null) { return; } //数据准备 pBSRiver.CCorrTriJunctionPtLt = new List <CPoint>(); pSSRiver.CCorrTriJunctionPtLt = new List <CPoint>(); List <CRiver> pBSTributaryLt = pBSRiver.CTributaryLt; List <CRiver> pSSTributaryLt = new List <CRiver>(); pSSTributaryLt.AddRange(pSSRiver.CTributaryLt); //遍历寻找对应河流 for (int i = 0; i < pBSTributaryLt.Count; i++) { bool blnIsOverlap = false; for (int j = 0; j < pSSTributaryLt.Count; j++) { blnIsOverlap = CGeoFunc.IsOverlap(pBSTributaryLt[i], pSSTributaryLt[j], pParameterThreshold.dblOverlapRatio); //判断两河流是否重叠 if (blnIsOverlap == true) { pBSRiver.CCorrTriJunctionPtLt.Add(pBSTributaryLt[i].Tocpt2); pSSRiver.CCorrTriJunctionPtLt.Add(pSSTributaryLt[j].Tocpt2); RecursiveFindCorrespondRiverLt(ref CCorrespondRiverLt, pBSTributaryLt[i], pSSTributaryLt[j], pParameterThreshold); //递归找到对应河流 pSSTributaryLt.RemoveAt(j); break; } } } //记录对应交汇点的目的是有助于将原河流进行对应分割以提高精度 //大多数情况下,交汇点都是“三叉路口”,此时数组"CCorrTriJunctionPtLt"中不会有重合点 //但当交汇点为“四、五甚至更多叉路口”时,数组"CCorrTriJunctionPtLt"中有重合点,应只保留其中一个点 for (int i = pBSRiver.CCorrTriJunctionPtLt.Count - 1; i > 0; i--) { if (pBSRiver.CCorrTriJunctionPtLt[i].Equals2D(pBSRiver.CCorrTriJunctionPtLt[i - 1])) { pBSRiver.CCorrTriJunctionPtLt.RemoveAt(i); pSSRiver.CCorrTriJunctionPtLt.RemoveAt(i); } } }