/// <summary> /// Gets the request URL to perform a query to snap points to roads. This method will only generate an post URL. /// </summary> /// <returns>A request URL to perform a query to snap points to roads.</returns> public override string GetRequestUrl() { //https://dev.virtualearth.net/REST/v1/Routes/SnapToRoad?key=BingMapsKey if (Points == null || Points.Count < 1) { throw new Exception("Points not specified."); } else if (Points.Count > maxAsyncPoints) { throw new Exception(string.Format("More than {0} Points specified.", maxAsyncPoints)); } if (TravelMode == TravelModeType.Transit) { throw new Exception("Transit is not supported by SnapToRoad API."); } for (int i = 1; i < Points.Count; i++) { var d = SpatialTools.HaversineDistance(Points[i - 1], Points[i], DistanceUnitType.Kilometers); if (d > maxDistanceKmBetweenPoints) { throw new Exception(string.Format("The distance between point {0} and point {1} is greater than {2} kilometers.", i - 1, i, maxDistanceKmBetweenPoints)); } } if (Points.Count > maxSyncPoints) { //Make an async request. return(this.Domain + "Routes/SnapToRoadAsync?key=" + this.BingMapsKey); } return(this.Domain + "Routes/SnapToRoad?key=" + this.BingMapsKey); }
/// <summary> /// Calculates a Distance Matrix for the origins and destinations based on the euclidean distance (straight line/as the crow flies). This calculation only uses; Origins, Destinations, and Distance Units properties from the request and only calculates travel distance. /// </summary> /// <returns>A Distance Matrix for the origins and destinations based on the euclidean distance (straight line/as the crow flies).</returns> public async Task <DistanceMatrix> GetEuclideanDistanceMatrix() { if (this.Origins != null && this.Origins.Count > 0) { //Make sure all origins and destinations are geocoded. await GeocodeWaypoints(); } var dm = new DistanceMatrix() { Origins = this.Origins.ToArray() }; int cnt = 0; if (this.Destinations == null || this.Destinations.Count == 0) { dm.Destinations = this.Origins.ToArray(); dm.Results = new DistanceMatrixCell[this.Origins.Count * this.Origins.Count]; for (var i = 0; i < Origins.Count; i++) { for (var j = 0; j < Origins.Count; j++) { dm.Results[cnt] = new DistanceMatrixCell() { OriginIndex = i, DestinationIndex = j, TravelDistance = SpatialTools.HaversineDistance(Origins[i].Coordinate, Origins[j].Coordinate, DistanceUnits) }; cnt++; } } } else { dm.Destinations = this.Destinations.ToArray(); dm.Results = new DistanceMatrixCell[this.Origins.Count * this.Destinations.Count]; for (var i = 0; i < Origins.Count; i++) { for (var j = 0; j < Destinations.Count; j++) { dm.Results[cnt] = new DistanceMatrixCell() { OriginIndex = i, DestinationIndex = j, TravelDistance = SpatialTools.HaversineDistance(Origins[i].Coordinate, Destinations[j].Coordinate, DistanceUnits) }; cnt++; } } } return(dm); }
/// <summary> /// Creates a NxN distance matrix with straight line distances. /// </summary> /// <param name="waypoints">The waypoints to generate a matrix for.</param> /// <param name="distanceUnits">The distance units to calculate the distances in.</param> /// <param name="bingMapsKey">A bing maps key that can be used to geocode waypoints, if needed.</param> /// <returns>A NxN distance matrix with straight line distances.</returns> public static async Task <DistanceMatrix> CreateStraightLineNxNMatrix(List <SimpleWaypoint> waypoints, DistanceUnitType distanceUnits, string bingMapsKey) { //Ensure all the waypoints are geocoded. if (waypoints == null || waypoints.Count < 2) { throw new Exception("Not enough Waypoints specified."); } if (!string.IsNullOrEmpty(bingMapsKey)) { await SimpleWaypoint.TryGeocodeWaypoints(waypoints, bingMapsKey); } var numWaypoints = waypoints.Count; var cells = new DistanceMatrixCell[numWaypoints * numWaypoints]; await Task.Run(() => Parallel.For(0, numWaypoints, i => { for (var j = 0; j < numWaypoints; j++) { double distance = -1; if (i != j && waypoints[i].Coordinate != null && waypoints[j].Coordinate != null) { distance = SpatialTools.HaversineDistance(waypoints[i].Coordinate, waypoints[j].Coordinate, distanceUnits); } cells[i * numWaypoints + j] = new DistanceMatrixCell() { OriginIndex = i, DestinationIndex = j, TravelDistance = distance }; } })); return(new DistanceMatrix() { Origins = waypoints, Destinations = waypoints, Results = cells }); }
/// <summary> /// Gets a list of coordinates that are related to the returned index of the elevation data. /// </summary> /// <returns>A list of coordinates that are related to the index of the returned elevation data.</returns> public List <Coordinate> GetElevationCoordinates() { if (Points != null && Points.Count > 0) { if (GetGeoidOffset || samples == 0) { return(Points); } else { //Calculate distance of polyline double totalDistance = 0; for (int i = 0; i < Points.Count - 1; i++) { totalDistance += SpatialTools.HaversineDistance(Points[i], Points[i + 1], DistanceUnitType.KM); } double segementLength = totalDistance / samples; var coords = new List <Coordinate>(samples); coords.Add(Points[0]); int idx = 0; //Calculate equally spaced coordinates along polyline for (var s = 0; s < samples; s++) { double dist = 0; double travel = segementLength * s; double dx = travel; for (var i = 0; i < Points.Count - 1; i++) { dist += SpatialTools.HaversineDistance(Points[i], Points[i + 1], DistanceUnitType.KM); if (dist >= travel) { idx = i; break; } dx = travel - dist; } if (dx != 0 && idx < Points.Count - 1) { var bearing = SpatialTools.CalculateBearing(Points[idx], Points[idx + 1]); coords.Add(SpatialTools.CalculateCoord(Points[idx], bearing, dx, DistanceUnitType.KM)); } } return(coords); } } else if (Bounds != null) { double dLat = Math.Abs(Bounds.NorthLatitude - Bounds.SouthLatitude) / row; double dLon = Math.Abs(Bounds.WestLongitude - Bounds.EastLongitude) / col; double x, y; var coords = new Coordinate[row * col]; //The elevation values are ordered starting with the southwest corner, and then proceed west to east and south to north. for (int r = 0; r < row; r++) { y = Bounds.SouthLatitude + (dLat * r); for (int c = 0; c < col; c++) { x = Bounds.WestLongitude + (dLon * c); int idx = r * row + c; coords[idx] = new Coordinate() { Latitude = y, Longitude = x }; } } return(new List <Coordinate>(coords)); } return(null); }