private INetworkCoverage GetRenderedCoverage(INetworkCoverage networkCoverage)
        {
            if (networkCoverage.IsTimeDependent)
            {
                if (TimeSelectionStart == null)
                {
                    SetCurrentTimeSelection(networkCoverage.Time.Values.FirstOrDefault(), null);
                }

                //is it already filtered..update the time
                if (networkCoverage.Filters.Any(f => f.Variable is Variable <DateTime>) || networkCoverage.Parent != null)
                {
                    var currentTimeFilter = networkCoverage.Filters
                                            .OfType <IVariableValueFilter>().FirstOrDefault(f => f.Variable is Variable <DateTime>);

                    //update the time filter and we're done
                    currentTimeFilter.Values[0] = TimeSelectionStart;
                    return(networkCoverage);
                }

                //create a filtered version
                return((INetworkCoverage)networkCoverage.FilterTime(TimeSelectionStart.Value));
            }
            return(networkCoverage);
        }
        private INetworkCoverage GetRenderedCoverage(INetworkCoverage networkCoverage)
        {
            if (networkCoverage.IsTimeDependent)
            {
                //use current time or some other time.
                var timeToSet = CurrentTime ?? DateTime.MinValue;
                //is it already filtered..update the time
                if (networkCoverage.Filters.Any(f => f.Variable is Variable<DateTime>) || networkCoverage.Parent != null)
                {
                    var currentTimeFilter = networkCoverage.Filters
                        .OfType<IVariableValueFilter>()
                        .Where(f => f.Variable is Variable<DateTime>)
                        .FirstOrDefault();

                    //update the time filter and we're done
                    currentTimeFilter.Values[0] = timeToSet;
                    return networkCoverage;

                }

                //create a filtered version
                return (INetworkCoverage)networkCoverage.FilterTime(timeToSet);
            }
            return networkCoverage;
        }
        public static void Operate(this INetworkCoverage coverageA, INetworkCoverage coverageB, Func <double, double, double> operation)
        {
            var allLocations = GetAllLocations(coverageA, coverageB);

            if (coverageA.IsTimeDependent && coverageB.IsTimeDependent)
            {
                ThrowIfCoverageTimeValuesNotEqual(coverageA, coverageB);

                foreach (var time in coverageA.Time.Values)
                {
                    OperateOneTimestep(coverageA.AddTimeFilter(time), coverageB.AddTimeFilter(time), allLocations, operation);
                }
                return;
            }
            if (coverageA.IsTimeDependent)
            {
                foreach (var time in coverageA.Time.Values)
                {
                    OperateOneTimestep(coverageA.AddTimeFilter(time), coverageB, allLocations, operation);
                }
                return;
            }
            if (coverageB.IsTimeDependent)
            {
                foreach (var time in coverageB.Time.Values)
                {
                    OperateOneTimestep(coverageA, coverageB.AddTimeFilter(time), allLocations, operation);
                }
                return;
            }
            OperateOneTimestep(coverageA, coverageB, allLocations, operation);
        }
        private INetworkCoverage GetRenderedCoverage(INetworkCoverage networkCoverage)
        {
            if (networkCoverage.IsTimeDependent)
            {
                if(TimeSelectionStart == null)
                {
                    SetCurrentTimeSelection(networkCoverage.Time.Values.FirstOrDefault(), null);
                }

                //is it already filtered..update the time
                if (networkCoverage.Filters.Any(f => f.Variable is Variable<DateTime>) || networkCoverage.Parent != null)
                {
                    var currentTimeFilter = networkCoverage.Filters
                                                           .OfType<IVariableValueFilter>().FirstOrDefault(f => f.Variable is Variable<DateTime>);

                    //update the time filter and we're done
                    currentTimeFilter.Values[0] = TimeSelectionStart;
                    return networkCoverage;

                }

                //create a filtered version
                return (INetworkCoverage)networkCoverage.FilterTime(TimeSelectionStart.Value);
            
            }
            return networkCoverage;
        }
Пример #5
0
        private static INetworkLocation FindNodePoint(INode node, INetworkCoverage coverage)
        {
            var incommingBranchPoints = coverage.Locations.Values.Where(l => Math.Abs(l.Chainage - l.Branch.Length) < BranchFeature.Epsilon && node.IncomingBranches.Contains(l.Branch));
            var outGoingBranchPoints  = coverage.Locations.Values.Where(l => Math.Abs(l.Chainage) < BranchFeature.Epsilon && node.OutgoingBranches.Contains(l.Branch));

            return(incommingBranchPoints.Concat(outGoingBranchPoints).FirstOrDefault());
        }
Пример #6
0
        private static INetworkLocation FindNodePoint(INode node, INetworkCoverage coverage)
        {
            var incommingBranchPoints = coverage.Locations.Values.Where(l => l.Offset == l.Branch.Length && node.IncomingBranches.Contains(l.Branch));
            var outGoingBranchPoints  = coverage.Locations.Values.Where(l => l.Offset == 0 && node.OutgoingBranches.Contains(l.Branch));

            return(incommingBranchPoints.Concat(outGoingBranchPoints).FirstOrDefault());
        }
