/// <summary>
        /// Gets the complete shape, including start end end vertices.
        /// </summary>
        /// <param name="enumerator">The enumerator.</param>
        /// <returns>The complete shape.</returns>
        public static IEnumerable <Coordinate> GetCompleteShape(this RouterDbEdgeEnumerator enumerator)
        {
            yield return(enumerator.FromLocation());

            var shape = enumerator.GetShape();

            if (shape != null)
            {
                foreach (var s in shape)
                {
                    yield return(s);
                }
            }

            yield return(enumerator.ToLocation());
        }
示例#2
0
        /// <summary>
        /// Gets the length of an edge in centimeters.
        /// </summary>
        /// <param name="enumerator">The enumerator.</param>
        /// <returns>The length in meters.</returns>
        internal static uint EdgeLength(this RouterDbEdgeEnumerator enumerator)
        {
            var distance = 0.0;

            // compose geometry.
            var shape           = enumerator.GetCompleteShape();
            var shapeEnumerator = shape.GetEnumerator();

            shapeEnumerator.MoveNext();
            var previous = shapeEnumerator.Current;

            while (shapeEnumerator.MoveNext())
            {
                var current = shapeEnumerator.Current;
                distance += Coordinate.DistanceEstimateInMeter(previous, current);
                previous  = current;
            }

            return((uint)(distance * 100));
        }
 /// <summary>
 /// Gets the location of the from vertex.
 /// </summary>
 /// <param name="enumerator">The enumerator.</param>
 /// <returns>The location.</returns>
 public static Coordinate FromLocation(this RouterDbEdgeEnumerator enumerator)
 {
     return(enumerator.RouterDb.GetVertex(enumerator.From));
 }
示例#4
0
        /// <summary>
        /// Returns the part of the edge between the two offsets not including the vertices at the start or the end.
        /// </summary>
        /// <param name="enumerator">The enumerator.</param>
        /// <param name="offset1">The start offset.</param>
        /// <param name="offset2">The end offset.</param>
        /// <param name="includeVertices">Include vertices in case the range start at min offset or ends at max.</param>
        /// <returns>The shape points between the given offsets. Includes the vertices by default when offsets at min/max.</returns>
        public static IEnumerable <Coordinate> GetShapeBetween(this RouterDbEdgeEnumerator enumerator,
                                                               ushort offset1 = 0, ushort offset2 = ushort.MaxValue, bool includeVertices = true)
        {
            if (offset1 > offset2)
            {
                throw new ArgumentException($"{nameof(offset1)} has to smaller than or equal to {nameof(offset2)}");
            }

            // get edge and shape details.
            var shape = enumerator.GetShape();

            if (shape == null)
            {
                shape = new ShapeEnumerable(Enumerable.Empty <Coordinate>());
            }

            // return the entire edge if requested.
            if (offset1 == 0 && offset2 == ushort.MaxValue)
            {
                foreach (var s in enumerator.GetCompleteShape())
                {
                    yield return(s);
                }
                yield break;
            }

            // calculate offsets in meters.
            var edgeLength    = enumerator.EdgeLength();
            var offset1Length = (offset1 / (double)ushort.MaxValue) * edgeLength;
            var offset2Length = (offset2 / (double)ushort.MaxValue) * edgeLength;

            // TODO: can we make this easier with the complete shape enumeration?
            // calculate coordinate shape.
            var before   = offset1 > 0; // when there is a start offset.
            var length   = 0.0;
            var previous = enumerator.FromLocation();

            if (offset1 == 0 && includeVertices)
            {
                yield return(previous);
            }
            for (var i = 0; i < shape.Count + 1; i++)
            {
                Coordinate next;
                if (i < shape.Count)
                { // the
                    next = shape[i];
                }
                else
                { // the last location.
                    next = enumerator.ToLocation();
                }

                var segmentLength = Coordinate.DistanceEstimateInMeter(previous, next);
                if (before)
                { // check if offset1 length has exceeded.
                    if (segmentLength + length >= offset1Length &&
                        offset1 > 0)
                    { // we are before, but not we have move to after.
                        var segmentOffset = offset1Length - length;
                        var location      = Coordinate.PositionAlongLine(previous, next, (segmentOffset / segmentLength));
                        previous = next;
                        before   = false;
                        yield return(location);
                    }
                }

                if (!before)
                { // check if offset2 length has exceeded.
                    if (segmentLength + length > offset2Length &&
                        offset2 < ushort.MaxValue)
                    { // we are after but now we are after.
                        var segmentOffset = offset2Length - length;
                        var location      = Coordinate.PositionAlongLine(previous, next, (segmentOffset / segmentLength));
                        yield return(location);

                        yield break;
                    }

                    // the case where include vertices is false.
                    if (i == shape.Count && !includeVertices)
                    {
                        yield break;
                    }
                    yield return(next);
                }

                // move to the next segment.
                previous = next;
                length  += segmentLength;
            }
        }
示例#5
0
 /// <summary>
 /// Returns the location on the given edge using the given offset.
 /// </summary>
 /// <param name="enumerator">The enumerator.</param>
 /// <param name="offset">The offset.</param>
 /// <returns>The location on the network.</returns>
 public static Coordinate LocationOnEdge(this RouterDbEdgeEnumerator enumerator, in ushort offset)