private static void OperateOneTimestep(INetworkCoverage coverageA, INetworkCoverage coverageB, IEnumerable <INetworkLocation> allLocations, Func <double, double, double> operation) { IDictionary <INetworkLocation, double> locationToValueMapping = new Dictionary <INetworkLocation, double>(); foreach (var loc in allLocations) { //in case of different networks the actual location is retrieved using coordinates: var locationInCoverageA = GetLocationInCoverage(coverageA, loc); if (locationInCoverageA != null) { var valueForA = coverageA.Evaluate(locationInCoverageA); var locationInCoverageB = GetLocationInCoverage(coverageB, loc); var valueForB = locationInCoverageB != null?coverageB.Evaluate(locationInCoverageB) : 0.0; var value = operation(valueForA, valueForB); locationToValueMapping.Add(locationInCoverageA, value); } } //apply values in a second loop to prevent evaluation being affected! SetResults(locationToValueMapping, coverageA); }
public void ExtractTimeSlice() { var network = GetNetwork(); var networkCoverage = new NetworkCoverage("test", true) { Network = network }; DateTime [] dateTimes = new DateTime[10]; for (int i = 0; i < 10; i++) { dateTimes[i] = new DateTime(2000, 1, 1, 1, /* minute */ i, 0); networkCoverage[dateTimes[i], new NetworkLocation(network.Branches[0], 10.0)] = 10.0 + i; networkCoverage[dateTimes[i], new NetworkLocation(network.Branches[0], 90.0)] = 90.0 + i; networkCoverage[dateTimes[i], new NetworkLocation(network.Branches[1], 10.0)] = 110.0 + i; networkCoverage[dateTimes[i], new NetworkLocation(network.Branches[1], 90.0)] = 190.0 + i; } INetworkCoverage slice = NetworkCoverageHelper.ExtractTimeSlice(networkCoverage, new DateTime(2000, 1, 1, 1, /* minute */ 0, 0)); Assert.AreEqual(false, slice.IsTimeDependent); Assert.AreEqual(10.0 + 0, slice.Evaluate(new NetworkLocation(network.Branches[0], 10.0))); Assert.AreEqual(90.0 + 0, slice.Evaluate(new NetworkLocation(network.Branches[0], 90.0))); Assert.AreEqual(110.0 + 0, slice.Evaluate(new NetworkLocation(network.Branches[1], 10.0))); Assert.AreEqual(190.0 + 0, slice.Evaluate(new NetworkLocation(network.Branches[1], 90.0))); //slice = NetworkCoverageHelper.ExtractTimeSlice(networkCoverage, new DateTime(2000, 1, 1, 1, /* minute */9, 0)); slice = new NetworkCoverage(networkCoverage.Name, false); NetworkCoverageHelper.ExtractTimeSlice(networkCoverage, slice, new DateTime(2000, 1, 1, 1, /* minute */ 9, 0), true); Assert.AreEqual(false, slice.IsTimeDependent); Assert.AreEqual(10.0 + 9, slice.Evaluate(new NetworkLocation(network.Branches[0], 10.0))); Assert.AreEqual(90.0 + 9, slice.Evaluate(new NetworkLocation(network.Branches[0], 90.0))); Assert.AreEqual(110.0 + 9, slice.Evaluate(new NetworkLocation(network.Branches[1], 10.0))); Assert.AreEqual(190.0 + 9, slice.Evaluate(new NetworkLocation(network.Branches[1], 90.0))); // just repeat the previous action; refilling a coverage should also work NetworkCoverageHelper.ExtractTimeSlice(networkCoverage, slice, new DateTime(2000, 1, 1, 1, /* minute */ 9, 0), true); Assert.AreEqual(false, slice.IsTimeDependent); Assert.AreEqual(10.0 + 9, slice.Evaluate(new NetworkLocation(network.Branches[0], 10.0))); Assert.AreEqual(90.0 + 9, slice.Evaluate(new NetworkLocation(network.Branches[0], 90.0))); Assert.AreEqual(110.0 + 9, slice.Evaluate(new NetworkLocation(network.Branches[1], 10.0))); Assert.AreEqual(190.0 + 9, slice.Evaluate(new NetworkLocation(network.Branches[1], 90.0))); }
private static void Operate(INetworkCoverage coverageA, INetworkCoverage coverageB, Func <double, double, double> operation) { ThrowIfInputIsInvalid(coverageA, coverageB); var allLocations = coverageA.Locations.Values.Concat(coverageB.Locations.Values).Distinct().OrderBy(loc => loc).ToList(); var locationToValueMapping = allLocations.ToDictionary(location => location, location => operation(coverageA.Evaluate(location), coverageB.Evaluate(location))); foreach (var location in allLocations) { coverageA[location] = locationToValueMapping[location]; } }
private static void OperateOneTimestep <T>(INetworkCoverage coverage, IEnumerable <INetworkCoverage> otherCoverages, IEnumerable <INetworkLocation> allLocations, Func <IEnumerable <double>, T> operation, INetworkCoverage outputCoverage = null) { IDictionary <INetworkLocation, T> locationToValueMapping = new Dictionary <INetworkLocation, T>(); foreach (var loc in allLocations) { //in case of different networks the actual location is retrieved using coordinates: var locationInCoverageA = GetLocationInCoverage(coverage, loc); if (locationInCoverageA != null) { var valuesAtLocation = new List <double>(); var valueForA = coverage.Evaluate(locationInCoverageA); valuesAtLocation.Add(valueForA); foreach (var networkCoverage in otherCoverages) { var locationInOtherCoverage = GetLocationInCoverage(networkCoverage, loc); var valueForOther = locationInOtherCoverage != null ? networkCoverage.Evaluate(locationInOtherCoverage) : double.NaN; valuesAtLocation.Add(valueForOther); } var value = operation(valuesAtLocation); locationToValueMapping.Add(locationInCoverageA, value); } } //apply values in a second loop to prevent evaluation being affected! SetResults(locationToValueMapping, outputCoverage ?? coverage); }
private static void OperateOneTimeStep <T>(INetworkCoverage coverage, double referenceValue, IEnumerable <INetworkLocation> allLocations, Func <double, double, T> operation, INetworkCoverage outputCoverage = null) { IDictionary <INetworkLocation, T> locationToValueMapping = new Dictionary <INetworkLocation, T>(); foreach (var loc in allLocations) { //in case of different networks the actual location is retrieved using coordinates: var locationInCoverageA = GetLocationInCoverage(coverage, loc); if (locationInCoverageA != null) { var valueForA = coverage.Evaluate(locationInCoverageA); var value = operation(valueForA, referenceValue); locationToValueMapping.Add(locationInCoverageA, value); } } //apply values in a second loop to prevent evaluation being affected! SetResults(locationToValueMapping, outputCoverage ?? coverage); }
// 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); } }
// 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); } }
/// <summary> /// Creates a new coverage, based on <paramref name="coverage"/>, with a <see cref="TimeSpan"/> value /// for the duration where <paramref name="operation"/> resolves to true. /// </summary> /// <param name="coverage">Coverage to perform the measurement on.</param> /// <param name="referenceValue">A scalar reference value.</param> /// <param name="operation">A <see cref="Func{T1,T2,TResult}"/> where the first argument are values for <paramref name="coverage"/>, /// the second argument is <paramref name="referenceValue"/> and returns a bool value.</param> /// <param name="timeInterpolation">What type of interpolation to use for expressing the component value interpolated over time.</param> /// <param name="expressInDaysAsDouble">Optional argument for expressing the result as double instead of <see cref="TimeSpan"/>, using <see cref="TimeSpan.TotalDays"/></param> /// <returns>Returns a time independent <see cref="INetworkCoverage"/> with 1 TimeSpan (or Ticks as double) component.</returns> public static INetworkCoverage MeasureDurationWhereTrue(this INetworkCoverage coverage, double referenceValue, Func <double, double, bool> operation, InterpolationType timeInterpolation, bool expressInDaysAsDouble = false) { var outputCoverage = CopyNetworkCoverage(coverage); outputCoverage.IsTimeDependent = false; outputCoverage.Components.RemoveAt(0); if (expressInDaysAsDouble) { outputCoverage.Components.Add(new Variable <double>()); } else { outputCoverage.Components.Add(new Variable <TimeSpan>()); } outputCoverage.Components[0].Unit = new Unit("", ""); foreach (var location in coverage.Locations.Values) { var totalDuration = new TimeSpan(0); var operationWasTrue = false; var dateTimePrevious = new DateTime(); var dateTimeTransitionToTrue = new DateTime(); foreach (var dateTime in coverage.Time.Values) { var coverageValue = coverage.Evaluate(dateTime, location); if (IsNoDataValue(coverage, coverageValue)) { continue; } if (operation(coverageValue, referenceValue)) { if (!operationWasTrue) { operationWasTrue = true; dateTimeTransitionToTrue = CalculateDateTimeTransition(coverage, referenceValue, location, dateTimePrevious, dateTime, timeInterpolation); } } else { if (operationWasTrue) { operationWasTrue = false; var transitionDateTimeToFalse = CalculateDateTimeTransition(coverage, referenceValue, location, dateTimePrevious, dateTime, timeInterpolation); totalDuration += transitionDateTimeToFalse - dateTimeTransitionToTrue; } } // Remember last with valid data value: dateTimePrevious = dateTime; } if (operationWasTrue) { totalDuration += coverage.Time.Values.Last() - dateTimeTransitionToTrue; } if (expressInDaysAsDouble) { outputCoverage[location] = totalDuration.TotalDays; } else { outputCoverage[location] = totalDuration; } } return(outputCoverage); }