Пример #7
0
        /// <summary>
        /// Updates the segments for all branches with branchlocation following this scheme:
        ///                b1
        /// n1---------------------------------n2
        /// 
        /// A----------C---------B----------D--    - network locations
        ///                                        - segments
        /// </summary>
        /// <param name="coverage"></param>
        /// <param name="fullyCover"></param>
        /// when set to true the segment of the branch 
        private static void UpdateSegmentsSegmentBetweenLocations(INetworkCoverage coverage, bool fullyCover)
        {
            coverage.Segments.Values.Clear();
            //var coverageLocations = coverage.Locations.Values.OrderBy(l => l.Offset).OrderBy(l => l.Branch);
            //sorting is done in coverage locations..don't need to do it here. This supports for reversed segments.
            var coverageLocations = coverage.Locations.Values;

            IBranch branch = null;
            INetworkLocation previous = null;
            IList<INetworkLocation> branchLocations = new List<INetworkLocation>();
            foreach (var location in coverageLocations)
            {
                if ((null != previous) && (previous.Branch != location.Branch))
                {
                    IEnumerable<INetworkSegment> segments = UpdateSegmentsBranchSegmentBetweenLocations(fullyCover, branch, branchLocations);
                    foreach (var segment in segments)
                    {
                        coverage.Segments.Values.Add(segment);
                    }
                    branchLocations.Clear();
                }
                branchLocations.Add(location);
                branch = location.Branch;
                previous = location;
            }
            if (branchLocations.Count > 0)
            {
                IEnumerable<INetworkSegment> segments = UpdateSegmentsBranchSegmentBetweenLocations(fullyCover, branch, branchLocations);
                foreach (var segment in segments)
                {
                    coverage.Segments.Values.Add(segment);
                }
            }
        }
        /// <summary>
        /// Updates the segments for all branches with branchlocation following this scheme:
        ///                b1
        /// n1---------------------------------n2
        ///
        /// A----------C---------B----------D--    - network locations
        ///                                        - segments
        /// </summary>
        /// <param name="coverage"></param>
        /// <param name="fullyCover"></param>
        /// when set to true the segment of the branch
        private static void UpdateSegmentsSegmentBetweenLocations(INetworkCoverage coverage, bool fullyCover)
        {
            coverage.Segments.Values.Clear();
            //var coverageLocations = coverage.Locations.Values.OrderBy(l => l.Offset).OrderBy(l => l.Branch);
            //sorting is done in coverage locations..don't need to do it here. This supports for reversed segments.
            var coverageLocations = coverage.Locations.Values;

            IBranch                  branch          = null;
            INetworkLocation         previous        = null;
            IList <INetworkLocation> branchLocations = new List <INetworkLocation>();

            foreach (var location in coverageLocations)
            {
                if ((null != previous) && (previous.Branch != location.Branch))
                {
                    IEnumerable <INetworkSegment> segments = UpdateSegmentsBranchSegmentBetweenLocations(fullyCover, branch, branchLocations);
                    foreach (var segment in segments)
                    {
                        coverage.Segments.Values.Add(segment);
                    }
                    branchLocations.Clear();
                }
                branchLocations.Add(location);
                branch   = location.Branch;
                previous = location;
            }
            if (branchLocations.Count > 0)
            {
                IEnumerable <INetworkSegment> segments = UpdateSegmentsBranchSegmentBetweenLocations(fullyCover, branch, branchLocations);
                foreach (var segment in segments)
                {
                    coverage.Segments.Values.Add(segment);
                }
            }
        }
Пример #9
0
        /// <summary>
        /// Returns the NetworkLocations for segment in the source coverage. If the start and/or end location of the 
        /// segment are not in the source they are added.
        /// </summary>
        /// <param name="segment"></param>
        /// <param name="source"></param>
        /// <param name="addNewLocations">Should the end and start of the segment be returned?</param>
        /// <returns></returns>
        public static IEnumerable<INetworkLocation> GetLocationsForSegment(INetworkSegment segment, INetworkCoverage source, bool addNewLocations)
        {
            double min = Math.Min(segment.EndChainage, segment.Chainage);
            double max = Math.Max(segment.EndChainage, segment.Chainage);

            IList<INetworkLocation> locations = new List<INetworkLocation>();
            
            if (addNewLocations)
            {
                var startChainage = segment.DirectionIsPositive ? segment.Chainage : segment.EndChainage;
                locations.Add(new NetworkLocation(segment.Branch, startChainage));
            }
            //need a cast here ..but we are sure since we just built it.
            foreach (var location in source.Locations.Values.Where(
                    nl =>
                    nl.Branch == segment.Branch && nl.Chainage >= min && nl.Chainage <= max))
            {
                if (!locations.Contains(location))
                {
                    locations.Add(location);
                }
            }

            if (addNewLocations)
            {
                var endChainage = segment.DirectionIsPositive ? segment.EndChainage : segment.Chainage;
                var location = new NetworkLocation(segment.Branch, endChainage);
                if (!locations.Contains(location))
                {
                    locations.Add(location);
                }
            }
            
            return !segment.DirectionIsPositive ? locations.Reverse() : locations;
        }
 private static void ThrowIfCoverageTimeValuesNotEqual(INetworkCoverage coverage, IEnumerable <INetworkCoverage> otherCoverages)
 {
     foreach (var networkCoverage in otherCoverages)
     {
         ThrowIfCoverageTimeValuesNotEqual(coverage, networkCoverage);
     }
 }
        private static DateTime CalculateDateTimeTransition(INetworkCoverage coverage, double referenceValue, INetworkLocation location, DateTime dateTimePrevious, DateTime dateTimeCurrent, InterpolationType timeInterpolation)
        {
            var dateTimeIndex = coverage.Time.Values.IndexOf(dateTimeCurrent);

            if (dateTimeIndex == 0)
            {
                return(dateTimeCurrent);
            }

            TimeSpan timeSpan;

            switch (timeInterpolation)
            {
            case InterpolationType.None:
                return(dateTimeCurrent);

            case InterpolationType.Constant:
                // Constant interpolation: value changes in the middle of 'dateTime' and 'dateTimePrevious'
                timeSpan = dateTimeCurrent - dateTimePrevious;
                return(dateTimePrevious + new TimeSpan(timeSpan.Ticks / 2));

            case InterpolationType.Linear:
                var currentValue  = (double)coverage[dateTimeCurrent, location];
                var previousValue = (double)coverage[dateTimePrevious, location];
                timeSpan = dateTimeCurrent - dateTimePrevious;

                return(dateTimePrevious + new TimeSpan(Convert.ToInt64(timeSpan.Ticks * Math.Abs(previousValue - referenceValue) / Math.Abs(currentValue - previousValue))));

            default:
                throw new NotImplementedException(String.Format("Interpolation method {0} not supported", coverage.Time.InterpolationType));
            }
        }
Пример #12
0
        /// <summary>
        /// Snaps the points to the network coverage, given the tolerance. Existing locations/values will be cleared only
        /// when there are new points mapped to that branch.
        /// </summary>
        /// <param name="pointValuePairs"></param>
        /// <param name="networkCoverage"></param>
        /// <param name="tolerance"></param>
        public static void SnapToCoverage(IEnumerable <Tuple <IPoint, double> > pointValuePairs,
                                          INetworkCoverage networkCoverage, double tolerance)
        {
            var tree = new Quadtree <IBranch>();

            networkCoverage.Network.Branches.ForEach(b => tree.Insert(b.Geometry.EnvelopeInternal, b));

            // match points to branch buffers
            var locations = new List <Tuple <INetworkLocation, double> >();

            foreach (var pointValue in pointValuePairs)
            {
                var envelope = pointValue.Item1.EnvelopeInternal;
                envelope.ExpandBy(tolerance);
                var branches = tree.Query(envelope).Cast <IBranch>();

                var location = MapPointToClosestBranch(pointValue.Item1, branches, tolerance);
                if (location != null)
                {
                    locations.Add(new Tuple <INetworkLocation, double>(location, pointValue.Item2));
                }
            }

            // remove values for all branches that have new values imported
            var branchesToClear = locations.Select(l => l.Item1.Branch).Distinct();

            branchesToClear.ForEach(b => NetworkHelper.ClearLocations(networkCoverage, b));

            // add new values/locations to coverage
            locations.ForEach(l => networkCoverage[l.Item1] = l.Item2);
        }
        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);
        }
