GeographicLib.NET
2.3.2
dotnet add package GeographicLib.NET --version 2.3.2
NuGet\Install-Package GeographicLib.NET -Version 2.3.2
<PackageReference Include="GeographicLib.NET" Version="2.3.2" />
paket add GeographicLib.NET --version 2.3.2
#r "nuget: GeographicLib.NET, 2.3.2"
// Install GeographicLib.NET as a Cake Addin #addin nuget:?package=GeographicLib.NET&version=2.3.2 // Install GeographicLib.NET as a Cake Tool #tool nuget:?package=GeographicLib.NET&version=2.3.2
GeographicLib.NET
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#.
What's different from NETGeographicLib
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.
Features
Bellow is a list of implemented features.
- Projections (
AlbersEqualArea
,AzimuthalEquidistant
,CassiniSoldner
,Gnomonic
,LambertConformalConic
,PolarStereographic
andTransverseMercator
) - Geocodes (
GARS
,Geohash
,Georef
,MGRS
andOSGB
) - Coordinate conversions (
UTMUPS
,Geocentric
andLocalCartesian
) - Coordinate parsing/formatting (
DMS
andGeoCoords
) - Geodesic (
Geodesic
,GeodesicLine
,GeodesicExact
andGeodesicLineExact
) - Geodesic intersections (
Intersect
) - Rhumb (
Rhumb
andRhumbLine
) - PolygonArea (
PolygonArea<T>
,PolygonArea
,PolygonAreaExact
andPolygonAreaRhumb
) - Geoid (
Geoid
) - GravityModel (
GravityCircle
,NormalGravity
andGravityModel
) - MagneticModel (
MagneticModel
,MagneticCircle
) - Auxiliary classes (
MathEx
,Ellipoid
,EllipticFunction
,SphericalHarmonic
,AuxAngle
,AuxLatitude
andDAuxLatitude
)
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.
Installing
Stable
Stable releases of GeographicLib.NET are hosted on NuGet. You can install them using the following command:
dotnet add package GeographicLib.NET
Preview
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
Usage
This section lists some common usage examples of GeographicLib.NET. For detailed documentation, please refer GeographicLib's documentation.
Inverse calculation
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);
Direct calculation
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);
Geodesic intersection
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);
Mathematical Functions
GeographicLib uses several C mathematical functions that are not available in all versions of .NET. These functions are:
- remquo
- frexp
- sincos (available since .NET 7.0, but not used due to this issue)
- hypot (available since .NET 7.0, but not used due to this issue)
- log1p (a naive implementation is available since .NET 7.0, not used by GeographicLib.NET)
- expm1 (a naive implementation is available since .NET 7.0, not used by GeographicLib.NET)
- exp2 (a naive implementation is available since .NET 7.0, not used by GeographicLib.NET)
- log2 (available since .NET 5.0)
- fma (available since .NET 5.0)
- scalbn (available since .NET 5.0)
- copysign (available since .NET 5.0)
- atanh (available since .NET Standard 2.1)
- asinh (available since .NET Standard 2.1)
- cbrt (available since .NET Standard 2.1)
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
.
Performance
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 |
Change Log
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.
Version 2.3.2 (released 2024/10/23)
Version 2.3.1 (released 2024/03/20)
- NEW
- Improve performance of
Geodesic.Direct
,Rhumb.Direct
,GeodesicExact.Direct
,GeodesicExact.Inverse
and their overloads/variants. These are now heap allocation free. - Allow constructing
MagneticModel
andGravityModel
fromStream
and byte array. (#30) AuxLatitude
now implementsIEllipsoid
interface.- Parameter
p0
ofIntersect.Closest()
now defaults toPoint.Zero
.
- Improve performance of
- FIX
- Fixed wrong
GravityFlags
handling inGravityCircle
class.
- Fixed wrong
Version 2.3.0 (released 2024/02/23)
- NEW
- Target .NET 7.0 and .NET 8.0.
- Add managed implementation and libc wrapper for exp2.
- Managed implementations and libc wrappers for log1p, expm1 and exp2 are now used for all versions of .NET, because the implementations provided by .NET runtime are just wrappers over
Math.Log
andMath.Pow
.
- FIX
Version 2.1.2 (released 2023/01/17)
- FIX
- Fixed an issue where number and date time parsing may fail or produce unexpected result when working with
number and date time formats provided by
CultureInfo.CurrentCulture
. This fixes issue #27.
- Fixed an issue where number and date time parsing may fail or produce unexpected result when working with
number and date time formats provided by
Version 2.0.0 (released 2022/08/24)
- NEW
- Add
IPolygonArea
interface to provide better support for unit testing and dependency injection. - Add
Count
andIsPolyline
properties (corresponding toNumPoints
andPolyline
methods in GeographicLib) toPolygonArea
. - Add a new method
Utility.FractionalYear
which can parse floating point number and date time string as fractional year. - Allow constructing
Geoid
fromStream
and byte array.
- Add
- FIX
- String accepting APIs now handle lowercase "nan" correctly.
- Ensure consistent rounding mode (
MidpointRounding.ToEven
) across different runtimes when converting floating point number to string. MGRS.Reverse
now allows lowercase input.
Version 1.52.1 (released 2022/04/12)
NEW
- Target .NET 6.0 in addition to .NET 5.0, .NET Standard 2.1 and .NET Standard 2.0.
- Source Link support.
BREAKING
- Fixed typos in
Ellipsoid
. (RenamedSecondFlatterning
toSecondFlattening
andThirdFlatterning
toThirdFlattening
)
- Fixed typos in
FIX
- Fixed an issue that
Freeze
method inAlbersEqualArea
,LambertConformalConic
andPolarStereographic
was not working correctly. - Fixed duplicate instantiation of
WGS84
andGRS80
static properties defined inNormalGravity
. - Add missing support for World Magnetic Model Format v2.
- Fixed an issue that
Version 1.52.0 (released 2021/07/07)
BREAKING
- Modify overloads of
Forward
andReverse
inAlbersEqualArea
,AzimuthalEquidistant
,CassiniSoldner
andLambertConformalConic
to return coordinates as tuples. - Modify methods using
out
parameters defined inNormalGravity
,GravityModel
,GravityCircle
,MagneticModel
andMagnegticCircle
to return results as tuples.
- Modify overloads of
NEW
- Add constructor overloads that accept
IEllipsoid
as parameter forAlbersEqualArea
andLambertConformalConic
. - Add managed implementation of
log2
. - Add overloads of
Direct
andInverse
inGeodesic
/GeodesicLine
,GeodesicExact
/GeodesicLineExact
andRhumb
/RhumbLineExact
, that return the computation results as a single object. - Add definitions of popular reference ellipsoids in
Ellipsoid
class.
- Add constructor overloads that accept
FIX
- Fix stack overflow bug for
Forward(double lon0, double lat, double lon)
andReverse(double lon0, double x, double y)
inTransverseMercatorExact
.
- Fix stack overflow bug for
Version 1.51.0 (released 2021/03/14)
Initial stable release.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 is compatible. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- System.Memory (>= 4.5.5)
- System.Runtime.Extensions (>= 4.3.1)
-
.NETStandard 2.1
- No dependencies.
-
net5.0
- No dependencies.
-
net6.0
- No dependencies.
-
net7.0
- No dependencies.
-
net8.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories (1)
Showing the top 1 popular GitHub repositories that depend on GeographicLib.NET:
Repository | Stars |
---|---|
drewnoakes/metadata-extractor-dotnet
Extracts Exif, IPTC, XMP, ICC and other metadata from image, video and audio files
|