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 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 (bool result, string node) CheckSegmentContains(NetworkSegment segment, string[] segmentNodes) { foreach (var node in segmentNodes) { if (!segment.ContainsKey(node)) { return(false, node); } } return(true, string.Empty); }
public void EndChainageDependsOnDirection() { var segment = new NetworkSegment { Chainage = 40, Length = 10, DirectionIsPositive = true }; Assert.AreEqual(50, segment.EndChainage); //change direction changes the end offset segment.DirectionIsPositive = false; Assert.AreEqual(30, segment.EndChainage); }
public void EndOffsetDependsOnDirection() { NetworkSegment segment = new NetworkSegment(); segment.Offset = 40; segment.Length = 10; segment.DirectionIsPositive = true; Assert.AreEqual(50, segment.EndOffset); //change direction changes the end offset segment.DirectionIsPositive = false; Assert.AreEqual(30, segment.EndOffset); }
private static IList <INetworkSegment> GetSegmentsForPath(INode sourceNode, IEnumerable <IBranch> path) { var segments = new List <INetworkSegment>(); var currentSourceNode = sourceNode; foreach (var branch in path) { var isDirectionPositive = branch.Source == currentSourceNode; var currentTargetNode = isDirectionPositive ? branch.Target : branch.Source; var originalBranch = (IBranch)branch.Attributes["OriginalFeature"]; var originalFeature = currentSourceNode.Attributes.ContainsKey("OriginalFeature") ? currentSourceNode.Attributes["OriginalFeature"] : null; var newSegment = new NetworkSegment { Branch = originalBranch }; if (isDirectionPositive) { newSegment.Length = branch.Length; var branchFeature = originalFeature as IBranchFeature; if (branchFeature != null) { // If the node is a boundary node it may be defined on an adjacent branch, and the chainage is zero. newSegment.Chainage = Equals(originalBranch, branchFeature.Branch) ? branchFeature.Chainage : 0; } newSegment.Geometry = (IGeometry)branch.Geometry.Clone(); } else { newSegment.DirectionIsPositive = false; newSegment.Length = branch.Length; var branchFeature = originalFeature as IBranchFeature; if (branchFeature != null) { // If the node is a boundary node it may be defined on an adjacent branch, and the chainage is the full length. newSegment.Chainage = Equals(originalBranch, branchFeature.Branch) ? branchFeature.Chainage : originalBranch.Length; } else { newSegment.Chainage = originalBranch.Length; } newSegment.Geometry = new LineString(branch.Geometry.Coordinates.Reverse().ToArray()); } segments.Add(newSegment); currentSourceNode = currentTargetNode; } return(segments); }
private static IList <INetworkSegment> GetSegmentsForPath(INode sourceNode, IEnumerable <IBranch> path) { var segments = new List <INetworkSegment>(); var currentSourceNode = sourceNode; var i = 0; foreach (var branch in path) { var isDirectionPositive = branch.Source == currentSourceNode; var currentTargetNode = isDirectionPositive ? branch.Target : branch.Source; var originalBranch = (IBranch)branch.Attributes["OriginalFeature"]; var originalFeature = currentSourceNode.Attributes.ContainsKey("OriginalFeature") ? currentSourceNode.Attributes["OriginalFeature"] : null; var newSegment = new NetworkSegment { Branch = originalBranch }; if (isDirectionPositive) { newSegment.Length = branch.Length; if (originalFeature is IBranchFeature) { newSegment.Offset = ((IBranchFeature)originalFeature).Offset; } newSegment.Geometry = (IGeometry)branch.Geometry.Clone(); } else { newSegment.DirectionIsPositive = false; newSegment.Length = branch.Length; if (originalFeature is IBranchFeature) { newSegment.Offset = ((IBranchFeature)originalFeature).Offset; } else { newSegment.Offset = originalBranch.Length; } //newSegment.Offset = 0; newSegment.Geometry = new LineString(branch.Geometry.Coordinates.Reverse().ToArray()); } segments.Add(newSegment); i++; currentSourceNode = currentTargetNode; } return(segments); }
public void GetLocationsForSegmentInCorrectOrder() { var network = CreateThreeNodesNetwork(); var branch = (Branch)network.Branches[0]; var source = new NetworkCoverage { Network = network }; source[new NetworkLocation(branch, 10.0)] = 10.0; source[new NetworkLocation(branch, 50.0)] = 30.0; source[new NetworkLocation(branch, 60.0)] = 20.0; source[new NetworkLocation(branch, 80.0)] = 10.0; // retrieve the location of source that overlap with segmentUp var segmentUp = new NetworkSegment { Branch = branch, Chainage = 30, Length = 40 }; var locationsUp = RouteHelper.GetLocationsForSegment(segmentUp, source, false).ToList(); Assert.AreEqual(new NetworkLocation(branch, 50.0), locationsUp[0]); Assert.AreEqual(new NetworkLocation(branch, 60.0), locationsUp[1]); // retrieve the location of source that overlap with segmentDown; the direction // is negative and the location offset are thus descending var segmentDown = new NetworkSegment { Branch = branch, Chainage = 90, Length = 50, DirectionIsPositive = false }; var locationsDown = RouteHelper.GetLocationsForSegment(segmentDown, source, false).ToList(); Assert.AreEqual(new NetworkLocation(branch, 80.0), locationsDown[0]); Assert.AreEqual(new NetworkLocation(branch, 60.0), locationsDown[1]); Assert.AreEqual(new NetworkLocation(branch, 50.0), locationsDown[2]); }
// Evaluate value at start and end of segment and interpolate the colors based on colors from theme. // The 4 dictinctive cases below should be properly handled by coverage.Evaluate //A 0 8 0 // [ ][ ][ ] // interpolate - linear // extrapolate - constant // 0000012334566788877776665555444333322211110000000 //B 0 8 0 // [ ][ ][ ] // interpolate - linear // extrapolate - linear // -10001233456678887777666555544433332221111000-1-1 //C 0 8 0 // [ ][ ][ ] // interpolate - linear // extrapolate - none // ddd00123345667888777766655554443333222111100ddddd where d is default value for coverage //D0 8 0 // [ ][ ][ ] // interpolate - linear // extrapolate - n.a. // 0011233455667888777766565555444433332222111110000 // no interpolation; only locations are visible // 0 8 0 // [ ][ ][ ] // interpolate - constant // 0000000008888888888888888888800000000000000000000 // 0 8 0 // [ ][ ][ ] // interpolate - constant // 0000000088888888888888888888888880000000000000000 private static void RenderBranchSegments(IBranch branch, VectorLayer segmentsLayer, Graphics graphics, INetworkCoverage coverage, Dictionary <INetworkLocation, INetworkSegment> locationsToSegmentDictonary) { var knownBranchLocations = coverage.GetLocationsForBranch(branch); var theme = segmentsLayer.Theme; var defaultStyle = (theme != null) ? (VectorStyle)theme.GetStyle(coverage.DefaultValue) : segmentsLayer.Style; var first = true; var allBranchLocations = new List <double>(); var branchSegments = new List <INetworkSegment>(); foreach (var location in knownBranchLocations) { if (!locationsToSegmentDictonary.Keys.Contains(location)) { continue; } var segment = locationsToSegmentDictonary[location]; branchSegments.Add(segment); if (first) { allBranchLocations.Add(segment.Chainage); } allBranchLocations.Add(location.Chainage); allBranchLocations.Add(segment.Chainage + segment.Length); first = false; } if (allBranchLocations.Any()) { var allBranchLocationValues = coverage.EvaluateWithinBranch(branch, allBranchLocations.OrderBy(o => o), knownBranchLocations); for (var i = 0; i < branchSegments.Count; i++) { var firstSegment = (i == 0); var lastSegment = (i == branchSegments.Count - 1); var segment = branchSegments[i]; var offset = knownBranchLocations[i].Chainage; DrawSegment(segmentsLayer, coverage, theme, i, allBranchLocationValues, firstSegment, lastSegment, graphics, segment, defaultStyle, offset); } } else { // When no locations, we still render because there // might be interpolation across nodes (ordered branches), // otherwise it will be rendered at the default coverage value. var values = new List <double>() { coverage.Evaluate(new NetworkLocation(branch, 0)), coverage.Evaluate(new NetworkLocation(branch, branch.Length / 2)), coverage.Evaluate(new NetworkLocation(branch, branch.Length)) }; var segment = new NetworkSegment() { Branch = branch, Chainage = 0.0, Length = branch.Length, Geometry = branch.Geometry }; DrawSegment(segmentsLayer, coverage, theme, 0, values, true, true, graphics, segment, defaultStyle, branch.Length / 2); } }