Last active
September 8, 2020 21:54
-
-
Save fedemkr/9a8d7a1812d58f760d1a11464947a9f2 to your computer and use it in GitHub Desktop.
Method extension to get a latitude, longitude Coordinates object of a location string formatted as ISO-6709 Annex H. See https://en.wikipedia.org/wiki/ISO_6709. This is used for example when getting metadata location on Xamarin Android using the MediaMetadataRetriever.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Globalization; | |
using System.Text.RegularExpressions; | |
namespace Utilities.Extensions | |
{ | |
public static class LocationExtensions | |
{ | |
/// <summary> | |
/// Retrieves latitude, longitude coordinates from a ISO-6709 standard string | |
/// </summary> | |
/// <remarks> | |
/// https://en.wikipedia.org/wiki/ISO_6709 | |
/// | |
/// Format: | |
/// | |
/// ±[latitude]±[longitude]±[height or depth]CRS[CRSDetails] | |
/// | |
/// where height/depth and CRS are optional, but if height/depth is specified CRS has to be there too. | |
/// | |
/// Examples: | |
/// | |
/// Atlantic Ocean +00-025/ | |
/// France +46+002/ | |
/// Paris +48.52+002.20/ | |
/// Eiffel Tower +48.8577+002.295/ | |
/// Mount Everest +27.5916+086.5640+8850CRSWGS_84/ | |
/// North Pole +90+000/ | |
/// Pacific Ocean +00-160/ | |
/// South Pole -90+000+2800CRSWGS_84/ | |
/// United States +38-097/ | |
/// New York City +40.75-074.00/ | |
/// Statue of Liberty +40.6894-074.0447/ | |
/// </remarks> | |
/// <param name="locationString">Location as ISO-6709 Annex H string to retrieve coordinates</param> | |
/// <returns>The coordinate object of the location</returns> | |
public static Coordinate? LocationFromISO6709AnnexHString(this String locationString) | |
{ | |
if (string.IsNullOrWhiteSpace(locationString)) | |
{ | |
return null; | |
} | |
var sanitizedLocationString = locationString.TrimEnd('/'); | |
var pattern = @"(?<latitude>[+-][0-9\.]+)(?<longitude>[+-][0-9\.]+)((?<extrainfo>[+-]\w+)?)"; | |
var matchCollection = Regex.Matches(sanitizedLocationString, pattern); | |
if (matchCollection.Count != 1) | |
{ | |
return null; | |
} | |
var latString = matchCollection[0].Groups["latitude"]?.Value; | |
var lngString = matchCollection[0].Groups["longitude"]?.Value; | |
if (!double.TryParse(latString, NumberStyles.Float, CultureInfo.InvariantCulture, out var lat) || | |
!double.TryParse(lngString, NumberStyles.Float, CultureInfo.InvariantCulture, out var lng) || | |
lat == 0 && lng == 0) | |
{ | |
return null; | |
} | |
return new Coordinate | |
{ | |
Latitude = lat, | |
Longitude = lng | |
}; | |
} | |
} | |
public class Coordinate | |
{ | |
public double Latitude { get; set; } | |
public double Longitude { get; set; } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment