コード例 #1
0
        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);
        }
コード例 #2
0
        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)));
        }
コード例 #3
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];
            }
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        // 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);
            }
        }
コード例 #7
0
        // 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);
            }
        }
コード例 #8
0
        /// <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);
        }