Пример #14
0
        private static void UpdateSegmentsRouteBetweenLocations(INetworkCoverage coverage)
        {
            coverage.Segments.Values.Clear();

            var coverageLocations = coverage.Locations.Values;

            for (var i = 0; i < coverageLocations.Count - 1; i++)
            {
#if MONO
                var source = (INetworkLocation)((IMultiDimensionalArray)coverageLocations)[i];
                var target = (INetworkLocation)((IMultiDimensionalArray)coverageLocations)[i + 1];
#else
                var source = coverageLocations[i];
                var target = coverageLocations[i + 1];
#endif
                var segments = NetworkHelper.GetShortestPathBetweenBranchFeaturesAsNetworkSegments(coverage.Network,
                                                                                                   source, target);
                foreach (var segment in segments)
                {
                    if (segment.Chainage < 0 || segment.EndChainage < 0)
                    {
                        throw new ArgumentException("EndOffset or segment offset invalid");
                    }
                    coverage.Segments.Values.Add(segment);
                }
            }
        }
        private static void PerformOperation <T>(INetworkCoverage coverage, IEnumerable <INetworkCoverage> otherCoverages,
                                                 Func <IEnumerable <double>, T> operation, INetworkCoverage outputCoverage = null)
        {
            var allLocations = GetAllLocations(coverage, otherCoverages);

            if (coverage.IsTimeDependent)
            {
                ThrowIfCoverageTimeValuesNotEqual(coverage, otherCoverages);

                foreach (var time in coverage.Time.Values)
                {
                    foreach (var networkCoverage in otherCoverages)
                    {
                        networkCoverage.AddTimeFilter(time);
                    }
                    if (outputCoverage != null)
                    {
                        OperateOneTimestep(coverage.AddTimeFilter(time), otherCoverages, allLocations, operation, outputCoverage.AddTimeFilter(time));
                    }
                    else
                    {
                        OperateOneTimestep(coverage.AddTimeFilter(time), otherCoverages, allLocations, operation);
                    }
                }
            }
            else
            {
                OperateOneTimestep(coverage, otherCoverages, allLocations, operation, outputCoverage);
            }
        }
        private static void PerformOperation <T>(INetworkCoverage coverage, double referenceValue, Func <double, double, T> operation,
                                                 INetworkCoverage outputCoverage = null)
        {
            var allLocations = coverage.Locations.Values.Distinct().OrderBy(loc => loc).ToList();

            if (coverage.IsTimeDependent)
            {
                foreach (var time in coverage.Time.Values)
                {
                    if (outputCoverage != null)
                    {
                        OperateOneTimeStep(coverage.AddTimeFilter(time), referenceValue, allLocations, operation,
                                           outputCoverage.AddTimeFilter(time));
                    }
                    else
                    {
                        OperateOneTimeStep(coverage.AddTimeFilter(time), referenceValue, allLocations, operation);
                    }
                }
            }
            else
            {
                OperateOneTimeStep(coverage, referenceValue, allLocations, operation, outputCoverage);
            }
        }
        /// <summary>
        /// Creates a new coverage, based on <paramref name="coverage"/>, with a <see cref="bool"/> value
        /// defined by <paramref name="operation"/>.
        /// </summary>
        /// <param name="coverage">Coverage to perform the operation 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 from <paramref name="coverage"/>,
        /// the second argument is <paramref name="referenceValue"/> and returns a bool value.</param>
        /// <returns>Returns a <see cref="INetworkCoverage"/>, with the same time dependency as <paramref name="coverage"/>,
        /// that has 1 bool component.</returns>
        public static INetworkCoverage OperateToNewCoverage <T>(this INetworkCoverage coverage, double referenceValue, Func <double, double, T> operation)
        {
            var outputCoverage = CreateOutputCoverage <T>(coverage);

            PerformOperation(coverage, referenceValue, operation, outputCoverage);

            return(outputCoverage);
        }
Пример #18
0
 ///<summary>
 ///</summary>
 ///<param name="networkCoverage"></param>
 ///<param name="branch"></param>
 ///<param name="offsets"></param>
 public static void CreateSegments(INetworkCoverage networkCoverage, IBranch branch, IList <double> offsets)
 {
     //ClearSegments(networkCoverage, branch);
     foreach (var offset in offsets)
     {
         networkCoverage[new NetworkLocation(branch, offset)] = 0.0;
     }
 }
 private static void ThrowIfInputIsInvalid(INetworkCoverage coverageA, INetworkCoverage coverageB)
 {
     if (coverageB.Network != coverageA.Network)
     {
         throw new InvalidOperationException("Network of coverage {0} does not math network of {1}," +
                                             " math operations are not possible");
     }
 }
 private static IEnumerable <INetworkLocation> GetAllLocations(INetworkCoverage coverage, IEnumerable <INetworkCoverage> otherCoverages)
 {
     if (CheckIfNetworksMismatch(coverage.Network, otherCoverages.Select(c => c.Network)))
     {
         return(coverage.Locations.Values.ToList());
     }
     return(coverage.Locations.Values.Concat(otherCoverages.SelectMany(c => c.Locations.Values)).Distinct().OrderBy(loc => loc).ToList());
 }
 private static IEnumerable <INetworkLocation> GetAllLocations(INetworkCoverage coverageA, INetworkCoverage coverageB)
 {
     if (CheckIfNetworksMismatch(coverageA.Network, coverageB.Network))
     {
         return(coverageA.Locations.Values.ToList());
     }
     return(coverageA.Locations.Values.Concat(coverageB.Locations.Values).Distinct().OrderBy(loc => loc).ToList());
 }
        public static INetworkCoverage OperateToNewCoverage <T>(this INetworkCoverage coverage, IEnumerable <INetworkCoverage> otherCoverages, Func <IEnumerable <double>, T> operation)
        {
            var outputCoverage = CreateOutputCoverage <T>(coverage);

            PerformOperation(coverage, otherCoverages, operation, outputCoverage);

            return(outputCoverage);
        }
