///// <summary> ///// Adds an edge. ///// </summary> ///// <param name="forward"></param> ///// <param name="from"></param> ///// <param name="to"></param> ///// <param name="tags"></param> ///// <param name="intermediates"></param> //protected override void AddRoadEdge(TagsCollectionBase tags, bool forward, uint from, uint to, List<GeoCoordinateSimple> intermediates) //{ // float latitude; // float longitude; // GeoCoordinate fromCoordinate = null; // if (this.DynamicGraph.GetVertex(from, out latitude, out longitude)) // { // // fromCoordinate = new GeoCoordinate(latitude, longitude); // } // GeoCoordinate toCoordinate = null; // if (this.DynamicGraph.GetVertex(to, out latitude, out longitude)) // { // // toCoordinate = new GeoCoordinate(latitude, longitude); // } // if (fromCoordinate != null && toCoordinate != null) // { // calculate the edge data. // var edgeData = this.CalculateEdgeData(this.Interpreter.EdgeInterpreter, this.TagsIndex, tags, forward, fromCoordinate, toCoordinate, intermediates); // ICoordinateCollection intermediatesCollection = null; // if(intermediates != null) // { // intermediatesCollection = new CoordinateArrayCollection<GeoCoordinateSimple>(intermediates.ToArray()); // } // this.DynamicGraph.AddEdge(from, to, edgeData, intermediatesCollection, this.EdgeComparer); // } //} /// <summary> /// Calculates edge data. /// </summary> /// <param name="tagsIndex"></param> /// <param name="tags"></param> /// <param name="directionForward"></param> /// <param name="from"></param> /// <param name="to"></param> /// <param name="edgeInterpreter"></param> /// <param name="intermediates"></param> /// <returns></returns> protected override LiveEdge CalculateEdgeData(IEdgeInterpreter edgeInterpreter, ITagsCollectionIndex tagsIndex, TagsCollectionBase tags, bool tagsForward, GeoCoordinate from, GeoCoordinate to, List <GeoCoordinateSimple> intermediates) { if (edgeInterpreter == null) { throw new ArgumentNullException("edgeInterpreter"); } if (tagsIndex == null) { throw new ArgumentNullException("tagsIndex"); } if (tags == null) { throw new ArgumentNullException("tags"); } if (from == null) { throw new ArgumentNullException("from"); } if (to == null) { throw new ArgumentNullException("to"); } uint tagsId = tagsIndex.Add(tags); return(new LiveEdge() { Forward = tagsForward, Tags = tagsId, Distance = (float)from.DistanceEstimate(to).Value }); }
/// <summary> /// Calculates edge data. /// </summary> /// <param name="tagsIndex"></param> /// <param name="tags"></param> /// <param name="tagsForward"></param> /// <param name="from"></param> /// <param name="to"></param> /// <param name="edgeInterpreter"></param> /// <param name="intermediates"></param> /// <returns></returns> protected override Edge CalculateEdgeData(IEdgeInterpreter edgeInterpreter, ITagsIndex tagsIndex, TagsCollectionBase tags, bool tagsForward, GeoCoordinate from, GeoCoordinate to, List <GeoCoordinateSimple> intermediates) { if (edgeInterpreter == null) { throw new ArgumentNullException("edgeInterpreter"); } if (tagsIndex == null) { throw new ArgumentNullException("tagsIndex"); } if (tags == null) { throw new ArgumentNullException("tags"); } if (from == null) { throw new ArgumentNullException("from"); } if (to == null) { throw new ArgumentNullException("to"); } uint tagsId = tagsIndex.Add(tags); var shapeInBox = true; if (intermediates != null) { // verify shape-in-box. var box = new GeoCoordinateBox(from, to); for (int idx = 0; idx < intermediates.Count; idx++) { if (!box.Contains(intermediates[idx].Longitude, intermediates[idx].Latitude)) { // shape not in box. shapeInBox = false; break; } } } return(new Edge() { Forward = tagsForward, Tags = tagsId, Distance = (float)from.DistanceEstimate(to).Value, ShapeInBox = shapeInBox }); }
/// <summary> /// Calculates edge data. /// </summary> /// <param name="tagsIndex"></param> /// <param name="tags"></param> /// <param name="directionForward"></param> /// <param name="from"></param> /// <param name="to"></param> /// <param name="edgeInterpreter"></param> /// <param name="intermediates"></param> /// <returns></returns> protected override LiveEdge CalculateEdgeData(IEdgeInterpreter edgeInterpreter, ITagsCollectionIndex tagsIndex, TagsCollectionBase tags, bool directionForward, GeoCoordinate from, GeoCoordinate to, List <GeoCoordinateSimple> intermediates) { if (edgeInterpreter == null) { throw new ArgumentNullException("edgeInterpreter"); } if (tagsIndex == null) { throw new ArgumentNullException("tagsIndex"); } if (tags == null) { throw new ArgumentNullException("tags"); } if (from == null) { throw new ArgumentNullException("from"); } if (to == null) { throw new ArgumentNullException("to"); } uint tagsId = tagsIndex.Add(tags); GeoCoordinateSimple[] coordinates = null; if (intermediates != null && intermediates.Count > 0) { // only instiate if needed. coordinates = intermediates.ToArray(); } return(new LiveEdge() { Forward = directionForward, Tags = tagsId, Distance = (float)from.DistanceEstimate(to).Value }); }
/// <summary> /// Returns the weight between two points on an edge with the given tags for the vehicle. /// </summary> /// <param name="tags"></param> /// <param name="from"></param> /// <param name="to"></param> /// <returns></returns> public virtual float Weight(TagsCollectionBase tags, GeoCoordinate from, GeoCoordinate to) { var distance = from.DistanceEstimate(to).Value; return((float)(distance / (this.ProbableSpeed(tags).Value) * 3.6)); }
/// <summary> /// Finds candidate vertices for a location reference point. /// </summary> /// <param name="lrp"></param> /// <param name="maxVertexDistance"></param> /// <returns></returns> public virtual IEnumerable <CandidateVertex> FindCandidateVerticesFor(LocationReferencePoint lrp, Meter maxVertexDistance) { // convert to geo coordinate. var geoCoordinate = new GeoCoordinate(lrp.Coordinate.Latitude, lrp.Coordinate.Longitude); // build candidates list. var candidates = new HashSet <long>(); var scoredCandidates = new List <CandidateVertex>(); float latitude, longitude; // create a search box. var box = new GeoCoordinateBox(geoCoordinate, geoCoordinate); box = box.Resize(_candidateSearchBoxSize); // get arcs. var arcs = this.Graph.GetEdges(box); foreach (var arc in arcs) { long vertex = arc.Item1; if (!candidates.Contains(vertex)) { this.Graph.GetVertex(vertex, out latitude, out longitude); var distance = geoCoordinate.DistanceEstimate(new GeoCoordinate(latitude, longitude)); if (distance.Value < maxVertexDistance.Value) { candidates.Add(vertex); scoredCandidates.Add(new CandidateVertex() { Score = Score.New(Score.VERTEX_DISTANCE, string.Format("The vertex score compare to max distance {0}", _maxVertexDistance), (float)System.Math.Max(0, (1.0 - (distance.Value / _maxVertexDistance.Value))), 1), // calculate scoring compared to the fixed max distance. Vertex = vertex }); } } vertex = arc.Item2; if (!candidates.Contains(vertex)) { this.Graph.GetVertex(vertex, out latitude, out longitude); var distance = geoCoordinate.DistanceEstimate(new GeoCoordinate(latitude, longitude)); if (distance.Value < maxVertexDistance.Value) { candidates.Add(vertex); scoredCandidates.Add(new CandidateVertex() { Score = Score.New(Score.VERTEX_DISTANCE, string.Format("The vertex score compare to max distance {0}", _maxVertexDistance), (float)System.Math.Max(0, (1.0 - (distance.Value / _maxVertexDistance.Value))), 1), // calculate scoring compared to the fixed max distance. Vertex = vertex }); } } } if (scoredCandidates.Count == 0) { // no candidates, create a virtual candidate. var closestEdge = this.Graph.GetClosestEdge(geoCoordinate, maxVertexDistance, 0.1); if (closestEdge != null) { var coordinates = this.Graph.GetCoordinates(closestEdge); OsmSharp.Math.Primitives.PointF2D bestProjected; OsmSharp.Math.Primitives.LinePointPosition bestPosition; Meter bestOffset; int bestIndex; if (coordinates.ProjectOn(geoCoordinate, out bestProjected, out bestPosition, out bestOffset, out bestIndex)) { // successfully projected, insert virtual vertex. var distance = geoCoordinate.DistanceEstimate(new GeoCoordinate(bestProjected[1], bestProjected[0])); if (distance.Value < maxVertexDistance.Value) { this.Graph.RemoveEdge(closestEdge.Item1, closestEdge.Item2); this.Graph.RemoveEdge(closestEdge.Item2, closestEdge.Item1); var newVertex = this.Graph.AddVertex((float)bestProjected[1], (float)bestProjected[0]); // build distance before/after. var distanceBefore = bestOffset.Value; var distanceAfter = closestEdge.Item3.Distance - bestOffset.Value; // build coordinates before/after. var coordinatesBefore = new List <GeoCoordinateSimple>( coordinates.GetRange(1, bestIndex).Select(x => new GeoCoordinateSimple() { Latitude = (float)x.Latitude, Longitude = (float)x.Longitude })); var coordinatesAfter = new List <GeoCoordinateSimple>( coordinates.GetRange(bestIndex + 1, coordinates.Count - 1 - bestIndex - 1).Select(x => new GeoCoordinateSimple() { Latitude = (float)x.Latitude, Longitude = (float)x.Longitude })); this.Graph.AddEdge(closestEdge.Item1, newVertex, new LiveEdge() { Distance = (float)distanceBefore, Forward = closestEdge.Item3.Forward, Tags = closestEdge.Item3.Tags }, coordinatesBefore.Count > 0 ? coordinatesBefore.ToArray() : null); this.Graph.AddEdge(newVertex, closestEdge.Item2, new LiveEdge() { Distance = (float)distanceAfter, Forward = closestEdge.Item3.Forward, Tags = closestEdge.Item3.Tags }, coordinatesAfter.Count > 0 ? coordinatesAfter.ToArray() : null); scoredCandidates.Add(new CandidateVertex() { Score = Score.New(Score.VERTEX_DISTANCE, string.Format("The vertex score compare to max distance {0}", _maxVertexDistance), (float)System.Math.Max(0, (1.0 - (distance.Value / _maxVertexDistance.Value))), 1), // calculate scoring compared to the fixed max distance. Vertex = newVertex }); } } } } return(scoredCandidates); }
/// <summary> /// Returns the weight between two points on an edge with the given tags for the vehicle. /// </summary> /// <param name="tags"></param> /// <param name="from"></param> /// <param name="to"></param> /// <returns></returns> public virtual float Weight(TagsCollectionBase tags, GeoCoordinate from, GeoCoordinate to) { var distance = (float)from.DistanceEstimate(to).Value; return(this.Weight(tags, distance)); }
/// <summary> /// Returns the weight between two points on an edge with the given tags for the given vehicle. /// </summary> /// <param name="tags"></param> /// <param name="vehicle"></param> /// <param name="from"></param> /// <param name="to"></param> /// <returns></returns> public double Weight(IDictionary<string, string> tags, VehicleEnum vehicle, GeoCoordinate from, GeoCoordinate to) { double distance = from.DistanceEstimate(to).Value; return distance / (this.MaxSpeed(vehicle, tags).Value) * 3.6; }
/// <summary> /// Searches the data for a point on an edge closest to the given coordinate. /// </summary> /// <param name="graph"></param> /// <param name="vehicle"></param> /// <param name="coordinate"></param> /// <param name="delta"></param> /// <param name="matcher"></param> /// <param name="pointTags"></param> /// <param name="interpreter"></param> /// <param name="verticesOnly"></param> /// <param name="parameters"></param> public SearchClosestResult <TEdgeData> SearchClosest(IRoutingAlgorithmData <TEdgeData> graph, IRoutingInterpreter interpreter, Vehicle vehicle, GeoCoordinate coordinate, float delta, IEdgeMatcher matcher, TagsCollectionBase pointTags, bool verticesOnly, Dictionary <string, object> parameters) { Meter distanceEpsilon = .1; // 10cm is the tolerance to distinguish points. var closestWithMatch = new SearchClosestResult <TEdgeData>(double.MaxValue, 0); GeoCoordinateBox closestWithMatchBox = null; var closestWithoutMatch = new SearchClosestResult <TEdgeData>(double.MaxValue, 0); GeoCoordinateBox closestWithoutMatchBox = null; double searchBoxSize = delta; // create the search box. var searchBox = new GeoCoordinateBox(new GeoCoordinate( coordinate.Latitude - searchBoxSize, coordinate.Longitude - searchBoxSize), new GeoCoordinate( coordinate.Latitude + searchBoxSize, coordinate.Longitude + searchBoxSize)); // get the arcs from the data source. var edges = graph.GetEdges(searchBox); if (!verticesOnly) { // find both closest arcs and vertices. // loop over all. while (edges.MoveNext()) { //if (!graph.TagsIndex.Contains(edges.EdgeData.Tags)) //{ // skip this edge, no valid tags found. // continue; //} // test the two points. float fromLatitude, fromLongitude; float toLatitude, toLongitude; double distance; if (graph.GetVertex(edges.Vertex1, out fromLatitude, out fromLongitude) && graph.GetVertex(edges.Vertex2, out toLatitude, out toLongitude)) { // return the vertex. var vertex1Coordinate = new GeoCoordinate(fromLatitude, fromLongitude); var vertex2Coordinate = new GeoCoordinate(toLatitude, toLongitude); if (edges.EdgeData.ShapeInBox) { // ok, check if it is needed to even check this edge. var edgeBox = new GeoCoordinateBox(vertex1Coordinate, vertex2Coordinate); var edgeBoxOverlap = false; if (closestWithoutMatchBox == null || closestWithoutMatchBox.Overlaps(edgeBox)) { // edge box overlap. edgeBoxOverlap = true; } else if (closestWithMatchBox == null || closestWithMatchBox.Overlaps(edgeBox)) { // edge box overlap. edgeBoxOverlap = true; } if (!edgeBoxOverlap) { // no overlap, impossible this edge is a candidate. continue; } } var arcTags = graph.TagsIndex.Get(edges.EdgeData.Tags); var canBeTraversed = vehicle.CanTraverse(arcTags); if (canBeTraversed) { // the edge can be traversed. distance = coordinate.DistanceEstimate(vertex1Coordinate).Value; if (distance < distanceEpsilon.Value) { // the distance is smaller than the tolerance value. var diff = coordinate - vertex1Coordinate; closestWithoutMatchBox = new GeoCoordinateBox(new GeoCoordinate(coordinate + diff), new GeoCoordinate(coordinate - diff)); closestWithoutMatch = new SearchClosestResult <TEdgeData>( distance, edges.Vertex1); if (matcher == null || (pointTags == null || pointTags.Count == 0) || matcher.MatchWithEdge(vehicle, pointTags, arcTags)) { closestWithMatchBox = new GeoCoordinateBox(new GeoCoordinate(coordinate + diff), new GeoCoordinate(coordinate - diff)); closestWithMatch = new SearchClosestResult <TEdgeData>( distance, edges.Vertex1); break; } } if (distance < closestWithoutMatch.Distance) { // the distance is smaller for the without match. var diff = coordinate - vertex1Coordinate; closestWithoutMatchBox = new GeoCoordinateBox(new GeoCoordinate(coordinate + diff), new GeoCoordinate(coordinate - diff)); closestWithoutMatch = new SearchClosestResult <TEdgeData>( distance, edges.Vertex1); } if (distance < closestWithMatch.Distance) { // the distance is smaller for the with match. if (matcher == null || (pointTags == null || pointTags.Count == 0) || matcher.MatchWithEdge(vehicle, pointTags, graph.TagsIndex.Get(edges.EdgeData.Tags))) { var diff = coordinate - vertex1Coordinate; closestWithMatchBox = new GeoCoordinateBox(new GeoCoordinate(coordinate + diff), new GeoCoordinate(coordinate - diff)); closestWithMatch = new SearchClosestResult <TEdgeData>( distance, edges.Vertex1); } } distance = coordinate.DistanceEstimate(vertex2Coordinate).Value; if (distance < closestWithoutMatch.Distance) { // the distance is smaller for the without match. var diff = coordinate - vertex2Coordinate; closestWithoutMatchBox = new GeoCoordinateBox(new GeoCoordinate(coordinate + diff), new GeoCoordinate(coordinate - diff)); closestWithoutMatch = new SearchClosestResult <TEdgeData>( distance, edges.Vertex2); } if (distance < closestWithMatch.Distance) { // the distance is smaller for the with match. if (matcher == null || (pointTags == null || pointTags.Count == 0) || matcher.MatchWithEdge(vehicle, pointTags, arcTags)) { var diff = coordinate - vertex2Coordinate; closestWithMatchBox = new GeoCoordinateBox(new GeoCoordinate(coordinate + diff), new GeoCoordinate(coordinate - diff)); closestWithMatch = new SearchClosestResult <TEdgeData>( distance, edges.Vertex2); } } // search along the line. var coordinatesArray = new ICoordinate[0]; var distanceTotal = 0.0; var arcValueValueCoordinates = edges.Intermediates; if (arcValueValueCoordinates != null) { // calculate distance along all coordinates. coordinatesArray = arcValueValueCoordinates.ToArray(); } // loop over all edges that are represented by this arc (counting intermediate coordinates). var previous = vertex1Coordinate; GeoCoordinateLine line; var distanceToSegment = 0.0; if (arcValueValueCoordinates != null) { for (int idx = 0; idx < coordinatesArray.Length; idx++) { var current = new GeoCoordinate( coordinatesArray[idx].Latitude, coordinatesArray[idx].Longitude); var edgeBox = new GeoCoordinateBox(previous, current); var edgeBoxOverlap = false; if (closestWithoutMatchBox == null || closestWithoutMatchBox.Overlaps(edgeBox)) { // edge box overlap. edgeBoxOverlap = true; } else if (closestWithMatchBox == null || closestWithMatchBox.Overlaps(edgeBox)) { // edge box overlap. edgeBoxOverlap = true; } if (edgeBoxOverlap) { // overlap, possible this edge is a candidate. line = new GeoCoordinateLine(previous, current, true, true); distance = line.DistanceReal(coordinate).Value; if (distance < closestWithoutMatch.Distance) { // the distance is smaller. var projectedPoint = line.ProjectOn(coordinate); // calculate the position. if (projectedPoint != null) { // calculate the distance. if (distanceTotal == 0) { // calculate total distance. var pCoordinate = vertex1Coordinate; for (int cIdx = 0; cIdx < coordinatesArray.Length; cIdx++) { var cCoordinate = new GeoCoordinate(coordinatesArray[cIdx].Latitude, coordinatesArray[cIdx].Longitude); distanceTotal = distanceTotal + cCoordinate.DistanceReal(pCoordinate).Value; pCoordinate = cCoordinate; } distanceTotal = distanceTotal + vertex2Coordinate.DistanceReal(pCoordinate).Value; } var distancePoint = previous.DistanceReal(new GeoCoordinate(projectedPoint)).Value + distanceToSegment; var position = distancePoint / distanceTotal; var diff = coordinate - new GeoCoordinate(projectedPoint); closestWithoutMatchBox = new GeoCoordinateBox(new GeoCoordinate(coordinate + diff), new GeoCoordinate(coordinate - diff)); closestWithoutMatch = new SearchClosestResult <TEdgeData>( distance, edges.Vertex1, edges.Vertex2, position, edges.EdgeData, coordinatesArray); } } if (distance < closestWithMatch.Distance) { var projectedPoint = line.ProjectOn(coordinate); // calculate the position. if (projectedPoint != null) { // calculate the distance if (distanceTotal == 0) { // calculate total distance. var pCoordinate = vertex1Coordinate; for (int cIdx = 0; cIdx < coordinatesArray.Length; cIdx++) { var cCoordinate = new GeoCoordinate(coordinatesArray[cIdx].Latitude, coordinatesArray[cIdx].Longitude); distanceTotal = distanceTotal + cCoordinate.DistanceReal(pCoordinate).Value; pCoordinate = cCoordinate; } distanceTotal = distanceTotal + vertex2Coordinate.DistanceReal(pCoordinate).Value; } var distancePoint = previous.DistanceReal(new GeoCoordinate(projectedPoint)).Value + distanceToSegment; var position = distancePoint / distanceTotal; if (matcher == null || (pointTags == null || pointTags.Count == 0) || matcher.MatchWithEdge(vehicle, pointTags, arcTags)) { var diff = coordinate - new GeoCoordinate(projectedPoint); closestWithMatchBox = new GeoCoordinateBox(new GeoCoordinate(coordinate + diff), new GeoCoordinate(coordinate - diff)); closestWithMatch = new SearchClosestResult <TEdgeData>( distance, edges.Vertex1, edges.Vertex2, position, edges.EdgeData, coordinatesArray); } } } } // add current segment distance to distanceToSegment for the next segment. distanceToSegment = distanceToSegment + previous.DistanceEstimate(current).Value; // set previous. previous = current; } } // check the last segment. line = new GeoCoordinateLine(previous, vertex2Coordinate, true, true); distance = line.DistanceReal(coordinate).Value; if (distance < closestWithoutMatch.Distance) { // the distance is smaller. var projectedPoint = line.ProjectOn(coordinate); // calculate the position. if (projectedPoint != null) { // calculate the distance if (distanceTotal == 0) { // calculate total distance. var pCoordinate = vertex1Coordinate; for (int cIdx = 0; cIdx < coordinatesArray.Length; cIdx++) { var cCoordinate = new GeoCoordinate(coordinatesArray[cIdx].Latitude, coordinatesArray[cIdx].Longitude); distanceTotal = distanceTotal + cCoordinate.DistanceReal(pCoordinate).Value; pCoordinate = cCoordinate; } distanceTotal = distanceTotal + vertex2Coordinate.DistanceReal(pCoordinate).Value; } double distancePoint = previous.DistanceReal(new GeoCoordinate(projectedPoint)).Value + distanceToSegment; double position = distancePoint / distanceTotal; var diff = coordinate - new GeoCoordinate(projectedPoint); closestWithoutMatchBox = new GeoCoordinateBox(new GeoCoordinate(coordinate + diff), new GeoCoordinate(coordinate - diff)); closestWithoutMatch = new SearchClosestResult <TEdgeData>( distance, edges.Vertex1, edges.Vertex2, position, edges.EdgeData, coordinatesArray); } } if (distance < closestWithMatch.Distance) { var projectedPoint = line.ProjectOn(coordinate); // calculate the position. if (projectedPoint != null) { // calculate the distance if (distanceTotal == 0) { // calculate total distance. var pCoordinate = vertex1Coordinate; for (int cIdx = 0; cIdx < coordinatesArray.Length; cIdx++) { var cCoordinate = new GeoCoordinate(coordinatesArray[cIdx].Latitude, coordinatesArray[cIdx].Longitude); distanceTotal = distanceTotal + cCoordinate.DistanceReal(pCoordinate).Value; pCoordinate = cCoordinate; } distanceTotal = distanceTotal + vertex2Coordinate.DistanceReal(pCoordinate).Value; } double distancePoint = previous.DistanceReal(new GeoCoordinate(projectedPoint)).Value + distanceToSegment; double position = distancePoint / distanceTotal; if (matcher == null || (pointTags == null || pointTags.Count == 0) || matcher.MatchWithEdge(vehicle, pointTags, arcTags)) { var diff = coordinate - new GeoCoordinate(projectedPoint); closestWithMatchBox = new GeoCoordinateBox(new GeoCoordinate(coordinate + diff), new GeoCoordinate(coordinate - diff)); closestWithMatch = new SearchClosestResult <TEdgeData>( distance, edges.Vertex1, edges.Vertex2, position, edges.EdgeData, coordinatesArray); } } } } } } } else { // only find closest vertices. // loop over all. while (edges.MoveNext()) { float fromLatitude, fromLongitude; float toLatitude, toLongitude; if (graph.GetVertex(edges.Vertex1, out fromLatitude, out fromLongitude) && graph.GetVertex(edges.Vertex2, out toLatitude, out toLongitude)) { var vertexCoordinate = new GeoCoordinate(fromLatitude, fromLongitude); double distance = coordinate.DistanceReal(vertexCoordinate).Value; if (distance < closestWithoutMatch.Distance) { // the distance found is closer. var diff = coordinate - vertexCoordinate; closestWithoutMatchBox = new GeoCoordinateBox(new GeoCoordinate(coordinate + diff), new GeoCoordinate(coordinate - diff)); closestWithoutMatch = new SearchClosestResult <TEdgeData>( distance, edges.Vertex1); } vertexCoordinate = new GeoCoordinate(toLatitude, toLongitude); distance = coordinate.DistanceReal(vertexCoordinate).Value; if (distance < closestWithoutMatch.Distance) { // the distance found is closer. var diff = coordinate - vertexCoordinate; closestWithoutMatchBox = new GeoCoordinateBox(new GeoCoordinate(coordinate + diff), new GeoCoordinate(coordinate - diff)); closestWithoutMatch = new SearchClosestResult <TEdgeData>( distance, edges.Vertex2); } var arcValueValueCoordinates = edges.Intermediates; if (arcValueValueCoordinates != null) { // search over intermediate points. var arcValueValueCoordinatesArray = arcValueValueCoordinates.ToArray(); for (int idx = 0; idx < arcValueValueCoordinatesArray.Length; idx++) { vertexCoordinate = new GeoCoordinate( arcValueValueCoordinatesArray[idx].Latitude, arcValueValueCoordinatesArray[idx].Longitude); distance = coordinate.DistanceReal(vertexCoordinate).Value; if (distance < closestWithoutMatch.Distance) { // the distance found is closer. var diff = coordinate - vertexCoordinate; closestWithoutMatchBox = new GeoCoordinateBox(new GeoCoordinate(coordinate + diff), new GeoCoordinate(coordinate - diff)); closestWithoutMatch = new SearchClosestResult <TEdgeData>( distance, edges.Vertex1, edges.Vertex2, idx, edges.EdgeData, arcValueValueCoordinatesArray); } } } } } } // return the best result. if (closestWithMatch.Distance < double.MaxValue) { return(closestWithMatch); } return(closestWithoutMatch); }
/// <summary> /// Returns the weight between two points on an edge with the given tags for the vehicle. /// </summary> /// <param name="tags"></param> /// <param name="from"></param> /// <param name="to"></param> /// <returns></returns> public virtual double Weight(TagsCollection tags, GeoCoordinate from, GeoCoordinate to) { var distance = from.DistanceEstimate(to).Value; return(distance / (MaxSpeed(tags).Value) * 3.6); }