/// <summary> /// Computes a trivial result /// </summary> /// <returns>Whether a trivial result could be computed</returns> private bool ComputeTrivialResult(out ContourPolygon result) { // When one of the polygons is empty, the result is trivial if (Subject.VertexCount == 0 || Clipping.VertexCount == 0) { switch (Operation) { case OperationType.Difference: result = Subject; break; case OperationType.Union: case OperationType.Xor: result = Subject.VertexCount > 0 ? Subject : Clipping; break; case OperationType.Intersection: result = new ContourPolygon(); break; default: throw new ArgumentException("Invalid Operation"); } return(true); } // Optimization 1: When the polygons do not overlap, the result is trivial if (!SubjectBoundingBox.Overlaps(ClippingBoundingBox)) { // The bounding boxes do not overlap switch (Operation) { case OperationType.Difference: result = Subject; break; case OperationType.Union: case OperationType.Xor: result = Subject; result.Join(Clipping); break; case OperationType.Intersection: result = new ContourPolygon(); break; default: throw new ArgumentException("Invalid Operation"); } return(true); } result = null; return(false); }
private ContourPolygon GetFilledRandomContourPolygon(string OmitPropName) { ContourPolygon contourPolygon = new ContourPolygon(); if (OmitPropName != "ContourValue") { contourPolygon.ContourValue = GetRandomDouble(0.0D, 10.0D); } if (OmitPropName != "Layer") { contourPolygon.Layer = GetRandomInt(1, 100); } if (OmitPropName != "Depth_m") { contourPolygon.Depth_m = GetRandomDouble(1.0D, 10000.0D); } //CSSPError: property [ContourNodeList] and type [ContourPolygon] is not implemented return(contourPolygon); }
private IEnumerable <ValidationResult> Validate(ValidationContext validationContext, ActionDBTypeEnum actionDBType) { string retStr = ""; Enums enums = new Enums(LanguageRequest); ContourPolygon contourPolygon = validationContext.ObjectInstance as ContourPolygon; contourPolygon.HasErrors = false; if (contourPolygon.ContourValue < 0) { contourPolygon.HasErrors = true; yield return(new ValidationResult(string.Format(CSSPServicesRes._MinValueIs_, "ContourValue", "0"), new[] { "ContourValue" })); } if (contourPolygon.Layer < 1 || contourPolygon.Layer > 100) { contourPolygon.HasErrors = true; yield return(new ValidationResult(string.Format(CSSPServicesRes._ValueShouldBeBetween_And_, "Layer", "1", "100"), new[] { "Layer" })); } if (contourPolygon.Depth_m < 1 || contourPolygon.Depth_m > 10000) { contourPolygon.HasErrors = true; yield return(new ValidationResult(string.Format(CSSPServicesRes._ValueShouldBeBetween_And_, "Depth_m", "1", "10000"), new[] { "Depth_m" })); } //CSSPError: Type not implemented [ContourNodeList] of type [List`1] //CSSPError: Type not implemented [ContourNodeList] of type [Node] retStr = ""; // added to stop compiling CSSPError if (retStr != "") // will never be true { contourPolygon.HasErrors = true; yield return(new ValidationResult("AAA", new[] { "AAA" })); } }
/// <summary> /// Creates a new object for executing a single boolean operation using the Martinez algorithm. Usually, the /// next call will be a call to <see cref="Run"/>. The created object can only be used for executing the algorithm /// once. /// </summary> /// <param name="subject">The subject polygon. It must adhere to the orientation as specified in the documentation of ContourPolygon.</param> /// <param name="clipping">The clipping polygon. It must adhere to the orientation as specified in the documentation of ContourPolygon.</param> /// <param name="operation"></param> public Martinez(ContourPolygon subject, ContourPolygon clipping, OperationType operation = OperationType.Union) { Subject = subject; Clipping = clipping; Operation = operation; }
private ContourPolygon ConnectEdges() { var result = new ContourPolygon(); var resultEvents = ResultEvents .Where(it => (it.IsStart && it.InResult) || (!it.IsStart && it.OtherEvent.InResult)).ToList(); // Due to overlapping edges the resultEvents list can be not wholly sorted var sorted = false; while (!sorted) { sorted = true; for (int i = 0; i < resultEvents.Count; i++) { if (i + 1 < resultEvents.Count && SweepEvent.CompareTo(resultEvents[i], resultEvents[i + 1]) == 1) { var tmp = resultEvents[i]; resultEvents[i] = resultEvents[i + 1]; resultEvents[i + 1] = tmp; sorted = false; } } } // We cannot do a foreach because we need to set PositionInResult for (int i = 0; i < resultEvents.Count; i++) { var resultEvent = resultEvents[i]; resultEvent.PositionInResult = i; } foreach (var resultEvent in resultEvents) { if (!resultEvent.IsStart) { var tmp = resultEvent.PositionInResult; resultEvent.PositionInResult = resultEvent.OtherEvent.PositionInResult; resultEvent.OtherEvent.PositionInResult = tmp; } } var processed = new BitArray(resultEvents.Count); var depth = new List <int>(); var holeOf = new List <int>(); for (int i = 0; i < resultEvents.Count; i++) { if (processed[i]) { continue; } var contour = new Contour(); result.Add(contour); var contourId = result.NumberOfContours - 1; depth.Add(0); holeOf.Add(-1); if (resultEvents[i].PreviousInResult != null) { var lowerContourId = resultEvents[i].PreviousInResult.ContourId; if (!resultEvents[i].PreviousInResult.ResultInOut) { result[lowerContourId].AddHole(contourId); holeOf[contourId] = lowerContourId; depth[contourId] = depth[lowerContourId] + 1; contour.External = false; } else if (!result[lowerContourId].External) { result[holeOf[lowerContourId]].AddHole(contourId); holeOf[contourId] = holeOf[lowerContourId]; depth[contourId] = depth[lowerContourId]; contour.External = false; } } var pos = i; var initial = resultEvents[i].Point; contour.AddVertex(initial); while (pos >= i) { processed[pos] = true; if (resultEvents[pos].IsStart) { resultEvents[pos].ResultInOut = false; resultEvents[pos].ContourId = contourId; } else { resultEvents[pos].OtherEvent.ResultInOut = true; resultEvents[pos].OtherEvent.ContourId = contourId; } pos = resultEvents[pos].PositionInResult; processed[pos] = true; contour.AddVertex(resultEvents[pos].Point); pos = NextPos(pos, resultEvents, processed, i); } pos = pos == -1 ? i : pos; processed[pos] = processed[resultEvents[pos].PositionInResult] = true; resultEvents[pos].OtherEvent.ResultInOut = true; resultEvents[pos].OtherEvent.ContourId = contourId; if ((depth[contourId] & 1) != 0) { contour.ChangeOrientation(); } } return(result); }
public bool GetStudyAreaContourPolygonList(List <ContourPolygon> contourPolygonList) { //contourPolygonList = new List<ContourPolygon>(); using (DFSU dfsu = new DFSU(fi)) { List <List <Node> > StudyAreaList = new List <List <Node> >(); DfsuFile dfsuFile; List <int> PolygonIndexes = new List <int>(); try { dfsuFile = DfsuFile.Open(fi.FullName); } catch (Exception ex) { ErrorMessage = string.Format(CSSPDHIRes.CouldNotOpen_Error_, fi.FullName, ex.Message + (ex.InnerException != null ? "Inner: " + ex.InnerException.Message : "")); OnCSSPDHIChanged(new CSSPDHIEventArgs(new CSSPDHIMessage("Error", -1, false, ErrorMessage))); contourPolygonList.Add(new ContourPolygon() { Error = ErrorMessage }); return(false); } int TotalNumberWithCodeBigger0 = dfsuFile.Code.Where(c => c > 0).Count(); List <Element> ElementList = new List <Element>(); List <Node> NodeList = new List <Node>(); // ---------------------------------------- // filling the ElementList and The NodeList // ---------------------------------------- FillElementListAndNodeList(ElementList, NodeList); List <Node> AllNodeList = new List <Node>(); //List<ContourPolygon> ContourPolygonList = new List<ContourPolygon>(); List <Node> AboveNodeList = (from n in NodeList where n.Code != 0 select n).ToList <Node>(); foreach (Node sn in AboveNodeList) { List <Node> EndNodeList = (from n in sn.ConnectNodeList where n.Code != 0 select n).ToList <Node>(); foreach (Node en in EndNodeList) { AllNodeList.Add(en); } if (sn.Code != 0) { AllNodeList.Add(sn); } } List <Element> UniqueElementList = new List <Element>(); List <Element> TempUniqueElementList = new List <Element>(); // filling UniqueElementList TempUniqueElementList = (from el in ElementList where (el.Type == 21 || el.Type == 32) select el).Distinct().ToList <Element>(); foreach (Element el in TempUniqueElementList) { if ((el.NodeList[0].Code != 0 && el.NodeList[1].Code != 0) || (el.NodeList[0].Code != 0 && el.NodeList[2].Code != 0) || (el.NodeList[1].Code != 0 && el.NodeList[2].Code != 0)) { UniqueElementList.Add(el); } } TempUniqueElementList = (from el in ElementList where (el.Type == 25 || el.Type == 33) select el).Distinct().ToList <Element>(); foreach (Element el in TempUniqueElementList) { if ((el.NodeList[0].Code != 0 && el.NodeList[1].Code != 0) || (el.NodeList[1].Code != 0 && el.NodeList[2].Code != 0) || (el.NodeList[2].Code != 0 && el.NodeList[3].Code != 0) || (el.NodeList[3].Code != 0 && el.NodeList[0].Code != 0)) { UniqueElementList.Add(el); } } List <Node> UniqueNodeList = (from n in AllNodeList orderby n.ID select n).Distinct().ToList <Node>(); Dictionary <String, Vector> ForwardVector = new Dictionary <String, Vector>(); Dictionary <String, Vector> BackwardVector = new Dictionary <String, Vector>(); //_TaskRunnerBaseService.SendPercentToDB(_TaskRunnerBaseService._BWObj.appTaskModel.AppTaskID, 30); foreach (Element el in UniqueElementList) { Node Node0 = new Node(); Node Node1 = new Node(); Node Node2 = new Node(); Node Node3 = new Node(); if (el.Type == 21 || el.Type == 32) { Node0 = el.NodeList[0]; Node1 = el.NodeList[1]; Node2 = el.NodeList[2]; int ElemCount01 = (from el1 in UniqueElementList from el2 in Node0.ElementList from el3 in Node1.ElementList where el1 == el2 && el1 == el3 select el1).Count(); int ElemCount02 = (from el1 in UniqueElementList from el2 in Node0.ElementList from el3 in Node2.ElementList where el1 == el2 && el1 == el3 select el1).Count(); int ElemCount12 = (from el1 in UniqueElementList from el2 in Node1.ElementList from el3 in Node2.ElementList where el1 == el2 && el1 == el3 select el1).Count(); if (Node0.Code != 0 && Node1.Code != 0) { if (ElemCount01 == 1) { ForwardVector.Add(Node0.ID.ToString() + "," + Node1.ID.ToString(), new Vector() { StartNode = Node0, EndNode = Node1 }); BackwardVector.Add(Node1.ID.ToString() + "," + Node0.ID.ToString(), new Vector() { StartNode = Node1, EndNode = Node0 }); } } if (Node0.Code != 0 && Node2.Code != 0) { if (ElemCount02 == 1) { ForwardVector.Add(Node0.ID.ToString() + "," + Node2.ID.ToString(), new Vector() { StartNode = Node0, EndNode = Node2 }); BackwardVector.Add(Node2.ID.ToString() + "," + Node0.ID.ToString(), new Vector() { StartNode = Node2, EndNode = Node0 }); } } if (Node1.Code != 0 && Node2.Code != 0) { if (ElemCount12 == 1) { ForwardVector.Add(Node1.ID.ToString() + "," + Node2.ID.ToString(), new Vector() { StartNode = Node1, EndNode = Node2 }); BackwardVector.Add(Node2.ID.ToString() + "," + Node1.ID.ToString(), new Vector() { StartNode = Node2, EndNode = Node1 }); } } } else if (el.Type == 25 || el.Type == 33) { Node0 = el.NodeList[0]; Node1 = el.NodeList[1]; Node2 = el.NodeList[2]; Node3 = el.NodeList[3]; int ElemCount01 = (from el1 in UniqueElementList from el2 in Node0.ElementList from el3 in Node1.ElementList where el1 == el2 && el1 == el3 select el1).Count(); int ElemCount03 = (from el1 in UniqueElementList from el2 in Node0.ElementList from el3 in Node3.ElementList where el1 == el2 && el1 == el3 select el1).Count(); int ElemCount12 = (from el1 in UniqueElementList from el2 in Node1.ElementList from el3 in Node2.ElementList where el1 == el2 && el1 == el3 select el1).Count(); int ElemCount23 = (from el1 in UniqueElementList from el2 in Node2.ElementList from el3 in Node3.ElementList where el1 == el2 && el1 == el3 select el1).Count(); if (Node0.Code != 0 && Node1.Code != 0) { if (ElemCount01 == 1) { ForwardVector.Add(Node0.ID.ToString() + "," + Node1.ID.ToString(), new Vector() { StartNode = Node0, EndNode = Node1 }); BackwardVector.Add(Node1.ID.ToString() + "," + Node0.ID.ToString(), new Vector() { StartNode = Node1, EndNode = Node0 }); } } if (Node0.Code != 0 && Node3.Code != 0) { if (ElemCount03 == 1) { ForwardVector.Add(Node0.ID.ToString() + "," + Node3.ID.ToString(), new Vector() { StartNode = Node0, EndNode = Node3 }); BackwardVector.Add(Node3.ID.ToString() + "," + Node0.ID.ToString(), new Vector() { StartNode = Node3, EndNode = Node0 }); } } if (Node1.Code != 0 && Node2.Code != 0) { if (ElemCount12 == 1) { ForwardVector.Add(Node1.ID.ToString() + "," + Node2.ID.ToString(), new Vector() { StartNode = Node1, EndNode = Node2 }); BackwardVector.Add(Node2.ID.ToString() + "," + Node1.ID.ToString(), new Vector() { StartNode = Node2, EndNode = Node1 }); } } if (Node2.Code != 0 && Node3.Code != 0) { if (ElemCount23 == 1) { ForwardVector.Add(Node2.ID.ToString() + "," + Node3.ID.ToString(), new Vector() { StartNode = Node2, EndNode = Node3 }); BackwardVector.Add(Node3.ID.ToString() + "," + Node2.ID.ToString(), new Vector() { StartNode = Node3, EndNode = Node2 }); } } } else { ErrorMessage = string.Format(CSSPDHIRes.ElementTypeIsOtherThan_Its_, "21, 25, 32, 33", el.Type.ToString()); OnCSSPDHIChanged(new CSSPDHIEventArgs(new CSSPDHIMessage("Error", -1, false, ErrorMessage))); contourPolygonList.Add(new ContourPolygon() { Error = ErrorMessage }); return(false); } } //_TaskRunnerBaseService.SendPercentToDB(_TaskRunnerBaseService._BWObj.appTaskModel.AppTaskID, 40); bool MoreStudyAreaLine = true; int PolygonCount = 0; //MapInfoService mapInfoService = new MapInfoService(_TaskRunnerBaseService._BWObj.appTaskModel.Language, _TaskRunnerBaseService._User); while (MoreStudyAreaLine) { PolygonCount += 1; List <Node> FinalContourNodeList = new List <Node>(); Vector LastVector = new Vector(); LastVector = ForwardVector.First().Value; FinalContourNodeList.Add(LastVector.StartNode); FinalContourNodeList.Add(LastVector.EndNode); ForwardVector.Remove(LastVector.StartNode.ID.ToString() + "," + LastVector.EndNode.ID.ToString()); BackwardVector.Remove(LastVector.EndNode.ID.ToString() + "," + LastVector.StartNode.ID.ToString()); bool PolygonCompleted = false; while (!PolygonCompleted) { List <string> KeyStrList = (from k in ForwardVector.Keys where k.StartsWith(LastVector.EndNode.ID.ToString() + ",") && !k.EndsWith("," + LastVector.StartNode.ID.ToString()) select k).ToList <string>(); if (KeyStrList.Count != 1) { KeyStrList = (from k in BackwardVector.Keys where k.StartsWith(LastVector.EndNode.ID.ToString() + ",") && !k.EndsWith("," + LastVector.StartNode.ID.ToString()) select k).ToList <string>(); if (KeyStrList.Count != 1) { PolygonCompleted = true; break; } else { LastVector = BackwardVector[KeyStrList[0]]; BackwardVector.Remove(LastVector.StartNode.ID.ToString() + "," + LastVector.EndNode.ID.ToString()); ForwardVector.Remove(LastVector.EndNode.ID.ToString() + "," + LastVector.StartNode.ID.ToString()); } } else { LastVector = ForwardVector[KeyStrList[0]]; ForwardVector.Remove(LastVector.StartNode.ID.ToString() + "," + LastVector.EndNode.ID.ToString()); BackwardVector.Remove(LastVector.EndNode.ID.ToString() + "," + LastVector.StartNode.ID.ToString()); } FinalContourNodeList.Add(LastVector.EndNode); if (FinalContourNodeList[FinalContourNodeList.Count - 1] == FinalContourNodeList[0]) { PolygonCompleted = true; } } double Area = CalculateAreaOfPolygon(FinalContourNodeList); if (Area < 0) { FinalContourNodeList.Reverse(); Area = CalculateAreaOfPolygon(FinalContourNodeList); } FinalContourNodeList.Add(FinalContourNodeList[0]); ContourPolygon contourLine = new ContourPolygon() { }; contourLine.ContourNodeList = FinalContourNodeList; contourLine.ContourValue = 0; contourPolygonList.Add(contourLine); if (ForwardVector.Count == 0) { MoreStudyAreaLine = false; } } } return(true); }
public ContourPolygonTest() { contourPolygon = new ContourPolygon(); }