public static bool IsCutValid(List <CPoint> cptlt, CEdgeGrid pEdgeGrid, double dblThreshold, out int intIndexMaxDis) { var tplWithinTDis = IsWithinTDis(cptlt, dblThreshold); intIndexMaxDis = tplWithinTDis.Item2; if (tplWithinTDis.Item1 == false) { return(false); } //if the baseline is outside of the polygon, then the baseline is not a valid choice throw new ArgumentException( "IsClockwise is not helpful. instead test if the edge between the two edges. see CCptbCtgl"); if (CGeoFunc.IsClockwise(cptlt, false) == false) { return(false); } var cedgebaseline = new CEdge(cptlt[0], cptlt.Last()); //we don't test the four edges var IgnoreCEdgeSS = new SortedSet <CEdge> { cedgebaseline.FrCpt.InCEdge, cedgebaseline.FrCpt.OutCEdge, cedgebaseline.ToCpt.InCEdge, cedgebaseline.ToCpt.OutCEdge }; var blnIntersect = pEdgeGrid.BlnIntersect(cedgebaseline, true, true, true, IgnoreCEdgeSS); return(!blnIntersect); }
/// <summary> /// we can improve by saving a pEdgeGrid for every orginal cpg; ******************************** /// for the EnlargedCEdgeHS, we make another pEdgeGrid ******************************** /// </summary> /// <param name="cptlt"></param> /// <param name="OriginalCEdgeLt"></param> /// <param name="EnlargedCEdgeHS"></param> /// <param name="dblThreshold"></param> /// <returns></returns> private static IEnumerable <CPoint> ImaiIriSimplifyAccordExistEdges(List <CPoint> cptlt, List <CEdge> OriginalCEdgeLt, HashSet <CEdge> EnlargedCEdgeHS, double dblThreshold) { if (cptlt.Count <= 1) { throw new ArgumentOutOfRangeException("There is no points for simplification!"); } else if (cptlt.Count == 2) { yield return(cptlt[0]); yield return(cptlt[1]); } else { var allcedgelt = new List <CEdge>(OriginalCEdgeLt); allcedgelt.AddRange(EnlargedCEdgeHS); var pEdgeGrid = new CEdgeGrid(allcedgelt); var CNodeLt = new List <CNode>(cptlt.Count); CNodeLt.EveryElementNew(); CNodeLt.SetIndexID(); for (int i = 0; i < cptlt.Count - 1; i++) { CNodeLt[i].NbrCNodeLt = new List <CGeometry.CNode>(); CNodeLt[i].NbrCNodeLt.Add(CNodeLt[i + 1]); for (int j = i + 2; j < cptlt.Count; j++) { var subcptlt = cptlt.GetRange(i, j - i + 1); int intIndexMaxdis; if (IsCutValid(subcptlt, pEdgeGrid, dblThreshold, out intIndexMaxdis)) { CNodeLt[i].NbrCNodeLt.Add(CNodeLt[j]); } } } CImaiIriSimplify.BFS(CNodeLt[0], CNodeLt.Last()); var currentCNode = CNodeLt[0]; while (currentCNode != null) { yield return(cptlt[currentCNode.indexID]); currentCNode = currentCNode.NextCNode; } } }
////*******************check the codes below*************************** ////****************** should we keep at least three points? /// <summary> /// for an exterior ring, cptlt should be clockwise; for a hole, cptlt should be counter clockwise /// </summary> private static IEnumerable <CPoint> DPSimplifyAccordExistEdges(List <CPoint> cptlt, List <CEdge> OriginalCEdgeLt, HashSet <CEdge> EnlargedCEdgeHS, double dblThreshold) { if (cptlt.Count <= 1) { throw new ArgumentOutOfRangeException("There is no points for simplification!"); } else if (cptlt.Count == 2) { yield return(cptlt[0]); yield return(cptlt[1]); } else { var allcedgelt = new List <CEdge>(OriginalCEdgeLt); allcedgelt.AddRange(EnlargedCEdgeHS); var pEdgeGrid = new CEdgeGrid(allcedgelt); var IndexSk = new Stack <CValPair <int, int> >(); IndexSk.Push(new CValPair <int, int>(0, cptlt.Count - 1)); do { var StartEndVP = IndexSk.Pop(); var subcptlt = cptlt.GetRange(StartEndVP.val1, StartEndVP.val2 - StartEndVP.val1 + 1); int intIndexMaxdis; if (subcptlt.Count <= 2 || IsCutValid(subcptlt, pEdgeGrid, dblThreshold, out intIndexMaxdis)) { yield return(cptlt[StartEndVP.val1]); } else { IndexSk.Push(new CValPair <int, int>(intIndexMaxdis + StartEndVP.val1, StartEndVP.val2)); IndexSk.Push(new CValPair <int, int>(StartEndVP.val1, intIndexMaxdis + StartEndVP.val1)); } } while (IndexSk.Count > 0); yield return(cptlt.Last()); } }
public void TopologyCheck() { var ParameterInitialize = _ParameterInitialize; List <CEdge> pAllReadCEdgeLt = _AllReadCEdgeLt; long lngStartTime = System.Environment.TickCount; double dblVerySmall = CConstants.dblVerySmallCoord; throw new ArgumentException("consider setting of dblverysmall!"); for (int i = 0; i < 10; i++) { CConstants.dblVerySmallCoord = dblVerySmall / Math.Pow(10, i - 5); var fEdgeGrid = new CEdgeGrid(pAllReadCEdgeLt); var IntersectionLt = fEdgeGrid.DetectIntersectionsOfExistingEdges(true, true, true); foreach (var cedge in pAllReadCEdgeLt) { cedge.FrCpt.IntersectionLt = new List <CIntersection>(); cedge.ToCpt.IntersectionLt = new List <CIntersection>(); cedge.FrCpt.isTraversed = false; cedge.ToCpt.isTraversed = false; } List <CPoint> CrossCptLt = new List <CPoint>(); //List<CEdge> OverlapEdgeLt = new List<CEdge>(); //to save memory, we don't record overlap edges anymore, instead, we only record an end of the overlap edge List <CPoint> OverlapCptLt = new List <CPoint>(); foreach (CIntersection pIntersection in IntersectionLt) { switch (pIntersection.enumIntersectionType) { case CEnumIntersectionType.NoNo: break; case CEnumIntersectionType.FrFr: pIntersection.CEdge1.FrCpt.IntersectionLt.Add(pIntersection); //End Intersection pIntersection.CEdge2.FrCpt.IntersectionLt.Add(pIntersection); //End Intersection break; case CEnumIntersectionType.FrIn: //CrossCptLt.AddLast(pIntersection.IntersectCpt); //Cross //pIntersection.CEdge1.FrCpt.IntersectionLt.Add(pIntersection); //we don't want to notice this intersection twice, so we add this intersection to the vertice break; case CEnumIntersectionType.FrTo: pIntersection.CEdge1.FrCpt.IntersectionLt.Add(pIntersection); //End Intersection pIntersection.CEdge2.ToCpt.IntersectionLt.Add(pIntersection); //End Intersection break; case CEnumIntersectionType.InFr: //CrossCptLt.AddLast(pIntersection.IntersectCpt); //Cross //pIntersection.CEdge2.FrCpt.IntersectionLt.Add(pIntersection); //we don't want to notice this intersection twice, so we add this intersection to the vertice break; case CEnumIntersectionType.InIn: CrossCptLt.Add(pIntersection.IntersectCpt); //Cross break; case CEnumIntersectionType.InTo: //CrossCptLt.AddLast(pIntersection.IntersectCpt); //Cross //pIntersection.CEdge2.ToCpt.IntersectionLt.Add(pIntersection); //we don't want to notice this intersection twice, so we add this intersection to the vertice break; case CEnumIntersectionType.ToFr: pIntersection.CEdge1.ToCpt.IntersectionLt.Add(pIntersection); //End Intersection pIntersection.CEdge2.FrCpt.IntersectionLt.Add(pIntersection); //End Intersection break; case CEnumIntersectionType.ToIn: //CrossCptLt.AddLast(pIntersection.IntersectCpt); //Cross //pIntersection.CEdge1.ToCpt.IntersectionLt.Add(pIntersection); //we don't want to notice this intersection twice, so we add this intersection to the vertice break; case CEnumIntersectionType.ToTo: pIntersection.CEdge1.ToCpt.IntersectionLt.Add(pIntersection); //End Intersection pIntersection.CEdge2.ToCpt.IntersectionLt.Add(pIntersection); //End Intersection break; case CEnumIntersectionType.Overlap: //OverlapEdgeLt.Add(pIntersection.OverlapCEdge); OverlapCptLt.Add(pIntersection.IntersectCpt); //pIntersection.OverlapCEdge.FrCpt.IntersectionLt.Add(pIntersection); //we don't want to notice this intersection twice, so we add this intersection to the vertice //pIntersection.OverlapCEdge.ToCpt.IntersectionLt.Add(pIntersection); //we don't want to notice this intersection twice, so we add this intersection to the vertice break; default: break; } } CConstants.dblVerySmallCoord = dblVerySmall; List <CPoint> UnLinkedCptLt = new List <CPoint>(); foreach (var cedge in pAllReadCEdgeLt) { if (cedge.FrCpt.isTraversed == false && cedge.FrCpt.IntersectionLt.Count == 0) { UnLinkedCptLt.Add(cedge.FrCpt); } if (cedge.ToCpt.isTraversed == false && cedge.ToCpt.IntersectionLt.Count == 0) { UnLinkedCptLt.Add(cedge.ToCpt); } cedge.FrCpt.IntersectionLt = null; cedge.ToCpt.IntersectionLt = null; cedge.FrCpt.isTraversed = true; cedge.ToCpt.isTraversed = true; } IntersectionLt = null; CSaveFeature.SaveCGeoEb(UnLinkedCptLt, esriGeometryType.esriGeometryPoint, "UnLinkedCpt_" + i.ToString() + "__" + UnLinkedCptLt.Count, blnVisible: false); CHelpFunc.SetAEGeometryNull(UnLinkedCptLt); CSaveFeature.SaveCGeoEb(CrossCptLt, esriGeometryType.esriGeometryPoint, "Crosses_" + i.ToString() + "__" + CrossCptLt.Count, blnVisible: false); CHelpFunc.SetAEGeometryNull(CrossCptLt); CSaveFeature.SaveCGeoEb(OverlapCptLt, esriGeometryType.esriGeometryPoint, "OverlapCpt_" + i.ToString() + "__" + OverlapCptLt.Count, blnVisible: false); CHelpFunc.SetAEGeometryNull(OverlapCptLt); } long lngEndTime = System.Environment.TickCount; //记录结束时间 ParameterInitialize.tsslTime.Text = "Running Time: " + Convert.ToString(lngEndTime - lngStartTime) + "ms"; //显示运行时 }