1 module geodetic; 2 3 import std.traits : isFloatingPoint, isSomeString; 4 5 /** WGS84 Coordinate 6 See also: https://en.wikipedia.org/wiki/World_Geodetic_System 7 */ 8 struct WGS84Coordinate(T = double) 9 if (isFloatingPoint!T) 10 { 11 @safe: // TODO nothrow @nogc 12 13 this(T latitude, 14 T longitude) pure 15 { 16 this.latitude = latitude; 17 this.longitude = longitude; 18 } 19 20 this(S, Separator)(S s, Separator separator = ` `) 21 if (isSomeString!S, 22 isSomeString!Separator) 23 { 24 import std.algorithm : findSplit; 25 if (auto parts = s.findSplit(separator)) // TODO reuse functional findSplit in DMD 2.070 26 { 27 import std.conv : to; 28 this(parts[0].to!T, parts[2].to!T); 29 } 30 else 31 { 32 this(T.nan, T.nan); 33 } 34 } 35 36 auto toString() const 37 { 38 import std.conv : to; 39 return latitude.to!string ~ `° N ` ~ longitude.to!string ~ `° W`; 40 } 41 42 T latitude; 43 T longitude; 44 } 45 46 auto wgs84Coordinate(T)(T latitude, 47 T longitude) 48 if (isFloatingPoint!T) 49 { 50 return WGS84Coordinate!T(latitude, longitude); 51 } 52 53 auto wgs84Coordinate(T = double, S, Separator)(S s, Separator separator = ` `) 54 if (isSomeString!S, 55 isSomeString!Separator) 56 { 57 return WGS84Coordinate!T(s, separator); 58 } 59 60 @safe // TODO pure/ nothrow 61 unittest 62 { 63 alias T = float; 64 65 T latitude = 1.5; 66 T longitude = 2.5; 67 68 import std.conv : to; 69 assert(wgs84Coordinate(latitude, longitude) == 70 wgs84Coordinate!T("1.5 2.5")); 71 72 auto x = wgs84Coordinate("36.7,3.216666666666667", ","); 73 assert(x.to!string == "36.7° N 3.21667° W"); 74 }