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",
 )

Reply via email to