///<summary> ///</summary> ///<param name="branchFeature"></param> ///<param name="nearestBranch"></param> public static void AddBranchFeatureToBranch(IBranchFeature branchFeature, IBranch nearestBranch) { var currentBranch = branchFeature.Branch; if (Equals(currentBranch, nearestBranch)) { return; } if (currentBranch != null) // remove feature from previous branch { branchFeature.Branch = null; currentBranch.BranchFeatures.Remove(branchFeature); } // add feature to new branch //don't add network locations to the branchfeatures of the branch. //this makes no sense since they belong to the coverage and this is not how they are mapped //see issue 2358 if (branchFeature is INetworkLocation) { return; } branchFeature.Branch = nearestBranch; nearestBranch.BranchFeatures.Add(branchFeature); }
public virtual int CompareTo(IBranchFeature other) { if (this == other) { return(0); } if (null == Branch) { throw new Exception("Cannot compare branch features that are not connected to a branch."); } if (other.Branch != branch) { return(Branch.CompareTo(other.Branch)); } if (Chainage > other.Chainage) { return(1); } if (Math.Abs(Chainage - other.Chainage) < Epsilon) { // in some cases branch features are defined at the same location and differ only in name if (Name != other.Name) { return(String.Compare(Name, other.Name, StringComparison.Ordinal)); } return(0); } return(-1); }
public static void AddBranchFeatureToBranch(IBranchFeature branchFeature, IBranch branch, double chainage) { branchFeature.Branch = branch; // set branch in advance branchFeature.Chainage = BranchFeature.SnapChainage(branch.Length, chainage); if (!(branchFeature is INetworkLocation)) { branch.BranchFeatures.Add(branchFeature); } }
private static void FitBranchFeatureWithLengthInBranch(IBranchFeature branchFeature, double branchCalculationLength) { if (branchFeature.Length > branchCalculationLength) { branchFeature.Chainage = 0; branchFeature.Length = branchCalculationLength; } else if ((branchFeature.Length + branchFeature.Chainage) > branchCalculationLength) { branchFeature.Chainage = branchCalculationLength - branchFeature.Length; } }
public static void AddBranchFeatureToBranch(IBranchFeature branchFeature, IBranch branch, double offset) { if (offset > branch.Length) { offset = branch.Length; } branchFeature.Branch = branch; branchFeature.Offset = offset; if (!(branchFeature is INetworkLocation)) { branch.BranchFeatures.Add(branchFeature); } }
///<summary> ///</summary> ///<param name="branchFeature"></param> ///<param name="nearestBranch"></param> public static void AddBranchFeatureToBranch(IBranchFeature branchFeature, IBranch nearestBranch) { var currentBranch = branchFeature.Branch; if (currentBranch != null && currentBranch != branchFeature.Branch) // remove feature from previous branch { branchFeature.Branch = null; currentBranch.BranchFeatures.Remove(branchFeature); } if (currentBranch != nearestBranch) // add feature to new branch { branchFeature.Branch = nearestBranch; nearestBranch.BranchFeatures.Add(branchFeature); } }
/// <summary> /// Gets or creates a new node on the branch by splitting the branch /// </summary> private static INode GetOrCreateNodeOnBranch(double offset, IBranchFeature node, IBranch branch) { var splitNode = SplitBranchAtNode(branch, offset); if (null != splitNode) { splitNode.Name = node.ToString(); } else { //no split so it must be the end or the start of the node //find out if it was start or end using geometry of the startNode splitNode = (branch.Source.Geometry.Equals(node.Geometry)) ? branch.Source : branch.Target; } splitNode.Attributes["OriginalFeature"] = node; return(splitNode); }
public static double GetRouteOffset(Route route, IBranchFeature branchFeature) { var offset = GetRouteOffsetInternal(route, branchFeature); if (offset >= 0) { if (offset > GetRouteLength(route)) { offset = -1; } } else { offset = -1; } return(offset); }
public static double GetRouteChainage(Route route, IBranchFeature branchFeature) { var chainage = GetRouteChainageInternal(route, branchFeature); if (chainage >= 0) { if (chainage > GetRouteLength(route)) { chainage = -1; } } else { chainage = -1; } return(chainage); }
public void GetNeighboursOnBranch() { var network = new Network(); Branch branch = new Branch { Source = new Node("n1"), Target = new Node("n2"), Geometry = GeometryFromWKT.Parse("LINESTRING(0 0, 100 0)") }; network.Branches.Add(branch); for (int i = 1; i < 10; i++) { branch.BranchFeatures.Add(new SimpleBranchFeature { Branch = branch, Chainage = 10 * i }); } IBranchFeature before = null; IBranchFeature after = null; NetworkHelper.GetNeighboursOnBranch(branch, 5, out before, out after); Assert.IsNull(before); Assert.AreEqual(branch.BranchFeatures[0], after); NetworkHelper.GetNeighboursOnBranch(branch, 45, out before, out after); Assert.AreEqual(branch.BranchFeatures[3], before); Assert.AreEqual(branch.BranchFeatures[4], after); NetworkHelper.GetNeighboursOnBranch(branch, 50, out before, out after); Assert.AreEqual(branch.BranchFeatures[3], before); Assert.AreEqual(branch.BranchFeatures[5], after); NetworkHelper.GetNeighboursOnBranch(branch, 95, out before, out after); Assert.AreEqual(branch.BranchFeatures[8], before); Assert.IsNull(after); }
public int CompareTo(IBranchFeature other) { if (this == other) { return 0; } if (null == Branch) { throw new Exception("Cannot compare branch features that are not connected to a branch."); } if (other.Branch != branch) { return Branch.CompareTo(other.Branch); } if (Offset > other.Offset) { return 1; } return -1; }
public int CompareTo(IBranchFeature other) { if (this == other) { return(0); } if (null == Branch) { throw new Exception("Cannot compare branch features that are not connected to a branch."); } if (other.Branch != branch) { return(Branch.CompareTo(other.Branch)); } if (Offset > other.Offset) { return(1); } return(-1); }
/// <summary> /// Gets or creates a new node on the branch by splitting the branch /// /// HACK, TODO: node is of type IBranchFeature?!? node / branch feature are messed-up here. /// </summary> private static INode GetOrCreateNodeOnBranch(double chainage, IBranchFeature node, IBranch branch) { var splitResult = SplitBranchAtNode(branch, chainage); var splitNode = (splitResult != null) ? splitResult.NewNode : null; if (null != splitNode) { splitNode.Name = node.ToString(); splitResult.NewBranch.Network = branch.Network; } else { //no split so it must be the end or the start of the node //find out if it was start or end using geometry of the startNode var isSource = branch.Source.Geometry.Coordinate.X == node.Geometry.Coordinate.X && branch.Source.Geometry.Coordinate.Y == node.Geometry.Coordinate.Y; splitNode = isSource ? branch.Source : branch.Target; } splitNode.Attributes["OriginalFeature"] = node; return(splitNode); }
/// <summary> /// returns the chainage of the branchfeature in the route. -1 if branchfeature is not in the route. /// </summary> /// <param name="route"></param> /// <param name="branchFeature"></param> /// <returns></returns> private static double GetRouteChainageInternal(Route route, IBranchFeature branchFeature) { double chainage = 0; foreach (var segment in route.Segments.Values) { if (branchFeature.Branch != segment.Branch) { chainage += segment.Length; } else { if (segment.DirectionIsPositive) { if (branchFeature.Chainage > segment.Chainage + segment.Length + ErrorMargin) { chainage += segment.Length; } else { chainage += (branchFeature.Chainage - segment.Chainage); return(chainage); } } else { if (branchFeature.Chainage > segment.Chainage)// + segment.Length) { chainage += segment.Length; } else { chainage += (segment.Chainage - branchFeature.Chainage); return(chainage); } } } } return(-1); }
/// <summary> /// returns the offset of the branchfeature in the route. -1 if branchfeature is not in the route. /// </summary> /// <param name="route"></param> /// <param name="branchFeature"></param> /// <returns></returns> public static double GetRouteOffset(INetworkCoverage route, IBranchFeature branchFeature) { double offset = 0; foreach (var segment in route.Segments.Values) { if (branchFeature.Branch != segment.Branch) { offset += segment.Length; } else { if (segment.DirectionIsPositive) { if (branchFeature.Offset > segment.Offset + segment.Length) { offset += segment.Length; } else { offset += (branchFeature.Offset - segment.Offset); return(offset); } } else { if (branchFeature.Offset > segment.Offset)// + segment.Length) { offset += segment.Length; } else { offset += (segment.Offset - branchFeature.Offset); return(offset); } } } } return(-1); }
/// <summary> /// returns the offset of the branchfeature in the route. -1 if branchfeature is not in the route. /// </summary> /// <param name="route"></param> /// <param name="branchFeature"></param> /// <returns></returns> private static double GetRouteOffsetInternal(Route route, IBranchFeature branchFeature) { double offset = 0; foreach (var segment in route.Segments.Values) { if (branchFeature.Branch != segment.Branch) { offset += segment.Length; } else { if (segment.DirectionIsPositive) { if (branchFeature.Offset > segment.Offset + segment.Length + errorMargin) { offset += segment.Length; } else { offset += (branchFeature.Offset - segment.Offset); return(offset); } } else { if (branchFeature.Offset > segment.Offset)// + segment.Length) { offset += segment.Length; } else { offset += (segment.Offset - branchFeature.Offset); return(offset); } } } } return(-1); }
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 virtual int CompareTo(IBranchFeature other) { if (this == other) { return 0; } if (null == Branch) { throw new Exception("Cannot compare branch features that are not connected to a branch."); } if (other.Branch != branch) { return Branch.CompareTo(other.Branch); } if (Chainage > other.Chainage) { return 1; } if (Math.Abs(Chainage - other.Chainage) < Epsilon) { // in some cases branch features are defined at the same location and differ only in name if (Name != other.Name) { return String.Compare(Name, other.Name, StringComparison.Ordinal); } return 0; } return -1; }
public static double MapChainage(IBranchFeature branchFeature) { return(MapChainage(branchFeature.Branch, branchFeature.Chainage)); }
public static void UpdateBranchFeatureOffsetFromGeometry(IBranchFeature branchFeature) { branchFeature.Offset = GeometryHelper.Distance((ILineString)branchFeature.Branch.Geometry, branchFeature.Geometry.Coordinates[0]); }
private static void UpdateLineGeometry(IBranchFeature branchFeature) { var lengthIndexedLine = new LengthIndexedLine(branchFeature.Branch.Geometry); branchFeature.Geometry = lengthIndexedLine.ExtractLine(branchFeature.Chainage, branchFeature.Chainage + branchFeature.Length); }
/// <summary> /// returns the offset of the branchfeature in the route. -1 if branchfeature is not in the route. /// </summary> /// <param name="route"></param> /// <param name="branchFeature"></param> /// <returns></returns> public static double GetRouteOffset(INetworkCoverage route, IBranchFeature branchFeature) { double offset = 0; foreach (var segment in route.Segments.Values) { if (branchFeature.Branch != segment.Branch) { offset += segment.Length; } else { if (segment.DirectionIsPositive) { if (branchFeature.Offset > segment.Offset + segment.Length) { offset += segment.Length; } else { offset += (branchFeature.Offset - segment.Offset); return offset; } } else { if (branchFeature.Offset > segment.Offset)// + segment.Length) { offset += segment.Length; } else { offset += (segment.Offset - branchFeature.Offset); return offset; } } } } return -1; }
/// <summary> /// returns the chainage of the branchfeature in the route. -1 if branchfeature is not in the route. /// </summary> /// <param name="route"></param> /// <param name="branchFeature"></param> /// <returns></returns> private static double GetRouteChainageInternal(Route route, IBranchFeature branchFeature) { double chainage = 0; foreach (var segment in route.Segments.Values) { if (branchFeature.Branch != segment.Branch) { chainage += segment.Length; } else { if (segment.DirectionIsPositive) { if (branchFeature.Chainage > segment.Chainage + segment.Length + ErrorMargin) { chainage += segment.Length; } else { chainage += (branchFeature.Chainage - segment.Chainage); return chainage; } } else { if (branchFeature.Chainage > segment.Chainage)// + segment.Length) { chainage += segment.Length; } else { chainage += (segment.Chainage - branchFeature.Chainage); return chainage; } } } } return -1; }
public static void AddBranchFeatureToBranch(IBranch branch, IBranchFeature branchFeature, double offset) { branchFeature.Branch = branch; branchFeature.Offset = offset; branch.BranchFeatures.Add(branchFeature); }
public static NetworkLocation ToNetworkLocation(this IBranchFeature branchFeature) { return(new NetworkLocation(branchFeature.Branch, branchFeature.Offset)); }
public double Evaluate(IBranchFeature branchFeature) { return(Evaluate(new NetworkLocation(branchFeature.Branch, branchFeature.Offset))); }
public static void UpdateBranchFeatureChainageFromGeometry(IBranchFeature branchFeature) { branchFeature.Chainage = GetBranchFeatureChainageFromGeometry(branchFeature.Branch, branchFeature.Geometry); }
public static double GetRouteChainage(Route route, IBranchFeature branchFeature) { var chainage = GetRouteChainageInternal(route, branchFeature); if (chainage >= 0) { if (chainage > GetRouteLength(route)) { chainage = -1; } } else { chainage = -1; } return chainage; }
/// <summary> /// connects branchFeature to the first branch is in range. This is not correct it should /// take the nearest or only use a very small tolerance. Update in coordinates is primarily /// the responsibility of the snapping layer. /// TODO: pass snapped info here? Small refactoring is required /// </summary> /// <param name="branches"></param> /// <param name="branchFeature"></param> /// <param name="tolerance">set distance tolerance used to detect nearest branch</param> public static IBranch AddBranchFeatureToNearestBranch(IEnumerable <IBranch> branches, IBranchFeature branchFeature, double tolerance) { var nearestBranch = GetNearestBranch(branches, branchFeature.Geometry, tolerance); if (nearestBranch == null) { if (branchFeature.Branch != null) { return(branchFeature.Branch); } throw new ArgumentException("Consistency problem, feature can't be connected to the branch, no valid geometry overlapping found"); } AddBranchFeatureToBranch(branchFeature, nearestBranch); return(nearestBranch); }
public static bool IsBranchFeatureInRoute(Route route, IBranchFeature branchFeature) { return(GetRouteChainage(route, branchFeature) >= 0); }
public static IList <INetworkSegment> GetShortestPathBetweenBranchFeaturesAsNetworkSegments(INetwork network, IBranchFeature source, IBranchFeature target) { var graph = CreateLightNetworkCopyWithOldItemsAsAttributes(network); FixBranchReferencesOnNode(graph); var sourceGraphBranch = graph.Branches[network.Branches.IndexOf(source.Branch)]; var targetGraphBranch = graph.Branches[network.Branches.IndexOf(target.Branch)]; INode sourceNode = GetOrCreateNodeOnBranch(MapChainage(sourceGraphBranch, source.Chainage), source, sourceGraphBranch); FixBranchReferencesOnNode(graph); var splitOccured = (network.Branches.Count != graph.Branches.Count); //if the first node split the branch and the target was on that branch the target needs to move. var targetChainage = target.Chainage; if (splitOccured && target.Branch == source.Branch) { if (target.Chainage > source.Chainage) { targetGraphBranch = graph.Branches.Last(); //have to update the chainage because the branch was split at source chainage. Hence subtract this chainage targetChainage -= source.Chainage; } } INode targetNode = GetOrCreateNodeOnBranch(MapChainage(targetGraphBranch, targetChainage), target, targetGraphBranch); FixBranchReferencesOnNode(graph); // check if we don't have adjacent nodes var result = graph.ShortestPathsDijkstra(b => b.Length, sourceNode); IEnumerable <IBranch> path; if (result(targetNode, out path)) // path exists { return(GetSegmentsForPath(sourceNode, path)); } //return an empty segment list return(new List <INetworkSegment>()); }
// TODO: make it work for T, make interpolators injectable //public override T GetInterpolatedValue<T>(params IVariableFilter[] filters) public double Evaluate(DateTime time, IBranchFeature branchFeature) { return(Evaluate(time, new NetworkLocation(branchFeature.Branch, branchFeature.Offset))); }
public static void UpdateBranchFeatureOffsetFromGeometry(IBranchFeature branchFeature) { branchFeature.Offset = GetBranchFeatureOffsetFromGeometry(branchFeature.Branch, branchFeature.Geometry); }
public virtual int CompareTo(IBranchFeature other) { throw new NotImplementedException(); }
public int CompareTo(IBranchFeature other) { throw new NotImplementedException(); }
private void UpdateBranchFeatureGeometry(IGeometry target, ILineString newLineString, double newFraction, IBranch branch, IBranchFeature branchFeature) { var newOffset = !branch.IsLengthCustom ? BranchFeature.SnapChainage(newLineString.Length, newLineString.Length * newFraction) : BranchFeature.SnapChainage(newLineString.Length, branchFeature.Chainage * newLineString.Length / branch.Length); if (!branch.IsLengthCustom) { branchFeature.Chainage = newOffset; } branchFeature.Geometry = GeometryHelper.SetCoordinate(target, 0, GeometryHelper.LineStringCoordinate(newLineString, newOffset)); }
public static bool IsBranchFeatureInRoute(Route route, IBranchFeature branchFeature) { return GetRouteChainage(route, branchFeature) >= 0; }