//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); }
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); }
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; source[new NetworkLocation(branch, 50.0)] = 30; source[new NetworkLocation(branch, 60.0)] = 20; source[new NetworkLocation(branch, 80.0)] = 10; // retrieve the location of source that overlap with segmentUp var segmentUp = new NetworkSegment { Branch = branch, Offset = 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, Offset = 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]); }
//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; }
// 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); } }
//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; }
//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); }