Пример #23
0
        private static void DrawSegment(VectorLayer segmentsLayer, INetworkCoverage coverage, ITheme theme, int segmentNumber, IList <double> allBranchLocationValues, bool firstSegment, bool lastSegment, Graphics graphics, INetworkSegment segment, VectorStyle defaultStyle, double offset)
        {
            var valueAtStart = allBranchLocationValues[segmentNumber * 2];
            var value        = allBranchLocationValues[segmentNumber * 2 + 1];
            var valueAtEnd   = allBranchLocationValues[segmentNumber * 2 + 2];

            // extract based on valueAtStart and valueAtEnd the colors from the
            var styleStart = (theme != null) ? (VectorStyle)theme.GetStyle(valueAtStart) : segmentsLayer.Style;
            var themeStyle = (theme != null) ? (VectorStyle)theme.GetStyle(value) : segmentsLayer.Style;
            var styleEnd   = (theme != null) ? (VectorStyle)theme.GetStyle(valueAtEnd) : segmentsLayer.Style;

            // check if within limits (preventing GDI+ overflow on 'ultrazoom')
            var strokes = Transform.TransformToImage((ILineString)segment.Geometry, segmentsLayer.Map);

            if (strokes.Any(s => !graphics.ClipBounds.Contains(s)))
            {
                return;
            }

            if (firstSegment && lastSegment)
            {
                // 1 segment; render segement based on coverage.Locations.InterpolationType
                if (coverage.Locations.ExtrapolationType == ExtrapolationType.None)
                {
                    VectorRenderingHelper.RenderGeometry(graphics, segmentsLayer.Map, segment.Geometry, defaultStyle, null,
                                                         true);
                    return;
                }
                if (coverage.Locations.ExtrapolationType == ExtrapolationType.Linear)
                {
                    VectorRenderingHelper.RenderGeometry(graphics, segmentsLayer.Map, segment.Geometry, themeStyle, null, true);
                    return;
                }
                // todo use proper colors/styles from Theme; now 'via' styles are ignored.
                var kcolors = new[]
                {
                    ((SolidBrush)styleStart.Fill).Color, ((SolidBrush)themeStyle.Fill).Color,
                    ((SolidBrush)styleEnd.Fill).Color
                };
                var kpositions = new[] { 0.0F, (float)((offset - segment.Chainage) / segment.Length), 1.0F };
                DrawStrokesLinear(graphics, strokes, (int)themeStyle.Line.Width, kcolors, kpositions);
                return;
            }

            var positions = new[]
            {
                0.0F, (float)((offset - segment.Chainage) / segment.Length),
                (float)((offset - segment.Chainage) / segment.Length), 1.0F
            };

            var colors = CreateBeginEndColors(coverage, firstSegment, lastSegment, GetStyleColor(themeStyle), GetStyleColor(styleStart), GetStyleColor(styleEnd), GetStyleColor(defaultStyle));

            // todo use proper colors/styles from Theme; now 'via' styles are ignored.
            if (!segment.Geometry.IsEmpty)
            {
                DrawStrokesLinear(graphics, strokes, (int)themeStyle.Line.Width, colors, positions);
            }
        }
Пример #24
0
        public static void ClearLocations(INetworkCoverage networkCoverage, IBranch branch)
        {
            var locationsToRemove = networkCoverage.GetLocationsForBranch(branch);

            if (locationsToRemove.Count != 0)
            {
                networkCoverage.Locations.RemoveValues(networkCoverage.Locations.CreateValuesFilter(locationsToRemove));
            }
        }
        private static INetworkCoverage CreateOutputCoverage <T>(INetworkCoverage coverage)
        {
            var outputCoverage = CopyNetworkCoverage(coverage);

            outputCoverage.Components.RemoveAt(0);
            outputCoverage.Components.Add(new Variable <T>());
            outputCoverage.Components[0].Unit = new Unit("", "");

            return(outputCoverage);
        }
Пример #26
0
        private static void UpdateSegmentsSegmentPerLocation(INetworkCoverage coverage)
        {
            //for performance reasons..get the locations all at once.
            var allLocations = coverage.Locations.Values;

            foreach (var branch in coverage.Network.Branches)
            {
                UpdateSegments(coverage, branch, allLocations);
            }
        }
 private static INetworkLocation GetLocationInCoverage(INetworkCoverage coverage, INetworkLocation location)
 {
     if (CheckIfNetworksMismatch(coverage.Network, location.Network)) //defined on different network
     {
         var coordinate = location.Geometry.Coordinate;
         var loc        = coverage.GetLocationOnBranch(coordinate.X, coordinate.Y);
         return(loc);
     }
     return(location);
 }
Пример #28
0
        /// <summary>
        /// Updates the segments for all branches with branch location following this scheme:
        ///                b1
        /// n1---------------------------------n2
        ///
        /// A----------C---------B----------D--    - network locations
        ///                                        - segments
        /// </summary>
        /// <param name="coverage"></param>
        /// <param name="fullyCover"></param>
        /// when set to true the segment of the branch
        private static void UpdateSegmentsSegmentBetweenLocations(INetworkCoverage coverage, bool fullyCover)
        {
            coverage.Segments.Values.Clear();

            //sorting is done in coverage locations..don't need to do it here. This supports for reversed segments.
            coverage.Segments.SetValues(coverage.Locations.Values.GroupBy(l => l.Branch)
                                        .SelectMany(
                                            g =>
                                            UpdateSegmentsBranchSegmentBetweenLocations(fullyCover, g.Key, g)));
        }
Пример #29
0
        /// <summary>
        /// Draw a branch with no segments; this will usually be drawn with the style for the default value.
        /// </summary>
        /// <param name="map"></param>
        /// <param name="coverage"></param>
        /// <param name="g"></param>
        /// <param name="style"></param>
        /// <param name="mapExtents"></param>
        /// <param name="drawnBranches"></param>
        /// <param name="theme"></param>
        private static void RenderSegmentFreeBranches(Map map, INetworkCoverage coverage, Graphics g, VectorStyle style, IEnvelope mapExtents, HashSet <IBranch> drawnBranches, ITheme theme)
        {
            var visibleBranches = coverage.Network.Branches.Where(b => b.Geometry.EnvelopeInternal.Intersects(mapExtents)).ToList();

            visibleBranches.ForEach(vb =>
            {
                if (!drawnBranches.Contains(vb))
                {
                    VectorRenderingHelper.RenderGeometry(g, map, vb.Geometry, style, null, true);
                }
            });
        }
