/// <summary> /// Gets the shape points starting at the given vertex until the max distance. /// </summary> public static List <Coordinate> GetShape(this GeometricGraph graph, GeometricEdge geometricEdge, float minDistance, float maxDistance) { var points = new List <Coordinate>(); if (geometricEdge.Shape == null) { return(points); } var previous = graph.GetVertex(geometricEdge.From); var distance = 0.0f; var shapeEnumerator = geometricEdge.Shape.GetEnumerator(); shapeEnumerator.Reset(); while (shapeEnumerator.MoveNext()) { var current = shapeEnumerator.Current; distance += Coordinate.DistanceEstimateInMeter( previous, current); if (minDistance < distance && distance < maxDistance) { points.Add(current); } previous = current; } return(points); }
/// <summary> /// Gets the length of an edge. /// </summary> public static float Length(this GeometricGraph graph, GeometricEdge edge) { var totalLength = 0.0f; var previous = graph.GetVertex(edge.From); Coordinate?current = null; var shape = edge.Shape; if (shape != null) { var shapeEnumerator = shape.GetEnumerator(); shapeEnumerator.Reset(); while (shapeEnumerator.MoveNext()) { current = shapeEnumerator.Current; totalLength += Coordinate.DistanceEstimateInMeter( previous.Latitude, previous.Longitude, current.Value.Latitude, current.Value.Longitude); previous = current.Value; } } current = graph.GetVertex(edge.To); totalLength += Coordinate.DistanceEstimateInMeter( previous.Latitude, previous.Longitude, current.Value.Latitude, current.Value.Longitude); return(totalLength); }
/// <summary> /// Returns the location on the graph. /// </summary> public static Coordinate LocationOnGraph(this GeometricGraph graph, uint edgeId, ushort offset) { var geometricEdge = graph.GetEdge(edgeId); var shape = graph.GetShape(geometricEdge); var length = graph.Length(geometricEdge); var currentLength = 0.0; var targetLength = length * (offset / (double)ushort.MaxValue); for (var i = 1; i < shape.Count; i++) { var segmentLength = Coordinate.DistanceEstimateInMeter(shape[i - 1], shape[i]); if (segmentLength + currentLength > targetLength) { var segmentOffsetLength = segmentLength + currentLength - targetLength; var segmentOffset = 1 - (segmentOffsetLength / segmentLength); short?elevation = null; if (shape[i - 1].Elevation.HasValue && shape[i].Elevation.HasValue) { elevation = (short)(shape[i - 1].Elevation.Value + (segmentOffset * (shape[i].Elevation.Value - shape[i - 1].Elevation.Value))); } return(new Coordinate() { Latitude = (float)(shape[i - 1].Latitude + (segmentOffset * (shape[i].Latitude - shape[i - 1].Latitude))), Longitude = (float)(shape[i - 1].Longitude + (segmentOffset * (shape[i].Longitude - shape[i - 1].Longitude))), Elevation = elevation }); } currentLength += segmentLength; } return(shape[shape.Count - 1]); }
/// <summary> /// Projects a point onto an edge. /// </summary> /// <returns></returns> public static bool ProjectOn(this GeometricGraph graph, GeometricEdge edge, float latitude, float longitude, out float projectedLatitude, out float projectedLongitude, out float projectedDistanceFromFirst, out int projectedShapeIndex, out float distanceToProjected) { float totalLength; return(graph.ProjectOn(edge, latitude, longitude, out projectedLatitude, out projectedLongitude, out projectedDistanceFromFirst, out projectedShapeIndex, out distanceToProjected, out totalLength)); }
/// <summary> /// Gets the shape points starting at the given vertex until the max distance. /// </summary> public static List <Coordinate> GetShape(this GeometricGraph graph, GeometricEdge geometricEdge, uint vertex, float maxDistance) { var points = new List <Coordinate>(); if (geometricEdge.Shape == null) { return(points); } if (geometricEdge.From == vertex) { // start at from. var previous = graph.GetVertex(vertex); var distance = 0.0f; var shapeEnumerator = geometricEdge.Shape.GetEnumerator(); while (shapeEnumerator.MoveNext()) { var current = shapeEnumerator.Current; distance += Coordinate.DistanceEstimateInMeter( previous, current); if (distance >= maxDistance) { // do not include this point anymore. break; } points.Add(current); previous = current; } return(points); } else if (geometricEdge.To == vertex) { // start at to. var shape = geometricEdge.Shape.Reverse(); var previous = graph.GetVertex(vertex); var distance = 0.0f; var shapeEnumerator = shape.GetEnumerator(); while (shapeEnumerator.MoveNext()) { var current = shapeEnumerator.Current; distance += Coordinate.DistanceEstimateInMeter( previous, current); if (distance >= maxDistance) { // do not include this point anymore. break; } points.Add(current); previous = current; } return(points); } throw new ArgumentOutOfRangeException(string.Format("Vertex {0} is not part of edge {1}.", vertex, geometricEdge.Id)); }
/// <summary> /// Gets the shape of the given edge. /// </summary> public static ShapeBase GetShape(this GeometricGraph graph, long directedEdgeId) { if (directedEdgeId == 0) { throw new ArgumentOutOfRangeException("directedEdgeId"); } uint edgeId; if (directedEdgeId > 0) { edgeId = (uint)directedEdgeId - 1; } else { edgeId = (uint)((-directedEdgeId) - 1); } return(graph.GetShape(edgeId)); }
/// <summary> /// Gets the shape points including the two vertices. /// </summary> public static List <Coordinate> GetShape(this GeometricGraph graph, GeometricEdge geometricEdge) { var points = new List <Coordinate>(); points.Add(graph.GetVertex(geometricEdge.From)); var shape = geometricEdge.Shape; if (shape != null) { if (geometricEdge.DataInverted) { shape = shape.Reverse(); } var shapeEnumerator = shape.GetEnumerator(); shapeEnumerator.Reset(); while (shapeEnumerator.MoveNext()) { points.Add(shapeEnumerator.Current); } } points.Add(graph.GetVertex(geometricEdge.To)); return(points); }
/// <summary> /// Projects a point onto an edge. /// </summary> public static bool ProjectOn(this GeometricGraph graph, GeometricEdge edge, float latitude, float longitude, out float projectedLatitude, out float projectedLongitude, out float projectedDistanceFromFirst, out int projectedShapeIndex, out float distanceToProjected, out float totalLength) { distanceToProjected = float.MaxValue; projectedDistanceFromFirst = 0; projectedLatitude = float.MaxValue; projectedLongitude = float.MaxValue; projectedShapeIndex = -1; var previous = graph.GetVertex(edge.From); var shape = edge.Shape; IEnumerator <Coordinate> shapeEnumerator = null; if (shape != null) { shapeEnumerator = shape.GetEnumerator(); shapeEnumerator.Reset(); } var previousShapeDistance = 0.0f; var previousShapeIndex = -1; while (true) { // get current point. var isShapePoint = true; Coordinate?current = null; if (shapeEnumerator != null && shapeEnumerator.MoveNext()) { // one more shape point. current = shapeEnumerator.Current; } else { // no more shape points. isShapePoint = false; current = graph.GetVertex(edge.To); } var line = new Line(previous, current.Value); var coordinate = new Coordinate(latitude, longitude); var projectedPoint = line.ProjectOn(coordinate); if (projectedPoint != null) { // ok, projection succeeded. var distance = Coordinate.DistanceEstimateInMeter( projectedPoint.Value.Latitude, projectedPoint.Value.Longitude, latitude, longitude); if (distance < distanceToProjected) { // ok, new best edge yay! distanceToProjected = distance; projectedLatitude = projectedPoint.Value.Latitude; projectedLongitude = projectedPoint.Value.Longitude; projectedDistanceFromFirst = (previousShapeDistance + Coordinate.DistanceEstimateInMeter( projectedLatitude, projectedLongitude, previous.Latitude, previous.Longitude)); projectedShapeIndex = previousShapeIndex + 1; } } if (!isShapePoint) { // if the current is not a shape point, it's time to stop. var to = graph.GetVertex(edge.To); totalLength = previousShapeDistance + Coordinate.DistanceEstimateInMeter( previous.Latitude, previous.Longitude, to.Latitude, to.Longitude); break; } // add up the current shape distance. previousShapeDistance += Coordinate.DistanceEstimateInMeter( previous.Latitude, previous.Longitude, current.Value.Latitude, current.Value.Longitude); previousShapeIndex++; previous = current.Value; } return(distanceToProjected != float.MaxValue); }
/// <summary> /// Adds a new edge. /// </summary> public static uint AddEdge(this GeometricGraph graph, uint vertex1, uint vertex2, uint[] data, IEnumerable <Coordinate> shape) { return(graph.AddEdge(vertex1, vertex2, data, new ShapeEnumerable(shape))); }
internal EdgeEnumerator(GeometricGraph graph, Graph.EdgeEnumerator enumerator) { _graph = graph; _enumerator = enumerator; }