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)); }
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); }
protected override Coordinate ExtractOffsetAt(Geometry linearGeom, Coordinate testPt, double offsetDistance) { var indexedLine = new LengthIndexedLine(linearGeom); double index = indexedLine.IndexOf(testPt); return(indexedLine.ExtractPoint(index, offsetDistance)); }
protected override bool IndexOfAfterCheck(Geometry linearGeom, Coordinate testPt) { var indexedLine = new LengthIndexedLine(linearGeom); // check locations are consecutive double loc1 = indexedLine.IndexOf(testPt); double loc2 = indexedLine.IndexOfAfter(testPt, loc1); if (loc2 <= loc1) { return(false); } // check extracted points are the same as the input var pt1 = indexedLine.ExtractPoint(loc1); var pt2 = indexedLine.ExtractPoint(loc2); if (!pt1.Equals2D(testPt)) { return(false); } if (!pt2.Equals2D(testPt)) { return(false); } return(true); }
public static double CalculateGeometryDifferenceRatio(ILineString oldGeom, ILineString newGeom) { int n = newGeom.Coordinates.Length; Coordinate startCoodinate = newGeom.Coordinates[0]; Coordinate endCoordinate = newGeom.Coordinates[n - 1]; LengthIndexedLine lil = new LengthIndexedLine(oldGeom); double projStartIndex = lil.IndexOf(startCoodinate); double projEndIndex = lil.IndexOf(endCoordinate); double lenOld = oldGeom.Length; double lenNew = Math.Abs(projEndIndex - projStartIndex); return(lenNew / lenOld); }
/// <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); }
/// <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); 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); }