Пример #30
0
        public static void UpdateSegments(INetworkCoverage coverage, IBranch branch,
                                          IMultiDimensionalArray <INetworkLocation> allLocations)
        {
            if (coverage.Network == null)
            {
                return;
            }

            // remove old segments for selected branch
            foreach (var segment in coverage.Segments.Values.Where(s => s.Branch == branch).ToArray())
            {
                coverage.Segments.Values.Remove(segment);
            }

            var branchNetworkLocations = allLocations.Where(l => l.Branch == branch).Cast <INetworkLocation>();
            var skipFirst = branchNetworkLocations.FirstOrDefault() == allLocations.FirstOrDefault();
            var skipLast  = branchNetworkLocations.LastOrDefault() == allLocations.LastOrDefault();

            IEnumerable <INetworkSegment> segments;

            switch (coverage.SegmentGenerationMethod)
            {
            case SegmentGenerationMethod.RouteBetweenLocations:
                segments = NetworkHelper.GenerateSegmentsBetweenLocations(branchNetworkLocations, branch, skipFirst,
                                                                          skipLast);
                break;

            case SegmentGenerationMethod.SegmentBetweenLocations:
                //segments = NetworkHelper.GenerateSegmentsPerLocation(branchNetworkLocations, branch);
                segments = UpdateSegmentsBranchSegmentBetweenLocations(false, branch, branchNetworkLocations);
                break;

            case SegmentGenerationMethod.SegmentPerLocation:
                segments = NetworkHelper.GenerateSegmentsPerLocation(branchNetworkLocations, branch);
                break;

            default:
                throw new ArgumentException(
                          string.Format("Method {0} not supported", coverage.SegmentGenerationMethod), "coverage");
            }

            foreach (var s in segments)
            {
                // todo set branch and offset to NetworkSegmentAttributeAccessor?
                // assume number of location to be at least number of segments per branch
                coverage.Segments.Values.Add(s);
            }
        }
Пример #31
0
        public static void UpdateSegments(INetworkCoverage coverage)
        {
            if (coverage.Network == null)
            {
                return;
            }

            try
            {
                coverage.Segments.Clear();

                switch (coverage.SegmentGenerationMethod)
                {
                case SegmentGenerationMethod.SegmentPerLocation:
                    UpdateSegmentsSegmentPerLocation(coverage);
                    break;

                case SegmentGenerationMethod.RouteBetweenLocations:
                    UpdateSegmentsRouteBetweenLocations(coverage);
                    break;

                case SegmentGenerationMethod.SegmentBetweenLocations:
                    UpdateSegmentsSegmentBetweenLocations(coverage, false);
                    break;

                case SegmentGenerationMethod.SegmentBetweenLocationsFullyCovered:
                    UpdateSegmentsSegmentBetweenLocations(coverage, true);
                    break;

                case SegmentGenerationMethod.None:
                    UpdateSegmentsNone(coverage);
                    break;
                }
            }
            //why catch all exceptions here??? there might be something wrong that is WORTH crashing the app
            //TODO: only catch the exception you know and want to catch
            catch (Exception exception)
            {
                Log.ErrorFormat("Fatal error updating network coverage {0}; reason {1}", coverage.Name,
                                exception.Message);
                // do not rethrow, it will crash ui
            }

            for (int i = 1; i < coverage.Segments.Values.Count + 1; i++)
            {
                coverage.Segments.Values[i - 1].SegmentNumber = i;
            }
        }
Пример #32
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)));
        }
        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];
            }
        }
Пример #34
0
        public static void UpdateSegments(INetworkCoverage coverage)
        {
            if (coverage.Network == null)
            {
                return;
            }

            try
            {
                coverage.Segments.Clear();

                switch (coverage.SegmentGenerationMethod)
                {
                    case SegmentGenerationMethod.SegmentPerLocation:
                        UpdateSegmentsSegmentPerLocation(coverage);
                        break;
                    case SegmentGenerationMethod.RouteBetweenLocations:
                        UpdateSegmentsRouteBetweenLocations(coverage);
                        break;
                    case SegmentGenerationMethod.SegmentBetweenLocations:
                        UpdateSegmentsSegmentBetweenLocations(coverage, false);
                        break;
                    case SegmentGenerationMethod.SegmentBetweenLocationsFullyCovered:
                        UpdateSegmentsSegmentBetweenLocations(coverage, true);
                        break;
                    case SegmentGenerationMethod.None:
                        UpdateSegmentsNone(coverage);
                        break;
                }
            }
                //why catch all exceptions here??? there might be something wrong that is WORTH crashing the app
                //TODO: only catch the exception you know and want to catch
            catch (Exception exception)
            {
                Log.ErrorFormat("Fatal error updating network coverage {0}; reason {1}", coverage.Name,
                                exception.Message);
                // do not rethrow, it will crash ui
            }

            for (int i = 1; i < coverage.Segments.Values.Count + 1; i++)
            {
                coverage.Segments.Values[i - 1].SegmentNumber = i;
            }

        }
Пример #35
0
        /// <summary>
        /// Extract a time slice for 1 time step out a time dependent network coverage
        /// </summary>
        /// <param name="source"></param>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static INetworkCoverage ExtractTimeSlice(INetworkCoverage source, DateTime dateTime)
        {
            if (!source.Arguments[0].Values.Contains(dateTime))
            {
                throw new ArgumentException("ExtractTimeSlice: invalid time.",
                                            "dateTime");
            }
            INetworkCoverage slice = new NetworkCoverage(source.Name, false);

            //slice.Components[0].NoDataValues = new ArrayList(source.Components[0].NoDataValues);
            //slice.Locations.Values.AddRange(source.Arguments[1].Values);
            //var values = source.GetValues(new VariableValueFilter(source.Arguments[0], new [] {dateTime}));
            //slice.SetValues(values);

            // extract a time slice from the source and also copy the networklocations.
            ExtractTimeSlice(source, slice, dateTime, true);
            return(slice);
        }
Пример #36
0
 /// <summary>
 /// Returns all locations in the route. Route cannot contain doubles for now because side view should
 /// draw structures double etc. Would complicate more then the use-case would justify
 /// </summary>
 /// <param name="source"></param>
 /// <param name="route"></param>
 /// <returns></returns>
 public static IList<INetworkLocation> GetLocationsInRoute(INetworkCoverage source, Route route)
 {
     IList<INetworkLocation> locations = new List<INetworkLocation>();
     
     foreach (INetworkSegment segment in route.Segments.Values)
     {
         var locationsForSegment = GetLocationsForSegment(segment, source, true);
         foreach (var location in locationsForSegment)
         {
             //add location if we didn't just add it..this can happens when segments go like 1-->3 3-->4 4-->5 
             //don't want the start and endnodes causing doubles so should be like 1-->3-->4-->5
             if (!location.Equals(locations.LastOrDefault()))
             {
                 locations.Add(location);    
             }
             
         }
     }
     return locations;
 }
