public void SplitStrassenabschnittGISAtXY(Guid strassenabschnittId, string x, string y) { StrassenabschnittGIS strassenabschnittToSplit = GetEntityById(strassenabschnittId); //check whether the strassenabschnitt (inspektionsroute) is checked out (=locked) if (strassenabschnittToSplit.IsLocked) { return; } //1. find achsenref. to split IGeometry splitPoint = GISService.CreateGeometryFactory().CreatePoint(new Coordinate(double.Parse(x, System.Globalization.NumberFormatInfo.InvariantInfo), double.Parse(y, System.Globalization.NumberFormatInfo.InvariantInfo), 0)); AchsenReferenz achsenreferenceToSplit = gisService.GetNearestGeometry(splitPoint, strassenabschnittToSplit.ReferenzGruppe.AchsenReferenzen); //2. split achsenref LengthIndexedLine line = new LengthIndexedLine(achsenreferenceToSplit.Shape); IGeometry split1 = line.ExtractLine(0, line.IndexOf(splitPoint.Coordinate)); IGeometry split2 = line.ExtractLine(line.IndexOf(splitPoint.Coordinate), line.EndIndex); //create new strassenabschnitte StrassenabschnittGIS copiedStrassenabschnittGIS1 = PrepareNewStrassenabschnitt(strassenabschnittToSplit, achsenreferenceToSplit, split1); StrassenabschnittGIS copiedStrassenabschnittGIS2 = PrepareNewStrassenabschnitt(strassenabschnittToSplit, achsenreferenceToSplit, split2); //3. relate other achsenrefs to the new two references foreach (AchsenReferenz achsref in strassenabschnittToSplit.ReferenzGruppe.AchsenReferenzen.Where(ac => !ac.Equals(achsenreferenceToSplit))) { if (achsref.Shape.Distance(split1) <= achsref.Shape.Distance(split2)) { copiedStrassenabschnittGIS1.ReferenzGruppe.AddAchsenReferenz(PrepareAchsenreferenz(achsref)); copiedStrassenabschnittGIS1.Shape = copiedStrassenabschnittGIS1.Shape.Union(achsref.Shape); } else { copiedStrassenabschnittGIS2.ReferenzGruppe.AddAchsenReferenz(PrepareAchsenreferenz(achsref)); copiedStrassenabschnittGIS2.Shape = copiedStrassenabschnittGIS2.Shape.Union(achsref.Shape); } } copiedStrassenabschnittGIS1.Laenge = getLength(copiedStrassenabschnittGIS1); copiedStrassenabschnittGIS2.Laenge = getLength(copiedStrassenabschnittGIS2); //update inspektionsroute strassenabschnittToSplit.InspektionsRtStrAbschnitte.ForEach(s => s.InspektionsRouteGIS.AddStrassenabschnittGIS(copiedStrassenabschnittGIS1)); strassenabschnittToSplit.InspektionsRtStrAbschnitte.ForEach(s => s.InspektionsRouteGIS.AddStrassenabschnittGIS(copiedStrassenabschnittGIS2)); strassenabschnittToSplit.InspektionsRtStrAbschnitte.ForEach(s => s.InspektionsRouteGIS.RemoveStrassenabschnittGIS(strassenabschnittToSplit)); //5. save/delete splitted strassenabschnitte Delete(strassenabschnittToSplit); CreateEntity(copiedStrassenabschnittGIS1); CreateEntity(copiedStrassenabschnittGIS2); }
private static void SplitBranchFeaturesWithLength(IBranch firstBranch, IBranch secondBranch) { var featuresToSplit = firstBranch.BranchFeatures.Where(f => f.Chainage + f.Length > firstBranch.Length).ToList(); foreach (var branchFeature in featuresToSplit) { if (branchFeature.Geometry is IPoint) { // A culvert has length, but it's geometry is a point. We're mixing Length propery meaning, but I'm not // sure what the solution is. Fixing exception for now using this. continue; } branchFeature.SetBeingMoved(true); var lengthFirstBranchFeature = firstBranch.Length - branchFeature.Chainage; var lengthSecondBranchFeature = branchFeature.Length - lengthFirstBranchFeature; var firstBranchFeatureChainage = branchFeature.Chainage; var featureOnFirstBranch = (lengthFirstBranchFeature >= lengthSecondBranchFeature); if (!featureOnFirstBranch) { firstBranch.BranchFeatures.Remove(branchFeature); } var newBranchFeature = (IBranchFeature)Activator.CreateInstance(branchFeature.GetType()); var firstBranchFeature = featureOnFirstBranch ? branchFeature : newBranchFeature; var secondBranchFeature = featureOnFirstBranch ? newBranchFeature : branchFeature; var originalName = branchFeature.Name; var lengthIndexedLine = new LengthIndexedLine(branchFeature.Geometry); var factor = firstBranch.Geometry.Length / firstBranch.Length; firstBranchFeature.Length = lengthFirstBranchFeature; firstBranchFeature.Name = originalName + "_1"; firstBranchFeature.Geometry = (IGeometry)lengthIndexedLine.ExtractLine(lengthIndexedLine.StartIndex, lengthFirstBranchFeature * factor).Clone(); secondBranchFeature.Length = lengthSecondBranchFeature; secondBranchFeature.Name = originalName + "_2"; secondBranchFeature.Geometry = (IGeometry)lengthIndexedLine.ExtractLine(lengthFirstBranchFeature * factor, lengthIndexedLine.EndIndex).Clone(); AddBranchFeatureToBranch(secondBranchFeature, secondBranch, 0); if (!featureOnFirstBranch) { AddBranchFeatureToBranch(firstBranchFeature, firstBranch, firstBranchFeatureChainage); } branchFeature.SetBeingMoved(false); } }
public static INetworkSegment CreateSegment(IBranch branch, double startOffset, double endOffset) { var lengthIndexedLine = new LengthIndexedLine(branch.Geometry); var geometryStartOffset = startOffset; var geometryEndOffset = endOffset; IGeometry geometry = null; if (branch.Geometry != null) { if (branch.IsLengthCustom) { geometryStartOffset = startOffset * (branch.Geometry.Length / branch.Length); geometryEndOffset = endOffset * (branch.Geometry.Length / branch.Length); } geometry = branch.Geometry == null ? null : (IGeometry)lengthIndexedLine.ExtractLine(geometryStartOffset, geometryEndOffset).Clone(); } var segment = new NetworkSegment { Geometry = geometry, Branch = branch, Offset = startOffset, Length = endOffset - startOffset }; return(segment); }
private void HandleSelfClosingCase(GpxProlongerExecutorInput input, LineAndCoordinate current, LineAndCoordinate next, List <ILineString> linesToProlong) { var lengthIndexedLine = new LengthIndexedLine(current.Line); var closestCoordinateCurrentIndex = lengthIndexedLine.Project(current.Coordinate); var closestCoordinateNextIndex = lengthIndexedLine.Project(next.Coordinate); var segment = lengthIndexedLine.ExtractLine(closestCoordinateCurrentIndex, closestCoordinateNextIndex); var coordinates = segment.Coordinates.Concat(new[] { segment.Coordinates.First() }).ToArray(); if (coordinates.Length < 4) { return; } var polygon = new Polygon(new LinearRing(coordinates)); if (polygon.Area < input.MinimalAreaSize) { return; } var currentCoordinate = lengthIndexedLine.ExtractPoint(closestCoordinateCurrentIndex); var nextCoordinate = lengthIndexedLine.ExtractPoint(closestCoordinateNextIndex); if (!AddCoordinate(current.Line, currentCoordinate, nextCoordinate, linesToProlong, input.MinimalDistance)) { linesToProlong.Add(_geometryFactory.CreateLineString(new[] { currentCoordinate, nextCoordinate })); } }
public static INetworkSegment CreateSegment(IBranch branch, double startChainage, double endChainage) { var lengthIndexedLine = new LengthIndexedLine(branch.Geometry); var geometryStartChainage = startChainage; var geometryEndChainage = endChainage; IGeometry geometry = null; if (branch.Geometry != null) { if (branch.IsLengthCustom) { geometryStartChainage = startChainage * (branch.Geometry.Length / branch.Length); geometryEndChainage = endChainage * (branch.Geometry.Length / branch.Length); } geometry = (IGeometry)lengthIndexedLine.ExtractLine(geometryStartChainage, geometryEndChainage).Clone(); } var segment = new NetworkSegment { Geometry = geometry, Branch = branch, Chainage = startChainage, Length = endChainage - startChainage }; return(segment); }
public GeometryTransformerResult Transform() { newRefGeometryOut = null; int n = oldRefGeometry.Coordinates.Length; Coordinate startCoodinate = TransformCoordiante(oldRefGeometry.Coordinates[0]); Coordinate endCoordinate = TransformCoordiante(oldRefGeometry.Coordinates[n - 1]); LengthIndexedLine lil = new LengthIndexedLine(newSegmentGeometry); double projStartIndex = lil.IndexOf(startCoodinate); double projEndIndex = lil.IndexOf(endCoordinate); if (projStartIndex > projEndIndex) { double temp = projStartIndex; projStartIndex = projEndIndex; projEndIndex = temp; } if (Math.Abs(projStartIndex - projEndIndex) < 1) { if (projStartIndex == 0 || (Math.Abs(projStartIndex - lil.EndIndex) < double.Epsilon)) { return(new GeometryTransformerResult(GeometryTransformerResultState.FailedWouldBeOutside, newRefGeometryOut)); } return(new GeometryTransformerResult(GeometryTransformerResultState.FailedWouldBeTooShort, newRefGeometryOut)); } newRefGeometryOut = (ILineString)lil.ExtractLine(projStartIndex, projEndIndex); return(new GeometryTransformerResult(GeometryTransformerResultState.Success, newRefGeometryOut)); }
//INetworkCoverage coverage, private static IList <INetworkSegment> UpdateSegmentsBranchSegmentBetweenLocations(bool fullyCover, IBranch branch, IEnumerable <INetworkLocation> branchLocations) { var segments = new List <INetworkSegment>(); var length = branch.Length; // select all locations that have an offset within the branch var factor = 1.0; // branch.IsLengthCustom ? (branch.Geometry.Length / branch.Length) : 1.0; IList <double> offsets = branchLocations.Where(l => l.Chainage <= length).Select(l => factor * l.Chainage).ToList(); if (0 == offsets.Count) { if (fullyCover) { offsets.Add(0); offsets.Add(length); } else { return(segments); } } else { if (fullyCover) { if (Math.Abs(offsets[0]) > BranchFeature.Epsilon) { offsets.Insert(0, 0.0); } if (Math.Abs(offsets[offsets.Count - 1] - length) > BranchFeature.Epsilon) { offsets.Add(length); } } } var lengthIndexedLine = new LengthIndexedLine(branch.Geometry); for (int i = 1; i < offsets.Count; i++) { var segment = new NetworkSegment { Branch = branch, Chainage = offsets[i - 1], Length = Math.Abs(offsets[i] - offsets[i - 1]), DirectionIsPositive = offsets[i] >= offsets[i - 1], // thousand bombs and grenades: ExtractLine will give either a new coordinate or // a reference to an existing object Geometry = (IGeometry)lengthIndexedLine.ExtractLine(offsets[i - 1], offsets[i]).Clone() }; segments.Add(segment); } return(segments); }
private void CheckExtractLine(string wkt, double start, double end, string expected) { var linearGeom = Read(wkt); var indexedLine = new LengthIndexedLine(linearGeom); var result = indexedLine.ExtractLine(start, end); CheckExpected(result, expected); }
private void CheckExtractLine(String wkt, double start, double end, String expected) { IGeometry linearGeom = Read(wkt); LengthIndexedLine indexedLine = new LengthIndexedLine(linearGeom); IGeometry result = indexedLine.ExtractLine(start, end); CheckExpected(result, expected); }
protected override Geometry IndicesOfThenExtract(Geometry linearGeom, Geometry subLine) { var indexedLine = new LengthIndexedLine(linearGeom); double[] loc = indexedLine.IndicesOf(subLine); var result = indexedLine.ExtractLine(loc[0], loc[1]); return(result); }
private void HandleIntersectionCase(GpxProlongerExecutorInput input, SegmentWithLines segment, List <ILineString> linesToProlong) { var intersection = segment.Start.Line.Intersection(segment.End.Line).Coordinates .OrderBy(c => c.Distance(segment.Start.Coordinate) + c.Distance(segment.End.Coordinate)).FirstOrDefault(); if (intersection == null) { var distance = new DistanceOp(segment.Start.Line, segment.End.Line); intersection = distance.NearestPoints().First(); } var currentLengthIndexedLine = new LengthIndexedLine(segment.Start.Line); var closestCoordinateCurrentIndex = currentLengthIndexedLine.Project(segment.Start.Coordinate); var closestCoordinateCurrentIntersectionIndex = currentLengthIndexedLine.Project(intersection); var currentSegment = currentLengthIndexedLine.ExtractLine(closestCoordinateCurrentIndex, closestCoordinateCurrentIntersectionIndex); var nextLengthIndexedLine = new LengthIndexedLine(segment.End.Line); var closestCoordinateNextIndex = nextLengthIndexedLine.Project(segment.End.Coordinate); var closestCoordinateNextIntersectionIndex = nextLengthIndexedLine.Project(intersection); var nextSegment = nextLengthIndexedLine.ExtractLine(closestCoordinateNextIntersectionIndex, closestCoordinateNextIndex); var coordinates = currentSegment.Coordinates.Concat(nextSegment.Coordinates) .Concat(new[] { currentSegment.Coordinates.First() }).ToArray(); if (coordinates.Length < 4) { return; } var polygon = new Polygon(new LinearRing(coordinates)); if (polygon.Area < input.MinimalAreaSize) { return; } var currentCoordinate = currentLengthIndexedLine.ExtractPoint(closestCoordinateCurrentIndex); var nextCoordinate = nextLengthIndexedLine.ExtractPoint(closestCoordinateNextIndex); var line = CreateLineString(currentCoordinate, segment.OriginalCoordinates, nextCoordinate); linesToProlong.Add(line); }
public static Geometry Project(Geometry g, Geometry g2) { var ll = new LengthIndexedLine(g); if (g2.Dimension == Dimension.Curve) { var line = (LineString)g2.GetGeometryN(0); var pStart = line.GetCoordinateN(0); var pEnd = line.GetCoordinateN(line.NumPoints - 1); double indexStart = ll.Project(pStart); double indexEnd = ll.Project(pEnd); return(ll.ExtractLine(indexStart, indexEnd)); } else { double index = ll.Project(g2.Coordinate); var p = ll.ExtractPoint(index); return(g.Factory.CreatePoint(p)); } }
/// <summary> /// /// </summary> /// <param name="wkt"></param> /// <param name="start"></param> /// <param name="end"></param> public void RunExtractedLine(string wkt, double start, double end) { Console.WriteLine("========================="); IGeometry g1 = rdr.Read(wkt); Console.WriteLine("Input Geometry: " + g1); Console.WriteLine("Indices to extract: " + start + " " + end); LengthIndexedLine indexedLine = new LengthIndexedLine(g1); IGeometry subLine = indexedLine.ExtractLine(start, end); Console.WriteLine("Extracted Line: " + subLine); double[] index = indexedLine.IndicesOf(subLine); Console.WriteLine("Indices of extracted line: " + index[0] + " " + index[1]); Coordinate midpt = indexedLine.ExtractPoint((index[0] + index[1]) / 2); Console.WriteLine("Midpoint of extracted line: " + midpt); }
private void HandleSelfClosingCase(GpxProlongerExecutorInput input, SegmentWithLines segment, List <ILineString> linesToProlong) { var lengthIndexedLine = new LengthIndexedLine(segment.Start.Line); var closestCoordinateCurrentIndex = lengthIndexedLine.Project(segment.Start.Coordinate); var closestCoordinateNextIndex = lengthIndexedLine.Project(segment.End.Coordinate); var indexedSegment = lengthIndexedLine.ExtractLine(closestCoordinateCurrentIndex, closestCoordinateNextIndex); var coordinates = indexedSegment.Coordinates.Concat(new[] { indexedSegment.Coordinates.First() }).ToArray(); if (coordinates.Length < 4) { return; } var polygon = new Polygon(new LinearRing(coordinates)); if (polygon.Area < input.MinimalAreaSize) { return; } if (!AddSegmentToLine(segment.Start.Line, segment, linesToProlong, input.MinimalDistance)) { linesToProlong.Add(CreateLineString(segment.StartProjected, segment.OriginalCoordinates, segment.EndProjected)); } }
public static void UpdateLineGeometry(IBranchFeature branchFeature, IGeometry effectiveBranchGeometry) { double mapChainage, mapLength; var branch = branchFeature.Branch; if (branch != null) { var branchLength = branch.IsLengthCustom ? branch.Length : effectiveBranchGeometry.Length; FitBranchFeatureWithLengthInBranch(branchFeature, branchLength); mapChainage = MapChainage(branchFeature.Branch, effectiveBranchGeometry, branchFeature.Chainage); mapLength = MapChainage(branchFeature.Branch, effectiveBranchGeometry, branchFeature.Length); } else { mapChainage = branchFeature.Chainage; mapLength = branchFeature.Length; } var lengthIndexedLine = new LengthIndexedLine(effectiveBranchGeometry); branchFeature.Geometry = lengthIndexedLine.ExtractLine(mapChainage, mapChainage + mapLength); }
public static IGeometry ExtractLine(IGeometry g, double start, double end) { var ll = new LengthIndexedLine(g); return(ll.ExtractLine(start, end)); }
/// <summary> /// Splits a branch at the given node and connect resulting 2 branches to the node. /// All related branch features are moved to the corresponding branch based on their geometry. /// </summary> /// <param name="network"></param> /// <param name="branch"></param> /// <param name="node"></param> public static IBranch SplitBranchAtNode(INetwork network, IBranch branch, INode node) { var originalFirstBranchGeometryLength = branch.Geometry.Length; var lengthIndexedLine = new LengthIndexedLine(branch.Geometry); double firstBranchGeometryLength = lengthIndexedLine.IndexOf(node.Geometry.Coordinates[0]); // compute geometries IGeometry firstBranchGeometry = (IGeometry)lengthIndexedLine.ExtractLine(0.0, firstBranchGeometryLength).Clone(); if (firstBranchGeometry == GeometryCollection.Empty) { throw new ArgumentException(String.Format("Node {0} not located at line; unable to split branch {1}", node.Id, branch.Id)); } IGeometry secondBranchGeometry = (IGeometry)lengthIndexedLine.ExtractLine(firstBranchGeometryLength, originalFirstBranchGeometryLength).Clone(); if (secondBranchGeometry == GeometryCollection.Empty) { throw new ArgumentException(String.Format("Node {0} not located at line; unable to split branch {1}", node.Id, branch.Id)); } if (secondBranchGeometry.Coordinates.Count() == 0 || firstBranchGeometry.Coordinates.Count() == 0 || firstBranchGeometry.Length == 0.0 || secondBranchGeometry.Length == 0.0) { return(null); // nothing to split } // update existing branch var toNode = branch.Target; branch.Target = node; // create and add second branch var fraction = firstBranchGeometryLength / originalFirstBranchGeometryLength; var secondBranch = (IBranch)Activator.CreateInstance(branch.GetType()); secondBranch.Name = GetUniqueName(null, branch.Network.Branches, "branch"); secondBranch.Source = node; secondBranch.Target = toNode; secondBranch.Geometry = secondBranchGeometry; secondBranch.IsLengthCustom = branch.IsLengthCustom; secondBranch.Attributes = branch.Attributes == null ? null : (IFeatureAttributeCollection)branch.Attributes.Clone(); network.Branches.Add(secondBranch); branch.Geometry = firstBranchGeometry; // only update length of branch if it is not same as geometry. var originalLength = branch.Length; if (branch.IsLengthCustom) { branch.Length = originalLength * fraction; secondBranch.Length = originalLength * (1 - fraction); } else { branch.Length = branch.Geometry.Length; secondBranch.Length = secondBranch.Geometry.Length; } // adjust last segment of the first branch (+center, boundary) // SplitBranchSegments(node, firstBranch, secondBranch, originalFirstBranchGeometryLength); // remember all branch features to be moved to the second branch IBranchFeature[] branchFeatureToMove = branch.BranchFeatures.Where(bf => bf.Offset >= firstBranchGeometryLength).ToArray(); // move all features from first branch to the second branch foreach (var branchFeature in branchFeatureToMove) { branch.BranchFeatures.Remove(branchFeature); branchFeature.Offset -= branch.Length; AddBranchFeatureToBranch(secondBranch, branchFeature, branchFeature.Offset); //secondBranch.BranchFeatures.Add(branchFeature); //branchFeature.Offset -= branch.Length; } return(secondBranch); }
//INetworkCoverage coverage, private static IEnumerable <INetworkSegment> UpdateSegmentsBranchSegmentBetweenLocations(bool fullyCover, IBranch branch, IEnumerable <INetworkLocation> branchLocations) { var segments = new List <INetworkSegment>(); var length = branch.Length; //note do we really want this?? should this not be handled in branch! /*if (branch.Geometry != null) * { * length = branch.Geometry.Length; // TODO: check if it is geometry-based, length can be in local units * }*/ // select all locations that have an offset within the branch IList <double> offsets = branchLocations.Where(l => l.Offset <= length).Select(l => l.Offset).ToList(); if (0 == offsets.Count) { if (fullyCover) { offsets.Add(0); offsets.Add(length); } else { return(segments); } } else { if (fullyCover) { if (Math.Abs(offsets[0]) > 1.0e-6) { offsets.Add(0.0); } if (Math.Abs(offsets[offsets.Count - 1] - length) > 1.0e-6) { offsets.Add(length); } } } var lengthIndexedLine = new LengthIndexedLine(branch.Geometry); for (int i = 1; i < offsets.Count; i++) { var segment = new NetworkSegment { Branch = branch, Offset = offsets[i - 1], Length = Math.Abs(offsets[i] - offsets[i - 1]), DirectionIsPositive = offsets[i] >= offsets[i - 1], // thousand bombs and granates: ExtractLine will give either a new coordinate or // a reference to an existing object Geometry = (IGeometry)lengthIndexedLine.ExtractLine(offsets[i - 1], offsets[i]).Clone() }; segments.Add(segment); //coverage.Segments.Values.Add(segment); } return(segments); }
private static void UpdateLineGeometry(IBranchFeature branchFeature) { var lengthIndexedLine = new LengthIndexedLine(branchFeature.Branch.Geometry); branchFeature.Geometry = lengthIndexedLine.ExtractLine(branchFeature.Chainage, branchFeature.Chainage + branchFeature.Length); }
/// <summary> /// Splits a branch at the given node and connect resulting 2 branches to the node. /// All related branch features are moved to the corresponding branch based on their geometry. /// </summary> /// <param name="network"></param> /// <param name="branch"></param> /// <param name="node"></param> public static IBranch SplitBranchAtNode(INetwork network, IBranch branch, INode node, bool doBeginEdit = false) { var originalFirstBranchGeometryLength = branch.Geometry.Length; var lengthIndexedLine = new LengthIndexedLine(branch.Geometry); var firstBranchGeometryLength = lengthIndexedLine.IndexOf(node.Geometry.Coordinates[0]); // compute geometries var firstBranchGeometry = (IGeometry)lengthIndexedLine.ExtractLine(0.0, firstBranchGeometryLength).Clone(); if (firstBranchGeometry == GeometryCollection.Empty) { throw new ArgumentException(String.Format("Node {0} not located at line; unable to split branch {1}", node.Id, branch.Id)); } var secondBranchGeometry = (IGeometry)lengthIndexedLine.ExtractLine(firstBranchGeometryLength, originalFirstBranchGeometryLength).Clone(); if (secondBranchGeometry == GeometryCollection.Empty) { throw new ArgumentException(String.Format("Node {0} not located at line; unable to split branch {1}", node.Id, branch.Id)); } if (secondBranchGeometry.Coordinates.Count() == 0 || firstBranchGeometry.Coordinates.Count() == 0 || firstBranchGeometry.Length == 0.0 || secondBranchGeometry.Length == 0.0) { return(null); // nothing to split } // update existing branch var toNode = branch.Target; branch.Target = node; // create and add second branch var fraction = firstBranchGeometryLength / originalFirstBranchGeometryLength; var secondBranch = (IBranch)Activator.CreateInstance(branch.GetType()); secondBranch.Name = GetUniqueName(null, branch.Network.Branches, "branch"); secondBranch.Source = node; secondBranch.Target = toNode; secondBranch.Geometry = secondBranchGeometry; secondBranch.IsLengthCustom = branch.IsLengthCustom; secondBranch.Attributes = branch.Attributes == null ? null : (IFeatureAttributeCollection)branch.Attributes.Clone(); network.Branches.Add(secondBranch); var originalOffsets = branch.BranchFeatures.ToDictionary(bf => bf, bf => bf.Offset); branch.Geometry = firstBranchGeometry; // FIX the branch geometries..NTS might have introduced NaNs that mess up serialization foreach (var coordinate in branch.Geometry.Coordinates.Concat(secondBranch.Geometry.Coordinates)) { coordinate.Z = 0; } // only update length of branch if it is not same as geometry. var originalLength = branch.Length; double newFirstLength, newSecondLength; if (branch.IsLengthCustom) { newFirstLength = originalLength * fraction; newSecondLength = originalLength * (1 - fraction); } else { newFirstLength = branch.Geometry.Length; newSecondLength = secondBranch.Geometry.Length; } // remember all branch features to be moved to the second branch var branchFeatureToMove = branch.BranchFeatures.Where(bf => bf.Offset >= newFirstLength).ToArray(); var newOffsets = new List <double>(); foreach (var branchFeature in branchFeatureToMove) { newOffsets.Add(branchFeature.Offset - newFirstLength); branchFeature.SetBeingMoved(true); branch.BranchFeatures.Remove(branchFeature); } branch.Length = newFirstLength; secondBranch.Length = newSecondLength; // move all features from first branch to the second branch for (var i = 0; i < branchFeatureToMove.Length; i++) { var branchFeature = branchFeatureToMove[i]; branchFeature.Offset = newOffsets[i]; AddBranchFeatureToBranch(branchFeature, secondBranch, branchFeature.Offset); branchFeature.SetBeingMoved(false); } // update offset in first branch to original offset for (int i = 0; i < branch.BranchFeatures.Count; i++) { var branchFeature = branch.BranchFeatures[i]; branchFeature.Offset = originalOffsets[branchFeature]; } return(secondBranch); }
/// <summary> /// Splits a branch at the given node and connect resulting 2 branches to the node. /// All related branch features are moved to the corresponding branch based on their geometry. /// </summary> /// <param name="network"></param> /// <param name="branch"></param> /// <param name="node"></param> public static IBranch SplitBranchAtNode(INetwork network, IBranch branch, INode node) { var originalFirstBranchGeometryLength = branch.Geometry.Length; var lengthIndexedLine = new LengthIndexedLine(branch.Geometry); var firstBranchGeometryLength = lengthIndexedLine.IndexOf(node.Geometry.Coordinates[0]); // compute geometries var firstBranchGeometry = (IGeometry)lengthIndexedLine.ExtractLine(0.0, firstBranchGeometryLength).Clone(); var secondBranchGeometry = (IGeometry)lengthIndexedLine.ExtractLine(firstBranchGeometryLength, originalFirstBranchGeometryLength).Clone(); if (firstBranchGeometry == GeometryCollection.Empty || secondBranchGeometry == GeometryCollection.Empty) { throw new ArgumentException(String.Format("Node {0} not located at line; unable to split branch {1}", node.Id, branch.Id)); } if (!secondBranchGeometry.Coordinates.Any() || !firstBranchGeometry.Coordinates.Any() || firstBranchGeometry.Length == 0.0 || secondBranchGeometry.Length == 0.0) { return(null); // nothing to split } // update existing branch var toNode = branch.Target; branch.Target = node; // create and add second branch var secondBranch = (IBranch)Activator.CreateInstance(branch.GetType()); secondBranch.Name = GetUniqueName(null, branch.Network.Branches, "branch"); secondBranch.Source = node; secondBranch.Target = toNode; secondBranch.Geometry = secondBranchGeometry; secondBranch.IsLengthCustom = branch.IsLengthCustom; secondBranch.OrderNumber = branch.OrderNumber; secondBranch.Attributes = branch.Attributes == null ? null : (IFeatureAttributeCollection)branch.Attributes.Clone(); network.Branches.Add(secondBranch); // FIX the branch geometries..NTS might have introduced NaNs that mess up serialization foreach (var coordinate in firstBranchGeometry.Coordinates.Concat(secondBranch.Geometry.Coordinates)) { coordinate.Z = 0; } if (branch.IsLengthCustom) { // Need to remember the current chainage values because setting the length of a branch with a custom // length causes chainages to be compensated. var originalChainages = branch.BranchFeatures.Concat(secondBranch.BranchFeatures).ToDictionary(f => f, f => f.Chainage); var originalLength = branch.Length; var fraction = firstBranchGeometryLength / originalFirstBranchGeometryLength; branch.Length = originalLength * fraction; secondBranch.Length = originalLength * (1 - fraction); // restore original chainages foreach (var branchFeature in originalChainages.Keys) { branchFeature.Chainage = originalChainages[branchFeature]; } } MoveBranchFeatures(branch, branch.IsLengthCustom ? branch.Length : firstBranchGeometry.Length, secondBranch); // update 1st branch length branch.Geometry = firstBranchGeometry; SplitBranchFeaturesWithLength(branch, secondBranch); return(secondBranch); }
public static IList <StrassenabschnittGIS> GenerateStrassenabschnittGIS(ISession session, ErfassungsPeriod currentPeriod, IList <AchsenSegment> achsensegmente) { var belastungskategories = session.Query <Belastungskategorie>().ToList(); var Massnahmen = session.Query <MassnahmenvorschlagKatalog>().Where(mvk => mvk.ErfassungsPeriod.Id == currentPeriod.Id).ToList(); Random rnd = new Random(); int achsensegmente_count = achsensegmente.Count; var generator = new RandomGenerator(); var strassenabschnittBuilder = Builder <StrassenabschnittGIS> .CreateListOfSize(achsensegmente_count) .All() .With(s => s.Belastungskategorie = Pick <Belastungskategorie> .RandomItemFrom(belastungskategories)) .With(s => s.Mandant = currentPeriod.Mandant) .With(s => s.ErfassungsPeriod = currentPeriod) .With(s => s.Strassenname = generator.Phrase(20)) .With(s => s.IsLocked = false) .With(s => s.Trottoir = Pick <TrottoirTyp> .RandomItemFrom(Enum.GetValues(typeof(TrottoirTyp)).Cast <TrottoirTyp>().ToList())); var strassenabschnitte = strassenabschnittBuilder.Build(); var pageSize = 1; var index = 0; foreach (var strassenabschnitt in strassenabschnitte) { strassenabschnitt.Shape = achsensegmente[index].Shape; IGeometry shape = strassenabschnitt.Shape; foreach (Coordinate coord in shape.Coordinates) { coord.Z = double.NaN; } switch (strassenabschnitt.Trottoir) { case TrottoirTyp.Links: strassenabschnitt.BreiteTrottoirLinks = (decimal)rnd.NextDouble() + 1; break; case TrottoirTyp.Rechts: strassenabschnitt.BreiteTrottoirRechts = (decimal)rnd.NextDouble() + 1; break; case TrottoirTyp.BeideSeiten: strassenabschnitt.BreiteTrottoirLinks = (decimal)rnd.NextDouble() + 1; strassenabschnitt.BreiteTrottoirRechts = (decimal)rnd.NextDouble() + 1; break; case TrottoirTyp.NochNichtErfasst: case TrottoirTyp.KeinTrottoir: default: break; } LengthIndexedLine indexedLine = new LengthIndexedLine(shape); strassenabschnitt.Laenge = Convert.ToDecimal(Math.Round(indexedLine.EndIndex, 1)); strassenabschnitt.ReferenzGruppe = new ReferenzGruppe(); strassenabschnitt.ReferenzGruppe.StrassenabschnittGISList.Add(strassenabschnitt); AchsenReferenz achsenreferenz = new AchsenReferenz(); achsenreferenz.ReferenzGruppe = strassenabschnitt.ReferenzGruppe; achsenreferenz.AchsenSegment = achsensegmente[index]; achsenreferenz.Shape = achsensegmente[index].Shape; achsenreferenz.ReferenzGruppe = strassenabschnitt.ReferenzGruppe; strassenabschnitt.ReferenzGruppe.AddAchsenReferenz(achsenreferenz); double linelength = indexedLine.EndIndex; for (int i = 0; i < pageSize; i++) { ZustandsabschnittGIS zustandsabschnitt = new ZustandsabschnittGIS(); zustandsabschnitt.StrassenabschnittGIS = strassenabschnitt; zustandsabschnitt.ReferenzGruppe = new ReferenzGruppe(); zustandsabschnitt.ReferenzGruppe.ZustandsabschnittGISList.Add(zustandsabschnitt); AchsenReferenz achsenreferenzzustandsabschnitt = new AchsenReferenz(); achsenreferenzzustandsabschnitt.ReferenzGruppe = zustandsabschnitt.ReferenzGruppe; achsenreferenzzustandsabschnitt.AchsenSegment = achsensegmente[index]; IGeometry subline = indexedLine.ExtractLine(linelength / pageSize * i, linelength / pageSize * (i + 1)); achsenreferenzzustandsabschnitt.Shape = subline; zustandsabschnitt.Shape = subline; zustandsabschnitt.Laenge = decimal.Parse(new LengthIndexedLine(subline).EndIndex.ToString()); zustandsabschnitt.Zustandsindex = Pick <decimal> .RandomItemFrom(new List <decimal> { 0, 1, 2, 3, 4, 5 }); zustandsabschnitt.Erfassungsmodus = ZustandsErfassungsmodus.Manuel; achsenreferenzzustandsabschnitt.ReferenzGruppe = zustandsabschnitt.ReferenzGruppe; zustandsabschnitt.ReferenzGruppe.AddAchsenReferenz(achsenreferenzzustandsabschnitt); zustandsabschnitt.Aufnahmedatum = DateTime.Now.Date; zustandsabschnitt.Aufnahmeteam = generator.Phrase(20); zustandsabschnitt.Bemerkung = generator.Phrase(40); zustandsabschnitt.BezeichnungVon = strassenabschnitt.BezeichnungVon + generator.Phrase(10); zustandsabschnitt.BezeichnungBis = strassenabschnitt.BezeichnungBis + generator.Phrase(10); strassenabschnitt.Zustandsabschnitten.Add(zustandsabschnitt); zustandsabschnitt.MassnahmenvorschlagFahrbahn = Pick <MassnahmenvorschlagKatalog> .RandomItemFrom(Massnahmen.Where(mvk => mvk.KatalogTyp == MassnahmenvorschlagKatalogTyp.Fahrbahn && mvk.Belastungskategorie.Id == strassenabschnitt.Belastungskategorie.Id).ToList()); zustandsabschnitt.DringlichkeitFahrbahn = Pick <DringlichkeitTyp> .RandomItemFrom(Enum.GetValues(typeof(DringlichkeitTyp)).Cast <DringlichkeitTyp>().ToList()); switch (strassenabschnitt.Trottoir) { case TrottoirTyp.Links: zustandsabschnitt.MassnahmenvorschlagTrottoirLinks = Pick <MassnahmenvorschlagKatalog> .RandomItemFrom(Massnahmen.Where(mvk => mvk.KatalogTyp == MassnahmenvorschlagKatalogTyp.Trottoir && mvk.Belastungskategorie.Id == strassenabschnitt.Belastungskategorie.Id).ToList()); zustandsabschnitt.ZustandsindexTrottoirLinks = Pick <ZustandsindexTyp> .RandomItemFrom(Enum.GetValues(typeof(ZustandsindexTyp)).Cast <ZustandsindexTyp>().ToList()); zustandsabschnitt.DringlichkeitTrottoirLinks = Pick <DringlichkeitTyp> .RandomItemFrom(Enum.GetValues(typeof(DringlichkeitTyp)).Cast <DringlichkeitTyp>().ToList()); break; case TrottoirTyp.Rechts: zustandsabschnitt.MassnahmenvorschlagTrottoirRechts = Pick <MassnahmenvorschlagKatalog> .RandomItemFrom(Massnahmen.Where(mvk => mvk.KatalogTyp == MassnahmenvorschlagKatalogTyp.Trottoir && mvk.Belastungskategorie.Id == strassenabschnitt.Belastungskategorie.Id).ToList()); zustandsabschnitt.ZustandsindexTrottoirRechts = Pick <ZustandsindexTyp> .RandomItemFrom(Enum.GetValues(typeof(ZustandsindexTyp)).Cast <ZustandsindexTyp>().ToList()); zustandsabschnitt.DringlichkeitTrottoirRechts = Pick <DringlichkeitTyp> .RandomItemFrom(Enum.GetValues(typeof(DringlichkeitTyp)).Cast <DringlichkeitTyp>().ToList()); break; case TrottoirTyp.BeideSeiten: zustandsabschnitt.MassnahmenvorschlagTrottoirLinks = Pick <MassnahmenvorschlagKatalog> .RandomItemFrom(Massnahmen.Where(mvk => mvk.KatalogTyp == MassnahmenvorschlagKatalogTyp.Trottoir && mvk.Belastungskategorie.Id == strassenabschnitt.Belastungskategorie.Id).ToList()); zustandsabschnitt.MassnahmenvorschlagTrottoirRechts = Pick <MassnahmenvorschlagKatalog> .RandomItemFrom(Massnahmen.Where(mvk => mvk.KatalogTyp == MassnahmenvorschlagKatalogTyp.Trottoir && mvk.Belastungskategorie.Id == strassenabschnitt.Belastungskategorie.Id).ToList()); zustandsabschnitt.ZustandsindexTrottoirLinks = Pick <ZustandsindexTyp> .RandomItemFrom(Enum.GetValues(typeof(ZustandsindexTyp)).Cast <ZustandsindexTyp>().ToList()); zustandsabschnitt.ZustandsindexTrottoirRechts = Pick <ZustandsindexTyp> .RandomItemFrom(Enum.GetValues(typeof(ZustandsindexTyp)).Cast <ZustandsindexTyp>().ToList()); zustandsabschnitt.DringlichkeitTrottoirLinks = Pick <DringlichkeitTyp> .RandomItemFrom(Enum.GetValues(typeof(DringlichkeitTyp)).Cast <DringlichkeitTyp>().ToList()); zustandsabschnitt.DringlichkeitTrottoirRechts = Pick <DringlichkeitTyp> .RandomItemFrom(Enum.GetValues(typeof(DringlichkeitTyp)).Cast <DringlichkeitTyp>().ToList()); break; case TrottoirTyp.NochNichtErfasst: case TrottoirTyp.KeinTrottoir: default: break; } session.Save(zustandsabschnitt); } session.Save(strassenabschnitt); index++; } var test = strassenabschnitte.Where(s => s.IsLocked == true); return(strassenabschnitte); }