Changes between 2.5 (released 2024-12-28) and 2.4 versions:
New magnetic models provided
Changes between 2.4 (released 2024-07-14) and 2.3 versions:
Math::sind, Math::sincosd, etc., now return accurate results for
arguments = 30d, 45d, 60d, ...
Add Math::hypot3.
Add EllipticFunction::am.
Make constructor for AuxAngle explicit.
Include notes for plate carree areas.
C++14 compliant compiler required (this requirement tracks the
Boost Math library).
CMake configuration changes
Changes between 2.3 (released 2023-07-25) and 2.2 versions:
Add the Intersect class and the IntersectTool utility. The
methods are described in "Geodesic intersections",
https://arxiv.org/abs/2308.00495 (2023-08).
Add typedefs Geodesic::LineClass, GeodesicExact::LineClass,
Rhumb::LineClass, GeodesicLine::BaseClass,
GeodesicLineExact::BaseClass, RhumbLine::BaseClass.
Geodesic constructor accepts optional third argument exact, default
false. If true, then the calculations are delegated to
GeodesicExact. GeodSolve and Planimeter now use this simplified
interface.... read more
Changes between 2.2 (released 2023-03-07) and 2.1.2 versions:
Changes between 2.1.2 (released 2022-12-13) and 2.1.1 versions:
Add MGRS::Decode to break an MGRS string into its components.
Add definite integral overload for DST::integral. This is used in
GeodesicExact.
Add example code examples/AuxLatitude.[hc]pp implementating the
AuxAngle and AuxLatitude classes. These classes implement the
methods documented in the paper "On auxiliary latitudes",
https://arxiv.org/abs/2212.05818. They are not part of
GeographicLib. See Auxiliary latitudes for more details.... read more
I just posted this on arXiv:
C. F. F. Karney
Geodesics on an arbitrary ellipsoid of revolution
(Aug., 2022)
http://arxiv.org/abs/2208.00492
This documents the algorithms used for the GeodesicExact class and
the -E options for GeodSolve and Planimeter
Changes between 2.1.1 (released 2022-07-25) and 2.1 versions:
There's a sign error in the DST class in GeographicLib 2.1. This affects the DST::refine
member function which isn't used elsewhere in GeographicLib. Here's the fix
diff --git a/src/DST.cpp b/src/DST.cpp
index 6fc3ee90..1e70bfd1 100644
--- a/src/DST.cpp
+++ b/src/DST.cpp
@@ -67,7 +67,7 @@ namespace GeographicLib {
fft_transform(data, F+_N, true);
for (int i = 0; i < _N; ++i) data[i] = F[i+_N];
for (int i = _N; i < 2*_N; ++i)
- F[i] = (-data[2*_N-1-i] + F[2*_N-1-i])/2;
+ F[i] = (data[2*_N-1-i] - F[2*_N-1-i])/2;
for (int i = 0; i < _N; ++i)
F[i] = (data[i] + F[i])/2;
}
Changes between 2.1 (released 2022-06-09) and 2.0 versions:
Changes between 2.0 (released 2022-05-06) and 1.52 versions:
Remove non C++ implementations from this package. These are now
managed as separate packages. See
https://geographiclib.sourceforge.io/doc/library.html#languages
This allowed the cmake interface to be rationalized:
Changes between 1.52 (released 2021-06-22) and 1.51 versions:
Add MagneticModel::FieldGeocentric and
MagneticCircle::FieldGeocentric to return the field in geocentric
coordinates (thanks to Marcelo Banik de Padua).
Document realistic errors for PolygonAreaT and Planimeter.
Geodesic routines: be more aggressive in preventing negative s12
and m12 for short lines (all languages).... read more
Changes between 1.51 (released 2020-11-22) and 1.50.1 versions:
I've uploaded the International Geomagnetic Reference Field (13th generation), igrf13, magnetic model to
https://sourceforge.net/projects/geographiclib/files/magnetic-distrib/
This can be used with the MagneticField utility and the MagneticModel class. To install it on a Unix system use
sudo geographiclib-get-magnetic -f igrf13
The -f
is needed because igrf13 isn't yet known to geographiclib-get-magnetic
.
The CMake command
find_package (GeographicLib ...)
(for compiling your software using GeographicLib) fails with CMake versions 3.4 and 3.5. It works with CMake version 3.7. So I recommend using CMake 3.7 or later with GeographicLib.
Changes between 1.50.1 (released 2019-12-13) and 1.50 versions:
Add the World Magnetic Model 2020, wmm2020, covering the period
2020-2025. This is now the model returned by
MagneticModel::DefaultMagneticName and is default magnetic model
for MagneticField (replacing wmm2015v2 which is only valid thru
the end of 2019).
Include float instantiations of those templated Math functions
which migrated to Math.cpp in version 1.50.... read more
I've added the World Magnetic Model 2020, wmm2020. This can be
downloaded from the magnetic-distrib folder in the download area. No
changes are needed in GeographicLib to use this model. However, I will
shortly be releasing version 1.50.1 in which wmm2020 will replace
wmm2015v2 as the default magnetic model.
Changes between 1.50 (released 2019-09-24) and 1.49 versions:
User Federico reported a problem with the declaration of streamoff when
compiling GeographicLib with gcc version 8.2 with -std=c++1z. The
following patch fixes this:
diff --git a/include/GeographicLib/Geoid.hpp b/include/GeographicLib/Geoid.hpp
index 3a55adc8..7f41b651 100644
--- a/include/GeographicLib/Geoid.hpp
+++ b/include/GeographicLib/Geoid.hpp
@@ -120,7 +120,7 @@ namespace GeographicLib {
mutable real _v00, _v01, _v10, _v11;
mutable real _t[nterms_];
void filepos(int ix, int iy) const {
- _file.seekg(std::ios::streamoff
+ _file.seekg(std::streamoff
(_datastart +
pixel_size_ * (unsigned(iy)*_swidth + unsigned(ix))));
}... [read more](/p/geographiclib/news/2019/08/fix-to-declaration-of-streamoff-in-geoidhpp/)
There's a BUG in the PolygonArea::TestEdge routine in the Java
implementation of GeographicLib. The following patch fixes this:
diff --git a/java/src/main/java/net/sf/geographiclib/PolygonArea.java b/java/src/main/java/net/sf/geographiclib/PolygonArea.java
index 1e4ed1a1..b7379bcc 100644
--- a/java/src/main/java/net/sf/geographiclib/PolygonArea.java
+++ b/java/src/main/java/net/sf/geographiclib/PolygonArea.java
@@ -338,10 +338,10 @@ public class PolygonArea {
_earth.Direct(_lat1, _lon1, azi, false, s, _mask);
tempsum += g.S12;
crossings += transitdirect(_lon1, g.lon2);
+ crossings += transit(g.lon2, _lon0);
g = _earth.Inverse(g.lat2, g.lon2, _lat0, _lon0, _mask);
perimeter += g.s12;
tempsum += g.S12;
- crossings += transit(g.lon2, _lon0);
}... [read more](/p/geographiclib/news/2019/05/bug--fix-in-java-implementation-of-polygonareatestedge/)
The World Magnetic Model wmm2015v2 is now available for use with
GeographicLib. You can download it from
https://sourceforge.net/projects/geographiclib/files/magnetic-distrib/
This "out of cycle" release is described at
https://www.ncei.noaa.gov/news/world-magnetic-model-out-cycle-release
https://www.nytimes.com/2019/02/04/science/north-magnetic-pole-model.html
The original wmm2015 is still available, but this labeled "deprecated"
by NOAA.... read more
Changes between 1.49 (released 2017-10-05) and 1.48 versions:
Changes between 1.48 (released 2017-04-09) and 1.47 versions:
The "official" URL for GeographicLib is now
https://geographiclib.sourceforge.io (instead of
http://geographiclib.sourceforge.net).
The default range for longitude and azimuth is now (-180d, 180d],
instead of [-180d, 180d). This was already the case for the C++
library; now the change has been made to the other implementations
(C, Fortran, Java, JavaScript, Python, MATLAB, and Maxima).... read more
There's a bug in the MATLAB function geodreckon in calculating the area
when the distance argument is empty. The following patch fixes this.
This will be included in the next release of GeographicLib
diff --git a/matlab/geographiclib/geodreckon.m b/matlab/geographiclib/geodreckon.m
index 258e0e8..7751e7b 100644
--- a/matlab/geographiclib/geodreckon.m
+++ b/matlab/geographiclib/geodreckon.m
@@ -248,11 +248,14 @@ function [lat2, lon2, azi2, S12, m12, M12, M21, a12_s12] = geodreckon ...
ssig12 .* (csig1 .* ssig12 ./ (1 + csig12) + ssig1), ...
csig12 <= 0);
calp12 = salp0.^2 + calp0.^2 .* csig1 .* csig2;
- % Enlarge salp1, calp1 is case lat1 is an array and azi1 is a scalar
- s = zeros(size(salp0)); salp1 = salp1 + s; calp1 = calp1 + s;
- s = calp0 == 0 | salp0 == 0;
- salp12(s) = salp2(s) .* calp1(s) - calp2(s) .* salp1(s);
- calp12(s) = calp2(s) .* calp1(s) + salp2(s) .* salp1(s);
+ % Deal with geodreckon(10, 0, [], 0) which has calp2 = []
+ if length(Z) > 0
+ % Enlarge salp1, calp1 is case lat1 is an array and azi1 is a scalar
+ s = zeros(size(salp0)); salp1 = salp1 + s; calp1 = calp1 + s;
+ s = calp0 == 0 | salp0 == 0;
+ salp12(s) = salp2(s) .* calp1(s) - calp2(s) .* salp1(s);
+ calp12(s) = calp2(s) .* calp1(s) + salp2(s) .* salp1(s);
+ end
if e2 ~= 0
c2 = (a^2 + b^2 * eatanhe(1, e2) / e2) / 2;
else
There's a bug in the code for reading a NearestNeighbor object. The
following patch fixes this. This will be included in the next release
of GeographicLib
diff --git a/include/GeographicLib/NearestNeighbor.hpp b/include/GeographicLib/NearestNeighbor.hpp
index ebefeb9..2aa91e1 100644
--- a/include/GeographicLib/NearestNeighbor.hpp
+++ b/include/GeographicLib/NearestNeighbor.hpp
@@ -569,7 +569,7 @@ namespace GeographicLib {
// Sanity check on a Node
void Check(int numpoints, int treesize, int bucket) const {
- if (!( -1 <= index && index << numpoints ))
+ if (!( -1 <= index && index < numpoints ))
throw GeographicLib::GeographicErr("Bad index");
if (index >= 0) {
if (!( -1 <= data.child[0] && data.child[0] < treesize &&
The following only affects users of the Python GeographicLib package who
use Python 2.x on Windows 32-bit machines...
On these systems, there's a bug in the handling of -0.0 by math.fmod.
The following patch works aroung this bug. This patch will be
incorporated in the next version of GeographicLib.
diff --git a/python/geographiclib/geomath.py b/python/geographiclib/geomath.py
index 74d2c39..d5a535b 100644
--- a/python/geographiclib/geomath.py
+++ b/python/geographiclib/geomath.py
@@ -129,9 +129,12 @@ class Math(object):
def AngNormalize(x):
"""reduce angle to [-180,180)"""
- x = math.fmod(x, 360)
- return (x + 360 if x < -180 else
- (x if x < 180 else x - 360))
+ y = math.fmod(x, 360)
+ # On Windows 32-bit with python 2.7, math.fmod(-0.0, 360) = +0.0
+ # This fixes this bug. See also Math::sincosd in the C++ library.
+ y = x if x == 0 else y
+ return (y + 360 if y < -180 else
+ (y if y < 180 else y - 360))
AngNormalize = staticmethod(AngNormalize)
def LatFix(x):
@@ -162,6 +165,9 @@ class Math(object):
s, c = 0.0-s, 0.0-c
elif q == 3:
s, c = 0.0-c, s
+ # On Windows 32-bit with python 2.7, math.fmod(-0.0, 360) = +0.0
+ # This fixes this bug. See also Math::sincosd in the C++ library.
+ s = x if x == 0 else s
return s, c
sincosd = staticmethod(sincosd)