Пример #37
0
        public static void UpdateSegments(INetworkCoverage coverage)
        {
            if (coverage.Network == null)
            {
                return;
            }

            try
            {
                coverage.Segments.Clear();

                switch (coverage.SegmentGenerationMethod)
                {
                    case SegmentGenerationMethod.SegmentPerLocation:
                        UpdateSegmentsSegmentPerLocation(coverage);
                        break;
                    case SegmentGenerationMethod.RouteBetweenLocations:
                        UpdateSegmentsRouteBetweenLocations(coverage);
                        break;
                    case SegmentGenerationMethod.SegmentBetweenLocations:
                        UpdateSegmentsSegmentBetweenLocations(coverage, false);
                        break;
                    case SegmentGenerationMethod.SegmentBetweenLocationsFullyCovered:
                        UpdateSegmentsSegmentBetweenLocations(coverage, true);
                        break;
                    case SegmentGenerationMethod.None:
                        UpdateSegmentsNone(coverage);
                        break;
                }
            }
            catch (Exception exception)
            {
                Log.ErrorFormat("Fatal error updating network coverage {0}; reason {1}", coverage.Name, exception.Message);
                // do not rethrow, it will crash ui
            }
        }
Пример #38
0
 /// <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;
 }
Пример #39
0
        public static void ExtractTimeSlice(INetworkCoverage source, INetworkCoverage targetSlice /* bad name */,
                                            DateTime dateTime,
                                            bool copyLocations)
        {
            if (!source.IsTimeDependent)
            {
                throw new ArgumentException("ExtractTimeSlice: source network coverage should be time dependent.",
                                            "source");
            }

            IMultiDimensionalArray<INetworkLocation> networkLocations = copyLocations
                                                                            ? source.Locations.Values
                                                                            : targetSlice.Locations.Values;

            IMultiDimensionalArray values;

            if (copyLocations)
            {
                values = source.GetValues(new VariableValueFilter<DateTime>(source.Arguments[0], dateTime));
            }
            else
            {
                values = source.GetValues(new VariableValueFilter<DateTime>(source.Arguments[0], dateTime),
                                          new VariableValueFilter<INetworkLocation>(source.Arguments[1],
                                                                                    networkLocations));
            }

            var clonedValues = new ArrayList(values);
            var clonedLocations = networkLocations.ToArray();

            if (copyLocations)
            {
                targetSlice.Clear();
                targetSlice.Locations.Values.AddRange(clonedLocations);
                targetSlice.Components[0].NoDataValues = new ArrayList(source.Components[0].NoDataValues);
            }

            targetSlice.SetValues(clonedValues);
        }
Пример #40
0
        public static void UpdateSegments(INetworkCoverage coverage, IBranch branch,
                                          IMultiDimensionalArray<INetworkLocation> allLocations)
        {
            if (coverage.Network == null)
            {
                return;
            }

            // remove old segments for selected branch
            foreach (var segment in coverage.Segments.Values.Where(s => s.Branch == branch).ToArray())
            {
                coverage.Segments.Values.Remove(segment);
            }

            var branchNetworkLocations = allLocations.Where(l => l.Branch == branch).Cast<INetworkLocation>();
            var skipFirst = branchNetworkLocations.FirstOrDefault() == allLocations.FirstOrDefault();
            var skipLast = branchNetworkLocations.LastOrDefault() == allLocations.LastOrDefault();

            IEnumerable<INetworkSegment> segments;
            switch (coverage.SegmentGenerationMethod)
            {
                case SegmentGenerationMethod.RouteBetweenLocations:
                    segments = NetworkHelper.GenerateSegmentsBetweenLocations(branchNetworkLocations, branch, skipFirst,
                                                                              skipLast);
                    break;
                case SegmentGenerationMethod.SegmentBetweenLocations:
                    //segments = NetworkHelper.GenerateSegmentsPerLocation(branchNetworkLocations, branch);
                    segments = UpdateSegmentsBranchSegmentBetweenLocations(false, branch, branchNetworkLocations);
                    break;
                case SegmentGenerationMethod.SegmentPerLocation:
                    segments = NetworkHelper.GenerateSegmentsPerLocation(branchNetworkLocations, branch);
                    break;
                default:
                    throw new ArgumentException(
                        string.Format("Method {0} not supported", coverage.SegmentGenerationMethod), "coverage");
            }

            foreach (var s in segments)
            {
                // todo set branch and offset to NetworkSegmentAttributeAccessor?
                // assume number of location to be at least number of segments per branch 
                coverage.Segments.Values.Add(s);
            }
        }
Пример #41
0
 private static void UpdateSegmentsSegmentPerLocation(INetworkCoverage coverage)
 {
     //for performance reasons..get the locations all at once.
     var allLocations = coverage.Locations.Values;
     foreach (var branch in coverage.Network.Branches)
     {
         UpdateSegments(coverage, branch, allLocations);
     }
 }
Пример #42
0
        private static void UpdateSegmentsRouteBetweenLocations(INetworkCoverage coverage)
        {
            coverage.Segments.Values.Clear();

            var coverageLocations = coverage.Locations.Values;
            for (var i = 0; i < coverageLocations.Count - 1; i++)
            {
#if MONO				
                var source = (INetworkLocation)((IMultiDimensionalArray)coverageLocations)[i];
                var target = (INetworkLocation)((IMultiDimensionalArray)coverageLocations)[i + 1];
#else
                var source = coverageLocations[i];
                var target = coverageLocations[i + 1];
#endif
                var segments = NetworkHelper.GetShortestPathBetweenBranchFeaturesAsNetworkSegments(coverage.Network,
                                                                                                   source, target);
                foreach (var segment in segments)
                {
                    if (segment.Chainage < 0 || segment.EndChainage < 0)
                    {
                        throw new ArgumentException("EndOffset or segment offset invalid");
                    }
                    coverage.Segments.Values.Add(segment);
                }
            }
        }
        private static INetworkLocation FindNodePoint(INode node, INetworkCoverage coverage)
        {
            var incommingBranchPoints = coverage.Locations.Values.Where(l => Math.Abs(l.Chainage - l.Branch.Length) < BranchFeature.Epsilon && node.IncomingBranches.Contains(l.Branch));
            var outGoingBranchPoints = coverage.Locations.Values.Where(l => Math.Abs(l.Chainage) < BranchFeature.Epsilon && node.OutgoingBranches.Contains(l.Branch));

            return incommingBranchPoints.Concat(outGoingBranchPoints).FirstOrDefault();
        }
Пример #44
0
 private static void UpdateSegmentsNone(INetworkCoverage coverage)
 {
     coverage.Segments.Values.Clear();
 }
