GeographicLib is a small set of C++ classes for performing conversions between geographic, UTM, UPS, MGRS, geocentric, and local cartesian coordinates,for gravity (e.g., EGM2008), geoid height and geomagnetic field (e.g., WMM2020) calculations, and for solving geodesic problems.
GeographicLib.NET is a native .NET implementation of GeographicLib written in pure C#.
Unlike NETGeographicLib, GeographicLib.NET is implemented in pure C# without binding the C++ GeograpbicLib library by using C++/CLI or P/Invoke, thus achieves higher level of portability.
You should be able to use GeographicLib.NET with any target framework and platform that supports .NET Standard 2.0 or above.
Bellow is a list of implemented features.
AlbersEqualArea
, AzimuthalEquidistant
, CassiniSoldner
, Gnomonic
, LambertConformalConic
, PolarStereographic
and TransverseMercator
)GARS
, Geohash
, Georef
, MGRS
and OSGB
)UTMUPS
, Geocentric
and LocalCartesian
)DMS
and GeoCoords
)Geodesic
, GeodesicLine
, GeodesicExact
and GeodesicLineExact
)Intersect
)Rhumb
and RhumbLine
)PolygonArea<T>
, PolygonArea
, PolygonAreaExact
and PolygonAreaRhumb
)Geoid
)GravityCircle
, NormalGravity
and GravityModel
)MagneticModel
, MagneticCircle
)MathEx
, Ellipoid
, EllipticFunction
, SphericalHarmonic
, AuxAngle
, AuxLatitude
and DAuxLatitude
)Geodesic
and GeodesicExact
are tested with the test set for geodesic.
TransverseMercator
and TransverseMercatorExact
are tested with data generated by 64-bit TransverseMercatorProj
utility ran on Windows.
Managed implemetation of C mathematical functions in MathEx
are tested with data generated by 64-bit Windows Universal C Runtime.
Stable releases of GeographicLib.NET are hosted on NuGet. You can install them using the following command:
dotnet add package GeographicLib.NET
Preview versions of GeographicLib.NET are hosted on NuGet pre-release channel. You can install them using the following command:
dotnet add package GeographicLib.NET --prerelease
This section lists some common usage examples of GeographicLib.NET. For detailed documentation, please refer GeographicLib's documentation.
Distance from JFK to LHR.
double
lat1 = 40.6, lon1 = -73.8, // JFK Airport
lat2 = 51.6, lon2 = -0.5; // LHR Airport
double arcLength = Geodesic.WGS84.Inverse(lat1, lon1, lat2, lon2, out double distance);
The point 5500 km NE of JFK:
double
lat1 = 40.6, lon1 = -73.8,
s12 = 5500e3, azi1 = 51;
double arcLength = Geodesic.WGS84.Direct(lat1, lon1, azi1, s12, out double lat2, out double lon2);
Find closest intersection of two geodesics:
Geodesic geod = Geodesic.WGS84;
Intersect inter = new Intersect(geod);
IGeodesicLine
lineX = geod.Line(0, 0, 45),
lineY = geod.Line(45, 10, 135);
// Find displacement to closest intersection.
// Where point.X is the displacement from the starting point of lineX,
// and point.Y is the displacement from the starting point of lineY.
Point point = inter.Closest(lineX, lineY);
// Get the position of the intersection point by using the displacement on lineX.
lineX.Position(point.X, out double latx, out double lonx);
// Get the position of the intersection point by using the displacement on lineY.
lineY.Position(point.Y, out double laty, out double lony);
// (latx, lonx) and (laty, lony) should be pointing to the same location.
Assert.AreEqual(latx, laty, 1e-12);
Assert.AreEqual(lonx, lony, 1e-12);
GeographicLib uses several C mathematical functions that are not available in all versions of .NET. These functions are:
GeographicLib.NET provides managed implementations (ported from musl libc) and platform dependent native C wrappers for these functions.
By default, the library will use the managed implementation when the corresponding math function is not provided by .NET runtime.
You can also force the library to use platform dependent native C wrappers, by setting GeographicLib.MathEx.UseManagedCMath
property to false
.
BenchmarkDotNet v0.13.12, Windows 11 (10.0.22621.3155/22H2/2022Update/SunValley2)
Intel Xeon CPU E5-2689 0 2.60GHz, 1 CPU, 16 logical and 8 physical cores
.NET SDK 8.0.200
[Host] : .NET 6.0.27 (6.0.2724.6912), X64 RyuJIT AVX
.NET 6.0 : .NET 6.0.27 (6.0.2724.6912), X64 RyuJIT AVX
.NET 7.0 : .NET 7.0.16 (7.0.1624.6629), X64 RyuJIT AVX
.NET 8.0 : .NET 8.0.2 (8.0.224.6711), X64 RyuJIT AVX
Method | Job | Runtime | Target | Mean | Error | StdDev | Ratio | RatioSD | Allocated | Alloc Ratio |
---|---|---|---|---|---|---|---|---|---|---|
Direct | .NET 6.0 | .NET 6.0 | Geodesic | 814.7 ns | 15.27 ns | 17.59 ns | 1.00 | 0.00 | - | NA |
Direct | .NET 7.0 | .NET 7.0 | Geodesic | 765.3 ns | 10.03 ns | 9.38 ns | 0.94 | 0.02 | - | NA |
Direct | .NET 8.0 | .NET 8.0 | Geodesic | 804.1 ns | 12.70 ns | 14.63 ns | 0.99 | 0.02 | - | NA |
Inverse | .NET 6.0 | .NET 6.0 | Geodesic | 2,440.2 ns | 24.36 ns | 20.34 ns | 1.00 | 0.00 | - | NA |
Inverse | .NET 7.0 | .NET 7.0 | Geodesic | 2,278.6 ns | 25.80 ns | 22.87 ns | 0.93 | 0.01 | - | NA |
Inverse | .NET 8.0 | .NET 8.0 | Geodesic | 2,084.5 ns | 18.19 ns | 16.12 ns | 0.85 | 0.01 | - | NA |
Direct | .NET 6.0 | .NET 6.0 | GeodesicExact | 2,414.8 ns | 44.92 ns | 44.12 ns | 1.00 | 0.00 | - | NA |
Direct | .NET 7.0 | .NET 7.0 | GeodesicExact | 2,335.3 ns | 19.53 ns | 17.31 ns | 0.97 | 0.02 | - | NA |
Direct | .NET 8.0 | .NET 8.0 | GeodesicExact | 2,331.7 ns | 18.35 ns | 17.17 ns | 0.97 | 0.02 | - | NA |
Inverse | .NET 6.0 | .NET 6.0 | GeodesicExact | 6,057.7 ns | 50.90 ns | 47.61 ns | 1.00 | 0.00 | - | NA |
Inverse | .NET 7.0 | .NET 7.0 | GeodesicExact | 6,029.2 ns | 51.33 ns | 48.02 ns | 1.00 | 0.01 | - | NA |
Inverse | .NET 8.0 | .NET 8.0 | GeodesicExact | 5,947.1 ns | 31.88 ns | 28.26 ns | 0.98 | 0.01 | - | NA |
Direct | .NET 6.0 | .NET 6.0 | Rhumb | 1,057.2 ns | 12.27 ns | 11.47 ns | 1.00 | 0.00 | - | NA |
Direct | .NET 7.0 | .NET 7.0 | Rhumb | 1,046.5 ns | 16.96 ns | 15.04 ns | 0.99 | 0.02 | - | NA |
Direct | .NET 8.0 | .NET 8.0 | Rhumb | 943.8 ns | 7.27 ns | 6.07 ns | 0.89 | 0.01 | - | NA |
Inverse | .NET 6.0 | .NET 6.0 | Rhumb | 846.6 ns | 6.29 ns | 5.89 ns | 1.00 | 0.00 | - | NA |
Inverse | .NET 7.0 | .NET 7.0 | Rhumb | 841.4 ns | 8.24 ns | 7.30 ns | 0.99 | 0.01 | - | NA |
Inverse | .NET 8.0 | .NET 8.0 | Rhumb | 757.8 ns | 6.67 ns | 5.91 ns | 0.90 | 0.01 | - | NA |
GeographicLib.NET adopts changes made in GeographicLib and aligns its version number with GeographicLib releases.
Bellow is a list of stable releases of GeographicLib.NET and changes made in .NET side in each release. For changes adopted from GeographicLib, please refer the its change log here.
Geodesic.Direct
, Rhumb.Direct
, GeodesicExact.Direct
, GeodesicExact.Inverse
and their overloads/variants. These are now heap allocation free.MagneticModel
and GravityModel
from Stream
and byte array. (#30)AuxLatitude
now implements IEllipsoid
interface.p0
of Intersect.Closest()
now defaults to Point.Zero
.GravityFlags
handling in GravityCircle
class.Math.Log
and Math.Pow
.CultureInfo.CurrentCulture
. This fixes issue #27.IPolygonArea
interface to provide better support for unit testing and dependency injection.Count
and IsPolyline
properties (corresponding to NumPoints
and Polyline
methods in GeographicLib) to PolygonArea
.Utility.FractionalYear
which can parse floating point number and date time string as fractional year.Geoid
from Stream
and byte array.MidpointRounding.ToEven
) across different runtimes when converting floating point number to string.MGRS.Reverse
now allows lowercase input.NEW
BREAKING
Ellipsoid
. (Renamed SecondFlatterning
to SecondFlattening
and ThirdFlatterning
to ThirdFlattening
)FIX
Freeze
method in AlbersEqualArea
, LambertConformalConic
and PolarStereographic
was not working correctly.WGS84
and GRS80
static properties defined in NormalGravity
.BREAKING
Forward
and Reverse
in AlbersEqualArea
, AzimuthalEquidistant
, CassiniSoldner
and LambertConformalConic
to return coordinates as tuples.out
parameters defined in NormalGravity
, GravityModel
, GravityCircle
, MagneticModel
and MagnegticCircle
to return results as tuples.NEW
IEllipsoid
as parameter for AlbersEqualArea
and LambertConformalConic
.log2
.Direct
and Inverse
in Geodesic
/GeodesicLine
, GeodesicExact
/GeodesicLineExact
and Rhumb
/RhumbLineExact
,
that return the computation results as a single object.Ellipsoid
class.FIX
Forward(double lon0, double lat, double lon)
and Reverse(double lon0, double x, double y)
in TransverseMercatorExact
.Initial stable release.