pygeodesy 24.7.7__py2.py3-none-any.whl → 24.8.4__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {PyGeodesy-24.7.7.dist-info → PyGeodesy-24.8.4.dist-info}/METADATA +28 -26
- {PyGeodesy-24.7.7.dist-info → PyGeodesy-24.8.4.dist-info}/RECORD +39 -39
- pygeodesy/__init__.py +50 -51
- pygeodesy/auxilats/auxAngle.py +5 -5
- pygeodesy/auxilats/auxDST.py +9 -10
- pygeodesy/auxilats/auxily.py +2 -2
- pygeodesy/azimuthal.py +4 -4
- pygeodesy/cartesianBase.py +6 -7
- pygeodesy/css.py +5 -5
- pygeodesy/ecef.py +7 -9
- pygeodesy/ellipsoids.py +12 -12
- pygeodesy/formy.py +2 -2
- pygeodesy/fsums.py +12 -6
- pygeodesy/gars.py +59 -52
- pygeodesy/geodesici.py +232 -137
- pygeodesy/geodesicw.py +70 -45
- pygeodesy/geodesicx/gx.py +8 -8
- pygeodesy/geodesicx/gxline.py +5 -5
- pygeodesy/geodsolve.py +12 -3
- pygeodesy/geohash.py +484 -267
- pygeodesy/geoids.py +13 -11
- pygeodesy/heights.py +30 -40
- pygeodesy/internals.py +19 -6
- pygeodesy/karney.py +85 -79
- pygeodesy/ktm.py +2 -5
- pygeodesy/latlonBase.py +5 -6
- pygeodesy/lazily.py +21 -19
- pygeodesy/ltp.py +6 -6
- pygeodesy/ltpTuples.py +6 -6
- pygeodesy/named.py +3 -3
- pygeodesy/nvectorBase.py +4 -5
- pygeodesy/props.py +75 -17
- pygeodesy/rhumb/solve.py +2 -2
- pygeodesy/solveBase.py +26 -12
- pygeodesy/triaxials.py +6 -7
- pygeodesy/units.py +34 -17
- pygeodesy/wgrs.py +93 -83
- {PyGeodesy-24.7.7.dist-info → PyGeodesy-24.8.4.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.7.7.dist-info → PyGeodesy-24.8.4.dist-info}/top_level.txt +0 -0
pygeodesy/geodesici.py
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
|
-
u'''Classes L{Intersectool} and L{Intersector}
|
|
5
|
-
U{Intersect<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1Intersect.html>}
|
|
6
|
-
to find the intersections of two geodesic lines or line segments.
|
|
4
|
+
u'''Classes L{Intersectool} and L{Intersector} to find the intersections of two geodesic lines or line segments.
|
|
7
5
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
L{XDict} instances with 4 or more items. Adjacent methods C{All5}, C{Closest5}, C{Next5} and
|
|
11
|
-
C{Segment} return or yield L{Intersectool5Tuple} or L{Intersector5Tuple}s with the lat-, longitude
|
|
12
|
-
azimuth of each intersection as an extended or C{Position}-like L{GDict}.
|
|
6
|
+
Class L{Intersector} is a pure Python version of I{Karney}'s C++ class U{Intersect
|
|
7
|
+
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1Intersect.html>}.
|
|
13
8
|
|
|
14
9
|
Class L{Intersectool} is a wrapper to invoke I{Karney}'s U{IntersectTool
|
|
15
|
-
<https://GeographicLib.SourceForge.io/C++/doc/IntersectTool.1.html>} utility
|
|
16
|
-
|
|
10
|
+
<https://GeographicLib.SourceForge.io/C++/doc/IntersectTool.1.html>} utility, but intended I{for testing purposes only}.
|
|
11
|
+
|
|
12
|
+
Set env variable C{PYGEODESY_INTERSECTTOOL} to the (fully qualified) path of the C{IntersectTool} executable. For usage
|
|
13
|
+
and some examples run C{"env PYGEODESY_INTERSECTTOOL=<IntersectTool-path> python3 -m pygeodesy.geodesici --help"}.
|
|
17
14
|
|
|
18
|
-
|
|
15
|
+
Both L{Intersectool} and L{Intersector} provide methods C{All}, C{Closest}, C{Next} and C{Segment} and produce
|
|
16
|
+
L{XDict} instances with 4 or more items. Adjacent methods C{All5}, C{Closest5}, C{Next5} and C{Segment} return
|
|
17
|
+
or yield L{Intersectool5Tuple} or L{Intersector5Tuple}s with the lat-, longitude and azimuth of each intersection
|
|
18
|
+
as an extended, geodesic C{Position}-like L{GDict} instance.
|
|
19
19
|
|
|
20
20
|
For more details, see the C++ U{GeographicLib<https://GeographicLib.SourceForge.io/C++/doc/index.html>}
|
|
21
21
|
documentation, I{Charles F.F. Karney}'s paper U{Geodesics intersections<https://arxiv.org/abs/2308.00495>}
|
|
@@ -32,36 +32,38 @@ from pygeodesy.constants import EPS, INF, INT0, PI, PI2, PI_4, \
|
|
|
32
32
|
_90_0, isfinite
|
|
33
33
|
from pygeodesy.ellipsoids import _EWGS84, Fmt, unstr
|
|
34
34
|
from pygeodesy.errors import GeodesicError, IntersectionError, _an, \
|
|
35
|
-
_xgeodesics, _xkwds_get, _xkwds_kwds
|
|
35
|
+
_xgeodesics, _xkwds_get, _xkwds_kwds, \
|
|
36
|
+
_xkwds_pop2
|
|
36
37
|
# from pygeodesy.errors import exception_chaining # _MODS
|
|
37
38
|
from pygeodesy.fmath import euclid, fdot
|
|
38
39
|
from pygeodesy.fsums import Fsum, fsum1_, _ceil
|
|
39
40
|
from pygeodesy.interns import NN, _A_, _B_, _c_, _COMMASPACE_, \
|
|
40
41
|
_HASH_, _M_, _not_, _SPACE_, _too_
|
|
41
|
-
from pygeodesy.interns import _m_ # PYCHOK used!
|
|
42
42
|
from pygeodesy.karney import Caps, _diff182, GDict, _sincos2de
|
|
43
|
-
from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS, \
|
|
43
|
+
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS, \
|
|
44
44
|
_getenv, _PYGEODESY_INTERSECTTOOL_
|
|
45
45
|
from pygeodesy.named import ADict, _NamedBase, _NamedTuple, _Pass
|
|
46
|
+
# from pygeodesy.namedTuples import _LL4Tuple # _MODS
|
|
46
47
|
from pygeodesy.props import deprecated_method, Property, \
|
|
47
|
-
Property_RO, property_RO
|
|
48
|
+
Property_RO, property_RO, property_ROver
|
|
48
49
|
from pygeodesy.solveBase import _SolveCapsBase, pairs
|
|
49
50
|
# from pygeodesy.streprs import pairs # from .solveBase
|
|
50
51
|
# from pygeodesy.streprs import Fmt, unstr # from .ellipsoids
|
|
51
|
-
from pygeodesy.units import Degrees, Float, Int,
|
|
52
|
-
|
|
52
|
+
from pygeodesy.units import Azimuth as Azi, Degrees, Float, Int, \
|
|
53
|
+
_isDegrees, Lat, Lon, Meter, Meter_
|
|
53
54
|
from pygeodesy.utily import sincos2, atan2, fabs, radians
|
|
54
55
|
|
|
55
56
|
# from math import atan2, ceil as _ceil, fabs, radians # .fsums, .utily
|
|
56
57
|
|
|
57
58
|
__all__ = _ALL_LAZY.geodesici
|
|
58
|
-
__version__ = '24.07.
|
|
59
|
+
__version__ = '24.07.25'
|
|
59
60
|
|
|
60
61
|
_0t = 0, # int
|
|
61
62
|
_1_1t = -1, +1
|
|
62
63
|
_1_0_1t = -1, 0, +1
|
|
64
|
+
_aAB_ = 'aAB'
|
|
63
65
|
_c__ = '-c' # PYCHOK used!
|
|
64
|
-
|
|
66
|
+
_cWGS84 = _EWGS84.a * PI2 # outer circumference
|
|
65
67
|
_EPS3 = EPS * _3_0
|
|
66
68
|
_EPSr5 = pow(EPS, 0.2) # PYCHOK used! 7.4e-4 or ~3"
|
|
67
69
|
_i__ = '-i' # PYCHOK used!
|
|
@@ -75,12 +77,6 @@ _sX0_ = 'sX0'
|
|
|
75
77
|
_TRIPS = 128
|
|
76
78
|
|
|
77
79
|
|
|
78
|
-
class Azi(Degrees):
|
|
79
|
-
'''(INTERNAL) Azimuth C{Unit}.
|
|
80
|
-
'''
|
|
81
|
-
pass
|
|
82
|
-
|
|
83
|
-
|
|
84
80
|
class XDict(ADict):
|
|
85
81
|
'''4+Item result from L{Intersectool} and L{Intersector} methods
|
|
86
82
|
C{All}, C{Closest}, C{Next} and C{Segment} with the intersection
|
|
@@ -92,9 +88,14 @@ class XDict(ADict):
|
|
|
92
88
|
line C{glA} respectively C{glB}, but C{sX0} is the I{L1-distance}
|
|
93
89
|
between the intersection and the I{origin} C{X0}.
|
|
94
90
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
91
|
+
If present, distance C{sAB} and angular distance C{aAB} represent
|
|
92
|
+
the difference between the intersection point on geodesic lines
|
|
93
|
+
C{glA} and C{glB} in C{meter} respectively C{degrees}, typically
|
|
94
|
+
below C{5e-9 meter} or C{5 nm} and C{5e-14 degrees} or C{1 n"}.
|
|
95
|
+
|
|
96
|
+
For segments, indicators C{kA} and C{kB} are C{0} if the segments
|
|
97
|
+
intersect or C{-1} or C{+1} if the intersection is I{before} the
|
|
98
|
+
start, respectively I{after} the end of the segment, similar to
|
|
98
99
|
L{Intersection3Tuple<Intersection3Tuple>}. Segment indicator
|
|
99
100
|
C{k} is I{Karney}'s C{segmode}, equal C{kA * 3 + kB}.
|
|
100
101
|
'''
|
|
@@ -266,6 +267,10 @@ class _IntersectBase(_NamedBase):
|
|
|
266
267
|
|
|
267
268
|
equatoradius = a # = Requatorial
|
|
268
269
|
|
|
270
|
+
def All(self, glA, glB, **kwds): # PYCHOK no cover
|
|
271
|
+
'''(INTERNAL) I{Must be overloaded}.'''
|
|
272
|
+
self._notOverloaded(glA, glB, **kwds)
|
|
273
|
+
|
|
269
274
|
@Property_RO
|
|
270
275
|
def _cHalf(self): # normalizer, semi-circumference
|
|
271
276
|
return self.R * PI # ~20K Km WGS84
|
|
@@ -300,12 +305,109 @@ class _IntersectBase(_NamedBase):
|
|
|
300
305
|
'''
|
|
301
306
|
return self._g
|
|
302
307
|
|
|
308
|
+
def _illz2G(self, G, il):
|
|
309
|
+
'''(INTERNAL) Set C{InverseLine} 1-/2-attrs into C{G}, a C{GDict}.
|
|
310
|
+
'''
|
|
311
|
+
try:
|
|
312
|
+
G.set_(lat1=il.lat1, lon1=il.lon1, azi1=il.azi1, a12=il.a13, # .Arc()
|
|
313
|
+
lat2=il.lat2, lon2=il.lon2, azi2=il.azi2, s12=il.s13) # .Distance()
|
|
314
|
+
except AttributeError:
|
|
315
|
+
r = il.Position(il.s13, outmask=Caps._STD_LINE) # isfinite(il.s13)
|
|
316
|
+
G.set_(**r)
|
|
317
|
+
# for n, v in r.items():
|
|
318
|
+
# if not hasattr(il, n):
|
|
319
|
+
# setattr(il, n, v)
|
|
320
|
+
return G
|
|
321
|
+
|
|
322
|
+
def intersect7(self, start1, end1, start2, end2, X0=_X000, aMaX0=0, sMaX0=_cWGS84,
|
|
323
|
+
**LatLon_and_kwds):
|
|
324
|
+
'''Yield the intersection points of two lines, each defined by two (ellipsoidal)
|
|
325
|
+
points or by an (ellipsoidal) start point and an azimuth from North.
|
|
326
|
+
|
|
327
|
+
@arg start1: Start point of the first line (C{LatLon}).
|
|
328
|
+
@arg end1: End point of the first line (C{LatLon}) or the azimuth at the
|
|
329
|
+
B{C{start1}} point (compass C{degrees360}).
|
|
330
|
+
@arg start2: Start point of the second line (C{LatLon}).
|
|
331
|
+
@arg end2: End point of the second line (C{LatLon}) or the azimuth at the
|
|
332
|
+
B{C{start2}} point (compass C{degrees360}).
|
|
333
|
+
@kwarg X0: Optional I{origin} for I{L1-distances} (L{XDict}) or C{None} for
|
|
334
|
+
the L{Middle<Intersector.Middle>}, otherwise C{XDiff_(0, 0)}.
|
|
335
|
+
@kwarg aMaX0: Upper limit for the I{angular L1-distance}
|
|
336
|
+
(C{degrees}) or C{None} or C{0} for unlimited.
|
|
337
|
+
@kwarg sMaX0_C: Optional, upper limit C{B{sMaX0}=2*PI*R} for the
|
|
338
|
+
I{L1-distance} to B{C{X0}} (C{meter}).
|
|
339
|
+
@kwarg LatLon_and_kwds: Optional class C{B{LatLon}=None} to return intersection
|
|
340
|
+
points and optional, additional B{C{LatLon}} keyword arguments.
|
|
341
|
+
|
|
342
|
+
@note: The C{lat} and C{lon} attr of B{C{start1}}, B{C{end1}}, B{C{start2}} and
|
|
343
|
+
B{C{end2}} are used I{verbatim}, ignoring C{datum} or C{ellipsoid}.
|
|
344
|
+
|
|
345
|
+
@return: Yield an L{Intersect7Tuple}C{(A, B, sAB, aAB, c, kA, kB)} for every
|
|
346
|
+
intersection found, with C{A} and C{B} each a B{C{LatLon}} or if
|
|
347
|
+
C{B{LatLon} is None} or not specified, a L{LatLon4Tuple}C{(lat, lon,
|
|
348
|
+
height, datum)} with C{height 0} and this C{datum}.
|
|
349
|
+
|
|
350
|
+
@raise GeodesicError: Invalid B{C{start1}}, B{C{end1}}, B{C{start2}} or
|
|
351
|
+
B{C{end2}} or B{C{end1}} and B{C{end2}} differ in type.
|
|
352
|
+
|
|
353
|
+
@raise IntersectionError: No convergence.
|
|
354
|
+
'''
|
|
355
|
+
|
|
356
|
+
def _args(s, e):
|
|
357
|
+
t = (e,) if _isDegrees(e) else (e.lat, e.lon)
|
|
358
|
+
return (s.lat, s.lon) + t
|
|
359
|
+
|
|
360
|
+
try:
|
|
361
|
+
glA = self.Line(*_args(start1, end1))
|
|
362
|
+
glB = self.Line(*_args(start2, end2))
|
|
363
|
+
except Exception as x:
|
|
364
|
+
raise GeodesicError(start1=start1, end1=end1, start2=start2, end2=end2, cause=x)
|
|
365
|
+
|
|
366
|
+
LL, kwds = _xkwds_pop2(LatLon_and_kwds, LatLon=None)
|
|
367
|
+
d, kwds = _xkwds_pop2(kwds, datum=self.datum)
|
|
368
|
+
h, kwds = _xkwds_pop2(kwds, height=0)
|
|
369
|
+
|
|
370
|
+
_LL4T = _MODS.namedTuples._LL4Tuple
|
|
371
|
+
for X in self.All(glA, glB, X0=X0, aMaX0=aMaX0, sMaX0=sMaX0, _C=True):
|
|
372
|
+
A = B = _LL4T(X.latA, X.lonA, h, d, LL, kwds, iteration=X.iteration)
|
|
373
|
+
if X.sAB or X.latA != X.latB or X.lonA != X.lonB:
|
|
374
|
+
B = _LL4T(X.latB, X.lonB, h, d, LL, kwds, iteration=X.iteration)
|
|
375
|
+
yield Intersect7Tuple(A, B, X.sAB, X.aAB, X.c, _xkwds_get(X, kA=0),
|
|
376
|
+
_xkwds_get(X, kB=0))
|
|
377
|
+
|
|
303
378
|
def _Inversa12(self, A, B=None):
|
|
304
379
|
lls = (0, 0, A, 0) if B is None else (A.lat2, A.lon2,
|
|
305
380
|
B.lat2, B.lon2)
|
|
306
381
|
r = self._g.Inverse(*lls, outmask=Caps.DISTANCE)
|
|
307
382
|
return r.s12, r.a12 # .a12 always in r
|
|
308
383
|
|
|
384
|
+
def k2kAkB(self, k):
|
|
385
|
+
'''Unravel C{k} into C{kA} and C{kB}.
|
|
386
|
+
|
|
387
|
+
@arg k: Segment indicator C{kA * 3 + kB} (C{int}).
|
|
388
|
+
|
|
389
|
+
@return: An C{ADict(k=k, kA=kA, kB=kB)}.
|
|
390
|
+
|
|
391
|
+
@raise GeodesicError: Invalid B{C{k}}.
|
|
392
|
+
'''
|
|
393
|
+
for kA in range(-1, 2):
|
|
394
|
+
for kB in range(-1, 2):
|
|
395
|
+
if (kA * 3 + kB) == k:
|
|
396
|
+
return ADict(k=k, kA=kA, kB=kB)
|
|
397
|
+
raise GeodesicError(k=k)
|
|
398
|
+
|
|
399
|
+
# def k2kAkB(self, k):
|
|
400
|
+
# # unravel C{k} into C{kA} and C{kB}.
|
|
401
|
+
# kA, kB = divmod(k, 3)
|
|
402
|
+
# if kB > 1:
|
|
403
|
+
# kA += 1
|
|
404
|
+
# kB -= 3
|
|
405
|
+
# return kA, kB
|
|
406
|
+
|
|
407
|
+
def Line(self, lat1, lon1, azi1_lat2, *lon2, **name): # PYCHOK no cover
|
|
408
|
+
'''(INTERNAL) I{Must be overloaded}.'''
|
|
409
|
+
self._notOverloaded(lat1, lon1, azi1_lat2, *lon2, **name)
|
|
410
|
+
|
|
309
411
|
def _ll3z4ll(self, lat1, lon1, azi1_lat2, *lon2):
|
|
310
412
|
t = Lat(lat1=lat1), Lon(lon1=lon1)
|
|
311
413
|
if lon2: # get azis for All, keep lat-/lons
|
|
@@ -315,8 +417,8 @@ class _IntersectBase(_NamedBase):
|
|
|
315
417
|
return t
|
|
316
418
|
|
|
317
419
|
@deprecated_method
|
|
318
|
-
def Next5s(self, glA, glB, X0=_X000, aMax=1801, sMax=0, **unused):
|
|
319
|
-
'''DEPRECATED on 2024.07.02, use method
|
|
420
|
+
def Next5s(self, glA, glB, X0=_X000, aMax=1801, sMax=0, **unused): # PYCHOK no cover
|
|
421
|
+
'''DEPRECATED on 2024.07.02, use method C{All5}.'''
|
|
320
422
|
return self.All5(glA, glB, X0=X0, aMaX0=aMax, sMaX0=sMax) # PYCHOK attr
|
|
321
423
|
|
|
322
424
|
@Property_RO
|
|
@@ -325,17 +427,17 @@ class _IntersectBase(_NamedBase):
|
|
|
325
427
|
'''
|
|
326
428
|
return self.ellipsoid.R2
|
|
327
429
|
|
|
328
|
-
def _sMaX0_C2(self, aMaX0, **sMaX0_C):
|
|
430
|
+
def _sMaX0_C2(self, aMaX0=0, **sMaX0_C):
|
|
329
431
|
_g = _xkwds_get
|
|
330
432
|
s = _g(sMaX0_C, sMaX0=self._cMax)
|
|
331
433
|
s = _g(sMaX0_C, sMax=s) # for backward ...
|
|
332
434
|
a = _g(sMaX0_C, aMax=aMaX0) # ... compatibility
|
|
333
435
|
if a: # degrees to meter, approx.
|
|
334
|
-
s =
|
|
436
|
+
s = min(s, self.R * radians(a)) # ellipsoid.degrees2m(a)
|
|
335
437
|
s = _g(sMaX0_C, _R=s)
|
|
336
438
|
if s < _EPS3:
|
|
337
439
|
s = _EPS3 # raise GeodesicError(sMaX0=s)
|
|
338
|
-
return s,
|
|
440
|
+
return s, _g(sMaX0_C, _C=False)
|
|
339
441
|
|
|
340
442
|
def _xNext(self, glA, glB, eps1, **eps_C): # PYCHOK no cover
|
|
341
443
|
eps1 = _xkwds_get(eps_C, eps=eps1) # eps for backward compatibility
|
|
@@ -343,7 +445,7 @@ class _IntersectBase(_NamedBase):
|
|
|
343
445
|
a = glA.lat1 - glB.lat1
|
|
344
446
|
b = glA.lon1 - glB.lon1
|
|
345
447
|
if euclid(a, b) > eps1:
|
|
346
|
-
raise GeodesicError(
|
|
448
|
+
raise GeodesicError(lat_=a, lon_=b, eps1=eps1)
|
|
347
449
|
return _xkwds_kwds(eps_C, _C=False)
|
|
348
450
|
|
|
349
451
|
|
|
@@ -358,10 +460,15 @@ class Intersectool(_IntersectBase, _SolveCapsBase):
|
|
|
358
460
|
@note: This C{Intersectool} is intended I{for testing purposes only}, it invokes
|
|
359
461
|
the C{IntersectTool} executable for I{every} method call.
|
|
360
462
|
'''
|
|
463
|
+
_c_alt = _c__, # Closest latA lonA aziA latB lonB aziB
|
|
464
|
+
_C_option = '-C',
|
|
361
465
|
_Error = GeodesicError
|
|
466
|
+
_i_alt = _i__, # Segment latA1 lonA1 latA2 lonA2 latB1 lonB1 latB2 lonB2
|
|
362
467
|
_linelimit = 1200 # line printer width X 10
|
|
468
|
+
_n_alt = _n__, # Next latA lonA aziA aziB
|
|
363
469
|
_Names_ABs = _latA_, _lonA_, 'latB', 'lonB', _sAB_ # -C to stderr
|
|
364
470
|
_Names_XDict = 'sA', 'sB', _c_ # plus 'k' from -i or 'sX0' from -R
|
|
471
|
+
_o_alt = _o__, # Offset latA lonA aziA latB lonB aziB x0 y0
|
|
365
472
|
_Xable_name = 'IntersectTool'
|
|
366
473
|
_Xable_path = _getenv(_PYGEODESY_INTERSECTTOOL_, _PYGEODESY_INTERSECTTOOL_)
|
|
367
474
|
|
|
@@ -386,7 +493,7 @@ class Intersectool(_IntersectBase, _SolveCapsBase):
|
|
|
386
493
|
self._GeodesicExact(a_geodesic, f))
|
|
387
494
|
_IntersectBase.__init__(self, g, **name)
|
|
388
495
|
|
|
389
|
-
def All(self, glA, glB, X0=_X000, eps1=_0_0, aMaX0=0, **sMaX0_C):
|
|
496
|
+
def All(self, glA, glB, X0=_X000, eps1=_0_0, aMaX0=0, **sMaX0_C): # PYCHOK signature
|
|
390
497
|
'''Yield all intersection of two geodesic lines up to a limit.
|
|
391
498
|
|
|
392
499
|
@kwarg eps1: Optional margin for the L{euclid<pygeodesy.euclid>}ean distance
|
|
@@ -396,6 +503,12 @@ class Intersectool(_IntersectBase, _SolveCapsBase):
|
|
|
396
503
|
|
|
397
504
|
@return: An L{XDict} for each intersection.
|
|
398
505
|
'''
|
|
506
|
+
for X, _ in self._All2(glA, glB, X0, eps1, aMaX0=aMaX0, **sMaX0_C):
|
|
507
|
+
yield X
|
|
508
|
+
|
|
509
|
+
def _All2(self, glA, glB, X0, eps1, **aMaX0_sMaX0_C): # MCCABE 13
|
|
510
|
+
'''(INTERNAL) Helper for methods C{.All} and C{.All5}.
|
|
511
|
+
'''
|
|
399
512
|
def _xz2(**gl):
|
|
400
513
|
try:
|
|
401
514
|
n, gl = gl.popitem() # _xkwds_item2(gl)
|
|
@@ -423,22 +536,24 @@ class Intersectool(_IntersectBase, _SolveCapsBase):
|
|
|
423
536
|
_x = self._o_alt
|
|
424
537
|
b += X0.sA, X0.sB
|
|
425
538
|
|
|
426
|
-
sMaX0, _C = self._sMaX0_C2(
|
|
539
|
+
sMaX0, _C = self._sMaX0_C2(**aMaX0_sMaX0_C)
|
|
427
540
|
for X in self._XDictInvoke(_x, _sX0_, (A + a + B + b),
|
|
428
|
-
_R=sMaX0
|
|
429
|
-
|
|
541
|
+
_C=_C, _R=sMaX0):
|
|
542
|
+
if _C:
|
|
543
|
+
T = self._In5T(glA, glB, X, X)
|
|
544
|
+
if _aAB_ not in X:
|
|
545
|
+
X.set_(sAB=T.sAB, aAB=T.aAB)
|
|
546
|
+
else:
|
|
547
|
+
T = None
|
|
548
|
+
yield X.set_(c=int(X.c)), T
|
|
430
549
|
|
|
431
550
|
def All5(self, glA, glB, X0=_X000, **aMaX0_sMaX0):
|
|
432
551
|
'''Yield all intersection of two geodesic lines up to a limit.
|
|
433
552
|
|
|
434
553
|
@return: An L{Intersectool5Tuple} for each intersection.
|
|
435
554
|
'''
|
|
436
|
-
for
|
|
437
|
-
yield
|
|
438
|
-
|
|
439
|
-
@Property_RO
|
|
440
|
-
def _C_option(self):
|
|
441
|
-
return (_C__,)
|
|
555
|
+
for _, T in self._All2(glA, glB, X0, _0_0, _C=True, **aMaX0_sMaX0):
|
|
556
|
+
yield T
|
|
442
557
|
|
|
443
558
|
@Property_RO
|
|
444
559
|
def _cmdBasic(self):
|
|
@@ -448,12 +563,6 @@ class Intersectool(_IntersectBase, _SolveCapsBase):
|
|
|
448
563
|
self._E_option +
|
|
449
564
|
self._p_option)
|
|
450
565
|
|
|
451
|
-
@Property_RO
|
|
452
|
-
def _c_alt(self):
|
|
453
|
-
'''(INTERNAL) Get the C{Closest} format (C{tuple}).
|
|
454
|
-
'''
|
|
455
|
-
return _c__, # latA lonA aziA latB lonB aziB
|
|
456
|
-
|
|
457
566
|
def Closest(self, glA, glB, X0=_X000, _C=False):
|
|
458
567
|
'''Find the closest intersection of two geodesic lines.
|
|
459
568
|
|
|
@@ -478,18 +587,11 @@ class Intersectool(_IntersectBase, _SolveCapsBase):
|
|
|
478
587
|
X = self.Closest(glA, glB, _C=True)
|
|
479
588
|
return self._In5T(glA, glB, X, X)
|
|
480
589
|
|
|
481
|
-
@
|
|
590
|
+
@property_ROver
|
|
482
591
|
def _GeodesicExact(self):
|
|
483
592
|
'''Get the I{class} L{GeodesicExact}, I{once}.
|
|
484
593
|
'''
|
|
485
|
-
|
|
486
|
-
return G
|
|
487
|
-
|
|
488
|
-
@Property_RO
|
|
489
|
-
def _i_alt(self):
|
|
490
|
-
'''(INTERNAL) Get the C{Segment} format (C{tuple}).
|
|
491
|
-
'''
|
|
492
|
-
return _i__, # latA1 lonA1 latA2 lonA2 latB1 lonB1 latB2 lonB2
|
|
594
|
+
return _MODS.geodesicx.GeodesicExact # overwrite property_ROver
|
|
493
595
|
|
|
494
596
|
def _In5T(self, glA, glB, S, X, k2=False, **_2X):
|
|
495
597
|
A = GDict(glA).set_(lat2=X.latA, lon2=X.lonA, s12=S.sA)
|
|
@@ -523,7 +625,7 @@ class Intersectool(_IntersectBase, _SolveCapsBase):
|
|
|
523
625
|
|
|
524
626
|
def Line(self, lat1, lon1, azi1_lat2, *lon2, **name):
|
|
525
627
|
'''Return a geodesic line from this C{Intersector}'s geodesic, specified by
|
|
526
|
-
two (goedetic) points or a (goedetic) point and an (
|
|
628
|
+
two (goedetic) points or a (goedetic) point and an (forward) azimuth.
|
|
527
629
|
|
|
528
630
|
@return: A 3- or 6-item, named L{GDict}.
|
|
529
631
|
'''
|
|
@@ -562,7 +664,7 @@ class Intersectool(_IntersectBase, _SolveCapsBase):
|
|
|
562
664
|
|
|
563
665
|
sA, mA, iA, A = _smi4(glA=glA)
|
|
564
666
|
sB, mB, iB, B = _smi4(glB=glB)
|
|
565
|
-
X = XDict_(mA, mB) #
|
|
667
|
+
X = XDict_(mA, mB) # centers
|
|
566
668
|
_ = X._outSide(sA, sB)
|
|
567
669
|
if _C: # _Names_ABs
|
|
568
670
|
s, a = self._Inversa12(A, B)
|
|
@@ -577,13 +679,8 @@ class Intersectool(_IntersectBase, _SolveCapsBase):
|
|
|
577
679
|
'''
|
|
578
680
|
X, A, iA, B, iB = self._middle5(glA, glB, _C=True)
|
|
579
681
|
A, B, s, a, c = self._In5T(A, B, X, X, _2X=_M_)
|
|
580
|
-
return Middle5Tuple(
|
|
581
|
-
|
|
582
|
-
@Property_RO
|
|
583
|
-
def _n_alt(self):
|
|
584
|
-
'''(INTERNAL) Get the C{Next} format (C{tuple}).
|
|
585
|
-
'''
|
|
586
|
-
return _n__, # latA lonA aziA aziB
|
|
682
|
+
return Middle5Tuple(self._illz2G(A, iA),
|
|
683
|
+
self._illz2G(B, iB), s, a, c)
|
|
587
684
|
|
|
588
685
|
def Next(self, glA, glB, eps1=None, **_C): # PYCHOK no cover
|
|
589
686
|
'''Find the next intersection of two I{intersecting} geodesic lines.
|
|
@@ -606,12 +703,6 @@ class Intersectool(_IntersectBase, _SolveCapsBase):
|
|
|
606
703
|
X = self.Next(glA, glB, _C=True, **eps1)
|
|
607
704
|
return self._In5T(glA, glB, X, X)
|
|
608
705
|
|
|
609
|
-
@Property_RO
|
|
610
|
-
def _o_alt(self):
|
|
611
|
-
'''(INTERNAL) Get the C{Offset} format (C{tuple}).
|
|
612
|
-
'''
|
|
613
|
-
return _o__, # latA lonA aziA latB lonB aziB x0 y0
|
|
614
|
-
|
|
615
706
|
def _R_option(self, _R=None):
|
|
616
707
|
'''(INTERNAL) Get the C{-R maxdist} option.
|
|
617
708
|
'''
|
|
@@ -624,16 +715,15 @@ class Intersectool(_IntersectBase, _SolveCapsBase):
|
|
|
624
715
|
|
|
625
716
|
@return: An L{XDict}.
|
|
626
717
|
'''
|
|
627
|
-
X
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
raise GeodesicError(k=k, glA=glA, glB=glB, txt=repr(X))
|
|
718
|
+
X = self._XDictInvoke(self._i_alt, 'k',
|
|
719
|
+
(glA.lat1, glA.lon1, glA.lat2, glA.lon2,
|
|
720
|
+
glB.lat1, glB.lon1, glB.lat2, glB.lon2),
|
|
721
|
+
_C=_xkwds_get(_C_unused, _C=False)) # _R=None
|
|
722
|
+
try:
|
|
723
|
+
ks = self.k2kAkB(int(X.k))
|
|
724
|
+
except Exception as x:
|
|
725
|
+
raise GeodesicError(glA=glA, glB=glB, X=str(X), cause=x)
|
|
726
|
+
return X.set_(**ks)
|
|
637
727
|
|
|
638
728
|
def Segment5(self, glA, glB, **unused):
|
|
639
729
|
'''Find the next intersection of two I{intersecting} geodesic lines.
|
|
@@ -676,7 +766,7 @@ class Intersectool(_IntersectBase, _SolveCapsBase):
|
|
|
676
766
|
Names += self._Names_ABs
|
|
677
767
|
if _R:
|
|
678
768
|
cmd += self._R_option(**_R)
|
|
679
|
-
X, _R = self._DictInvoke2(cmd + alt, Names, XDict,
|
|
769
|
+
X, _R = self._DictInvoke2(cmd + alt, args, Names, XDict, **_R)
|
|
680
770
|
return X if _R else X.set_(c=int(X.c)) # generator or XDict
|
|
681
771
|
|
|
682
772
|
|
|
@@ -689,10 +779,6 @@ class Intersector(_IntersectBase):
|
|
|
689
779
|
@see: I{Karney}'s C++ class U{Intersect<https://GeographicLib.sourceforge.io/
|
|
690
780
|
C++/doc/classGeographicLib_1_1Intersect.html#details>} for more details.
|
|
691
781
|
'''
|
|
692
|
-
# _D1 = 0
|
|
693
|
-
# _D2 = 0
|
|
694
|
-
# _T1 = 0
|
|
695
|
-
# _T5 = 0
|
|
696
782
|
|
|
697
783
|
def __init__(self, geodesic, **name):
|
|
698
784
|
'''New L{Intersector}.
|
|
@@ -812,7 +898,7 @@ class Intersector(_IntersectBase):
|
|
|
812
898
|
for X in X_[a:]: # addended Xs
|
|
813
899
|
X._skip(S_, T2d3D)
|
|
814
900
|
|
|
815
|
-
return X_.sorter(sMaX0, self._C, glA, glB,
|
|
901
|
+
return X_.sorter(sMaX0, self._C, glA, glB, _C=_C) # generator
|
|
816
902
|
|
|
817
903
|
def All5(self, glA, glB, X0=_X000, **aMaX0_sMaX0_C):
|
|
818
904
|
'''Yield all intersection of two geodesic lines up to a limit.
|
|
@@ -838,7 +924,7 @@ class Intersector(_IntersectBase):
|
|
|
838
924
|
|
|
839
925
|
raise IntersectionError(Fmt.no_convergence(S.L1(), self._Tol))
|
|
840
926
|
|
|
841
|
-
def _C(self, X, glA, glB, _C=False,
|
|
927
|
+
def _C(self, X, glA, glB, _C=False, _MM=False):
|
|
842
928
|
# add the C{_C} items to C{X}, if requested.
|
|
843
929
|
if _C:
|
|
844
930
|
A = self._Position(glA, X.sA)
|
|
@@ -846,10 +932,10 @@ class Intersector(_IntersectBase):
|
|
|
846
932
|
s, a = self._Inversa12(A, B)
|
|
847
933
|
X.set_(latA=A.lat2, lonA=A.lon2,
|
|
848
934
|
latB=B.lat2, lonB=B.lon2)
|
|
849
|
-
if
|
|
850
|
-
X.set_(sAB=s, aAB=a)
|
|
851
|
-
else:
|
|
935
|
+
if _MM: # in .Middle5
|
|
852
936
|
X.set_(sMM=s, aMM=a)
|
|
937
|
+
else:
|
|
938
|
+
X.set_(sAB=s, aAB=a)
|
|
853
939
|
return X
|
|
854
940
|
|
|
855
941
|
def Closest(self, glA, glB, X0=_X000, **_C):
|
|
@@ -1032,28 +1118,30 @@ class Intersector(_IntersectBase):
|
|
|
1032
1118
|
Line} or other C{InverseLine}.
|
|
1033
1119
|
'''
|
|
1034
1120
|
M, _, _ = self._middle3(glA, glB, raiser)
|
|
1035
|
-
|
|
1036
|
-
return self._C(M, glA, glB, _AB=False, **_C) if _C else M
|
|
1121
|
+
return self._C(M, glA, glB, **_C) if _C else M
|
|
1037
1122
|
|
|
1038
|
-
def _middle3(self, glA, glB, raiser): # in .All
|
|
1123
|
+
def _middle3(self, glA, glB, raiser): # in .All, .Segment
|
|
1039
1124
|
# return segment length C{sA} and C{sB} and the
|
|
1040
1125
|
# center C{X0} of rectangle [sA, sB]
|
|
1041
|
-
self._xLines(glA, glB, s13=raiser) # need .Distance
|
|
1126
|
+
self._xLines(glA, glB, s13=raiser) # need .Arc, .Distance
|
|
1042
1127
|
sA = glA.Distance()
|
|
1043
1128
|
sB = glB.Distance()
|
|
1044
|
-
X = XDict_(sA * _0_5, sB * _0_5)
|
|
1129
|
+
X = XDict_(sA * _0_5, sB * _0_5)
|
|
1130
|
+
# _ = X._outSide(sA, sB)
|
|
1045
1131
|
return self._Delto(X), sA, sB
|
|
1046
1132
|
|
|
1047
|
-
def Middle5(self, glA, glB,
|
|
1133
|
+
def Middle5(self, glA, glB, raiser=True):
|
|
1048
1134
|
'''Get the mid-points of two geodesic line segments and distances.
|
|
1049
1135
|
|
|
1050
1136
|
@return: A L{Middle5Tuple}C{(A, B, sMM, aMM, c)}.
|
|
1051
1137
|
|
|
1052
1138
|
@see: Method L{Middle} for further details.
|
|
1053
1139
|
'''
|
|
1054
|
-
M = self.
|
|
1140
|
+
M, _, _ = self._middle3(glA, glB, raiser)
|
|
1141
|
+
M = self._C(M, glA, glB, _C=True, _MM=True)
|
|
1055
1142
|
A, B, s, a, c = self._In5T(glA, glB, M, M, _2X=_M_)
|
|
1056
|
-
return Middle5Tuple(
|
|
1143
|
+
return Middle5Tuple(self._illz2G(A, glA),
|
|
1144
|
+
self._illz2G(B, glB), s, a, c)
|
|
1057
1145
|
|
|
1058
1146
|
def _m12_M12_M21(self, gl, s):
|
|
1059
1147
|
P = gl.Position(s, outmask=Caps._REDUCEDLENGTH_GEODESICSCALE)
|
|
@@ -1201,7 +1289,7 @@ class Intersector(_IntersectBase):
|
|
|
1201
1289
|
C{B{proven}=None} to return the first or
|
|
1202
1290
|
C{B{proven}=False} the closest (C{bool}).
|
|
1203
1291
|
@kwarg raiser: If C{True}, check that B{C{glA}} and B{C{glB}}
|
|
1204
|
-
are
|
|
1292
|
+
are a 4-C{args} L{Line<Intersector.Line>} or
|
|
1205
1293
|
C{InverseLine} (C{bool}).
|
|
1206
1294
|
@kwarg _C: If C{True}, include the lat-/longitudes C{latA},
|
|
1207
1295
|
C{lonA}, C{latB}, C{lonB} of and distances C{sAB}
|
|
@@ -1228,7 +1316,7 @@ class Intersector(_IntersectBase):
|
|
|
1228
1316
|
d0 = X0.L1(Q)
|
|
1229
1317
|
if Q._outSide(sA, sB) and d0 <= X0.L1() and not proven:
|
|
1230
1318
|
i = Q.iteration
|
|
1231
|
-
for T in
|
|
1319
|
+
for T in Q._corners(sA, sB, self._T2):
|
|
1232
1320
|
X, i = self._Basic2(glA, glB, T, i)
|
|
1233
1321
|
X = T._fixCoincident(X)
|
|
1234
1322
|
if not X._outSide(sA, sB):
|
|
@@ -1336,6 +1424,19 @@ class Intersector(_IntersectBase):
|
|
|
1336
1424
|
raise GeodesicError(n, gl, cause=x)
|
|
1337
1425
|
|
|
1338
1426
|
|
|
1427
|
+
class Intersect7Tuple(_NamedTuple):
|
|
1428
|
+
'''7-Tuple C{(A, B, sAB, aAB, c, kA, kB)} with C{A} and C{B} each
|
|
1429
|
+
a C{LatLon} or L{LatLon4Tuple}C{(lat, lon, height, datum)} of
|
|
1430
|
+
the intersection on each geodesic line, the distance C{sAB} in
|
|
1431
|
+
in C{meter} and angular distance C{aAB} in C{degrees} between
|
|
1432
|
+
C{A} and C{B}, coincidence indicator C{c} and segment indicators
|
|
1433
|
+
C{kA} and C{kB} all C{int}, see L{XDict} and method U{intersect7
|
|
1434
|
+
<_IntersectBase.intersect7>}.
|
|
1435
|
+
'''
|
|
1436
|
+
_Names_ = (_A_, _B_, _sAB_, _aAB_, _c_, 'kA', 'kB')
|
|
1437
|
+
_Units_ = (_Pass, _Pass, Meter, Degrees, Int, Int, Int)
|
|
1438
|
+
|
|
1439
|
+
|
|
1339
1440
|
class Intersectool5Tuple(_NamedTuple):
|
|
1340
1441
|
'''5-Tuple C{(A, B, sAB, aAB, c)} with C{A} and C{B} the C{Position}
|
|
1341
1442
|
of the intersection on each geodesic line, the distance C{sAB}
|
|
@@ -1349,8 +1450,8 @@ class Intersectool5Tuple(_NamedTuple):
|
|
|
1349
1450
|
C{a1M} in C{degrees} and the segment indicator C{kX}. See
|
|
1350
1451
|
L{XDict} for more details.
|
|
1351
1452
|
'''
|
|
1352
|
-
_Names_ =
|
|
1353
|
-
_Units_ =
|
|
1453
|
+
_Names_ = Intersect7Tuple._Names_[:5]
|
|
1454
|
+
_Units_ = Intersect7Tuple._Units_[:5]
|
|
1354
1455
|
|
|
1355
1456
|
|
|
1356
1457
|
class Intersector5Tuple(Intersectool5Tuple):
|
|
@@ -1421,23 +1522,19 @@ def _L1(a, b):
|
|
|
1421
1522
|
return fabs(a) + fabs(b)
|
|
1422
1523
|
|
|
1423
1524
|
|
|
1424
|
-
|
|
1425
|
-
'''(INTERNAL) Set C{InverseLine} attrs in C{G}, a C{GDict}.
|
|
1426
|
-
'''
|
|
1427
|
-
return G.set_(lat1=gl.lat1, lon1=gl.lon1, azi1=il.azi1, a12=il.a13, # .Arc()
|
|
1428
|
-
lat2=gl.lat2, lon2=gl.lon2, azi2=il.azi2, s12=il.s13) # .Distance()
|
|
1429
|
-
|
|
1525
|
+
__all__ += _ALL_DOCS(_IntersectBase)
|
|
1430
1526
|
|
|
1431
1527
|
if __name__ == '__main__': # MCCABE 14
|
|
1432
1528
|
|
|
1433
1529
|
from pygeodesy import printf
|
|
1530
|
+
__help_ = '--help'
|
|
1434
1531
|
|
|
1435
1532
|
def _main(args):
|
|
1436
1533
|
|
|
1437
1534
|
from pygeodesy import GeodesicExact
|
|
1438
1535
|
from pygeodesy.internals import _plural, _usage
|
|
1439
|
-
from pygeodesy.interns import _COLONSPACE_,
|
|
1440
|
-
|
|
1536
|
+
from pygeodesy.interns import _COLONSPACE_, _DOT_, _EQUAL_, \
|
|
1537
|
+
_i_, _m_, _n_, _version_, _X_
|
|
1441
1538
|
import re
|
|
1442
1539
|
|
|
1443
1540
|
class XY0(Float):
|
|
@@ -1453,13 +1550,12 @@ if __name__ == '__main__': # MCCABE 14
|
|
|
1453
1550
|
alts=((_c_ + llz2),
|
|
1454
1551
|
(_i_ + ll4),
|
|
1455
1552
|
(_m_ + ll4),
|
|
1456
|
-
(_M_ + ll4),
|
|
1457
1553
|
(_n_ + llz + ' aziB'),
|
|
1458
1554
|
('o' + llz2 + ' x0 y0')),
|
|
1459
1555
|
help=_h if isinstance(_h, str) else NN)
|
|
1460
1556
|
|
|
1461
|
-
def _starts(
|
|
1462
|
-
return
|
|
1557
|
+
def _starts(Opt, arg):
|
|
1558
|
+
return arg == Opt[1:3] or (len(arg) > 2 and Opt.startswith(arg))
|
|
1463
1559
|
|
|
1464
1560
|
_isopt = re.compile('^[-]+[a-z]*$', flags=re.IGNORECASE).match
|
|
1465
1561
|
|
|
@@ -1469,38 +1565,37 @@ if __name__ == '__main__': # MCCABE 14
|
|
|
1469
1565
|
|
|
1470
1566
|
while args and _isopt(args[0]):
|
|
1471
1567
|
arg = args.pop(0)
|
|
1472
|
-
if arg ==
|
|
1473
|
-
_C = True
|
|
1474
|
-
elif arg == _c__:
|
|
1568
|
+
if arg == _c__:
|
|
1475
1569
|
M, m = I.Closest, 6 # latA lonA aziA latB lonB aziB
|
|
1476
|
-
elif
|
|
1570
|
+
elif _starts('--Check', arg):
|
|
1571
|
+
_C = True
|
|
1572
|
+
elif _starts(__help_, arg):
|
|
1477
1573
|
_h = args[0] if args and _isopt(args[0]) else True
|
|
1478
1574
|
elif arg == _i__:
|
|
1479
1575
|
M, m = I.Segment, 8 # latA1 lonA1 latA2 lonA2 latB1 lonB1 latB2 lonB2
|
|
1480
1576
|
elif arg == '-m':
|
|
1481
1577
|
M, m = I.Middle, 8 # latA1 lonA1 latA2 lonA2 latB1 lonB1 latB2 lonB2
|
|
1482
|
-
_R = None
|
|
1483
|
-
elif arg == '-M':
|
|
1484
|
-
M, m = I.Middle5, 8 # latA1 lonA1 latA2 lonA2 latB1 lonB1 latB2 lonB2
|
|
1485
|
-
_R = _C = None
|
|
1578
|
+
_R = None # zap -R
|
|
1486
1579
|
elif arg == _n__:
|
|
1487
1580
|
M, m = I.Next, 4 # latA lonA aziA aziB
|
|
1488
1581
|
elif arg == _o__:
|
|
1489
1582
|
M, m = I.Closest, 8 # latA lonA aziA latB lonB aziB x0 y0
|
|
1490
1583
|
elif arg == _R__ and args:
|
|
1491
1584
|
_R = args.pop(0)
|
|
1492
|
-
elif
|
|
1585
|
+
elif _starts('--Tool', arg):
|
|
1493
1586
|
I = Intersectool() # PYCHOK I
|
|
1494
1587
|
if _V:
|
|
1495
1588
|
I.verbose = True
|
|
1496
1589
|
if I.IntersectTool in (_PYGEODESY_INTERSECTTOOL_, None): # not set
|
|
1497
1590
|
I.IntersectTool = '/opt/local/bin/IntersectTool' # '/opt/local/Cellar/geographiclib/2.3/bin/IntersectTool' # HomeBrew
|
|
1591
|
+
elif _V:
|
|
1592
|
+
_ = I.version
|
|
1498
1593
|
M, _T = None, True
|
|
1499
|
-
elif
|
|
1594
|
+
elif _starts('--Verbose', arg):
|
|
1500
1595
|
_V = True
|
|
1501
1596
|
if _T:
|
|
1502
1597
|
I.verbose = True
|
|
1503
|
-
elif
|
|
1598
|
+
elif _starts('--version', arg):
|
|
1504
1599
|
printf(_COLONSPACE_(*((_version_, I.version) if _T else
|
|
1505
1600
|
(__version__, repr(I)))))
|
|
1506
1601
|
else:
|
|
@@ -1508,7 +1603,6 @@ if __name__ == '__main__': # MCCABE 14
|
|
|
1508
1603
|
|
|
1509
1604
|
if _h or M is None:
|
|
1510
1605
|
printf(_usage(__file__, **_opts(_h)), nl=1)
|
|
1511
|
-
# exit(0)
|
|
1512
1606
|
else:
|
|
1513
1607
|
n = len(args)
|
|
1514
1608
|
if n < m:
|
|
@@ -1547,7 +1641,7 @@ if __name__ == '__main__': # MCCABE 14
|
|
|
1547
1641
|
|
|
1548
1642
|
from sys import argv, stderr
|
|
1549
1643
|
try:
|
|
1550
|
-
if len(argv) == 2 and argv[1] ==
|
|
1644
|
+
if len(argv) == 2 and argv[1] == __help_:
|
|
1551
1645
|
from pygeodesy.internals import _usage_argv
|
|
1552
1646
|
|
|
1553
1647
|
s = _SPACE_(*_usage_argv(__file__))
|
|
@@ -1560,8 +1654,8 @@ if __name__ == '__main__': # MCCABE 14
|
|
|
1560
1654
|
'# % echo 0 0 10 10 50 -4 50S 4W | IntersectTool -i -p 0 -C',
|
|
1561
1655
|
'# -631414 5988887 0 -3',
|
|
1562
1656
|
'# -4.05187 -4.00000 -4.05187 -4.00000 0',
|
|
1657
|
+
'-m 0 0 10 10 50 -4 50S 4W',
|
|
1563
1658
|
'-C -m 0 0 10 10 50 -4 50S 4W',
|
|
1564
|
-
'-M 0 0 10 10 50 -4 50S 4W',
|
|
1565
1659
|
'-i 0 0 10 10 50 -4 50S 4W',
|
|
1566
1660
|
'-T -i 0 0 10 10 50 -4 50S 4W',
|
|
1567
1661
|
'-C -i 0 0 10 10 50 -4 50S 4W',
|
|
@@ -1587,13 +1681,14 @@ if __name__ == '__main__': # MCCABE 14
|
|
|
1587
1681
|
raise
|
|
1588
1682
|
exit(1)
|
|
1589
1683
|
|
|
1590
|
-
# % env PYGEODESY_INTERSECTTOOL=... python3 -m pygeodesy.geodesici
|
|
1684
|
+
# % env PYGEODESY_INTERSECTTOOL=... python3 -m pygeodesy.geodesici --help
|
|
1685
|
+
|
|
1686
|
+
# % python3 -m pygeodesy.geodesici -h
|
|
1591
1687
|
#
|
|
1592
1688
|
# usage: python3 -m ....pygeodesy.geodesici [--Verbose | -V] [--version | -v] [--help | -h] [--Tool | -T] [--Check | -C] [-R meter]
|
|
1593
1689
|
# [-c latA lonA aziA latB lonB aziB |
|
|
1594
1690
|
# -i latA1 lonA1 latA2 lonA2 latB1 lonB1 latB2 lonB2 |
|
|
1595
1691
|
# -m latA1 lonA1 latA2 lonA2 latB1 lonB1 latB2 lonB2 |
|
|
1596
|
-
# -M latA1 lonA1 latA2 lonA2 latB1 lonB1 latB2 lonB2 |
|
|
1597
1692
|
# -n latA lonA aziA aziB |
|
|
1598
1693
|
# -o latA lonA aziA latB lonB aziB x0 y0]
|
|
1599
1694
|
|
|
@@ -1620,11 +1715,11 @@ if __name__ == '__main__': # MCCABE 14
|
|
|
1620
1715
|
# -631414 5988887 0 -3
|
|
1621
1716
|
# -4.05187 -4.00000 -4.05187 -4.00000 0
|
|
1622
1717
|
|
|
1623
|
-
# % python3 -m ....pygeodesy.geodesici -
|
|
1624
|
-
# Intersector.Middle: XDict(
|
|
1718
|
+
# % python3 -m ....pygeodesy.geodesici -m 0 0 10 10 50 -4 50S 4W
|
|
1719
|
+
# Intersector.Middle: XDict(c=0, sA=782554.549609, sB=5536835.161499, sX0=0.0)
|
|
1625
1720
|
|
|
1626
|
-
# % python3 -m ....pygeodesy.geodesici -
|
|
1627
|
-
# Intersector.
|
|
1721
|
+
# % python3 -m ....pygeodesy.geodesici -C -m 0 0 10 10 50 -4 50S 4W
|
|
1722
|
+
# Intersector.Middle: XDict(aAB=10.262308, c=0, latA=5.019509, latB=0.036282, lonA=4.961883, lonB=-4.0, sA=782554.549609, sAB=1138574.546746, sB=5536835.161499, sX0=0.0)
|
|
1628
1723
|
|
|
1629
1724
|
# % python3 -m ....pygeodesy.geodesici -i 0 0 10 10 50 -4 50S 4W
|
|
1630
1725
|
# Intersector.Segment: XDict(c=0, k=-3, kA=-1, kB=0, sA=-631414.26877, sB=5988887.278435, sX0=1866020.935315)
|