Пример #45
0
        public static void ExtractTimeSlice(INetworkCoverage source, INetworkCoverage targetSlice /* bad name */, DateTime dateTime, 
            bool copyLocations)
        {
            if (!source.IsTimeDependent)
            {
                throw new ArgumentException("ExtractTimeSlice: source network coverage should be time dependent.",
                                            "source");
            }

            IEnumerable<INetworkLocation> networkLocations = null;
            if (copyLocations)
            {
                networkLocations = source.Arguments[1].GetValues().Cast<INetworkLocation>();
                targetSlice.Clear();
                targetSlice.Locations.Values.AddRange(networkLocations);   
            }
            else
            {
                networkLocations = targetSlice.Arguments[0].GetValues().Cast<INetworkLocation>();
            //    networkLocations = new ArrayList(targetSlice.Arguments[0].GetValues());
            }

            targetSlice.Components[0].NoDataValues = new ArrayList(source.Components[0].NoDataValues);

            IMultiDimensionalArray values;
            //var values = source.GetValues(new VariableValueFilter(source.Arguments[0], new[] { dateTime }));
            if (copyLocations)
            {
                values = source.GetValues(new VariableValueFilter<DateTime>(source.Arguments[0], dateTime));
            }
            else
            {
                values = source.GetValues(new VariableValueFilter<DateTime>(source.Arguments[0], dateTime),
                                              new VariableValueFilter<INetworkLocation>(source.Arguments[1], networkLocations));
            }
            targetSlice.SetValues(values);
        }
Пример #46
0
 public static double GetRouteLength(INetworkCoverage coverage)
 {
     return coverage.Segments.Values.Sum(seg => seg.Length);
 }
Пример #47
0
 public static bool LocationsAreUniqueOnRoute(INetworkCoverage source, Route route)
 {
     //find all locations and checks for doubles.
     var locationsSet = new HashSet<INetworkLocation>();
     foreach (var segment in route.Segments.Values)
     {
         IEnumerable<INetworkLocation> locations = GetLocationsForSegment(segment, source, false);
         
         if (locationsSet.Overlaps(locations))
             return false;
         foreach (var location in locations)
         {
             locationsSet.Add(location);
         }
     }
     return true;
 }
        // 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);
            }
        }
        private static void DrawSegment(VectorLayer segmentsLayer, INetworkCoverage coverage, ITheme theme, int segmentNumber, IList<double> allBranchLocationValues, bool firstSegment, bool lastSegment, Graphics graphics, INetworkSegment segment, VectorStyle defaultStyle, double offset)
        {
            var valueAtStart = allBranchLocationValues[segmentNumber * 2];
            var value = allBranchLocationValues[segmentNumber * 2 + 1];
            var valueAtEnd = allBranchLocationValues[segmentNumber * 2 + 2];

            // extract based on valueAtStart and valueAtEnd the colors from the 
            var styleStart = (theme != null) ? (VectorStyle)theme.GetStyle(valueAtStart) : segmentsLayer.Style;
            var themeStyle = (theme != null) ? (VectorStyle)theme.GetStyle(value) : segmentsLayer.Style;
            var styleEnd = (theme != null) ? (VectorStyle)theme.GetStyle(valueAtEnd) : segmentsLayer.Style;

            // check if within limits (preventing GDI+ overflow on 'ultrazoom')
            var strokes = Transform.TransformToImage((ILineString)segment.Geometry, segmentsLayer.Map);
            if (strokes.Any(s => !graphics.ClipBounds.Contains(s))) return;

            if (firstSegment && lastSegment)
            {
                // 1 segment; render segement based on coverage.Locations.InterpolationType
                if (coverage.Locations.ExtrapolationType == ExtrapolationType.None)
                {
                    VectorRenderingHelper.RenderGeometry(graphics, segmentsLayer.Map, segment.Geometry, defaultStyle, null,
                                                         true);
                    return;
                }
                if (coverage.Locations.ExtrapolationType == ExtrapolationType.Linear)
                {
                    VectorRenderingHelper.RenderGeometry(graphics, segmentsLayer.Map, segment.Geometry, themeStyle, null, true);
                    return;
                }
                // todo use proper colors/styles from Theme; now 'via' styles are ignored.
                var kcolors = new[]
                                  {
                                      ((SolidBrush) styleStart.Fill).Color, ((SolidBrush) themeStyle.Fill).Color,
                                      ((SolidBrush) styleEnd.Fill).Color
                                  };
                var kpositions = new[] { 0.0F, (float)((offset - segment.Chainage) / segment.Length), 1.0F };
                DrawStrokesLinear(graphics, strokes, (int)themeStyle.Line.Width, kcolors, kpositions);
                return;
            }

            var positions = new[]
                                {
                                    0.0F, (float) ((offset - segment.Chainage)/segment.Length),
                                    (float) ((offset - segment.Chainage)/segment.Length), 1.0F
                                };

            var colors = CreateBeginEndColors(coverage, firstSegment, lastSegment, GetStyleColor(themeStyle), GetStyleColor(styleStart), GetStyleColor(styleEnd), GetStyleColor(defaultStyle));

            // todo use proper colors/styles from Theme; now 'via' styles are ignored.
            if (!segment.Geometry.IsEmpty)
            {
                DrawStrokesLinear(graphics, strokes, (int)themeStyle.Line.Width, colors, positions);
            }
        }
        private static Color[] CreateBeginEndColors(INetworkCoverage coverage, bool firstSegment, bool lastSegment, Color themeColor, Color startColor, Color endColor, Color defaultColor)
        {
            var colors = new Color[4];

            var extrapolationType = coverage.Locations.ExtrapolationType;
            var interpolationType = coverage.Locations.InterpolationType;

            if (firstSegment)
            {
                switch (extrapolationType)
                {
                    case ExtrapolationType.None:
                        colors[0] = defaultColor;
                        colors[1] = defaultColor;
                        break;
                    case ExtrapolationType.Constant:
                        colors[0] = themeColor;
                        colors[1] = themeColor;
                        break;
                    default:
                        colors[0] = startColor;
                        colors[1] = themeColor;
                        break;
                }
            }
            else
            {
                switch (interpolationType)
                {
                    case InterpolationType.None:
                        colors[0] = defaultColor;
                        colors[1] = defaultColor;
                        break;
                    case InterpolationType.Constant:
                        colors[0] = themeColor;
                        colors[1] = themeColor;
                        break;
                    default:
                        colors[0] = startColor;
                        colors[1] = themeColor;
                        break;
                }
            }

            if (lastSegment)
            {
                switch (extrapolationType)
                {
                    case ExtrapolationType.None:
                        colors[2] = defaultColor;
                        colors[3] = defaultColor;
                        break;
                    case ExtrapolationType.Constant:
                        colors[2] = themeColor;
                        colors[3] = themeColor;
                        break;
                    default:
                        colors[2] = themeColor;
                        colors[3] = endColor;
                        break;
                }
            }
            else
            {
                switch (interpolationType)
                {
                    case InterpolationType.None:
                        colors[2] = defaultColor;
                        colors[3] = defaultColor;
                        break;
                    case InterpolationType.Constant:
                        colors[2] = themeColor;
                        colors[3] = themeColor;
                        break;
                    default:
                        colors[2] = themeColor;
                        colors[3] = endColor;
                        break;
                }
            }

            return colors;
        }
