/// <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);
        }
Пример #2
0
        /// <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);
        }
Пример #3
0
        /// <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
            });
        }
Пример #4
0
        /// <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);
        }