Example #1
0
        /// <summary>
        /// Calculates the distance between two <see cref="GeoCoordinate"/> values. This method
        /// uses the algorithm described at http://www.movable-type.co.uk/scripts/latlong.html.
        /// </summary>
        /// <param name="otherCoordinate">An instance of the <see cref="GeoCoordinate"/> class for comparison</param>
        /// <returns>The distance between this <see cref="GeoCoordinate"/> instances and the provided instance</returns>
        public double? GetDistanceTo(GeoCoordinate otherCoordinate)
        {
            if (otherCoordinate == null)
            {
                throw new ArgumentNullException("otherCoordinate");
            }

            // Ensure we have valid longitude and latitude values for the source
            if (this.Latitude == null || this.Longitude == null)
            {
                return null;
            }

            // Ensure we have valid longitude and latitude values for the target
            if (otherCoordinate.Latitude == null || otherCoordinate.Longitude == null)
            {
                return null;
            }

            const double radius = 6371; // Defines the radius of planet Earth. Often exposed simply as R.
            
            // Caclculate the latitude and longitude changes
            double deltaLat = (this.Latitude.ToDecimal().Value - otherCoordinate.Latitude.ToDecimal().Value).ToRad();
            double deltaLng = (this.Longitude.ToDecimal().Value - otherCoordinate.Longitude.ToDecimal().Value).ToRad();

            // Calculate the angle
            double angle = Math.Sin(deltaLat / 2) * Math.Sin(deltaLat / 2) +
                Math.Cos(this.Latitude.ToDecimal().Value.ToRad()) * Math.Cos(otherCoordinate.Latitude.ToDecimal().Value.ToRad()) *
                Math.Sin(deltaLng / 2) * Math.Sin(deltaLng / 2);

            // Calculate the circumference
            double c = 2 * Math.Atan2(Math.Sqrt(angle), Math.Sqrt(1 - angle));
            
            return radius * c;
        }
Example #2
0
        /// <summary>
        /// Attempts to parse a latitude and longitude string into a 
        /// new GeoCoordinate instance
        /// </summary>
        /// <param name="input">The longitude and latitude string</param>
        /// <param name="output">A newly created GeoCoordinate instance</param>
        /// <returns>true if the parsing was succesful; otherwsie false</returns>
        public static bool TryParse(string input, out GeoCoordinate output)
        {
            // Validate input parameter
            if (string.IsNullOrEmpty(input))
            {
                output = null;
                return false;
            }

            // TODO: SUPPORT MGRS IN THE FUTURE
            
            // The regex below parses Longitude and Latitude values and supports
            // the following different formats:
            // - 38° 47’ 44” N 077° 36’ 50” W
            // - 38°47’44”N077°36’50”W
            // - 38°47’44”N,077°36’50”W
            // - 384744N 0773650W
            // - 38°47’44”N 077°36’50”W
            // - 38 47 44 N 77 36 50 W
            // - 38 47 44.23 N 77 36 50.77 W
            //const string longlatParseString = "^(?<lat_degrees>\\d{2})[°]?\\s*(?<lat_minutes>\\d{2})[’']?\\s*(?<lat_seconds>[\\d\\.]+)[”\\\"]?\\s*(?<lat_direction>[NnSs]{1})[\\s,_-]?(?<lng_degrees>\\d{2,3})[°]?\\s*(?<lng_minutes>\\d{2})[’']?\\s*(?<lng_seconds>[\\d\\.]+)[”\\\"]?\\s*(?<lng_direction>[EeWw]{1})$";
            const string longlatParseString = @"^(?<lat_degrees>\d{2})[°]?\s*(?<lat_minutes>\d{2})[’']?\s*(?<lat_seconds>[\d\.]+)[”\""]?\s*(?<lat_direction>[NnSs]{1})[\s,_-]?(?<lng_degrees>\d{2,3})[°]?\s*(?<lng_minutes>\d{2})[’']?\s*(?<lng_seconds>[\d\.]+)[”\""]?\s*(?<lng_direction>[EeWw]{1})$";
            Regex regex = new Regex(longlatParseString);

            // Check if the regex matches the provided value
            if (regex.IsMatch(input))
            {
                Match match = regex.Match(input);

                //TODO: VALIDATE THE GROUPS

                // Create a DMS instance for Latitude and Longitude
                DMS latitude = new DMS(int.Parse(match.Groups["lat_degrees"].Value), int.Parse(match.Groups["lat_minutes"].Value), int.Parse(match.Groups["lat_seconds"].Value), (char)match.Groups["lat_direction"].Value[0]);
                DMS longitude = new DMS(int.Parse(match.Groups["lng_degrees"].Value), int.Parse(match.Groups["lng_minutes"].Value), int.Parse(match.Groups["lng_seconds"].Value), (char)match.Groups["lng_direction"].Value[0]);

                output = new GeoCoordinate(latitude, longitude);
                return true;
            }

            // The regex does not match so the provided input cannot be parsed as a longitude and latitude
            output = null;
            return false;
        }