Пример #51
0
        /// <summary>
        /// Extract a time slice for 1 time step out a time dependent network coverage
        /// </summary>
        /// <param name="source"></param>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static INetworkCoverage ExtractTimeSlice(INetworkCoverage source, DateTime dateTime)
        {
            if (!source.Arguments[0].Values.Contains(dateTime))
            {
                throw new ArgumentException("ExtractTimeSlice: invalid time.",
                                            "dateTime");
            }
            INetworkCoverage slice = new NetworkCoverage(source.Name, false);
            //slice.Components[0].NoDataValues = new ArrayList(source.Components[0].NoDataValues);
            //slice.Locations.Values.AddRange(source.Arguments[1].Values);
            //var values = source.GetValues(new VariableValueFilter(source.Arguments[0], new [] {dateTime}));
            //slice.SetValues(values);

            // extract a time slice from the source and also copy the networklocations.
            ExtractTimeSlice(source, slice, dateTime, true);
            return slice;
        }
Пример #52
0
 /// <summary>
 /// returns the segment where networkLocation is located.
 /// networkLocation does not have to be a networkLocation in route.Locations.
 /// </summary>
 /// <param name="route"></param>
 /// <param name="networkLocation"></param>
 /// <returns></returns>
 public static INetworkSegment GetSegmentForNetworkLocation(INetworkCoverage route, INetworkLocation networkLocation)
 {
     var segments = route.Segments.Values.ToArray();
     foreach (var segment in segments)
     {
         if (segment.Branch != networkLocation.Branch)
         {
             continue;
         }
         if ((networkLocation.Offset > segment.Offset) && (networkLocation.Offset < segment.EndOffset))
         {
             return segment;
         }
         // segment can be reversed in coverage
         if ((networkLocation.Offset < segment.Offset) && (networkLocation.Offset > segment.EndOffset))
         {
             return segment;
         }
     }
     return null;
 }
Пример #53
0
        /// <summary>
        /// Snaps the points to the network coverage, given the tolerance. Existing locations/values will be cleared only
        /// when there are new points mapped to that branch.
        /// </summary>
        /// <param name="pointValuePairs"></param>
        /// <param name="networkCoverage"></param>
        /// <param name="tolerance"></param>
        public static void SnapToCoverage(IEnumerable<Tuple<IPoint, double>> pointValuePairs,
                                          INetworkCoverage networkCoverage, double tolerance)
        {
            var tree = new Quadtree();
            networkCoverage.Network.Branches.ForEach(b => tree.Insert(b.Geometry.EnvelopeInternal, b));
            
            // match points to branch buffers
            var locations = new List<Tuple<INetworkLocation, double>>();
            foreach (var pointValue in pointValuePairs)
            {
                var envelope = pointValue.Item1.EnvelopeInternal;
                envelope.ExpandBy(tolerance);
                var branches = tree.Query(envelope).Cast<IBranch>();

                var location = MapPointToClosestBranch(pointValue.Item1, branches, tolerance);
                if (location != null)
                {
                    locations.Add(new Tuple<INetworkLocation, double>(location, pointValue.Item2));
                }
            }

            // remove values for all branches that have new values imported
            var branchesToClear = locations.Select(l => l.Item1.Branch).Distinct();
            branchesToClear.ForEach(b => NetworkHelper.ClearLocations(networkCoverage, b));

            // add new values/locations to coverage
            locations.ForEach(l => networkCoverage[l.Item1] = l.Item2);
        }
Пример #54
0
 ///<summary>
 ///</summary>
 ///<param name="networkCoverage"></param>
 ///<param name="branch"></param>
 ///<param name="offsets"></param>
 public static void CreateSegments(INetworkCoverage networkCoverage, IBranch branch, IList<double> offsets)
 {
     //ClearSegments(networkCoverage, branch);
     foreach (var offset in offsets)
     {
         networkCoverage[new NetworkLocation(branch, offset)] = 0.0;
     }
 }
Пример #55
0
        /// <summary>
        /// Updates the segments for all branches with branch location following this scheme:
        ///                b1
        /// n1---------------------------------n2
        /// 
        /// A----------C---------B----------D--    - network locations
        ///                                        - segments
        /// </summary>
        /// <param name="coverage"></param>
        /// <param name="fullyCover"></param>
        /// when set to true the segment of the branch 
        private static void UpdateSegmentsSegmentBetweenLocations(INetworkCoverage coverage, bool fullyCover)
        {
            coverage.Segments.Values.Clear();

            //sorting is done in coverage locations..don't need to do it here. This supports for reversed segments.
            coverage.Segments.SetValues(coverage.Locations.Values.GroupBy(l => l.Branch)
                                                .SelectMany(
                                                    g =>
                                                    UpdateSegmentsBranchSegmentBetweenLocations(fullyCover, g.Key, g)));
        }
 /// <summary>
 /// Draw a branch with no segments; this will usually be drawn with the style for the default value.
 /// </summary>
 /// <param name="map"></param>
 /// <param name="coverage"></param>
 /// <param name="g"></param>
 /// <param name="style"></param>
 /// <param name="mapExtents"></param>
 /// <param name="drawnBranches"></param>
 /// <param name="theme"></param>
 private static void RenderSegmentFreeBranches(IMap map, INetworkCoverage coverage, Graphics g, VectorStyle style, IEnvelope mapExtents, HashSet<IBranch> drawnBranches, ITheme theme)
 {
     var visibleBranches = coverage.Network.Branches.Where(b => b.Geometry.EnvelopeInternal.Intersects(mapExtents)).ToList();
     visibleBranches.ForEach(vb =>
     {
         if (!drawnBranches.Contains(vb))
         {
             VectorRenderingHelper.RenderGeometry(g, map, vb.Geometry, style, null, true);
         }
     });
 }