/// <summary> /// /// </summary> /// <param name="pCptbCtgl"></param> /// <param name="SgCpt"></param> /// <returns></returns> /// <remarks >the first or last vertex of a SgCpl can be computed many times, but it doesn't matter</remarks> private CPoint CalFirstAffineCpt(CCptbCtgl pCptbCtgl, CPoint SgCpt, SortedDictionary <CPoint, CPoint> pInterLSCptSD) { CTriangulation pFrCtgl = pCptbCtgl.FrCtgl; CTriangulation pToCtgl = pCptbCtgl.ToCtgl; CPoint AffineCpt = null; CPoint outcpt; bool blnContainsKey = pInterLSCptSD.TryGetValue(SgCpt, out outcpt); if (blnContainsKey == true) { AffineCpt = pToCtgl.CptLt[outcpt.indexID]; } else { AffineCpt = CalFirstSingleAffineCpt(SgCpt, pFrCtgl, pToCtgl); } return(AffineCpt); }
/// <summary> /// Transform interior polylines in one province /// </summary> /// <param name="pParameterInitialize"></param> /// <param name="InterLSIplLt"></param> /// <param name="InterSSIplLt"></param> /// <param name="SgIplLt"></param> /// <returns></returns> /// <remarks>InterLSIplLt and InterSSIplLt can be clockwise of counterclockwise. /// we will construct DCEL, in which the directions will be counterclockwise. /// InterLSIplLt and InterSSIplLt should have the same direction and the corresponding start points</remarks> private List <CPolyline> CTTransform(List <IPolyline5> InterLSIplLt, List <IPolyline5> InterSSIplLt, List <IPolyline5> SgIplLt, bool blnMaxCommonChords = true) { CConstants.dblVerySmallCoord /= 10; //this assignment should equal to _dblVerySmallDenominator = 10000000 var InterLSCplLt = CHelpFunc.GenerateCGeoEbAccordingToGeoEb <CPolyline>(InterLSIplLt).ToList(); var InterSSCplLt = CHelpFunc.GenerateCGeoEbAccordingToGeoEb <CPolyline>(InterSSIplLt).ToList(); var SgCplEb = CHelpFunc.GenerateCGeoEbAccordingToGeoEb <CPolyline>(SgIplLt); //there are only two faces: the super face and a normal face. Face *.FaceCpgLt[1] is the normal face var pInterLSDCEL = new CDCEL(InterLSCplLt); pInterLSDCEL.ConstructDCEL(); pInterLSDCEL.FaceCpgLt[1].SetOuterFaceCptlt(false, true, InterLSCplLt[0].CptLt[0]); //there are only two faces: the super face and a normal face. Face *.FaceCpgLt[1] is the normal face var pInterSSDCEL = new CDCEL(InterSSCplLt); pInterSSDCEL.ConstructDCEL(); pInterSSDCEL.FaceCpgLt[1].SetOuterFaceCptlt(false, true, InterSSCplLt[0].CptLt[0]); //we maintaine this SD so that for a point from single polyline, //we can know whether this single point overlaps a point of a larger-scale polyline var pInterLSCptSD = pInterLSDCEL.FaceCpgLt[1].CptLt.ToSD(cpt => cpt, new CCmpCptYX_VerySmall()); var pCptbCtgl = new CCptbCtgl(pInterLSDCEL.FaceCpgLt[1], pInterSSDCEL.FaceCpgLt[1], blnMaxCommonChords, _blnSave); pCptbCtgl.ConstructCcptbCtgl(); var TransSgCPlLt = new List <CPolyline>(SgIplLt.Count); foreach (var SgCpl in SgCplEb) { TransSgCPlLt.Add(GenerateCorrSgCpl(pCptbCtgl, SgCpl, pInterLSCptSD)); } CConstants.dblVerySmallCoord *= 10; return(TransSgCPlLt); }
//private void SgCplTraverse(CTriangulation pFrCtgl, List <CEdge > SgCEdgeLt, ref int intIndex) private CPolyline GenerateCorrSgCpl(CCptbCtgl pCptbCtgl, CPolyline SgCpl, SortedDictionary <CPoint, CPoint> pInterLSCptSD) { CTriangulation pFrCtgl = pCptbCtgl.FrCtgl; CTriangulation pToCtgl = pCptbCtgl.ToCtgl; var AffineCptLt = new List <CPoint>(SgCpl.CptLt.Count); AffineCptLt.Add(CalFirstAffineCpt(pCptbCtgl, SgCpl.CptLt[0], pInterLSCptSD)); //the first vertex SgCpl.JudgeAndFormCEdgeLt(); //CareCEdge is an edge that current edge may cross with current triangle //CareCEdgeLt has three edges at most var CareCEdgeLt = FindCareCEdgeLtForFirstCEdge(pFrCtgl, SgCpl.CEdgeLt[0], pInterLSCptSD); if (SgCpl.CEdgeLt.Count == 1 && CCmpMethods.CmpCEdgeCoord(CareCEdgeLt[0], SgCpl.CEdgeLt[0]) == 0) { //this is a special case where a single polyline has only one edge (SgCEdge), //at the same time, this edge is used by the combined triangulation var newCEdge = pToCtgl.HalfEdgeLt[CareCEdgeLt[0].indexID]; AffineCptLt.Add(newCEdge.ToCpt); return(new CPolyline(SgCpl.ID, AffineCptLt)); } int intEdgeCount = 0; var CurrentCEdge = SgCpl.CEdgeLt[intEdgeCount++]; do { bool isFoundExit = false; //whether this edge can go out current polygon (a triangle) foreach (var carecedge in CareCEdgeLt) { var pIntersection = CurrentCEdge.IntersectWith(carecedge); switch (pIntersection.enumIntersectionType) { case CEnumIntersectionType.NoNo: break; //this case is actually only for the fisrt vertex of a SgCpl, //because for other intersections which coincide a triangulation node, //we would not add the two neighbour edges in to CareCEdgeLt case CEnumIntersectionType.FrFr: CareCEdgeLt = GetCareCEdgeLtCptCoincident(carecedge.FrCpt, CurrentCEdge); isFoundExit = true; break; //this case is actually only for the fisrt vertex of a SgCpl, //because for other intersections which coincide a triangulation node, //we would not add the two neighbour edges in to CareCEdgeLt case CEnumIntersectionType.FrIn: //this can happen, when the first SgCpt is on an triangle edge of FrCtgl CareCEdgeLt = GetCareCEdgeLt(carecedge.cedgeTwin, false); isFoundExit = true; break; //this case is actually only for the fisrt vertex of a SgCpl, //because for other intersections which coincide a triangulation node, //we would not add the two neighbour edges in to CareCEdgeLt case CEnumIntersectionType.FrTo: CareCEdgeLt = GetCareCEdgeLtCptCoincident(carecedge.ToCpt, CurrentCEdge); //this can happen isFoundExit = true; break; case CEnumIntersectionType.InFr: AffineCptLt.Add(pToCtgl.CptLt[carecedge.FrCpt.indexID]); CareCEdgeLt = GetCareCEdgeLtCptCoincident(carecedge.FrCpt, CurrentCEdge); isFoundExit = true; break; case CEnumIntersectionType.InIn: AffineCptLt.Add(ComputeAffineCptForInbetween(pToCtgl, pIntersection)); CareCEdgeLt = GetCareCEdgeLt(carecedge.cedgeTwin, false); isFoundExit = true; break; case CEnumIntersectionType.InTo: AffineCptLt.Add(pToCtgl.CptLt[carecedge.ToCpt.indexID]); CareCEdgeLt = GetCareCEdgeLtCptCoincident(carecedge.ToCpt, CurrentCEdge); isFoundExit = true; break; case CEnumIntersectionType.ToFr: //come to the end of an edge AffineCptLt.Add(pToCtgl.CptLt[carecedge.FrCpt.indexID]); if (intEdgeCount < SgCpl.CEdgeLt.Count) { CurrentCEdge = SgCpl.CEdgeLt[intEdgeCount]; CareCEdgeLt = GetCareCEdgeLtCptCoincident(carecedge.FrCpt, CurrentCEdge); } intEdgeCount++; isFoundExit = true; break; case CEnumIntersectionType.ToIn: //come to the end of an edge AffineCptLt.Add(ComputeAffineCptForInbetween(pToCtgl, pIntersection)); if (intEdgeCount < SgCpl.CEdgeLt.Count) { CurrentCEdge = SgCpl.CEdgeLt[intEdgeCount]; CareCEdgeLt = GetCareCEdgeLt(carecedge.cedgeTwin, false); } intEdgeCount++; isFoundExit = true; break; case CEnumIntersectionType.ToTo: //come to the end of an edge AffineCptLt.Add(pToCtgl.CptLt[carecedge.ToCpt.indexID]); if (intEdgeCount < SgCpl.CEdgeLt.Count) { CurrentCEdge = SgCpl.CEdgeLt[intEdgeCount]; CareCEdgeLt = GetCareCEdgeLtCptCoincident(carecedge.ToCpt, CurrentCEdge); } intEdgeCount++; isFoundExit = true; break; //maybe we can just ignore overlap, because if there is overlap, then there is also other cases case CEnumIntersectionType.Overlap: MessageBox.Show("we didn't consider Overlap when GenerateCorrSgCpl in:" + this.ToString() + ".cs "); break; default: break; } if (isFoundExit == true) { break; } } if (isFoundExit == false) //come to the end of an edge { AffineCptLt.Add(CalAffineCpt(CurrentCEdge.ToCpt, CareCEdgeLt[0], pFrCtgl, pToCtgl)); if (intEdgeCount < SgCpl.CEdgeLt.Count) { CurrentCEdge = SgCpl.CEdgeLt[intEdgeCount]; CareCEdgeLt = GetCareCEdgeLt(CareCEdgeLt[0], true); } intEdgeCount++; } } while (intEdgeCount <= SgCpl.CEdgeLt.Count); return(new CPolyline(SgCpl.ID, AffineCptLt)); }