Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-geographiclib for
openSUSE:Factory checked in at 2021-06-01 10:35:04
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-geographiclib (Old)
and /work/SRC/openSUSE:Factory/.python-geographiclib.new.1898 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-geographiclib"
Tue Jun 1 10:35:04 2021 rev:2 rq:895182 version:1.50
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-geographiclib/python-geographiclib.changes
2019-08-13 13:22:54.833392341 +0200
+++
/work/SRC/openSUSE:Factory/.python-geographiclib.new.1898/python-geographiclib.changes
2021-06-01 10:35:31.292614852 +0200
@@ -1,0 +2,8 @@
+Mon May 24 14:03:36 UTC 2021 - [email protected]
+
+- version update to 1.50
+ * no upstream changelog found
+- modified sources
+ % LICENSE.txt
+
+-------------------------------------------------------------------
Old:
----
geographiclib-1.49.tar.gz
New:
----
geographiclib-1.50.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-geographiclib.spec ++++++
--- /var/tmp/diff_new_pack.pNQrvy/_old 2021-06-01 10:35:31.796615710 +0200
+++ /var/tmp/diff_new_pack.pNQrvy/_new 2021-06-01 10:35:31.800615717 +0200
@@ -1,7 +1,7 @@
#
# spec file for package python-geographiclib
#
-# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2021 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -12,24 +12,25 @@
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
+#
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-geographiclib
-Version: 1.49
+Version: 1.50
Release: 0
-License: MIT
Summary: Python geodesic routines
-Url: https://geographiclib.sourceforge.io/
+License: MIT
Group: Development/Languages/Python
+URL: https://geographiclib.sourceforge.io/
Source:
https://files.pythonhosted.org/packages/source/g/geographiclib/geographiclib-%{version}.tar.gz
Source1:
https://sourceforge.net/p/geographiclib/code/ci/master/tree/LICENSE.txt?format=raw#/LICENSE.txt
-BuildRequires: python-rpm-macros
BuildRequires: %{python_module base}
+BuildRequires: %{python_module setuptools}
BuildRequires: fdupes
+BuildRequires: python-rpm-macros
BuildArch: noarch
-
%python_subpackages
%description
@@ -51,10 +52,10 @@
%python_expand %fdupes %{buildroot}%{$python_sitelib}
%check
-%python_exec setup.py test
+%pyunittest discover -v geographiclib/test
%files %{python_files}
-%doc README.rst
+%doc README.md
%license LICENSE.txt
%{python_sitelib}/*
++++++ LICENSE.txt ++++++
--- /var/tmp/diff_new_pack.pNQrvy/_old 2021-06-01 10:35:31.832615771 +0200
+++ /var/tmp/diff_new_pack.pNQrvy/_new 2021-06-01 10:35:31.836615778 +0200
@@ -1,7 +1,7 @@
The MIT License (MIT); this license applies to GeographicLib,
versions 1.12 and later.
-Copyright (c) 2008-2017, Charles Karney
+Copyright (c) 2008-2019, Charles Karney
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
++++++ geographiclib-1.49.tar.gz -> geographiclib-1.50.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/geographiclib-1.49/MANIFEST.in
new/geographiclib-1.50/MANIFEST.in
--- old/geographiclib-1.49/MANIFEST.in 1970-01-01 01:00:00.000000000 +0100
+++ new/geographiclib-1.50/MANIFEST.in 2019-09-24 15:10:55.000000000 +0200
@@ -0,0 +1 @@
+include README.md
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/geographiclib-1.49/PKG-INFO
new/geographiclib-1.50/PKG-INFO
--- old/geographiclib-1.49/PKG-INFO 2017-10-05 13:13:23.000000000 +0200
+++ new/geographiclib-1.50/PKG-INFO 2019-09-24 15:11:22.000000000 +0200
@@ -1,18 +1,18 @@
-Metadata-Version: 1.1
+Metadata-Version: 2.1
Name: geographiclib
-Version: 1.49
+Version: 1.50
Summary: The geodesic routines from GeographicLib
-Home-page: https://geographiclib.sourceforge.io/1.49/python
+Home-page: https://geographiclib.sourceforge.io/1.50/python
Author: Charles Karney
Author-email: [email protected]
License: MIT
Description: This implements
- `algorithms for geodesics <https://doi.org/10.1007/s00190-012-0578-z>`_
+ [Algorithms for Geodesics](https://doi.org/10.1007/s00190-012-0578-z)
(Karney, 2013) for solving the direct and inverse problems for an
ellipsoid of revolution.
Documentation is available at
- `<https://geographiclib.sourceforge.io/1.49/python/>`_.
+ <https://geographiclib.sourceforge.io/1.50/python/>.
Keywords: gis geographical earth distance geodesic
Platform: UNKNOWN
@@ -24,3 +24,4 @@
Classifier: Programming Language :: Python
Classifier: Topic :: Scientific/Engineering :: GIS
Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Description-Content-Type: text/markdown
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/geographiclib-1.49/README.md
new/geographiclib-1.50/README.md
--- old/geographiclib-1.49/README.md 1970-01-01 01:00:00.000000000 +0100
+++ new/geographiclib-1.50/README.md 2019-09-24 14:55:55.000000000 +0200
@@ -0,0 +1,7 @@
+This implements
+[Algorithms for Geodesics](https://doi.org/10.1007/s00190-012-0578-z)
+(Karney, 2013) for solving the direct and inverse problems for an
+ellipsoid of revolution.
+
+Documentation is available at
+<https://geographiclib.sourceforge.io/1.50/python/>.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/geographiclib-1.49/README.rst
new/geographiclib-1.50/README.rst
--- old/geographiclib-1.49/README.rst 2017-10-05 12:11:24.000000000 +0200
+++ new/geographiclib-1.50/README.rst 1970-01-01 01:00:00.000000000 +0100
@@ -1,7 +0,0 @@
-This implements
-`algorithms for geodesics <https://doi.org/10.1007/s00190-012-0578-z>`_
-(Karney, 2013) for solving the direct and inverse problems for an
-ellipsoid of revolution.
-
-Documentation is available at
-`<https://geographiclib.sourceforge.io/1.49/python/>`_.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/geographiclib-1.49/geographiclib/__init__.py
new/geographiclib-1.50/geographiclib/__init__.py
--- old/geographiclib-1.49/geographiclib/__init__.py 2017-10-05
12:11:24.000000000 +0200
+++ new/geographiclib-1.50/geographiclib/__init__.py 2019-09-24
14:55:55.000000000 +0200
@@ -1,7 +1,7 @@
"""geographiclib: geodesic routines from GeographicLib"""
-__version_info__ = (1, 49, 0)
+__version_info__ = (1, 50, 0)
"""GeographicLib version as a tuple"""
-__version__ = "1.49"
+__version__ = "1.50"
"""GeographicLib version as a string"""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/geographiclib-1.49/geographiclib/accumulator.py
new/geographiclib-1.50/geographiclib/accumulator.py
--- old/geographiclib-1.49/geographiclib/accumulator.py 2017-10-05
12:11:24.000000000 +0200
+++ new/geographiclib-1.50/geographiclib/accumulator.py 2019-09-24
14:55:55.000000000 +0200
@@ -7,8 +7,8 @@
#
# https://geographiclib.sourceforge.io/html/annotated.html
#
-# Copyright (c) Charles Karney (2011) <[email protected]> and licensed under
-# the MIT/X11 License. For more information, see
+# Copyright (c) Charles Karney (2011-2019) <[email protected]> and
+# licensed under the MIT/X11 License. For more information, see
# https://geographiclib.sourceforge.io/
######################################################################
@@ -80,3 +80,8 @@
"""Negate sum"""
self._s *= -1
self._t *= -1
+
+ def Remainder(self, y):
+ """Remainder on division by y"""
+ self._s = Math.remainder(self._s, y)
+ self.Add(0.0)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/geographiclib-1.49/geographiclib/geodesicline.py
new/geographiclib-1.50/geographiclib/geodesicline.py
--- old/geographiclib-1.49/geographiclib/geodesicline.py 2017-10-05
12:11:24.000000000 +0200
+++ new/geographiclib-1.50/geographiclib/geodesicline.py 2019-09-24
14:55:55.000000000 +0200
@@ -51,7 +51,7 @@
# https://doi.org/10.1007/s00190-012-0578-z
# Addenda: https://geographiclib.sourceforge.io/geod-addenda.html
#
-# Copyright (c) Charles Karney (2011-2016) <[email protected]> and licensed
+# Copyright (c) Charles Karney (2011-2019) <[email protected]> and licensed
# under the MIT/X11 License. For more information, see
# https://geographiclib.sourceforge.io/
######################################################################
@@ -112,7 +112,7 @@
"""the cosine of the azimuth at the first point (readonly)"""
# real cbet1, sbet1
- sbet1, cbet1 = Math.sincosd(Math.AngRound(lat1)); sbet1 *= self._f1
+ sbet1, cbet1 = Math.sincosd(Math.AngRound(self.lat1)); sbet1 *= self._f1
# Ensure cbet1 = +epsilon at poles
sbet1, cbet1 = Math.norm(sbet1, cbet1); cbet1 = max(Geodesic.tiny_, cbet1)
self._dn1 = math.sqrt(1 + geod._ep2 * Math.sq(sbet1))
@@ -205,6 +205,7 @@
else:
# Interpret s12_a12 as distance
tau12 = s12_a12 / (self._b * (1 + self._A1m1))
+ tau12 = tau12 if Math.isfinite(tau12) else Math.nan
s = math.sin(tau12); c = math.cos(tau12)
# tau2 = tau1 + tau12
B12 = - Geodesic._SinCosSeries(True,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/geographiclib-1.49/geographiclib/geomath.py
new/geographiclib-1.50/geographiclib/geomath.py
--- old/geographiclib-1.49/geographiclib/geomath.py 2017-10-05
12:11:24.000000000 +0200
+++ new/geographiclib-1.50/geographiclib/geomath.py 2019-09-24
14:55:55.000000000 +0200
@@ -6,7 +6,7 @@
#
# https://geographiclib.sourceforge.io/html/annotated.html
#
-# Copyright (c) Charles Karney (2011-2017) <[email protected]> and
+# Copyright (c) Charles Karney (2011-2019) <[email protected]> and
# licensed under the MIT/X11 License. For more information, see
# https://geographiclib.sourceforge.io/
######################################################################
@@ -44,7 +44,7 @@
"""Real cube root of a number"""
y = math.pow(abs(x), 1/3.0)
- return y if x >= 0 else -y
+ return y if x > 0 else (-y if x < 0 else x)
cbrt = staticmethod(cbrt)
def log1p(x):
@@ -70,7 +70,7 @@
y = abs(x) # Enforce odd parity
y = Math.log1p(2 * y/(1 - y))/2
- return -y if x < 0 else y
+ return y if x > 0 else (-y if x < 0 else x)
atanh = staticmethod(atanh)
def copysign(x, y):
@@ -126,16 +126,22 @@
return 0.0 if x == 0 else (-y if x < 0 else y)
AngRound = staticmethod(AngRound)
- def AngNormalize(x):
- """reduce angle to (-180,180]"""
-
- y = math.fmod(x, 360)
+ def remainder(x, y):
+ """remainder of x/y in the range [-y/2, y/2]."""
+ z = math.fmod(x, y) if Math.isfinite(x) else Math.nan
# On Windows 32-bit with python 2.7, math.fmod(-0.0, 360) = +0.0
# This fixes this bug. See also Math::AngNormalize in the C++ library.
# sincosd has a similar fix.
- y = x if x == 0 else y
- return (y + 360 if y <= -180 else
- (y if y <= 180 else y - 360))
+ z = x if x == 0 else z
+ return (z + y if z < -y/2 else
+ (z if z < y/2 else z -y))
+ remainder = staticmethod(remainder)
+
+ def AngNormalize(x):
+ """reduce angle to (-180,180]"""
+
+ y = Math.remainder(x, 360)
+ return 180 if y == -180 else y
AngNormalize = staticmethod(AngNormalize)
def LatFix(x):
@@ -155,8 +161,8 @@
def sincosd(x):
"""Compute sine and cosine of x in degrees."""
- r = math.fmod(x, 360)
- q = Math.nan if Math.isnan(r) else int(math.floor(r / 90 + 0.5))
+ r = math.fmod(x, 360) if Math.isfinite(x) else Math.nan
+ q = 0 if Math.isnan(r) else int(round(r / 90))
r -= 90 * q; r = math.radians(r)
s = math.sin(r); c = math.cos(r)
q = q % 4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/geographiclib-1.49/geographiclib/polygonarea.py
new/geographiclib-1.50/geographiclib/polygonarea.py
--- old/geographiclib-1.49/geographiclib/polygonarea.py 2017-10-05
12:11:24.000000000 +0200
+++ new/geographiclib-1.50/geographiclib/polygonarea.py 2019-09-24
14:55:55.000000000 +0200
@@ -39,7 +39,7 @@
# https://doi.org/10.1007/s00190-012-0578-z
# Addenda: https://geographiclib.sourceforge.io/geod-addenda.html
#
-# Copyright (c) Charles Karney (2011-2017) <[email protected]> and licensed
+# Copyright (c) Charles Karney (2011-2019) <[email protected]> and licensed
# under the MIT/X11 License. For more information, see
# https://geographiclib.sourceforge.io/
######################################################################
@@ -67,14 +67,60 @@
def _transitdirect(lon1, lon2):
"""Count crossings of prime meridian for AddEdge."""
# We want to compute exactly
- # int(floor(lon2 / 360)) - int(floor(lon1 / 360))
+ # int(ceil(lon2 / 360)) - int(ceil(lon1 / 360))
# Since we only need the parity of the result we can use std::remquo but
# this is buggy with g++ 4.8.3 and requires C++11. So instead we do
lon1 = math.fmod(lon1, 720.0); lon2 = math.fmod(lon2, 720.0)
- return ( (0 if ((lon2 >= 0 and lon2 < 360) or lon2 < -360) else 1) -
- (0 if ((lon1 >= 0 and lon1 < 360) or lon1 < -360) else 1) )
+ return ( (1 if ((lon2 <= 0 and lon2 > -360) or lon2 > 360) else 0) -
+ (1 if ((lon1 <= 0 and lon1 > -360) or lon1 > 360) else 0) )
_transitdirect = staticmethod(_transitdirect)
+ def _areareduceA(area, area0, crossings, reverse, sign):
+ """Reduce accumulator area to allowed range."""
+ area.Remainder(area0)
+ if crossings & 1:
+ area.Add( (1 if area.Sum() < 0 else -1) * area0/2 )
+ # area is with the clockwise sense. If !reverse convert to
+ # counter-clockwise convention.
+ if not reverse: area.Negate()
+ # If sign put area in (-area0/2, area0/2], else put area in [0, area0)
+ if sign:
+ if area.Sum() > area0/2:
+ area.Add( -area0 )
+ elif area.Sum() <= -area0/2:
+ area.Add( area0 )
+ else:
+ if area.Sum() >= area0:
+ area.Add( -area0 )
+ elif area.Sum() < 0:
+ area.Add( area0 )
+
+ return 0.0 + area.Sum()
+ _areareduceA = staticmethod(_areareduceA)
+
+ def _areareduceB(area, area0, crossings, reverse, sign):
+ """Reduce double area to allowed range."""
+ area = Math.remainder(area, area0)
+ if crossings & 1:
+ area += (1 if area < 0 else -1) * area0/2
+ # area is with the clockwise sense. If !reverse convert to
+ # counter-clockwise convention.
+ if not reverse: area *= -1
+ # If sign put area in (-area0/2, area0/2], else put area in [0, area0)
+ if sign:
+ if area > area0/2:
+ area -= area0
+ elif area <= -area0/2:
+ area += area0
+ else:
+ if area >= area0:
+ area -= area0
+ elif area < 0:
+ area += area0
+
+ return 0.0 + area
+ _areareduceB = staticmethod(_areareduceB)
+
def __init__(self, earth, polyline = False):
"""Construct a PolygonArea object
@@ -169,7 +215,12 @@
the area for the rest of the earth
:return: a tuple of number, perimeter (meters), area (meters^2)
- If the object is a polygon (and not a polygon), the perimeter
+ Arbitrarily complex polygons are allowed. In the case of
+ self-intersecting polygons the area is accumulated "algebraically",
+ e.g., the areas of the 2 loops in a figure-8 polygon will partially
+ cancel.
+
+ If the object is a polygon (and not a polyline), the perimeter
includes the length of a final edge connecting the current point to
the initial point. If the object is a polyline, then area is nan.
@@ -192,24 +243,8 @@
tempsum = Accumulator(self._areasum)
tempsum.Add(S12)
crossings = self._crossings + PolygonArea._transit(self.lon1, self._lon0)
- if crossings & 1:
- tempsum.Add( (1 if tempsum.Sum() < 0 else -1) * self.area0/2 )
- # area is with the clockwise sense. If !reverse convert to
- # counter-clockwise convention.
- if not reverse: tempsum.Negate()
- # If sign put area in (-area0/2, area0/2], else put area in [0, area0)
- if sign:
- if tempsum.Sum() > self.area0/2:
- tempsum.Add( -self.area0 )
- elif tempsum.Sum() <= -self.area0/2:
- tempsum.Add( self.area0 )
- else:
- if tempsum.Sum() >= self.area0:
- tempsum.Add( -self.area0 )
- elif tempsum.Sum() < 0:
- tempsum.Add( self.area0 )
-
- area = 0.0 + tempsum.Sum()
+ area = PolygonArea._areareduceA(tempsum, self.area0, crossings,
+ reverse, sign)
return self.num, perimeter, area
# return number, perimeter, area
@@ -249,24 +284,8 @@
if self.polyline:
return num, perimeter, area
- if crossings & 1:
- tempsum += (1 if tempsum < 0 else -1) * self.area0/2
- # area is with the clockwise sense. If !reverse convert to
- # counter-clockwise convention.
- if not reverse: tempsum *= -1
- # If sign put area in (-area0/2, area0/2], else put area in [0, area0)
- if sign:
- if tempsum > self.area0/2:
- tempsum -= self.area0
- elif tempsum <= -self.area0/2:
- tempsum += self.area0
- else:
- if tempsum >= self.area0:
- tempsum -= self.area0
- elif tempsum < 0:
- tempsum += self.area0
-
- area = 0.0 + tempsum
+ area = PolygonArea._areareduceB(tempsum, self.area0, crossings,
+ reverse, sign)
return num, perimeter, area
# return num, perimeter, area
@@ -303,22 +322,6 @@
tempsum += S12
crossings += PolygonArea._transit(lon, self._lon0)
- if crossings & 1:
- tempsum += (1 if tempsum < 0 else -1) * self.area0/2
- # area is with the clockwise sense. If !reverse convert to
- # counter-clockwise convention.
- if not reverse: tempsum *= -1
- # If sign put area in (-area0/2, area0/2], else put area in [0, area0)
- if sign:
- if tempsum > self.area0/2:
- tempsum -= self.area0
- elif tempsum <= -self.area0/2:
- tempsum += self.area0
- else:
- if tempsum >= self.area0:
- tempsum -= self.area0
- elif tempsum < 0:
- tempsum += self.area0
-
- area = 0.0 + tempsum
+ area = PolygonArea._areareduceB(tempsum, self.area0, crossings,
+ reverse, sign)
return num, perimeter, area
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/geographiclib-1.49/geographiclib/test/test_geodesic.py
new/geographiclib-1.50/geographiclib/test/test_geodesic.py
--- old/geographiclib-1.49/geographiclib/test/test_geodesic.py 2017-10-05
12:11:24.000000000 +0200
+++ new/geographiclib-1.50/geographiclib/test/test_geodesic.py 2019-09-24
14:55:55.000000000 +0200
@@ -350,7 +350,7 @@
inv = Geodesic.WGS84.Inverse(5, 0.00000000000001, 10, 180)
self.assertAlmostEqual(inv["azi1"], 0.000000000000035, delta = 1.5e-14)
self.assertAlmostEqual(inv["azi2"], 179.99999999999996, delta = 1.5e-14)
- self.assertAlmostEqual(inv["s12"], 18345191.174332713, delta = 4e-9)
+ self.assertAlmostEqual(inv["s12"], 18345191.174332713, delta = 5e-9)
def test_GeodSolve61(self):
# Make sure small negative azimuths are west-going
@@ -425,24 +425,27 @@
# Check for backwards from the pole bug reported by Anon on 2016-02-13.
# This only affected the Java implementation. It was introduced in Java
# version 1.44 and fixed in 1.46-SNAPSHOT on 2016-01-17.
+ # Also the + sign on azi2 is a check on the normalizing of azimuths
+ # (converting -0.0 to +0.0).
dir = Geodesic.WGS84.Direct(90, 10, 180, -1e6)
self.assertAlmostEqual(dir["lat2"], 81.04623, delta = 0.5e-5)
self.assertAlmostEqual(dir["lon2"], -170, delta = 0.5e-5)
self.assertAlmostEqual(dir["azi2"], 0, delta = 0.5e-5)
+ self.assertTrue(Math.copysign(1, dir["azi2"]) > 0)
def test_GeodSolve74(self):
# Check fix for inaccurate areas, bug introduced in v1.46, fixed
# 2015-10-16.
inv = Geodesic.WGS84.Inverse(54.1589, 15.3872, 54.1591, 15.3877,
Geodesic.ALL)
- self.assertAlmostEqual(inv["azi1"], 55.723110355, delta = 5e-9);
- self.assertAlmostEqual(inv["azi2"], 55.723515675, delta = 5e-9);
- self.assertAlmostEqual(inv["s12"], 39.527686385, delta = 5e-9);
- self.assertAlmostEqual(inv["a12"], 0.000355495, delta = 5e-9);
- self.assertAlmostEqual(inv["m12"], 39.527686385, delta = 5e-9);
- self.assertAlmostEqual(inv["M12"], 0.999999995, delta = 5e-9);
- self.assertAlmostEqual(inv["M21"], 0.999999995, delta = 5e-9);
- self.assertAlmostEqual(inv["S12"], 286698586.30197, delta = 5e-4);
+ self.assertAlmostEqual(inv["azi1"], 55.723110355, delta = 5e-9)
+ self.assertAlmostEqual(inv["azi2"], 55.723515675, delta = 5e-9)
+ self.assertAlmostEqual(inv["s12"], 39.527686385, delta = 5e-9)
+ self.assertAlmostEqual(inv["a12"], 0.000355495, delta = 5e-9)
+ self.assertAlmostEqual(inv["m12"], 39.527686385, delta = 5e-9)
+ self.assertAlmostEqual(inv["M12"], 0.999999995, delta = 5e-9)
+ self.assertAlmostEqual(inv["M21"], 0.999999995, delta = 5e-9)
+ self.assertAlmostEqual(inv["S12"], 286698586.30197, delta = 5e-4)
def test_GeodSolve76(self):
# The distance from Wellington and Salamanca (a classic failure of
@@ -460,6 +463,79 @@
self.assertAlmostEqual(inv["azi2"], 134.22776532670, delta = 0.5e-11)
self.assertAlmostEqual(inv["s12"], 19974354.765767, delta = 0.5e-6)
+ def test_GeodSolve80(self):
+ # Some tests to add code coverage: computing scale in special cases + zero
+ # length geodesic (includes GeodSolve80 - GeodSolve83) + using an incapable
+ # line.
+ inv = Geodesic.WGS84.Inverse(0, 0, 0, 90, Geodesic.GEODESICSCALE)
+ self.assertAlmostEqual(inv["M12"], -0.00528427534, delta = 0.5e-10)
+ self.assertAlmostEqual(inv["M21"], -0.00528427534, delta = 0.5e-10)
+
+ inv = Geodesic.WGS84.Inverse(0, 0, 1e-6, 1e-6, Geodesic.GEODESICSCALE)
+ self.assertAlmostEqual(inv["M12"], 1, delta = 0.5e-10)
+ self.assertAlmostEqual(inv["M21"], 1, delta = 0.5e-10)
+
+ inv = Geodesic.WGS84.Inverse(20.001, 0, 20.001, 0, Geodesic.ALL)
+ self.assertAlmostEqual(inv["a12"], 0, delta = 1e-13)
+ self.assertAlmostEqual(inv["s12"], 0, delta = 1e-8)
+ self.assertAlmostEqual(inv["azi1"], 180, delta = 1e-13)
+ self.assertAlmostEqual(inv["azi2"], 180, delta = 1e-13)
+ self.assertAlmostEqual(inv["m12"], 0, delta = 1e-8)
+ self.assertAlmostEqual(inv["M12"], 1, delta = 1e-15)
+ self.assertAlmostEqual(inv["M21"], 1, delta = 1e-15)
+ self.assertAlmostEqual(inv["S12"], 0, delta = 1e-10)
+
+ inv = Geodesic.WGS84.Inverse(90, 0, 90, 180, Geodesic.ALL)
+ self.assertAlmostEqual(inv["a12"], 0, delta = 1e-13)
+ self.assertAlmostEqual(inv["s12"], 0, delta = 1e-8)
+ self.assertAlmostEqual(inv["azi1"], 0, delta = 1e-13)
+ self.assertAlmostEqual(inv["azi2"], 180, delta = 1e-13)
+ self.assertAlmostEqual(inv["m12"], 0, delta = 1e-8)
+ self.assertAlmostEqual(inv["M12"], 1, delta = 1e-15)
+ self.assertAlmostEqual(inv["M21"], 1, delta = 1e-15)
+ self.assertAlmostEqual(inv["S12"], 127516405431022.0, delta = 0.5)
+
+ # An incapable line which can't take distance as input
+ line = Geodesic.WGS84.Line(1, 2, 90, Geodesic.LATITUDE)
+ dir = line.Position(1000, Geodesic.EMPTY)
+ self.assertTrue(Math.isnan(dir["a12"]))
+
+ def test_GeodSolve84(self):
+ # Tests for python implementation to check fix for range errors with
+ # {fmod,sin,cos}(inf) (includes GeodSolve84 - GeodSolve91).
+ dir = Geodesic.WGS84.Direct(0, 0, 90, Math.inf)
+ self.assertTrue(Math.isnan(dir["lat2"]))
+ self.assertTrue(Math.isnan(dir["lon2"]))
+ self.assertTrue(Math.isnan(dir["azi2"]))
+ dir = Geodesic.WGS84.Direct(0, 0, 90, Math.nan)
+ self.assertTrue(Math.isnan(dir["lat2"]))
+ self.assertTrue(Math.isnan(dir["lon2"]))
+ self.assertTrue(Math.isnan(dir["azi2"]))
+ dir = Geodesic.WGS84.Direct(0, 0, Math.inf, 1000)
+ self.assertTrue(Math.isnan(dir["lat2"]))
+ self.assertTrue(Math.isnan(dir["lon2"]))
+ self.assertTrue(Math.isnan(dir["azi2"]))
+ dir = Geodesic.WGS84.Direct(0, 0, Math.nan, 1000)
+ self.assertTrue(Math.isnan(dir["lat2"]))
+ self.assertTrue(Math.isnan(dir["lon2"]))
+ self.assertTrue(Math.isnan(dir["azi2"]))
+ dir = Geodesic.WGS84.Direct(0, Math.inf, 90, 1000)
+ self.assertTrue(dir["lat1"] == 0)
+ self.assertTrue(Math.isnan(dir["lon2"]))
+ self.assertTrue(dir["azi2"] == 90)
+ dir = Geodesic.WGS84.Direct(0, Math.nan, 90, 1000)
+ self.assertTrue(dir["lat1"] == 0)
+ self.assertTrue(Math.isnan(dir["lon2"]))
+ self.assertTrue(dir["azi2"] == 90)
+ dir = Geodesic.WGS84.Direct(Math.inf, 0, 90, 1000)
+ self.assertTrue(Math.isnan(dir["lat2"]))
+ self.assertTrue(Math.isnan(dir["lon2"]))
+ self.assertTrue(Math.isnan(dir["azi2"]))
+ dir = Geodesic.WGS84.Direct(Math.nan, 0, 90, 1000)
+ self.assertTrue(Math.isnan(dir["lat2"]))
+ self.assertTrue(Math.isnan(dir["lon2"]))
+ self.assertTrue(Math.isnan(dir["azi2"]))
+
class PlanimeterTest(unittest.TestCase):
polygon = Geodesic.WGS84.Polygon(False)
@@ -542,3 +618,153 @@
num, perimeter, area = PlanimeterTest.Planimeter(points)
self.assertAlmostEqual(perimeter, 1160741, delta = 1)
self.assertAlmostEqual(area, 32415230256.0, delta = 1)
+
+ def test_Planimeter15(self):
+ # Coverage tests, includes Planimeter15 - Planimeter18 (combinations of
+ # reverse and sign) + calls to testpoint, testedge.
+ lat = [2, 1, 3]
+ lon = [1, 2, 3]
+ r = 18454562325.45119
+ a0 = 510065621724088.5093 # ellipsoid area
+ PlanimeterTest.polygon.Clear()
+ PlanimeterTest.polygon.AddPoint(lat[0], lon[0])
+ PlanimeterTest.polygon.AddPoint(lat[1], lon[1])
+ num, perimeter, area = PlanimeterTest.polygon.TestPoint(lat[2], lon[2],
+ False, True)
+ self.assertAlmostEqual(area, r, delta = 0.5)
+ num, perimeter, area = PlanimeterTest.polygon.TestPoint(lat[2], lon[2],
+ False, False)
+ self.assertAlmostEqual(area, r, delta = 0.5)
+ num, perimeter, area = PlanimeterTest.polygon.TestPoint(lat[2], lon[2],
+ True, True)
+ self.assertAlmostEqual(area, -r, delta = 0.5)
+ num, perimeter, area = PlanimeterTest.polygon.TestPoint(lat[2], lon[2],
+ True, False)
+ self.assertAlmostEqual(area, a0-r, delta = 0.5)
+ inv = Geodesic.WGS84.Inverse(lat[1], lon[1], lat[2], lon[2])
+ azi1 = inv["azi1"]
+ s12 = inv["s12"]
+ num, perimeter, area = PlanimeterTest.polygon.TestEdge(azi1, s12,
+ False, True)
+ self.assertAlmostEqual(area, r, delta = 0.5)
+ num, perimeter, area = PlanimeterTest.polygon.TestEdge(azi1, s12,
+ False, False)
+ self.assertAlmostEqual(area, r, delta = 0.5)
+ num, perimeter, area = PlanimeterTest.polygon.TestEdge(azi1, s12,
+ True, True)
+ self.assertAlmostEqual(area, -r, delta = 0.5)
+ num, perimeter, area = PlanimeterTest.polygon.TestEdge(azi1, s12,
+ True, False)
+ self.assertAlmostEqual(area, a0-r, delta = 0.5)
+ PlanimeterTest.polygon.AddPoint(lat[2], lon[2])
+ num, perimeter, area = PlanimeterTest.polygon.Compute(False, True)
+ self.assertAlmostEqual(area, r, delta = 0.5)
+ num, perimeter, area = PlanimeterTest.polygon.Compute(False, False)
+ self.assertAlmostEqual(area, r, delta = 0.5)
+ num, perimeter, area = PlanimeterTest.polygon.Compute(True, True)
+ self.assertAlmostEqual(area, -r, delta = 0.5)
+ num, perimeter, area = PlanimeterTest.polygon.Compute(True, False)
+ self.assertAlmostEqual(area, a0-r, delta = 0.5)
+
+ def test_Planimeter19(self):
+ # Coverage tests, includes Planimeter19 - Planimeter20 (degenerate
+ # polygons) + extra cases.
+ PlanimeterTest.polygon.Clear()
+ num, perimeter, area = PlanimeterTest.polygon.Compute(False, True)
+ self.assertTrue(area == 0)
+ self.assertTrue(perimeter == 0)
+ num, perimeter, area = PlanimeterTest.polygon.TestPoint(1, 1,
+ False, True)
+ self.assertTrue(area == 0)
+ self.assertTrue(perimeter == 0)
+ num, perimeter, area = PlanimeterTest.polygon.TestEdge(90, 1000,
+ False, True)
+ self.assertTrue(Math.isnan(area))
+ self.assertTrue(Math.isnan(perimeter))
+ PlanimeterTest.polygon.AddPoint(1, 1)
+ num, perimeter, area = PlanimeterTest.polygon.Compute(False, True)
+ self.assertTrue(area == 0)
+ self.assertTrue(perimeter == 0)
+ PlanimeterTest.polyline.Clear()
+ num, perimeter, area = PlanimeterTest.polyline.Compute(False, True)
+ self.assertTrue(perimeter == 0)
+ num, perimeter, area = PlanimeterTest.polyline.TestPoint(1, 1,
+ False, True)
+ self.assertTrue(perimeter == 0)
+ num, perimeter, area = PlanimeterTest.polyline.TestEdge(90, 1000,
+ False, True)
+ self.assertTrue(Math.isnan(perimeter))
+ PlanimeterTest.polyline.AddPoint(1, 1)
+ num, perimeter, area = PlanimeterTest.polyline.Compute(False, True)
+ self.assertTrue(perimeter == 0)
+ PlanimeterTest.polygon.AddPoint(1, 1)
+ num, perimeter, area = PlanimeterTest.polyline.TestEdge(90, 1000,
+ False, True)
+ self.assertAlmostEqual(perimeter, 1000, delta = 1e-10)
+ num, perimeter, area = PlanimeterTest.polyline.TestPoint(2, 2,
+ False, True)
+ self.assertAlmostEqual(perimeter, 156876.149, delta = 0.5e-3)
+
+ def test_Planimeter21(self):
+ # Some test to add code coverage: multiple circlings of pole (includes
+ # Planimeter21 - Planimeter28) + invocations via testpoint and testedge.
+ lat = 45
+ azi = 39.2144607176828184218
+ s = 8420705.40957178156285
+ r = 39433884866571.4277 # Area for one circuit
+ a0 = 510065621724088.5093 # Ellipsoid area
+ PlanimeterTest.polygon.Clear()
+ PlanimeterTest.polygon.AddPoint(lat, 60)
+ PlanimeterTest.polygon.AddPoint(lat, 180)
+ PlanimeterTest.polygon.AddPoint(lat, -60)
+ PlanimeterTest.polygon.AddPoint(lat, 60)
+ PlanimeterTest.polygon.AddPoint(lat, 180)
+ PlanimeterTest.polygon.AddPoint(lat, -60)
+ for i in [3, 4]:
+ PlanimeterTest.polygon.AddPoint(lat, 60)
+ PlanimeterTest.polygon.AddPoint(lat, 180)
+ num, perimeter, area = PlanimeterTest.polygon.TestPoint(lat, -60,
+ False, True)
+ self.assertAlmostEqual(area, i*r, delta = 0.5)
+ num, perimeter, area = PlanimeterTest.polygon.TestPoint(lat, -60,
+ False, False)
+ self.assertAlmostEqual(area, i*r, delta = 0.5)
+ num, perimeter, area = PlanimeterTest.polygon.TestPoint(lat, -60,
+ True, True)
+ self.assertAlmostEqual(area, -i*r, delta = 0.5)
+ num, perimeter, area = PlanimeterTest.polygon.TestPoint(lat, -60,
+ True, False)
+ self.assertAlmostEqual(area, -i*r + a0, delta = 0.5)
+ num, perimeter, area = PlanimeterTest.polygon.TestEdge(azi, s,
+ False, True)
+ self.assertAlmostEqual(area, i*r, delta = 0.5)
+ num, perimeter, area = PlanimeterTest.polygon.TestEdge(azi, s,
+ False, False)
+ self.assertAlmostEqual(area, i*r, delta = 0.5)
+ num, perimeter, area = PlanimeterTest.polygon.TestEdge(azi, s,
+ True, True)
+ self.assertAlmostEqual(area, -i*r, delta = 0.5)
+ num, perimeter, area = PlanimeterTest.polygon.TestEdge(azi, s,
+ True, False)
+ self.assertAlmostEqual(area, -i*r + a0, delta = 0.5)
+ PlanimeterTest.polygon.AddPoint(lat, -60)
+ num, perimeter, area = PlanimeterTest.polygon.Compute(False, True)
+ self.assertAlmostEqual(area, i*r, delta = 0.5)
+ num, perimeter, area = PlanimeterTest.polygon.Compute(False, False)
+ self.assertAlmostEqual(area, i*r, delta = 0.5)
+ num, perimeter, area = PlanimeterTest.polygon.Compute(True, True)
+ self.assertAlmostEqual(area, -i*r, delta = 0.5)
+ num, perimeter, area = PlanimeterTest.polygon.Compute(True, False)
+ self.assertAlmostEqual(area, -i*r + a0, delta = 0.5)
+
+ def test_Planimeter29(self):
+ # Check fix to transitdirect vs transit zero handling inconsistency
+ PlanimeterTest.polygon.Clear()
+ PlanimeterTest.polygon.AddPoint(0, 0)
+ PlanimeterTest.polygon.AddEdge( 90, 1000)
+ PlanimeterTest.polygon.AddEdge( 0, 1000)
+ PlanimeterTest.polygon.AddEdge(-90, 1000)
+ num, perimeter, area = PlanimeterTest.polygon.Compute(False, True)
+ # The area should be 1e6. Prior to the fix it was 1e6 - A/2, where
+ # A = ellipsoid area.
+ self.assertAlmostEqual(area, 1000000.0, delta = 0.01)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/geographiclib-1.49/geographiclib.egg-info/PKG-INFO
new/geographiclib-1.50/geographiclib.egg-info/PKG-INFO
--- old/geographiclib-1.49/geographiclib.egg-info/PKG-INFO 1970-01-01
01:00:00.000000000 +0100
+++ new/geographiclib-1.50/geographiclib.egg-info/PKG-INFO 2019-09-24
15:11:22.000000000 +0200
@@ -0,0 +1,27 @@
+Metadata-Version: 2.1
+Name: geographiclib
+Version: 1.50
+Summary: The geodesic routines from GeographicLib
+Home-page: https://geographiclib.sourceforge.io/1.50/python
+Author: Charles Karney
+Author-email: [email protected]
+License: MIT
+Description: This implements
+ [Algorithms for Geodesics](https://doi.org/10.1007/s00190-012-0578-z)
+ (Karney, 2013) for solving the direct and inverse problems for an
+ ellipsoid of revolution.
+
+ Documentation is available at
+ <https://geographiclib.sourceforge.io/1.50/python/>.
+
+Keywords: gis geographical earth distance geodesic
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: Intended Audience :: Science/Research
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Topic :: Scientific/Engineering :: GIS
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Description-Content-Type: text/markdown
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/geographiclib-1.49/geographiclib.egg-info/SOURCES.txt
new/geographiclib-1.50/geographiclib.egg-info/SOURCES.txt
--- old/geographiclib-1.49/geographiclib.egg-info/SOURCES.txt 1970-01-01
01:00:00.000000000 +0100
+++ new/geographiclib-1.50/geographiclib.egg-info/SOURCES.txt 2019-09-24
15:11:22.000000000 +0200
@@ -0,0 +1,17 @@
+MANIFEST.in
+README.md
+setup.py
+geographiclib/__init__.py
+geographiclib/accumulator.py
+geographiclib/constants.py
+geographiclib/geodesic.py
+geographiclib/geodesiccapability.py
+geographiclib/geodesicline.py
+geographiclib/geomath.py
+geographiclib/polygonarea.py
+geographiclib.egg-info/PKG-INFO
+geographiclib.egg-info/SOURCES.txt
+geographiclib.egg-info/dependency_links.txt
+geographiclib.egg-info/top_level.txt
+geographiclib/test/__init__.py
+geographiclib/test/test_geodesic.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/geographiclib-1.49/geographiclib.egg-info/dependency_links.txt
new/geographiclib-1.50/geographiclib.egg-info/dependency_links.txt
--- old/geographiclib-1.49/geographiclib.egg-info/dependency_links.txt
1970-01-01 01:00:00.000000000 +0100
+++ new/geographiclib-1.50/geographiclib.egg-info/dependency_links.txt
2019-09-24 15:11:22.000000000 +0200
@@ -0,0 +1 @@
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/geographiclib-1.49/geographiclib.egg-info/top_level.txt
new/geographiclib-1.50/geographiclib.egg-info/top_level.txt
--- old/geographiclib-1.49/geographiclib.egg-info/top_level.txt 1970-01-01
01:00:00.000000000 +0100
+++ new/geographiclib-1.50/geographiclib.egg-info/top_level.txt 2019-09-24
15:11:22.000000000 +0200
@@ -0,0 +1 @@
+geographiclib
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/geographiclib-1.49/setup.cfg
new/geographiclib-1.50/setup.cfg
--- old/geographiclib-1.49/setup.cfg 1970-01-01 01:00:00.000000000 +0100
+++ new/geographiclib-1.50/setup.cfg 2019-09-24 15:11:22.000000000 +0200
@@ -0,0 +1,4 @@
+[egg_info]
+tag_build =
+tag_date = 0
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/geographiclib-1.49/setup.py
new/geographiclib-1.50/setup.py
--- old/geographiclib-1.49/setup.py 2017-10-05 12:11:24.000000000 +0200
+++ new/geographiclib-1.50/setup.py 2019-09-24 14:55:55.000000000 +0200
@@ -19,49 +19,36 @@
# The initial version of this file was provided by
# Andrew MacIntyre <[email protected]>.
-from distutils.core import setup
-from distutils.cmd import Command
-
-class TestCommand(Command):
- user_options = []
- def initialize_options(self):
- pass
- def finalize_options(self):
- pass
- def run(self):
- import sys, subprocess
- raise SystemExit(subprocess.call([sys.executable,
- '-m',
- 'unittest',
- '-v',
- 'geographiclib.test.test_geodesic'
- ]))
+import setuptools
name = "geographiclib"
-version = "1.49"
+version = "1.50"
+
+with open("README.md", "r") as fh:
+ long_description = fh.read()
-setup(name = name,
- version = version,
- description = "The geodesic routines from GeographicLib",
- long_description = open("README.rst").read(),
- author = "Charles Karney",
- author_email = "[email protected]",
- url = "https://geographiclib.sourceforge.io/" + version + "/python",
- packages = ["geographiclib", "geographiclib/test"],
- data_files = [],
- license = "MIT",
- keywords = "gis geographical earth distance geodesic",
- classifiers = [
- "Development Status :: 5 - Production/Stable",
- "Intended Audience :: Developers",
- "Intended Audience :: Science/Research",
- "License :: OSI Approved :: MIT License",
- "Operating System :: OS Independent",
- "Programming Language :: Python",
- "Topic :: Scientific/Engineering :: GIS",
- "Topic :: Software Development :: Libraries :: Python Modules",
- ],
- cmdclass={
- 'test': TestCommand,
- },
+setuptools.setup(
+ name = name,
+ version = version,
+ author = "Charles Karney",
+ author_email = "[email protected]",
+ description = "The geodesic routines from GeographicLib",
+ long_description = long_description,
+ long_description_content_type = "text/markdown",
+ url = "https://geographiclib.sourceforge.io/" + version + "/python",
+ include_package_data = True,
+ packages = setuptools.find_packages(),
+ license = "MIT",
+ keywords = "gis geographical earth distance geodesic",
+ classifiers = [
+ "Development Status :: 5 - Production/Stable",
+ "Intended Audience :: Developers",
+ "Intended Audience :: Science/Research",
+ "License :: OSI Approved :: MIT License",
+ "Operating System :: OS Independent",
+ "Programming Language :: Python",
+ "Topic :: Scientific/Engineering :: GIS",
+ "Topic :: Software Development :: Libraries :: Python Modules",
+ ],
+ test_suite = "geographiclib.test.test_geodesic",
)