pygeodesy 24.3.24__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.
Files changed (115) hide show
  1. PyGeodesy-24.3.24.dist-info/METADATA +272 -0
  2. PyGeodesy-24.3.24.dist-info/RECORD +115 -0
  3. PyGeodesy-24.3.24.dist-info/WHEEL +6 -0
  4. PyGeodesy-24.3.24.dist-info/top_level.txt +1 -0
  5. pygeodesy/LICENSE +21 -0
  6. pygeodesy/__init__.py +615 -0
  7. pygeodesy/__main__.py +103 -0
  8. pygeodesy/albers.py +867 -0
  9. pygeodesy/auxilats/_CX_4.py +218 -0
  10. pygeodesy/auxilats/_CX_6.py +314 -0
  11. pygeodesy/auxilats/_CX_8.py +475 -0
  12. pygeodesy/auxilats/__init__.py +54 -0
  13. pygeodesy/auxilats/__main__.py +86 -0
  14. pygeodesy/auxilats/auxAngle.py +548 -0
  15. pygeodesy/auxilats/auxDLat.py +302 -0
  16. pygeodesy/auxilats/auxDST.py +296 -0
  17. pygeodesy/auxilats/auxLat.py +848 -0
  18. pygeodesy/auxilats/auxily.py +272 -0
  19. pygeodesy/azimuthal.py +1150 -0
  20. pygeodesy/basics.py +892 -0
  21. pygeodesy/booleans.py +2031 -0
  22. pygeodesy/cartesianBase.py +1062 -0
  23. pygeodesy/clipy.py +704 -0
  24. pygeodesy/constants.py +516 -0
  25. pygeodesy/css.py +660 -0
  26. pygeodesy/datums.py +752 -0
  27. pygeodesy/deprecated/__init__.py +61 -0
  28. pygeodesy/deprecated/bases.py +40 -0
  29. pygeodesy/deprecated/classes.py +262 -0
  30. pygeodesy/deprecated/consterns.py +54 -0
  31. pygeodesy/deprecated/datum.py +40 -0
  32. pygeodesy/deprecated/functions.py +375 -0
  33. pygeodesy/deprecated/nvector.py +48 -0
  34. pygeodesy/deprecated/rhumbBase.py +32 -0
  35. pygeodesy/deprecated/rhumbaux.py +33 -0
  36. pygeodesy/deprecated/rhumbsolve.py +33 -0
  37. pygeodesy/deprecated/rhumbx.py +33 -0
  38. pygeodesy/dms.py +986 -0
  39. pygeodesy/ecef.py +1348 -0
  40. pygeodesy/elevations.py +279 -0
  41. pygeodesy/ellipsoidalBase.py +1224 -0
  42. pygeodesy/ellipsoidalBaseDI.py +913 -0
  43. pygeodesy/ellipsoidalExact.py +343 -0
  44. pygeodesy/ellipsoidalGeodSolve.py +343 -0
  45. pygeodesy/ellipsoidalKarney.py +403 -0
  46. pygeodesy/ellipsoidalNvector.py +685 -0
  47. pygeodesy/ellipsoidalVincenty.py +590 -0
  48. pygeodesy/ellipsoids.py +2476 -0
  49. pygeodesy/elliptic.py +1198 -0
  50. pygeodesy/epsg.py +243 -0
  51. pygeodesy/errors.py +804 -0
  52. pygeodesy/etm.py +1190 -0
  53. pygeodesy/fmath.py +1013 -0
  54. pygeodesy/formy.py +1818 -0
  55. pygeodesy/frechet.py +865 -0
  56. pygeodesy/fstats.py +760 -0
  57. pygeodesy/fsums.py +1898 -0
  58. pygeodesy/gars.py +358 -0
  59. pygeodesy/geodesicw.py +581 -0
  60. pygeodesy/geodesicx/_C4_24.py +1699 -0
  61. pygeodesy/geodesicx/_C4_27.py +2395 -0
  62. pygeodesy/geodesicx/_C4_30.py +3301 -0
  63. pygeodesy/geodesicx/__init__.py +48 -0
  64. pygeodesy/geodesicx/__main__.py +91 -0
  65. pygeodesy/geodesicx/gx.py +1382 -0
  66. pygeodesy/geodesicx/gxarea.py +535 -0
  67. pygeodesy/geodesicx/gxbases.py +154 -0
  68. pygeodesy/geodesicx/gxline.py +669 -0
  69. pygeodesy/geodsolve.py +426 -0
  70. pygeodesy/geohash.py +914 -0
  71. pygeodesy/geoids.py +1884 -0
  72. pygeodesy/hausdorff.py +892 -0
  73. pygeodesy/heights.py +1155 -0
  74. pygeodesy/interns.py +687 -0
  75. pygeodesy/iters.py +545 -0
  76. pygeodesy/karney.py +919 -0
  77. pygeodesy/ktm.py +633 -0
  78. pygeodesy/latlonBase.py +1766 -0
  79. pygeodesy/lazily.py +960 -0
  80. pygeodesy/lcc.py +684 -0
  81. pygeodesy/ltp.py +1107 -0
  82. pygeodesy/ltpTuples.py +1563 -0
  83. pygeodesy/mgrs.py +721 -0
  84. pygeodesy/named.py +1324 -0
  85. pygeodesy/namedTuples.py +683 -0
  86. pygeodesy/nvectorBase.py +695 -0
  87. pygeodesy/osgr.py +781 -0
  88. pygeodesy/points.py +1686 -0
  89. pygeodesy/props.py +628 -0
  90. pygeodesy/resections.py +1048 -0
  91. pygeodesy/rhumb/__init__.py +46 -0
  92. pygeodesy/rhumb/aux_.py +397 -0
  93. pygeodesy/rhumb/bases.py +1148 -0
  94. pygeodesy/rhumb/ekx.py +563 -0
  95. pygeodesy/rhumb/solve.py +572 -0
  96. pygeodesy/simplify.py +647 -0
  97. pygeodesy/solveBase.py +472 -0
  98. pygeodesy/sphericalBase.py +724 -0
  99. pygeodesy/sphericalNvector.py +1264 -0
  100. pygeodesy/sphericalTrigonometry.py +1447 -0
  101. pygeodesy/streprs.py +627 -0
  102. pygeodesy/trf.py +2079 -0
  103. pygeodesy/triaxials.py +1484 -0
  104. pygeodesy/units.py +969 -0
  105. pygeodesy/unitsBase.py +349 -0
  106. pygeodesy/ups.py +538 -0
  107. pygeodesy/utily.py +1231 -0
  108. pygeodesy/utm.py +762 -0
  109. pygeodesy/utmups.py +318 -0
  110. pygeodesy/utmupsBase.py +517 -0
  111. pygeodesy/vector2d.py +785 -0
  112. pygeodesy/vector3d.py +968 -0
  113. pygeodesy/vector3dBase.py +1049 -0
  114. pygeodesy/webmercator.py +383 -0
  115. pygeodesy/wgrs.py +439 -0
pygeodesy/trf.py ADDED
@@ -0,0 +1,2079 @@
1
+
2
+ # -*- coding: utf-8 -*-
3
+
4
+ u'''I{Veness}' Terrestrial Reference Frames (TRF).
5
+
6
+ Classes L{RefFrame}, registry L{RefFrames} and L{TRFError}.
7
+
8
+ Transcoded from I{Chris Veness'} (C) 2006-2022 JavaScript originals U{latlon-ellipsoidal-referenceframe.js
9
+ <https://GitHub.com/ChrisVeness/geodesy/blob/master/latlon-ellipsoidal-referenceframe.js>} and
10
+ U{latlon-ellipsoidal-referenceframe-txparams.js
11
+ <https://GitHub.com/ChrisVeness/geodesy/blob/master/latlon-ellipsoidal-referenceframe-txparams.js>}.
12
+
13
+ Following is a copy of the comments in I{Veness}' U{latlon-ellipsoidal-referenceframe.js
14
+ <https://GitHub.com/ChrisVeness/geodesy/blob/master/latlon-ellipsoidal-referenceframe.js>}.
15
+
16
+ Modern geodetic reference frames: a latitude/longitude point defines a geographic location on,
17
+ above or below the earth’s surface, measured in degrees from the equator and the U{International
18
+ Reference Meridian<https://WikiPedia.org/wiki/IERS_Reference_Meridian>} (IRM) and metres above
19
+ the ellipsoid within a given I{Terrestrial Reference Frame} at a given I{epoch}.
20
+
21
+ This is scratching the surface of complexities involved in high precision geodesy, but may
22
+ be of interest and/or value to those with less demanding requirements. More information U{here
23
+ <https://www.Movable-Type.co.UK/scripts/geodesy-library.html>} and U{here
24
+ <https://www.Movable-Type.co.UK/scripts/geodesy-library.html#latlon-ellipsoidal-referenceframe>}.
25
+
26
+ Note that I{ITRF solutions} do not directly use an ellipsoid, but are specified by Cartesian
27
+ coordinates. The GRS80 ellipsoid is recommended for transformations to geographical coordinates.
28
+
29
+ Note WGS84(G730/G873/G1150) are coincident with ITRF at 10-centimetre level, see also U{here
30
+ <ftp://ITRF.ENSG.IGN.Fr/pub/itrf/WGS84.TXT>}. WGS84(G1674) and ITRF20014 / ITRF2008 I{"are likely
31
+ to agree at the centimeter level"}, see also U{QPS/Qinsy<https://Confluence.QPS.NL/qinsy/
32
+ en/how-to-deal-with-etrs89-datum-and-time-dependent-transformation-parameters-45353274.html>}.
33
+
34
+ @var RefFrames.ETRF2000: RefFrame(name='ETRF2000', epoch=2005, datum=Datums.GRS80) .Xforms=(0, -14)
35
+ @var RefFrames.ETRF2005: RefFrame(name='ETRF2005', epoch=2005, datum=Datums.GRS80) .Xforms=(0, -1)
36
+ @var RefFrames.ETRF2008: RefFrame(name='ETRF2008', epoch=2008, datum=Datums.GRS80) .Xforms=(0, 0)
37
+ @var RefFrames.ETRF2014: RefFrame(name='ETRF2014', epoch=2014, datum=Datums.GRS80) .Xforms=(0, -14)
38
+ @var RefFrames.ETRF2020: RefFrame(name='ETRF2020', epoch=2020, datum=Datums.GRS80) .Xforms=(0, -14)
39
+ @var RefFrames.ETRF88: RefFrame(name='ETRF88', epoch=1988, datum=Datums.GRS80) .Xforms=(0, 0)
40
+ @var RefFrames.ETRF89: RefFrame(name='ETRF89', epoch=1989, datum=Datums.GRS80) .Xforms=(0, -1)
41
+ @var RefFrames.ETRF90: RefFrame(name='ETRF90', epoch=1990, datum=Datums.GRS80) .Xforms=(0, -1)
42
+ @var RefFrames.ETRF91: RefFrame(name='ETRF91', epoch=1991, datum=Datums.GRS80) .Xforms=(0, -1)
43
+ @var RefFrames.ETRF92: RefFrame(name='ETRF92', epoch=1992, datum=Datums.GRS80) .Xforms=(0, -1)
44
+ @var RefFrames.ETRF93: RefFrame(name='ETRF93', epoch=1993, datum=Datums.GRS80) .Xforms=(0, -1)
45
+ @var RefFrames.ETRF94: RefFrame(name='ETRF94', epoch=1994, datum=Datums.GRS80) .Xforms=(0, -1)
46
+ @var RefFrames.ETRF96: RefFrame(name='ETRF96', epoch=1996, datum=Datums.GRS80) .Xforms=(0, -1)
47
+ @var RefFrames.ETRF97: RefFrame(name='ETRF97', epoch=1997, datum=Datums.GRS80) .Xforms=(0, -1)
48
+ @var RefFrames.GDA2020: RefFrame(name='GDA2020', epoch=2020, datum=Datums.GRS80) .Xforms=(0, -4)
49
+ @var RefFrames.GDA94: RefFrame(name='GDA94', epoch=1994, datum=Datums.GRS80) .Xforms=(0, -3)
50
+ @var RefFrames.ITRF2000: RefFrame(name='ITRF2000', epoch=1997, datum=Datums.GRS80) .Xforms=(15, -5)
51
+ @var RefFrames.ITRF2005: RefFrame(name='ITRF2005', epoch=2000, datum=Datums.GRS80) .Xforms=(8, -3)
52
+ @var RefFrames.ITRF2008: RefFrame(name='ITRF2008', epoch=2005, datum=Datums.GRS80) .Xforms=(17, -2)
53
+ @var RefFrames.ITRF2014: RefFrame(name='ITRF2014', epoch=2010, datum=Datums.GRS80) .Xforms=(16, -1)
54
+ @var RefFrames.ITRF2020: RefFrame(name='ITRF2020', epoch=2015, datum=Datums.GRS80) .Xforms=(16, 0)
55
+ @var RefFrames.ITRF88: RefFrame(name='ITRF88', epoch=1988, datum=Datums.GRS80) .Xforms=(3, -4)
56
+ @var RefFrames.ITRF89: RefFrame(name='ITRF89', epoch=1989, datum=Datums.GRS80) .Xforms=(4, -4)
57
+ @var RefFrames.ITRF90: RefFrame(name='ITRF90', epoch=1988, datum=Datums.GRS80) .Xforms=(6, -4)
58
+ @var RefFrames.ITRF91: RefFrame(name='ITRF91', epoch=1988, datum=Datums.GRS80) .Xforms=(4, -4)
59
+ @var RefFrames.ITRF92: RefFrame(name='ITRF92', epoch=1988, datum=Datums.GRS80) .Xforms=(4, -4)
60
+ @var RefFrames.ITRF93: RefFrame(name='ITRF93', epoch=1988, datum=Datums.GRS80) .Xforms=(4, -4)
61
+ @var RefFrames.ITRF94: RefFrame(name='ITRF94', epoch=1993, datum=Datums.GRS80) .Xforms=(4, -4)
62
+ @var RefFrames.ITRF96: RefFrame(name='ITRF96', epoch=1997, datum=Datums.GRS80) .Xforms=(5, -5)
63
+ @var RefFrames.ITRF97: RefFrame(name='ITRF97', epoch=1997, datum=Datums.GRS80) .Xforms=(5, -4)
64
+ @var RefFrames.NAD83: RefFrame(name='NAD83', epoch=1997, datum=Datums.GRS80) .Xforms=(0, -6)
65
+ @var RefFrames.NAD83cors96: RefFrame(name='NAD83cors96', epoch=1997, datum=Datums.GRS80) .Xforms=(1, 0)
66
+ @var RefFrames.WGS84: RefFrame(name='WGS84', epoch=1984, datum=Datums.GRS80) .Xforms=(0, -1)
67
+ @var RefFrames.WGS84g1150: RefFrame(name='WGS84g1150', epoch=2001, datum=Datums.GRS80) .Xforms=(1, 0)
68
+ @var RefFrames.WGS84g1674: RefFrame(name='WGS84g1674', epoch=2005, datum=Datums.GRS80) .Xforms=(0, 0)
69
+ @var RefFrames.WGS84g1762: RefFrame(name='WGS84g1762', epoch=2005, datum=Datums.GRS80) .Xforms=(0, 0)
70
+ '''
71
+
72
+ from pygeodesy.basics import map1, neg, isidentifier, isstr, _xinstanceof, _xisscalar
73
+ from pygeodesy.constants import _float as _F, _0_0s, _0_0, _0_001, _0_5, _1_0
74
+ from pygeodesy.datums import Datums, _earth_datum, _equall, _GDA2020_, _Names7, \
75
+ _negastr, Transform, _WGS84, _EWGS84, _operator
76
+ # from pygeodesy.ellipsoids import _EWGS84 # from .datums
77
+ from pygeodesy.errors import TRFError, _xattr, _xellipsoidall, _xkwds, _xkwds_item2
78
+ from pygeodesy.interns import MISSING, NN, _AT_, _COMMASPACE_, _conversion_, \
79
+ _datum_, _DOT_, _exists_, _invalid_, _MINUS_, \
80
+ _NAD83_, _no_, _PLUS_, _reframe_, _s_, _SPACE_, \
81
+ _STAR_, _to_, _vs_, _WGS84_, _x_, _intern as _i
82
+ # from pygeodesy.lazily import _ALL_LAZY # from .units
83
+ from pygeodesy.named import ADict, classname, _lazyNamedEnumItem as _lazy, _Named, \
84
+ _NamedEnum, _NamedEnumItem, _NamedTuple, Fmt, unstr
85
+ from pygeodesy.props import deprecated_method, property_doc_, Property_RO, property_RO
86
+ # from pygeodesy.streprs import Fmt, unstr # from .named
87
+ from pygeodesy.units import Epoch, Float, _ALL_LAZY
88
+ # from pygeodesy.utily import sincos2d_
89
+
90
+ from math import ceil as _ceil, fabs
91
+ # import operator as _operator # from .datums
92
+
93
+ __all__ = _ALL_LAZY.trf
94
+ __version__ = '24.03.12'
95
+
96
+ _EP0CH = Epoch(0, low=0)
97
+ _Es = {_EP0CH: _EP0CH} # L{Epoch}s, deleted below
98
+ _GRS80 = Datums.GRS80
99
+ _inverse_ = 'inverse'
100
+ _MAS = _MM = _PPB = Float # Units
101
+ _MM2M = _0_001 # scale mm2m, ppB2ppM, mas2as
102
+ _mDays = (0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0)
103
+ _366_0 = _F(sum(_mDays))
104
+ _rates_ = 'rates' # PYCHOK used!
105
+ _Rs = {} # L{TRFXform7Tuple}s de-dup, deleted below
106
+ _xform_ = 'xform' # PYCHOK used!
107
+ _Xs = {} # L{TRFXform7Tuple}s de-dup, deleted below
108
+
109
+ _ETRF88_ = _i('ETRF88')
110
+ _ETRF89_ = _i('ETRF89')
111
+ _ETRF90_ = _i('ETRF90')
112
+ _ETRF91_ = _i('ETRF91')
113
+ _ETRF92_ = _i('ETRF92')
114
+ _ETRF93_ = _i('ETRF93')
115
+ _ETRF94_ = _i('ETRF94')
116
+ _ETRF96_ = _i('ETRF96')
117
+ _ETRF97_ = _i('ETRF97')
118
+ _ETRF2000_ = _i('ETRF2000')
119
+ _ETRF2005_ = _i('ETRF2005')
120
+ _ETRF2008_ = _i('ETRF2008')
121
+ _ETRF2014_ = _i('ETRF2014')
122
+ _ETRF2020_ = _i('ETRF2020')
123
+ _GDA94_ = _i('GDA94')
124
+ _ITRF_ = _i('ITRF')
125
+ _ITRF88_ = _i('ITRF88')
126
+ _ITRF89_ = _i('ITRF89')
127
+ _ITRF90_ = _i('ITRF90')
128
+ _ITRF91_ = _i('ITRF91')
129
+ _ITRF92_ = _i('ITRF92')
130
+ _ITRF93_ = _i('ITRF93')
131
+ _ITRF94_ = _i('ITRF94')
132
+ _ITRF96_ = _i('ITRF96')
133
+ _ITRF97_ = _i('ITRF97')
134
+ _ITRF2000_ = _i('ITRF2000')
135
+ _ITRF2005_ = _i('ITRF2005')
136
+ _ITRF2008_ = _i('ITRF2008')
137
+ _ITRF2014_ = _i('ITRF2014')
138
+ _ITRF2020_ = _i('ITRF2020')
139
+ _NAD83cors96_ = _i('NAD83cors96')
140
+ _WGS84g1150_ = _i('WGS84g1150')
141
+ _WGS84g1674_ = _i('WGS84g1674')
142
+ _WGS84g1762_ = _i('WGS84g1762')
143
+
144
+
145
+ def _E(epoch): # deleted below
146
+ '''(INTERNAL) De-dup L{Epochs}s.
147
+ '''
148
+ e = Epoch(_F(epoch))
149
+ return _Es.setdefault(e, e) # PYCHOK del
150
+
151
+
152
+ def _P(ps, name, _Ps): # deleted below
153
+ '''(INTERNAL) De-dup L{TRFXform7Tuple}s.
154
+ '''
155
+ t = TRFXform7Tuple(map(_F, ps), name=name)
156
+ return _Ps.setdefault(t, t)
157
+
158
+
159
+ class RefFrame(_NamedEnumItem):
160
+ '''Terrestrial Reference Frame (TRF) parameters.
161
+ '''
162
+ _datum = _GRS80 # Datums.GRS80 or .WGS84 (L{Datum})
163
+ _epoch = _EP0CH # epoch, fractional year (L{Epoch})
164
+
165
+ def __init__(self, epoch, datum=_GRS80, name=NN):
166
+ '''New L{RefFrame}.
167
+
168
+ @arg epoch: Epoch, a fractional calendar year (C{scalar} or C{str}).
169
+ @arg datum: Datum or ellipsoid (L{Datum}, {Ellipsoid}, L{Ellipsoid2}
170
+ or L{a_f2Tuple}).
171
+ @kwarg name: Unique, non-empty name (C{str}).
172
+
173
+ @raise NameError: A L{RefFrame} with that B{C{name}} already exists.
174
+
175
+ @raise TRFError: Invalid B{C{epoch}}.
176
+
177
+ @raise TypeError: Invalid B{C{datum}}.
178
+ '''
179
+ if datum in (_GRS80, None):
180
+ pass
181
+ elif datum in (_WGS84, _EWGS84):
182
+ self._datum = _WGS84
183
+ else:
184
+ _earth_datum(self, datum, raiser=_datum_)
185
+ self._epoch = _Epoch(epoch)
186
+ self._Xto = {} # dict of Xforms
187
+ if name:
188
+ self._register(RefFrames, _stref(name=name))
189
+
190
+ def __eq__(self, other):
191
+ return isinstance(other, RefFrame) and other.epoch == self.epoch \
192
+ and other.datum == self.datum \
193
+ and other.name == self.name
194
+
195
+ def __lt__(self, other): # for sorting
196
+ return isinstance(other, RefFrame) and (self.name < other.name
197
+ or self.epoch < other.epoch)
198
+
199
+ @deprecated_method # PYCHOK Python 3.5+
200
+ def __matmul__(self, point):
201
+ '''DEPRECATED on 2024.02.16, use method C{B{point}.toRefFrame}.'''
202
+ return _toRefFrame(point, self)
203
+
204
+ @property_RO
205
+ def datum(self):
206
+ '''Get this reference frame's datum (L{Datum}).
207
+ '''
208
+ return self._datum
209
+
210
+ @property_RO
211
+ def ellipsoid(self):
212
+ '''Get this reference frame's ellipsoid (L{Ellipsoid} or L{Ellipsoid2}).
213
+ '''
214
+ return self._datum.ellipsoid
215
+
216
+ @Property_RO
217
+ def epoch(self):
218
+ '''Get this reference frame's epoch (C{Epoch}).
219
+ '''
220
+ return self._epoch
221
+
222
+ def toRefFrame(self, point, reframe2, **epoch_epoch2_name):
223
+ '''Convert an ellipsoidal point from this reframe and from C{epoch} to
224
+ an other C{reframe2} and C{epoch2 or epoch}.
225
+
226
+ @arg point: The point to convert (C{LatLon} or C{Cartesian}).
227
+ @arg reframe2: Reference frame to convert I{to} (L{RefFrame}).
228
+ @kwarg epoch_epoch2_name: Optional keyword arguments C{B{epoch}=None},
229
+ C{B{epoch2}=None} and C{B{name}=B{reframe2}.name}.
230
+
231
+ @return: A copy of the B{C{point}}, converted and renamed.
232
+
233
+ @raise TypeError: Invalid B{C{point}}.
234
+
235
+ @note: The C{B{point}.reframe} is overridden by this reframe and
236
+ C{B{point}.epoch} by C{B{epoch}} or this reframe.C{epoch}.
237
+
238
+ @see: Methods L{LatLon.toRefFrame<ellipsoidalBase.LatLonEllipsoidalBase.toRefFrame>}
239
+ and L{Cartesian.toRefFrame<ellipsoidalBase.CartesianEllipsoidalBase.toRefFrame>}
240
+ for more details.
241
+ '''
242
+ return _toRefFrame(point, reframe2, reframe=self, **_xkwds(epoch_epoch2_name,
243
+ name=_xattr(reframe2, name=self.name)))
244
+
245
+ def toStr(self, epoch=None, name=NN, **unused): # PYCHOK expected
246
+ '''Return this reference frame as a string.
247
+
248
+ @kwarg epoch: Override this reframe's epoch (C{scalar} or C{str}).
249
+ @kwarg name: Override name (C{str}) or C{None} to exclude the
250
+ reframe's name.
251
+
252
+ @return: This L{RefFrame}'s attributes (C{str}).
253
+ '''
254
+ D = self.datum
255
+ e = self.epoch if epoch is None else _Epoch(epoch)
256
+ t = (Fmt.EQUAL(name=repr(name or self.name)),
257
+ Fmt.EQUAL(epoch=e),
258
+ Fmt.EQUAL(datum=_DOT_(classname(D) + _s_, D.name)))
259
+ return _COMMASPACE_.join(t[int(name is None):])
260
+
261
+ def Xform(self, reframe2):
262
+ '''Get the converter Xform I{from} this reference frame I{to} C{reframe2}.
263
+
264
+ @arg reframe2: Destination frame to convert I{to} (L{RefFrame} or C{str}).
265
+
266
+ @return: The L{TRFXform} instance or C{None} if not available.
267
+
268
+ @raise TypeError: Invalid B{C{reframe2}}.
269
+ '''
270
+ _xinstanceof(RefFrame, str, reframe2=reframe2)
271
+ n2 = reframe2 if isstr(reframe2) else reframe2.name
272
+ return self._Xto.get(n2, None)
273
+
274
+ def Xforms(self, inverse=False):
275
+ '''Return all Xforms converting I{from} or I{to} this reference frame or both.
276
+
277
+ @kwarg inverse: If C{True}, get all I{from} otherwise I{to} Xforms
278
+ I{un-inverted} (C{bool}) or if C{B{inverse}=2} (C{int})
279
+ get all I{to} Xforms I{inverted} plus all I{from}s.
280
+
281
+ @return: An L{ADict} of C{name=}L{TRFXform}s I{from} this reframe or if
282
+ C{B{inverse}=True} I{to} this reframe or both if C{B{inverse}=2}.
283
+ '''
284
+ return ADict(self._Xitems(inverse, RefFrames))
285
+
286
+ def _Xfrom(self, RFs, inverted):
287
+ '''(INTERNAL) Yield all 2-tuples C{(name, I{from} Xform)} converting I{to}
288
+ this reframe, inverted if C{inverted is True}.
289
+ '''
290
+ n2 = self.name
291
+ for n1, r in RFs.items():
292
+ X = r._Xto.get(n2, None)
293
+ if X:
294
+ yield n1, (X.inverse() if inverted else X)
295
+
296
+ def _Xitems(self, inverse, RFs): # in _eXhaustives, .Xforms
297
+ '''(INTERNAL) Yield all C{._Xfrom} and C{._Xto}'s as 2-tuple items.
298
+ '''
299
+ i = inverse == 2
300
+ if i or inverse:
301
+ for item in self._Xfrom(RFs, i):
302
+ yield item
303
+ if i or not inverse:
304
+ for item in self._Xto.items():
305
+ yield item
306
+
307
+
308
+ class RefFrames(_NamedEnum):
309
+ '''(INTERNAL) L{RefFrame} registry, I{must} be a sub-class
310
+ to accommodate the L{_LazyNamedEnumItem} properties.
311
+ '''
312
+ def _Lazy(self, epoch, datum=_GRS80, name=NN):
313
+ '''(INTERNAL) Instantiate the L{RefFrame}.
314
+ '''
315
+ return RefFrame(epoch, datum, name=name)
316
+
317
+ RefFrames = RefFrames(RefFrame) # PYCHOK singleton
318
+ '''Some pre-defined L{RefFrame}s, all I{lazily} instantiated.'''
319
+ # <https://GitHub.com/ChrisVeness/geodesy/blob/master/latlon-ellipsoidal-referenceframe.js>
320
+ RefFrames._assert(
321
+ ETRF88 = _lazy(_ETRF88_, _E(1988)), # epoch, datum?
322
+ ETRF89 = _lazy(_ETRF89_, _E(1989)), # epoch, datum?
323
+ ETRF90 = _lazy(_ETRF90_, _E(1990)), # epoch, datum?
324
+ ETRF91 = _lazy(_ETRF91_, _E(1991)), # epoch, datum?
325
+ ETRF92 = _lazy(_ETRF92_, _E(1992)), # epoch, datum?
326
+ ETRF93 = _lazy(_ETRF93_, _E(1993)), # epoch, datum?
327
+ ETRF94 = _lazy(_ETRF94_, _E(1994)), # epoch, datum?
328
+ ETRF96 = _lazy(_ETRF96_, _E(1996)), # epoch, datum?
329
+ ETRF97 = _lazy(_ETRF97_, _E(1997)), # epoch, datum?
330
+ ETRF2000 = _lazy(_ETRF2000_, _E(2005)),
331
+ ETRF2005 = _lazy(_ETRF2005_, _E(2005)), # epoch, datum?
332
+ ETRF2008 = _lazy(_ETRF2008_, _E(2008)), # epoch, datum?
333
+ ETRF2014 = _lazy(_ETRF2014_, _E(2014)), # epoch, datum?
334
+ ETRF2020 = _lazy(_ETRF2020_, _E(2020)), # epoch, datum?
335
+ GDA94 = _lazy(_GDA94_, _E(1994)), # Australia
336
+ GDA2020 = _lazy(_GDA2020_, _E(2020)), # Australia
337
+ ITRF88 = _lazy(_ITRF88_, _E(1988)),
338
+ ITRF89 = _lazy(_ITRF89_, _E(1989)),
339
+ ITRF90 = _lazy(_ITRF90_, _E(1988)),
340
+ ITRF91 = _lazy(_ITRF91_, _E(1988)),
341
+ ITRF92 = _lazy(_ITRF92_, _E(1988)),
342
+ ITRF93 = _lazy(_ITRF93_, _E(1988)),
343
+ ITRF94 = _lazy(_ITRF94_, _E(1993)),
344
+ ITRF96 = _lazy(_ITRF96_, _E(1997)),
345
+ ITRF97 = _lazy(_ITRF97_, _E(1997)),
346
+ ITRF2000 = _lazy(_ITRF2000_, _E(1997)), # aka ITRF00
347
+ ITRF2005 = _lazy(_ITRF2005_, _E(2000)),
348
+ ITRF2008 = _lazy(_ITRF2008_, _E(2005)), # aka ITRF08
349
+ ITRF2014 = _lazy(_ITRF2014_, _E(2010)),
350
+ ITRF2020 = _lazy(_ITRF2020_, _E(2015)),
351
+ NAD83 = _lazy(_NAD83_, _E(1997)),
352
+ NAD83cors96 = _lazy(_NAD83cors96_, _E(1997)),
353
+ WGS84 = _lazy(_WGS84_, _E(1984), _WGS84),
354
+ WGS84g1150 = _lazy(_WGS84g1150_, _E(2001), _WGS84),
355
+ WGS84g1674 = _lazy(_WGS84g1674_, _E(2005), _WGS84),
356
+ WGS84g1762 = _lazy(_WGS84g1762_, _E(2005), _WGS84)) # same epoch
357
+
358
+
359
+ class TransformXform(Transform):
360
+ '''Helmert transformation, extended with an C{Xform} TRF converter.
361
+
362
+ @see: L{Transform<datums.Transform>} and L{Xform<TRFXform>}.
363
+ '''
364
+ _Xform = None
365
+
366
+ def __init__(self, name=NN, **tx_ty_tz_s_sx_sy_sz): # PYCHOK signature
367
+ '''New L{TransformXform}.
368
+
369
+ @kwarg name: Optional name (C{str}), I{not registered}.
370
+
371
+ @see: L{Transform<datums.Transform>} for details.
372
+
373
+ @note: This L{TransformXform}'s name starts with C{"-"} iff
374
+ I{inversed}.
375
+ '''
376
+ Transform.__init__(self, **tx_ty_tz_s_sx_sy_sz)
377
+ if name:
378
+ self.name = name # unregistered
379
+
380
+ def __eq__(self, other):
381
+ return isinstance(other, TransformXform) and _equall(other, self)
382
+
383
+ def __hash__(self):
384
+ return Transform.__hash__(self)
385
+
386
+ def inverse(self, name=NN):
387
+ '''Return the inverse of this transform.
388
+
389
+ @kwarg name: Optional, unique name (C{str}).
390
+
391
+ @return: Inverse (L{TransformXform}), unregistered.
392
+ '''
393
+ r = Transform.inverse(name=name)
394
+ r._Xform = r.Xform.inverse()
395
+ return r
396
+
397
+ def rename(self, name=NN):
398
+ '''Change this transform's name.
399
+
400
+ @arg name: New name (C{str}), overriding this transform's Xform's name.
401
+
402
+ @return: The previous name (C{str}).
403
+ '''
404
+ X = self.Xform
405
+ n = name or (X.toStr() if X else NN)
406
+ return Transform.rename(self, n)
407
+
408
+ def toRefFrame(self, point, name=NN): # PYCHOK signature
409
+ '''Convert an ellipsoidal point using this transform and Xform.
410
+
411
+ @arg point: The point to convert (C{Cartesian} or C{LatLon}).
412
+
413
+ @return: A copy of the B{C{point}}, converted I{directly} to
414
+ this transform's Xform's C{refName2} and C{epoch}.
415
+
416
+ @note: The B{C{point}}'s original C{reframe} and C{epoch} are
417
+ I{ignored}, its C{datum} and C{height} are preserved
418
+ but I{not} taken into account.
419
+ '''
420
+ _ = _xellipsoidall(point)
421
+ p = point.dup() if self.isunity else point.toTransform(self)
422
+ X = self.Xform
423
+ if X: # see _toRefFrame below
424
+ p._reframe = X.reframe2
425
+ p._epoch = X.epoch
426
+ p.rename(name or self.name)
427
+ return p
428
+
429
+ def toTransform(self, epoch1, **epoch2_inverse):
430
+ '''Return this transform observed at B{C{epoch1}} as a Helmert
431
+ L{TransformXform}, optionally at B{C{epoch2 or epoch1}}.
432
+
433
+ @arg epoch1: Epoch to observe I{from} (C{scalar}).
434
+ @kwarg epoch2_inverse: Optional C{B{epoch2}=None} to observe
435
+ I{to} and C{B{inverse}=False}, see method
436
+ L{toTransform<TRFXform.toTransform>} from
437
+ L{TRFXform}.
438
+
439
+ @return: The Helmert transform (L{TransformXform}).
440
+
441
+ @raise TRFError: Invalid B{C{epoch1}}, B{C{epoch2}} or
442
+ missing Xform.
443
+ '''
444
+ X = self.Xform
445
+ if X is None:
446
+ raise TRFError(Xform=X, txt=MISSING)
447
+ return X.toTransform(epoch1, **epoch2_inverse)
448
+
449
+ def transform2(self, x, y, z, vx=0, vy=0, vz=0, inverse=False, factor=_MM2M,
450
+ **Vector_and_kwds):
451
+ '''Transform a (cartesian) position I{with} velocities, forward or inverse.
452
+
453
+ @arg x: X coordinate (C{meter}).
454
+ @arg y: Y coordinate (C{meter}).
455
+ @arg z: Z coordinate (C{meter}).
456
+ @kwarg vx: X velocity (C{meter-per-year}).
457
+ @kwarg vy: Y velocity (C{meter-per-year}).
458
+ @kwarg vz: Z velocity (C{meter-per-year}).
459
+ @kwarg inverse: If C{True}, apply the inverse transform (C{bool}).
460
+ @kwarg factor: Factor to scale this Xform's C{rates} (C{scalar}),
461
+ default from C{milli-meter-} to C{meter-per-year},
462
+ from C{milli-arc-} to C{arc-seconds-per-year} and
463
+ from C{ppB-} to C{ppM-per-year}.
464
+ @kwarg Vector_and_kwds: An optional, (3-D) C{B{Vector}=None} or cartesian
465
+ class and additional C{B{Vector}} keyword arguments to
466
+ return the transformed position and the I{velocities}.
467
+
468
+ @return: 2-Tuple C{(position, velocities)}, the tranformed C{position}
469
+ and C{velocities}, each a L{Vector3Tuple}C{(x, y, z)} unless
470
+ some B{C{Vector_and_kwds}} are specified.
471
+
472
+ @note: If this transform's Xform is missing, the returned C{velocities}
473
+ are the given ones, I{un-transformed}.
474
+
475
+ @raise TypeError: Non-scalar B{C{factor}}.
476
+
477
+ @see: Soler, T. & Snay, R.A. "Transforming Positions and Velocities ...", U{equations
478
+ (4) and (5)<https://www.NGS.NOAA.gov/CORS/Articles/SolerSnayASCE.pdf>}
479
+ and HTDP functions C{VTRANF} and C{VTRANF_IERS} in file U{HTDP/hdtp.f
480
+ <https://Geodesy.NOAA.gov/TOOLS/Htdp/Htdp.shtml>}.
481
+ '''
482
+ p = self.transform(x, y, z, inverse=inverse, **Vector_and_kwds)
483
+ X = self.Xform
484
+ if X is not None:
485
+ r = X.rates * factor # equ (4) ...
486
+ # vx', vy', vz' = (.tx + x * .s + y * .rz - z * .ry,
487
+ # .ty - x * .rz + y * .s + z * .rx,
488
+ # .tz + x * .ry - y * .rx + z * .s)
489
+ # using counter-/clockwise .rx, .ry, and .rz
490
+ V = Transform(**dict(r.items())) # unregistered
491
+ _ = V._s_s1(0) # XXX r.s?
492
+ v = V.transform(p.x, p.y, p.z, inverse=inverse)
493
+ # + (vx, vy, vz) like HTDP
494
+ vx += v.x
495
+ vy += v.y
496
+ vz += v.z
497
+ v = p.dup(x=vx, y=vy, z=vz, name=NN(p.name, _vs_))
498
+ return p, v
499
+
500
+ def velocities(self, factor=_MM2M, **Vector_and_kwds):
501
+ '''Compute the X, Y and Z I{velocities} of this transform.
502
+
503
+ @kwarg factor: Factor to scale this Xform's C{rates} (C{scalar}),
504
+ default from C{milli-meter-} to C{meter-per-year},
505
+ from C{milli-arc-} to C{arc-seconds-per-year} and
506
+ from C{ppB-} to C{ppM-per-year}.
507
+ @kwarg Vector_and_kwds: An optional, (3-D) C{B{Vector}=None} or
508
+ cartesian class and additional C{B{Vector}} keyword
509
+ arguments to return the I{velocities}.
510
+
511
+ @return: A L{Vector3Tuple}C{(x, y, z)} unless some B{C{Vector_and_kwds}}
512
+ are specified or C{None} if this transform's Xform is missing.
513
+
514
+ @raise TypeError: Non-scalar B{C{factor}}.
515
+
516
+ @see: Altamimi, Z. "EUREF-TN-1-Jan-31-2024", U{Appendix A, equation (3)
517
+ <http://ETRS89.ENSG.IGN.FR/pub/EUREF-TN-1-Jan-31-2024.pdf>} and
518
+ method L{transform2<TransformXform.transform2>}.
519
+ '''
520
+ v = X = self.Xform
521
+ if X is not None:
522
+ r = X.rates * factor # equ (3) ...
523
+ V = self.dup(tx=r.sx, ty=r.sy, tz=r.sz, _Xform=None, # Xyy-dot
524
+ name=NN(self.name, _vs_)) # unregistered
525
+ _ = V._s_s1(0)
526
+ v = V.transform(r.tx, r.ty, r.tz, inverse=False, # Xyy
527
+ **Vector_and_kwds)
528
+ return v
529
+
530
+ @property_doc_(''' the Xform (L{TRFXform}).''')
531
+ def Xform(self):
532
+ '''Get this Helmert transform's Xform (L{TRFXform} or C{None}).
533
+ '''
534
+ return self._Xform
535
+
536
+ @Xform.setter # PYCHOK setter!
537
+ def Xform(self, Xform):
538
+ '''Set this Helmert transform's Xform (L{TRFXform}).
539
+
540
+ @raise TypeError: Invalid B{C{Xform}}.
541
+ '''
542
+ _xinstanceof(TRFXform, Xform=Xform)
543
+ self._Xform = Xform
544
+
545
+
546
+ class TRFXform7Tuple(_NamedTuple):
547
+ '''7-Tuple C{(tx, ty, tz, s, sx, sy, sz)} of conversion parameters with
548
+ translations C{tx}, C{ty} and C{tz} in C{milli-meter}, scale C{s} in
549
+ C{ppB} and rotations C{sx}, C{sy} and C{sz} in C{milli-arc-seconds}.
550
+ For C{rates} all are C{units-per-year}.
551
+
552
+ @note: The parameters are also named as C{(Tx, Ty, Tz, D, Rx, Ry, Rz)}
553
+ or C{(T1, T2, T3, D, R1, R2, R3)}.
554
+
555
+ @see: Class L{TransformXform}'s matching keyword argument names.
556
+ '''
557
+ _Names_ = _Names7 # ('tx', 'ty', 'tz', _s_, 'sx', 'sy', 'sz') == TransformXform.__init__
558
+ _Units_ = (_MM, _MM, _MM, _PPB, _MAS, _MAS, _MAS)
559
+
560
+ def __add__(self, other):
561
+ return self._add_sub(other, True)
562
+
563
+ def __eq__(self, other):
564
+ return isinstance(other, TRFXform7Tuple) and _equall(other, self)
565
+ # PYCHOK and self.name == other.name
566
+
567
+ def __hash__(self):
568
+ return _NamedTuple.__hash__(self)
569
+
570
+ def __mul__(self, factor):
571
+ _xisscalar(factor=factor)
572
+ return type(self)((x * factor for x in self), name=_STAR_) # .fsums._mul_op
573
+
574
+ def __neg__(self):
575
+ return self.inverse()
576
+
577
+ def __sub__(self, other):
578
+ return self._add_sub(other, False)
579
+
580
+ def _add_sub(self, other, p_):
581
+ '''(INTERNAL) Return C{this +/- other} L{TRFXform7Tuple}.
582
+ '''
583
+ _xinstanceof(TRFXform7Tuple, other=other)
584
+ op = _operator.add if p_ else _operator.sub
585
+ return type(self)(map(op, self, other), name=_PLUS_ if p_ else _MINUS_)
586
+
587
+ def inverse(self, name=NN):
588
+ '''Return the inverse of this transform.
589
+
590
+ @kwarg name: Optional name (C{str}).
591
+
592
+ @return: Inverse (L{TransformXform}).
593
+ '''
594
+ n = name or _negastr(self.name)
595
+ return type(self)(map(neg, self), name=n)
596
+
597
+ @Property_RO
598
+ def isunity(self):
599
+ '''Is this a C{unity, identity} transform (C{bool}).
600
+ '''
601
+ return not any(self)
602
+
603
+
604
+ class TRFXform(_Named):
605
+ '''A Terrestrial Reference Frame (TRF) converter between two
606
+ reference frames observed at an C{epoch}.
607
+ '''
608
+ _epoch = _EP0CH
609
+ _epoch_d = _0_0
610
+ _indir_d = NN # refName
611
+ _inver_d = False
612
+ refName1 = \
613
+ refName2 = NN
614
+ rates = \
615
+ xform = None
616
+
617
+ def __init__(self, refName1, refName2, epoch=None, xform=None,
618
+ rates=None, name=NN):
619
+ '''New L{TRFXform} TRF converter.
620
+
621
+ @arg refName1: Source reframe (C{str}), converting I{from}.
622
+ @arg refName2: Destination reframe (C{str}), converting I{to}.
623
+ @kwarg epoch: Epoch, a fractional year (L{Epoch}, C{scalar} or C{str}).
624
+ @kwarg xform: I{Transform} parameters at B{C{epoch}} (L{TRFXform7Tuple}).
625
+ @kwarg rates: I{Rate} parameters (L{TRFXform7Tuple}), like B{C{xform}},
626
+ but in C{units-per-year}.
627
+ @kwarg name: Optional name (C{str}), overriding the default from method
628
+ L{toStr<TRFXform.toStr>}.
629
+
630
+ @raise TRFError: Invalid B{C{refName1}}, B{C{refName2}} or B{C{epoch}}.
631
+
632
+ @raise TypeError: Invalid B{C{xform}} or B{C{rates}}.
633
+
634
+ @see: Functions L{trfXform}, L{trfTransform0} and L{trfTransforms}.
635
+ '''
636
+ self.refName1 = _stref(refName1=refName1)
637
+ self.refName2 = _stref(refName2=refName2)
638
+ _xinstanceof(TRFXform7Tuple, xform=xform, rates=rates)
639
+ self.epoch = epoch
640
+ self.xform = xform
641
+ self.rates = rates
642
+ self.rename(name or self.toStr())
643
+
644
+ def __add__(self, other):
645
+ return self._add_sub(other, True)
646
+
647
+ def __eq__(self, other):
648
+ return isinstance(other, TRFXform) and other.epoch == self.epoch \
649
+ and other.xform == self.xform \
650
+ and other.rates == self.rates
651
+
652
+ # def __hash__(self):
653
+ # return hash((self.epoch, self.xform, self.rates))
654
+
655
+ def __lt__(self, other): # for sorting
656
+ return isinstance(other, TRFXform) and (self.refName1 < other.refName1
657
+ or self.refName2 < other.refName2
658
+ or self.epoch < other.epoch)
659
+
660
+ def __neg__(self):
661
+ return self.inverse()
662
+
663
+ def __repr__(self):
664
+ return self.toRepr()
665
+
666
+ def __str__(self):
667
+ return self.toStr()
668
+
669
+ def __sub__(self, other):
670
+ return self._add_sub(other, False)
671
+
672
+ def _add_sub(self, other, p_, *n1_n2_n): # in _indirects below
673
+ '''(INTERNAL) Summate C{this +/- other} Xform at C{this.epoch}.
674
+
675
+ @see: U{Appendix, Table 7, last column "Sum of the previous ..."
676
+ <https://Geodesy.NOAA.gov/TOOLS/Htdp/Pearson_Snay_2012.pdf">}
677
+ '''
678
+ _xinstanceof(TRFXform, other=other)
679
+ X1 = self
680
+ e1 = X1.epoch
681
+ X2 = other.toEpoch(e1) # if other.epoch != e1 else other
682
+
683
+ n1, n2, n = n1_n2_n or _n1_n2_n3(X1, X2)
684
+
685
+ X = type(X1)(n1, n2, epoch=e1, xform=X1.xform._add_sub(X2.xform, p_),
686
+ rates=X1.rates._add_sub(X2.rates, p_),
687
+ name=_sumstr(X1.name, X2.name, p_))
688
+ X._epoch_d = X1.epoched + X2.epoched
689
+ X._indir_d = n # reframe?
690
+ X._inver_d = X1.inversed and X2.inversed
691
+ return X
692
+
693
+ def _at(self, epoch):
694
+ '''(INTERNAL) Return C{"self.nameB{@}epoch"}.
695
+ '''
696
+ n = self.name
697
+ if epoch != self.epoch:
698
+ _e = _AT_(NN, epoch)
699
+ if not n.endswith(_e):
700
+ n = NN(n, _e)
701
+ return n
702
+
703
+ @property_doc_(''' the epoch, fractional year (L{Epoch}).''')
704
+ def epoch(self):
705
+ '''Get the epoch (L{Epoch}).
706
+ '''
707
+ return self._epoch
708
+
709
+ @epoch.setter # PYCHOK setter!
710
+ def epoch(self, epoch):
711
+ '''Set the epoch (L{Epoch}, C{scalar} or C{str}).
712
+
713
+ @raise TRFError: Invalid B{C{epoch}}.
714
+ '''
715
+ e = _Epoch(epoch)
716
+ if self._epoch != e:
717
+ self.rename(self._at(e))
718
+ self._epoch = e
719
+
720
+ @property_RO
721
+ def epoched(self):
722
+ '''Get this Xform's aggregate I{epoch} deltas (C{float}).
723
+ '''
724
+ return self._epoch_d
725
+
726
+ @property_RO
727
+ def indirected(self):
728
+ '''Is this an I{indirected} Xform? (C{str} of space-separated
729
+ refNames) or C{NN}.
730
+ '''
731
+ return self._indir_d
732
+
733
+ def inverse(self, name=NN):
734
+ '''Return this Xform {inversed}, C{refName1} and C{-2} swapped.
735
+
736
+ @return: The inverse (L{TRFXform}).
737
+ '''
738
+ n = name or _negastr(self.name)
739
+ X = self.dup(refName1=self.refName2, xform=-self.xform,
740
+ refName2=self.refName1, rates=-self.rates,
741
+ name=n, _inver_d=not self.inversed)
742
+ # X = type(self)(self.refName2, self.refName1, epoch= self.epoch,
743
+ # xform=-self.xform,
744
+ # rates=-self.rates, name=n)
745
+ # if self.epoched:
746
+ # X._epoch_d = self.epoched
747
+ # if self.indirected:
748
+ # X._indir_d = self.indirected
749
+ # if not self.inversed:
750
+ # X._inver_d = True
751
+ return X
752
+
753
+ @property_RO
754
+ def inversed(self):
755
+ '''Is this an I{inversed} Xform? (C{bool}).
756
+ '''
757
+ return self._inver_d
758
+
759
+ def _reframe(self, name, datum=_GRS80):
760
+ '''(INTERNAL) Get an un-/registered frame.
761
+ '''
762
+ r = RefFrames.get(name)
763
+ if r is None or r.datum != datum:
764
+ r = RefFrame(self.epoch, datum)
765
+ r.name = name # unregistered
766
+ return r
767
+
768
+ @property_RO
769
+ def reframe1(self):
770
+ '''Get the un-/registered I{from} frame (C{RefFrame}).
771
+ '''
772
+ return self._reframe(self.refName1)
773
+
774
+ @property_RO
775
+ def reframe2(self):
776
+ '''Get the un-/registered I{to} frame (C{RefFrame}).
777
+ '''
778
+ return self._reframe(self.refName2)
779
+
780
+ def rename(self, name=NN):
781
+ '''Change this Xform's name.
782
+
783
+ @arg name: New name (C{str}), overriding the base
784
+ name C{"refName1B{@}epochB{x}refName2"}.
785
+
786
+ @return: The old name (C{str}).
787
+ '''
788
+ return _Named.rename(self, name or self.toStr())
789
+
790
+ def toEpoch(self, epoch):
791
+ '''Convert this Xform to B{C{epoch}}, if needed.
792
+
793
+ @arg epoch: Epoch, fractional year (C{Epoch}, C{scalar}
794
+ or C{str}).
795
+
796
+ @return: This Xform or a copy converted to B{C{epoch}}.
797
+
798
+ @raise TRFError: Invalid B{C{epoch}}.
799
+ '''
800
+ e = _Epoch(epoch)
801
+ X, d = self, e - self.epoch
802
+ if d:
803
+ t = X.xform + X.rates * d
804
+ X = X.dup(epoch=e, xform=t, name=X._at(e))
805
+ X._epoch_d += fabs(d)
806
+ return X
807
+
808
+ def toHelmert(self, factor=_MM2M):
809
+ '''Return the Helmert transform from this Xform scaled accordingly.
810
+
811
+ @kwarg factor: Factor to scale this Xform's C{xform} (C{scalar}),
812
+ default from C{milli-meter-} to C{meter-}, from
813
+ C{milli-arc-} to C{arc-seconds} and from C{ppB}
814
+ to C{ppM}.
815
+
816
+ @return: The Helmert transform (L{TransformXform}).
817
+ '''
818
+ h = self.xform * factor
819
+ H = TransformXform(**dict(h.items()))
820
+ H.name = self.name # unregistered
821
+ H.Xform = self
822
+ return H
823
+
824
+ def toRefFrame(self, point, datum=_GRS80, **epoch_epoch2_name):
825
+ '''Convert an ellipsoidal point from this Xform's C{refName1} and
826
+ C{epoch} to this Xform's C{refName2} and C{epoch2 or epoch}.
827
+
828
+ @arg point: The point to convert (C{Cartesian} or C{LatLon}).
829
+ @kwarg datum: Optional datum to define a temporary L{RefFrame} from
830
+ this Xform's C{refName1} or C{refName2} (C{datum}).
831
+ @kwarg epoch_epoch2_name: Optional keyword arguments C{B{epoch}=None},
832
+ B{C{epoch2}=None} and C{B{name}=refName1}.
833
+
834
+ @return: A copy of the B{C{point}}, converted and renamed.
835
+
836
+ @see: Method L{RefFrame.toRefFrame} for more details.
837
+ '''
838
+ r1 = self._reframe(self.refName1, datum=datum)
839
+ r2 = self._reframe(self.refName2, datum=datum)
840
+ return _toRefFrame(point, r2, reframe=r1,
841
+ **_xkwds(epoch_epoch2_name, name=r1.name))
842
+
843
+ def toRepr(self, **unused): # PYCHOK signature
844
+ '''Return the represention of this Xform (C{str}).
845
+ '''
846
+ return unstr(self.classname, name=self.name, epoch=self.epoch)
847
+
848
+ def toStr(self, epoch=None, **unused): # PYCHOK signature
849
+ '''Return this Xform as C{"refName1B{@}epochB{x}refName2"} (C{str}).
850
+
851
+ @kwarg epoch: Epoch (C{Epoch}, C{scalar} or C{str}), overriding
852
+ this Xform's epoch.
853
+ '''
854
+ e = self.epoch if epoch is None else _Epoch(epoch)
855
+ return NN(_AT_(self.refName1, e), _x_, self.refName2)
856
+
857
+ def toTransform(self, epoch=None, epoch2=None, inverse=False):
858
+ '''Combine this Xform observed at B{C{epoch}} into a Helmert
859
+ L{TransformXform}, optionally at B{C{epoch2 or epoch}}.
860
+
861
+ @kwarg epoch: Epoch to observe I{from} (C{scalar}),
862
+ overriding this converter's epoch.
863
+ @kwarg epoch2: Optional epoch to observe I{to} (C{scalar}),
864
+ overriding B{C{epoch}}.
865
+ @kwarg inverse: Use the Xform's inverse (C{bool}).
866
+
867
+ @return: The Helmert transform (L{TransformXform}).
868
+
869
+ @raise TRFError: Invalid B{C{epoch}} or B{C{epoch2}}.
870
+
871
+ @see: Method L{toHelmert}.
872
+ '''
873
+ if epoch2 is None:
874
+ e = self.epoch if epoch is None else epoch
875
+ elif isinstance(epoch2, Epoch):
876
+ e = epoch2
877
+ else:
878
+ e = Epoch(epoch2=epoch2)
879
+ X = self.toEpoch(e)
880
+ if inverse:
881
+ X = X.inverse()
882
+ return X.toHelmert()
883
+
884
+
885
+ def date2epoch(year, month, day):
886
+ '''Return the C{epoch} for a calendar day.
887
+
888
+ @arg year: Year of the date (C{scalar}).
889
+ @arg month: Month in the B{C{year}} (C{scalar}, 1..12).
890
+ @arg day: Day in the B{C{month}} (C{scalar}, 1..31).
891
+
892
+ @return: Epoch, the fractional year (C{float}).
893
+
894
+ @raise TRFError: Invalid B{C{year}}, B{C{month}} or B{C{day}}.
895
+
896
+ @note: Any B{C{year}} is considered a leap year, i.e. having
897
+ 29 days in February.
898
+ '''
899
+ try:
900
+ y, m, d = map1(int, year, month, day)
901
+ if y > 0 and 1 <= m <= 12 and 1 <= d <= _mDays[m]:
902
+ e = y + float(sum(_mDays[:m]) + d) / _366_0
903
+ return Epoch(e, low=0)
904
+
905
+ raise ValueError # _invalid_
906
+ except (TRFError, TypeError, ValueError) as x:
907
+ raise TRFError(year=year, month=month, day=day, cause=x)
908
+
909
+
910
+ def _direct(n1, n2):
911
+ '''(INTERNAL) Get the C{n1} to C{n2} Xform or C{None}.
912
+ '''
913
+ r = RefFrames.get(n1)
914
+ return r._Xto.get(n2, None) if r else None
915
+
916
+
917
+ def _Epoch(e, **kwds):
918
+ '''(INTERNAL) Get the C{Epoch(B{e})}.
919
+ '''
920
+ return e if isinstance(e, Epoch) and not kwds else Epoch(e, **kwds)
921
+
922
+
923
+ def epoch2date(epoch):
924
+ '''Return the date for a reference frame C{epoch}.
925
+
926
+ @arg epoch: Fractional year (C{scalar}).
927
+
928
+ @return: 3-Tuple C{(year, month, day)}.
929
+
930
+ @raise TRFError: Invalid B{C{epoch}}.
931
+
932
+ @note: Any B{C{year}} is considered a leap year, i.e. having
933
+ 29 days in February.
934
+ '''
935
+ e = Epoch(epoch, low=0)
936
+ y = int(e)
937
+ d = int(_ceil((e - y) * _366_0))
938
+ for m, n in enumerate(_mDays[1:]):
939
+ if d > n:
940
+ d -= n
941
+ else:
942
+ break
943
+ return y, (m + 1), max(1, d)
944
+
945
+
946
+ def _eXhaustives(n1, n2):
947
+ '''(INTERNAL) Yield all I{coalesced} Xforms from C{n1} to {n2}
948
+ via I{any number of} intermediate reframe conversions.
949
+ '''
950
+ def _k2(item):
951
+ return -item[1].epoch # most recent first
952
+
953
+ R = dict(RefFrames)
954
+ r = R.pop(n1, None)
955
+ if r:
956
+ Xs = list(sorted(tuple(r._Xitems(2, R)), key=_k2))
957
+ while Xs:
958
+ n, X = Xs.pop(0)
959
+ if n == n2:
960
+ yield _n_pop(X)
961
+ else:
962
+ r = R.pop(n, None)
963
+ if r:
964
+ for n, x in r._Xitems(2, R):
965
+ Xs.append((n, X + x))
966
+
967
+
968
+ def _indirects(n1, n2):
969
+ '''(INTERNAL) Yield all Xforms between C{n1} and C{n2} via
970
+ I{one} intermediate reframe C{n} conversion.
971
+ '''
972
+ def _X4(_Xto, n2):
973
+ _d = _direct
974
+ for n, X1 in _Xto.items():
975
+ X2 = _d(n, n2)
976
+ if X2:
977
+ yield X1, X2, n, True # X1 + X2
978
+ X2 = _d(n2, n)
979
+ if X2:
980
+ yield X1, X2, n, False # X1 - X2
981
+
982
+ r1 = RefFrames.get(n1)
983
+ if r1:
984
+ for X1, X2, n, p_ in _X4(r1._Xto, n2):
985
+ e1, e2 = X1.epoch, X2.epoch
986
+ if e1 < e2: # X1 to e2
987
+ X1 = X1.toEpoch(e2)
988
+ # elif e1 > e2: # X2 to e1
989
+ # X2 = X2.toEpoch(e1)
990
+ yield X1._add_sub(X2, p_, n1, n2, n)
991
+
992
+
993
+ def _n1_n2_n3(X1, X2):
994
+ '''(INTERNAL) L{TRFXform._add_sub} helper.
995
+ '''
996
+ n = X1.indirected
997
+ n = _SPACE_(n, X1.refName2) if n else X1.refName2
998
+ return X1.refName1, X2.refName2, n
999
+
1000
+
1001
+ def _n_pop(X):
1002
+ '''(INTERNAL) Pop L{TRFXform.indirected}'s ends.
1003
+ '''
1004
+ p, n = None, X.indirected.split()
1005
+ if n and n[-1] == X.refName2:
1006
+ p = n.pop()
1007
+ if n and n[ 0] == X.refName1:
1008
+ p = n.pop(0)
1009
+ if p:
1010
+ X._indir_d = _SPACE_.join(n) if n else NN
1011
+ return X
1012
+
1013
+
1014
+ def _reframe(**name_reframe):
1015
+ '''(INTERNAL) Get a C{reframe}.
1016
+ '''
1017
+ _, r = _xkwds_item2(name_reframe)
1018
+ if isstr(r) and r: # not NN
1019
+ r = RefFrames.get(r)
1020
+ if r and isinstance(r, RefFrame):
1021
+ return r
1022
+ raise TRFError(**name_reframe) # _invalid_
1023
+
1024
+
1025
+ def _stref(**name_refname):
1026
+ '''(INTERNAL) Check a reference frame name.
1027
+ '''
1028
+ _, n = _xkwds_item2(name_refname)
1029
+ if isstr(n) and isidentifier(n):
1030
+ return str(n)
1031
+ raise TRFError(**name_refname) # _invalid_
1032
+
1033
+
1034
+ def _sumstr(name1, name2, p_):
1035
+ '''(INTERNAL) "Sum" of C{name1 + ('+' if p_ else '-') + name2}.
1036
+ '''
1037
+ if name2:
1038
+ n = name2 if p_ else _negastr(name2)
1039
+ p = NN if n.startswith(_MINUS_) or \
1040
+ n.startswith(_PLUS_) else _PLUS_
1041
+ name1 = NN(name1, p, n)
1042
+ return name1
1043
+
1044
+
1045
+ def _toRefFrame(point, reframe2, reframe=None, epoch=None,
1046
+ epoch2=None, name=NN, **LatLon_kwds):
1047
+ '''(INTERNAL) Convert an ellipsoidal point to C{reframe2}
1048
+ and C{epoch2 or epoch or pont.epoch or reframe.epoch}.
1049
+ '''
1050
+ ll = _xellipsoidall(point)
1051
+ r1 = reframe or point.reframe
1052
+ if not r1:
1053
+ t = _SPACE_(_DOT_(repr(point), _reframe_), MISSING)
1054
+ raise TRFError(_no_(_conversion_), txt=t)
1055
+
1056
+ _xinstanceof(RefFrame, reframe2=reframe2, reframe=r1)
1057
+
1058
+ e1 = _Epoch(epoch or point.epoch or r1.epoch)
1059
+ e2 = e1 if epoch2 is None else Epoch(epoch2=epoch2)
1060
+ t0 = _toTransform0(r1.name, e1, reframe2.name, e2)
1061
+ if t0 is None:
1062
+ t = _SPACE_(RefFrame.__name__, _AT_(r1.name, e1),
1063
+ _to_, _AT_(reframe2.name, e2))
1064
+ raise TRFError(_no_(_conversion_), txt=t)
1065
+
1066
+ if t0: # is not ()
1067
+ if t0.isunity:
1068
+ p = point.dup()
1069
+ elif point.datum:
1070
+ p = point.toCartesian() if ll else point
1071
+ p = p.toDatum( r1.datum).toTransform(t0) \
1072
+ .toDatum(reframe2.datum).toDatum(point.datum)
1073
+ if ll:
1074
+ p = p.toLatLon(LatLon=point.classof, **LatLon_kwds)
1075
+ elif ll: # and LatLon_kwds
1076
+ p = point.toTransform(t0, **LatLon_kwds)
1077
+ else:
1078
+ p = point.toTransform(t0)
1079
+ p._reframe = reframe2 # see TRFXform.toRefFrame above
1080
+ p._epoch = _xattr(t0.Xform, epoch=e2)
1081
+ p.rename(name or reframe2.name)
1082
+ else:
1083
+ p = point.dup(_reframe=reframe2, # ditto
1084
+ _epoch=e2, name=name) if name else point
1085
+ return p
1086
+
1087
+
1088
+ def _toTransform0(n1, e1, n2, e2, **indirect_inverse):
1089
+ '''(INTERNAL) Return a L{TransformXform}, 0-tuple or C{None}.
1090
+ '''
1091
+ if n1 == n2 and e1 == e2:
1092
+ return () # unity?
1093
+
1094
+ for X in _toTransforms(n1, e1, n2, e2, **indirect_inverse):
1095
+ return X # first OK?
1096
+
1097
+ if (n1.startswith(_ITRF_) and n2.startswith(_WGS84_)) or \
1098
+ (n2.startswith(_ITRF_) and n1.startswith(_WGS84_)): # and e1 == e2?
1099
+ return () # unity?
1100
+
1101
+ return None
1102
+
1103
+
1104
+ def _toTransforms(n1, e1, n2, e2, indirect=True, inverse=True, exhaust=False): # MCCABE 16
1105
+ '''(INTERNAL) Yield all possible Helmert transforms, if any.
1106
+ '''
1107
+ class Ts(list): # L{TransformXform}s de-dup
1108
+ def __call__(self, Xs, e1=e1, e2=e2, **inverse):
1109
+ for X in Xs:
1110
+ if X:
1111
+ T = X.toTransform(e1, epoch2=e2, **inverse)
1112
+ if T not in self:
1113
+ self.append(T)
1114
+ yield T
1115
+
1116
+ # def __contains__(self, T):
1117
+ # _xinstanceof(TransformXform, T=T)
1118
+ # return any(t == T for t in self)
1119
+
1120
+ def _k(X):
1121
+ return -X.epoch # most recent first
1122
+
1123
+ _Ts = Ts()
1124
+
1125
+ for T in _Ts((_direct(n1, n2),), inverse=False):
1126
+ yield T
1127
+ if inverse:
1128
+ for T in _Ts((_direct(n2, n1),), inverse=True):
1129
+ yield T
1130
+
1131
+ if indirect:
1132
+ for T in _Ts(sorted(_indirects(n1, n2), key=_k), inverse=False):
1133
+ yield T
1134
+ if inverse:
1135
+ for T in _Ts(sorted(_indirects(n2, n1), key=_k), inverse=True):
1136
+ yield T
1137
+
1138
+ if exhaust:
1139
+ for T in _Ts(_eXhaustives(n1, n2), inverse=False):
1140
+ yield T
1141
+ for T in _Ts(_eXhaustives(n2, n1), inverse=True):
1142
+ yield T
1143
+
1144
+
1145
+ def trfTransform0(reframe, reframe2, epoch=None, epoch2=None, indirect=True, inverse=True, exhaust=False):
1146
+ '''Get a Helmert transform to convert one C{reframe} observed at C{epoch}
1147
+ to an other C{reframe2} at observed at C{epoch2 or epoch}.
1148
+
1149
+ @return: A L{TransformXform} instance, a C{0-tuple} for I{unity, identity} or
1150
+ C{None} if no conversion exists.
1151
+
1152
+ @see: Function L{trfTransforms} for futher details.
1153
+ '''
1154
+ return _trfT0s(_toTransform0, reframe, reframe2, epoch, epoch2,
1155
+ indirect=indirect, inverse=inverse, exhaust=exhaust)
1156
+
1157
+
1158
+ def trfTransforms(reframe, reframe2, epoch=None, epoch2=None, indirect=True, inverse=True, exhaust=False):
1159
+ '''Yield all Helmert transform to convert one C{reframe} observed at C{epoch}
1160
+ to an other C{reframe2} at observed at C{epoch2 or epoch}.
1161
+
1162
+ @arg reframe: The frame to convert I{from} (L{RefFrame} or C{str}).
1163
+ @arg reframe2: The frame to convert I{to} (L{RefFrame} or C{str}).
1164
+ @arg epoch: Epoch to observe I{from} (L{Epoch}, C{scalar} or C{str}),
1165
+ otherwise C{B{reframe}}'s C{epoch}.
1166
+ @kwarg epoch2: Optional epoch to observe I{to} (L{Epoch}, C{scalar} or C{str}),
1167
+ otherwise B{C{epoch}}.
1168
+ @kwarg indirect: If C{True}, include transforms via I{one} intermediate reframe,
1169
+ otherwise only I{direct} B{C{reframe}} to B{C{reframe2}}
1170
+ transforms (C{bool}).
1171
+ @kwarg inverse: If C{True}, include inverse, otherwise only forward transforms
1172
+ (C{bool}).
1173
+ @kwarg exhaust: If C{True}, exhaustively generate all transforms, forward and
1174
+ inverse and via any number of intermediate reframes (C{bool}).
1175
+
1176
+ @return: A L{TransformXform} instance for each available conversion, without
1177
+ duplicates.
1178
+
1179
+ @raise TRFError: Invalid B{C{reframe}}, B{C{reframe2}}, B{C{epoch}} or B{C{epoch2}}.
1180
+
1181
+ @raise TypeError: Invalid B{C{reframe}} or B{C{reframe2}}.
1182
+ '''
1183
+ return _trfT0s(_toTransforms, reframe, reframe2, epoch, epoch2,
1184
+ indirect=indirect, inverse=inverse, exhaust=exhaust)
1185
+
1186
+
1187
+ def _trfT0s(_toT0s, reframe, reframe2, epoch, epoch2, **indirect_inverse_exhaust):
1188
+ '''(INTERNAL) Handle C{trfTransforms0} and C{trfTransforms} calls.
1189
+ '''
1190
+ r1 = _reframe(reframe=reframe)
1191
+ e1 = r1.epoch if epoch is None else _Epoch(epoch)
1192
+ r2 = _reframe(reframe2=reframe2)
1193
+ e2 = e1 if epoch2 is None else Epoch(epoch2=epoch2)
1194
+ return _toT0s(r1.name, e1, r2.name, e2, **indirect_inverse_exhaust)
1195
+
1196
+
1197
+ def trfXform(reframe1, reframe2, epoch=None, xform=None, rates=None, raiser=True):
1198
+ '''Define a new Terrestrial Reference Frame (TRF) converter or get an
1199
+ existing one.
1200
+
1201
+ @arg reframe1: Source frame (L{RefFrame} or C{str}), converting I{from}.
1202
+ @arg reframe2: Destination frame (L{RefFrame} or C{str}), converting I{to}.
1203
+ @kwarg epoch: Epoch, a fractional year (L{Epoch}, C{scalar} or C{str})
1204
+ or C{None} for C{B{reframe2}}'s epoch.
1205
+ @kwarg xform: I{Transform} parameters (L{TRFXform7Tuple}).
1206
+ @kwarg rates: I{Rate} parameters (L{TRFXform7Tuple}), as B{C{xform}},
1207
+ but in C{units-per-year}.
1208
+ @kwarg raiser: If C{False}, do not raise an error if the converter
1209
+ exists, replace it (C{bool}).
1210
+
1211
+ @return: The new TRF converter (L{TRFXform}) or if no B{C{epoch}},
1212
+ B{C{xform}} and B{C{rates}} are given, return the existing
1213
+ one (L{TRFXform}) or C{None} if not available.
1214
+
1215
+ @raise TRFError: Invalid B{C{reframe1}}, B{C{reframe2}}, B{C{epoch}},
1216
+ B{C{xform}} or B{C{rates}} or the TRF converter
1217
+ already exists.
1218
+ '''
1219
+ try:
1220
+ r1 = _reframe(reframe1=reframe1)
1221
+ r2 = _reframe(reframe2=reframe2)
1222
+ if epoch is None:
1223
+ if xform is rates is None:
1224
+ return r1._Xto.get(r2.name, None)
1225
+ e = r2.epoch
1226
+ else:
1227
+ e = _Epoch(epoch)
1228
+ return _trfX(r1.name, r2.name, raiser=raiser, epoch=e,
1229
+ xform=xform, rates=rates)
1230
+ except (TypeError, ValueError) as x:
1231
+ t = unstr(trfXform, reframe1, reframe2, epoch=epoch)
1232
+ raise TRFError(t, cause=x)
1233
+
1234
+
1235
+ def _trfX(n1, n2, raiser=True, **epoch_xform_rates):
1236
+ '''(INTERNAL) New, I{unique} L{TRFXform} converter.
1237
+ '''
1238
+ r1 = RefFrames.get(n1)
1239
+ if r1 is None:
1240
+ raise ValueError(_invalid_)
1241
+ r2 = RefFrames.get(n2)
1242
+ if r2 is None:
1243
+ raise ValueError(_invalid_)
1244
+ if raiser:
1245
+ if n2 in r1._Xto:
1246
+ raise ValueError(_exists_)
1247
+ if n1 in r2._Xto:
1248
+ raise ValueError(_SPACE_(_inverse_, _exists_))
1249
+ r1._Xto[n2] = X = TRFXform(n1, n2, **epoch_xform_rates)
1250
+ return X
1251
+
1252
+
1253
+ # def velocities2neu(vx, vy, vz, lat=0, lon=0):
1254
+ # '''Convert X, Y, and Z I{velocities} to North, East, Up.
1255
+ #
1256
+ # @arg vx: X velocity (C{meter-per-time}).
1257
+ # @arg vx: Y velocity (C{meter-per-time}).
1258
+ # @arg vx: Z velocity (C{meter-per-time}).
1259
+ # @kwarg lat: Latitude (C{degrees}).
1260
+ # @kwarg lon: Longitude (C{degrees}).
1261
+ #
1262
+ # @return: 3-Tuple C{(vnorth, veast, vup)} with the
1263
+ # North, East and Up velocities, same units
1264
+ # as B{C{vx}, B{C{vy}} and B{C{vx}}.
1265
+ # '''
1266
+ # sa, ca, sb, cb = sincos2d_(lat, lon)
1267
+ # ve = cb * vy - sb * vx
1268
+ # v = cb * vx + sb * vy
1269
+ # vn = ca * vz - sa * v
1270
+ # vu = sa * vz + ca * v
1271
+ # return vn, ve, vu
1272
+
1273
+
1274
+ # def velocities2xyz(vn, ve, vu, lat=0, lon=0):
1275
+ # '''Convert North, East and Up I{velocities} to X, Y, Z.
1276
+ #
1277
+ # @arg vn: North velocity (C{meter-per-time}).
1278
+ # @arg ve: East velocity (C{meter-per-time}).
1279
+ # @arg vu: Up velocity (C{meter-per-time}).
1280
+ # @kwarg lat: Latitude (C{degrees}).
1281
+ # @kwarg lon: Longitude (C{degrees}).
1282
+ #
1283
+ # @return: 3-Tuple C{(vx, vy, vz)} with the X, Y
1284
+ # and Z velocities, same units as B{C{vn},
1285
+ # B{C{ve}} and B{C{vu}}.
1286
+ # '''
1287
+ # sa, ca, sb, cb = sincos2d_(lat, lon)
1288
+ # vz = ca * vn + sa * vu
1289
+ # v = ca * vu - sa * vn
1290
+ # vx = cb * v - sb * ve
1291
+ # vy = sb * v + cb * ve
1292
+ # return vx, vy, vz
1293
+
1294
+
1295
+ def _X(*ps): # deleted below
1296
+ return _P(ps, _xform_, _Xs) # PYCHOK del
1297
+
1298
+
1299
+ def _R(*ps): # deleted below
1300
+ return _P(ps, _rates_, _Rs) # PYCHOK del
1301
+
1302
+
1303
+ _P_0_0s = TRFXform7Tuple(_0_0s(len(_Names7)), name='unity')
1304
+
1305
+ # TRF conversions specified as an epoch and 2 sets of 7 parameters. Most from Altamimi, Z. U{"EUREF Technical
1306
+ # Note 1: Relationship and Transformation between the International and the European Terrestrial Reference
1307
+ # Systems"<https://ERTS89.ENSG.IFN.Fr/pub/EUREF-TN-1-Jan-31-2024.pdf>} Appendix A, more at U{Quinsy QPS <https://
1308
+ # confluence.QPS.NL/qinsy/files/latest/en/182618383/182618384/1/1579182881000/ITRF_Transformation_Parameters.xlsx>}.
1309
+ # See also U{Quinsy International Terrestrial Reference Frame 2014 (ITRF2014)<https://confluence.QPS.NL/qinsy/latest/
1310
+ # en/international-terrestrial-reference-frame-2014-itrf2014-182618383.html>}.
1311
+ _trfX(_ITRF2020_, _ITRF2014_, epoch=_E(2015), # <https://ITRF.IGN.Fr/docs/solutions/itrf2020/Transfo-ITRF2020_TRFs.txt>
1312
+ xform=_X( -1.4, -0.9, 1.4, -0.42, _0_0, _0_0, _0_0),
1313
+ rates=_R( _0_0, -0.1, 0.2, _0_0, _0_0, _0_0, _0_0))
1314
+ _trfX(_ITRF2020_, _ITRF2008_, epoch=_E(2015),
1315
+ xform=_X( 0.2, 1.0, 3.3, -0.29, _0_0, _0_0, _0_0),
1316
+ rates=_R( _0_0, -0.1, 0.1, 0.03, _0_0, _0_0, _0_0))
1317
+ _trfX(_ITRF2020_, _ITRF2005_, epoch=_E(2015),
1318
+ xform=_X( 2.7, 0.1, -1.4, 0.65, _0_0, _0_0, _0_0),
1319
+ rates=_R( 0.3, -0.1, 0.1, 0.03, _0_0, _0_0, _0_0))
1320
+ _trfX(_ITRF2020_, _ITRF2000_, epoch=_E(2015),
1321
+ xform=_X( -0.2, 0.8, -34.2, 2.25, _0_0, _0_0, _0_0),
1322
+ rates=_R( 0.1, _0_0, -1.7, 0.11, _0_0, _0_0, _0_0))
1323
+ _trfX(_ITRF2020_, _ITRF97_, epoch=_E(2015),
1324
+ xform=_X( 6.5, -3.9, -77.9, 3.98, _0_0, _0_0, 0.36),
1325
+ rates=_R( 0.1, -0.6, -3.1, 0.12, _0_0, _0_0, 0.02))
1326
+ _trfX(_ITRF2020_, _ITRF96_, epoch=_E(2015),
1327
+ xform=_X( 6.5, -3.9, -77.9, 3.98, _0_0, _0_0, 0.36),
1328
+ rates=_R( 0.1, -0.6, -3.1, 0.12, _0_0, _0_0, 0.02))
1329
+ _trfX(_ITRF2020_, _ITRF94_, epoch=_E(2015),
1330
+ xform=_X( 6.5, -3.9, -77.9, 3.98, _0_0, _0_0, 0.36),
1331
+ rates=_R( 0.1, -0.6, -3.1, 0.12, _0_0, _0_0, 0.02))
1332
+ _trfX(_ITRF2020_, _ITRF93_, epoch=_E(2015),
1333
+ xform=_X( -65.8, 1.9, -71.3, 4.47, -3.36, -4.33, 0.75),
1334
+ rates=_R( -2.8, -0.2, -2.3, 0.12, -0.11, -0.19, 0.07))
1335
+ _trfX(_ITRF2020_, _ITRF92_, epoch=_E(2015),
1336
+ xform=_X( 14.5, -1.9, -85.9, 3.27, _0_0, _0_0, 0.36),
1337
+ rates=_R( 0.1, -0.6, -3.1, 0.12, _0_0, _0_0, 0.02))
1338
+ _trfX(_ITRF2020_, _ITRF91_, epoch=_E(2015),
1339
+ xform=_X( 26.5, 12.1, -91.9, 4.67, _0_0, _0_0, 0.36),
1340
+ rates=_R( 0.1, -0.6, -3.1, 0.12, _0_0, _0_0, 0.02))
1341
+ _trfX(_ITRF2020_, _ITRF90_, epoch=_E(2015),
1342
+ xform=_X( 24.5, 8.1, -107.9, 4.97, _0_0, _0_0, 0.36),
1343
+ rates=_R( 0.1, -0.6, -3.1, 0.12, _0_0, _0_0, 0.02))
1344
+ _trfX(_ITRF2020_, _ITRF89_, epoch=_E(2015),
1345
+ xform=_X( 29.5, 32.1, -145.9, 8.37, _0_0, _0_0, 0.36),
1346
+ rates=_R( 0.1, -0.6, -3.1, 0.12, _0_0, _0_0, 0.02))
1347
+ _trfX(_ITRF2020_, _ITRF88_, epoch=_E(2015),
1348
+ xform=_X( 24.5, -3.9, -169.9, 11.47, 0.1, _0_0, 0.36),
1349
+ rates=_R( 0.1, -0.6, -3.1, 0.12, _0_0, _0_0, 0.02))
1350
+
1351
+ # see U{Transformation Parameters ITRF2014<http://ITRF.IGN.Fr/doc_ITRF/Transfo-ITRF2014_ITRFs.txt>} and
1352
+ # Altamimi, Z. U{"EUREF Technical Note 1: Relationship and Transformation between the International and
1353
+ # the European Terrestrial Reference Systems"<https://ERTS89.ENSG,IFN.Fr/pub/EUREF-TN-1.pdf>} Appendix A.
1354
+ _trfX(_ITRF2014_, _ITRF2008_, epoch=(2010), # <http://ITRF.ENSG.IGN.Fr/ITRF_solutions/2014/tp_14-08.php>
1355
+ xform=_X( 1.6, 1.9, 2.4, -0.02, _0_0, _0_0, _0_0),
1356
+ rates=_R( _0_0, _0_0, -0.1, 0.03, _0_0, _0_0, _0_0))
1357
+ _trfX(_ITRF2014_, _ITRF2005_, epoch=_E(2010),
1358
+ xform=_X( 2.6, _1_0, -2.3, 0.92, _0_0, _0_0, _0_0),
1359
+ rates=_R( 0.3, _0_0, -0.1, 0.03, _0_0, _0_0, _0_0))
1360
+ _trfX(_ITRF2014_, _ITRF2000_, epoch=_E(2010),
1361
+ xform=_X( 0.7, 1.2, -26.1, 2.12, _0_0, _0_0, _0_0),
1362
+ rates=_R( 0.1, 0.1, -1.9, 0.11, _0_0, _0_0, _0_0))
1363
+ _trfX(_ITRF2014_, _ITRF97_, epoch=_E(2010),
1364
+ xform=_X( 7.4, -0.5, -62.8, 3.8, _0_0, _0_0, 0.26),
1365
+ rates=_R( 0.1, -0.5, -3.3, 0.12, _0_0, _0_0, 0.02))
1366
+ _trfX(_ITRF2014_, _ITRF96_, epoch=_E(2010),
1367
+ xform=_X( 7.4, -0.5, -62.8, 3.8, _0_0, _0_0, 0.26),
1368
+ rates=_R( 0.1, -0.5, -3.3, 0.12, _0_0, _0_0, 0.02))
1369
+ _trfX(_ITRF2014_, _ITRF94_, epoch=_E(2010),
1370
+ xform=_X( 7.4, -0.5, -62.8, 3.8, _0_0, _0_0, 0.26),
1371
+ rates=_R( 0.1, -0.5, -3.3, 0.12, _0_0, _0_0, 0.02))
1372
+ _trfX(_ITRF2014_, _ITRF93_, epoch=_E(2010),
1373
+ xform=_X( -50.4, 3.3, -60.2, 4.29, -2.81, -3.38, 0.4),
1374
+ rates=_R( -2.8, -0.1, -2.5, 0.12, -0.11, -0.19, 0.07))
1375
+ _trfX(_ITRF2014_, _ITRF92_, epoch=_E(2010),
1376
+ xform=_X( 15.4, 1.5, -70.8, 3.09, _0_0, _0_0, 0.26),
1377
+ rates=_R( 0.1, -0.5, -3.3, 0.12, _0_0, _0_0, 0.02))
1378
+ _trfX(_ITRF2014_, _ITRF91_, epoch=_E(2010),
1379
+ xform=_X( 27.4, 15.5, -76.8, 4.49, _0_0, _0_0, 0.26),
1380
+ rates=_R( 0.1, -0.5, -3.3, 0.12, _0_0, _0_0, 0.02))
1381
+ _trfX(_ITRF2014_, _ITRF90_, epoch=_E(2010),
1382
+ xform=_X( 25.4, 11.5, -92.8, 4.79, _0_0, _0_0, 0.26),
1383
+ rates=_R( 0.1, -0.5, -3.3, 0.12, _0_0, _0_0, 0.02))
1384
+ _trfX(_ITRF2014_, _ITRF89_, epoch=_E(2010),
1385
+ xform=_X( 30.4, 35.5, -130.8, 8.19, _0_0, _0_0, 0.26),
1386
+ rates=_R( 0.1, -0.5, -3.3, 0.12, _0_0, _0_0, 0.02))
1387
+ _trfX(_ITRF2014_, _ITRF88_, epoch=_E(2010),
1388
+ xform=_X( 25.4, -0.5, -154.8, 11.29, 0.1, _0_0, 0.26),
1389
+ rates=_R( 0.1, -0.5, -3.3, 0.12, _0_0, _0_0, 0.02))
1390
+
1391
+ # Pearson, C. & Snay, R. U{"Introducing HTDP 3.1 to transform coordinates across time and spatial reference
1392
+ # frames"<https://Geodesy.NOAA.gov/TOOLS/Htdp/Pearson_Snay_2012.pdf> Table 7, 1st and 2nd column
1393
+ _trfX(_ITRF2008_, _ITRF2005_, epoch=_E(2005),
1394
+ xform=_X( -0.5, -0.9, -4.7, 0.94, _0_0, _0_0, _0_0),
1395
+ rates=_R( 0.3, _0_0, _0_0, _0_0, _0_0, _0_0, _0_0))
1396
+ # _trfX(_ITRF2008_, _ITRF2005_, epoch=_E(1997),
1397
+ # xform=_X( -2.9, -0.9, -4.7, 0.94, _0_0, _0_0, _0_0),
1398
+ # rates=_R( 0.3, _0_0, _0_0, _0_0, _0_0, _0_0, _0_0))
1399
+ # see U{Transformation Parameters ITRF2008<http://ITRF.IGN.Fr/doc_ITRF/Transfo-ITRF2008_ITRFs.txt>}
1400
+ # _trfX(_ITRF2008_, _ITRF2005_, epoch=_E(2000), # <http://ITRF.ENSG.IGN.Fr/ITRF_solutions/2008/tp_08-05.php>
1401
+ # xform=_X( -2.0, -0.9, -4.7, 0.94, _0_0, _0_0, _0_0),
1402
+ # rates=_R( 0.3, _0_0, _0_0, _0_0, _0_0, _0_0, _0_0))
1403
+ _trfX(_ITRF2008_, _ITRF2000_, epoch=_E(2000),
1404
+ xform=_X( -1.9, -1.7, -10.5, 1.34, _0_0, _0_0, _0_0),
1405
+ rates=_R( 0.1, 0.1, -1.8, 0.08, _0_0, _0_0, _0_0))
1406
+ _trfX(_ITRF2008_, _ITRF97_, epoch=_E(2000),
1407
+ xform=_X( 4.8, 2.6, -33.2, 2.92, _0_0, _0_0, 0.06),
1408
+ rates=_R( 0.1, -0.5, -3.2, 0.09, _0_0, _0_0, 0.02))
1409
+ _trfX(_ITRF2008_, _ITRF96_, epoch=_E(2000),
1410
+ xform=_X( 4.8, 2.6, -33.2, 2.92, _0_0, _0_0, 0.06),
1411
+ rates=_R( 0.1, -0.5, -3.2, 0.09, _0_0, _0_0, 0.02))
1412
+ _trfX(_ITRF2008_, _ITRF94_, epoch=_E(2000),
1413
+ xform=_X( 4.8, 2.6, -33.2, 2.92, _0_0, _0_0, 0.06),
1414
+ rates=_R( 0.1, -0.5, -3.2, 0.09, _0_0, _0_0, 0.02))
1415
+ _trfX(_ITRF2008_, _ITRF93_, epoch=_E(2000),
1416
+ xform=_X( -24.0, 2.4, -38.6, 3.41, -1.71, -1.48, -0.3),
1417
+ rates=_R( -2.8, -0.1, -2.4, 0.09, -0.11, -0.19, 0.07))
1418
+ _trfX(_ITRF2008_, _ITRF92_, epoch=_E(2000),
1419
+ xform=_X( 12.8, 4.6, -41.2, 2.21, _0_0, _0_0, 0.06),
1420
+ rates=_R( 0.1, -0.5, -3.2, 0.09, _0_0, _0_0, 0.02))
1421
+ _trfX(_ITRF2008_, _ITRF91_, epoch=_E(2000),
1422
+ xform=_X( 24.8, 18.6, -47.2, 3.61, _0_0, _0_0, 0.06),
1423
+ rates=_R( 0.1, -0.5, -3.2, 0.09, _0_0, _0_0, 0.02))
1424
+ _trfX(_ITRF2008_, _ITRF90_, epoch=_E(2000),
1425
+ xform=_X( 22.8, 14.6, -63.2, 3.91, _0_0, _0_0, 0.06),
1426
+ rates=_R( 0.1, -0.5, -3.2, 0.09, _0_0, _0_0, 0.02))
1427
+ _trfX(_ITRF2008_, _ITRF89_, epoch=_E(2000),
1428
+ xform=_X( 27.8, 38.6, -101.2, 7.31, _0_0, _0_0, 0.06),
1429
+ rates=_R( 0.1, -0.5, -3.2, 0.09, _0_0, _0_0, 0.02))
1430
+ _trfX(_ITRF2008_, _ITRF88_, epoch=_E(2000),
1431
+ xform=_X( 22.8, 2.6, -125.2, 10.41, 0.1, _0_0, 0.06),
1432
+ rates=_R( 0.1, -0.5, -3.2, 0.09, _0_0, _0_0, 0.02))
1433
+
1434
+ # Pearson, C. & Snay, R. U{"Introducing HTDP 3.1 to transform coordinates across time and spatial reference
1435
+ # frames"<https://Geodesy.NOAA.gov/TOOLS/Htdp/Pearson_Snay_2012.pdf> Table 7, 3rd column
1436
+ # _trfX(_ITRF2005_, _ITRF2000_, epoch=_E(1997),
1437
+ # xform=_X( 0.7, -1.1, -0.4, 0.16, -0.2, 0.1 -1.8),
1438
+ # rates=_R( -0.2, 0.1, -1.8, 0.08, _0_0, _0_0, _0_0))
1439
+ _trfX(_ITRF2005_, _ITRF2000_, epoch=_E(2000), # <http://ITRF.ENSG.IGN.Fr/ITRF_solutions/2005/tp_05-00.php>
1440
+ xform=_X( 0.1, -0.8, -5.8, 0.4, _0_0, _0_0, _0_0),
1441
+ rates=_R( -0.2, 0.1, -1.8, 0.08, _0_0, _0_0, _0_0))
1442
+
1443
+ _trfX(_ITRF2000_, _ITRF97_, epoch=_E(1997),
1444
+ xform=_X( 0.67, 0.61, -1.85, 1.55, _0_0, _0_0, _0_0),
1445
+ rates=_R( _0_0, -0.06, -0.14, 0.01, _0_0, _0_0, -0.02)) # 0.02?
1446
+ _trfX(_ITRF2000_, _ITRF96_, epoch=_E(1997),
1447
+ xform=_X( 0.67, 0.61, -1.85, 1.55, _0_0, _0_0, _0_0),
1448
+ rates=_R( _0_0, -0.06, -0.14, 0.01, _0_0, _0_0, 0.02))
1449
+ _trfX(_ITRF2000_, _ITRF94_, epoch=_E(1997),
1450
+ xform=_X( 0.67, 0.61, -1.85, 1.55, _0_0, _0_0, _0_0),
1451
+ rates=_R( _0_0, -0.06, -0.14, 0.01, _0_0, _0_0, 0.02))
1452
+ _trfX(_ITRF2000_, _ITRF93_, epoch=_E(1988),
1453
+ xform=_X( 12.7, 6.5, -20.9, 1.95, -0.39, 0.8, -1.14),
1454
+ rates=_R( -2.9, -0.2, -0.6, 0.01, -0.11, -0.19, 0.07))
1455
+ _trfX(_ITRF2000_, _ITRF92_, epoch=_E(1988),
1456
+ xform=_X( 1.47, 1.35, -1.39, 0.75, _0_0, _0_0, -0.18),
1457
+ rates=_R( _0_0, -0.06, -0.14, 0.01, _0_0, _0_0, 0.02))
1458
+ _trfX(_ITRF2000_, _ITRF91_, epoch=_E(1988),
1459
+ xform=_X( 26.7, 27.5, -19.9, 2.15, _0_0, _0_0, -0.18),
1460
+ rates=_R( _0_0, -0.6, -1.4, 0.01, _0_0, _0_0, 0.02))
1461
+ _trfX(_ITRF2000_, _ITRF90_, epoch=_E(1988),
1462
+ xform=_X( 2.47, 2.35, -3.59, 2.45, _0_0, _0_0, -0.18),
1463
+ rates=_R( _0_0, -0.06, -0.14, 0.01, _0_0, _0_0, 0.02))
1464
+ _trfX(_ITRF2000_, _ITRF89_, epoch=_E(1988),
1465
+ xform=_X( 2.97, 4.75, -7.39, 5.85, _0_0, _0_0, -0.18),
1466
+ rates=_R( _0_0, -0.06, -0.14, 0.01, _0_0, _0_0, 0.02))
1467
+ _trfX(_ITRF2000_, _ITRF88_, epoch=_E(1988),
1468
+ xform=_X( 2.47, 1.15, -9.79, 8.95, 0.1, _0_0, -0.18),
1469
+ rates=_R( _0_0, -0.06, -0.14, 0.01, _0_0, _0_0, 0.02))
1470
+
1471
+ # Soler, T .& Snay R.A. U{"Transforming Positions and Velocities between the International Terrestrial
1472
+ # Reference Frame of 2000 and North American Datum of 1983"<https://www.ResearchGate.net/publication/245291390>},
1473
+ # Pearson, C. & Snay, R. U{"Introducing HTDP 3.1 to transform coordinates across time and spatial reference
1474
+ # frames"<https://Geodesy.NOAA.gov/TOOLS/Htdp/Pearson_Snay_2012.pdf> Table 7, 5th and 6th column
1475
+ _trfX(_ITRF97_, _ITRF96_, epoch=_E(1997),
1476
+ xform=_X( -2.07, -0.21, 9.95, -0.93496, 0.1267, -0.22355, -0.06065,),
1477
+ rates=_R( 0.69, -0.1, 1.86, -0.19201, 0.01347, -0.01514, 0.00027))
1478
+ _trfX(_ITRF96_, _NAD83_, epoch=_E(1997),
1479
+ xform=_X( 991.0, -190.72, -512.9, _0_0, 25.79, 9.65, 11.66,),
1480
+ rates=_R( _0_0, _0_0, _0_0, _0_0, 0.0532, -0.7423, -0.0316,))
1481
+
1482
+ # see Altamimi, Z. U{"EUREF Technical Note 1: Relationship and Transformation between the International and
1483
+ # the European Terrestrial Reference Systems"<https://ERTS89.ENSG.IFN.Fr/pub/EUREF-TN-1-Jan-31-2024.pdf>} Table 1.
1484
+ # _trfX(_ITRF2020_, _ETRF2020_, epoch=_E(1989), # see Table 2 below
1485
+ # xform=_P_0_0s,
1486
+ # rates=_R( _0_0, _0_0, _0_0, _0_0, 0.086, 0.519, -0.753))
1487
+ # _trfX(_ITRF2014_, _ETRF2014_, epoch=_E(1989), # see Table 3 below
1488
+ # xform=_P_0_0s,
1489
+ # rates=_R( _0_0, _0_0, _0_0, _0_0, 0.085, 0.531, -0.77))
1490
+ _trfX(_ITRF2005_, _ETRF2005_, epoch=_E(1989),
1491
+ xform=_X( 56.0, 48.0, -37.0, _0_0, _0_0, _0_0, _0_0),
1492
+ rates=_R( _0_0, _0_0, _0_0, _0_0, 0.054, 0.518, -0.781))
1493
+ # _trfX(_ITRF2000_, _ETRF2000_, epoch=_E(1989), # see Table 4 below
1494
+ # xform=_X( 54.0, 51.0, -48.0, _0_0, _0_0, _0_0, _0_0),
1495
+ # rates=_R( _0_0, _0_0, _0_0, _0_0, 0.081, 0.49, -0.792))
1496
+ _trfX(_ITRF97_, _ETRF97_, epoch=_E(1989),
1497
+ xform=_X( 41.0, 41.0, -49.0, _0_0, _0_0, _0_0, _0_0),
1498
+ rates=_R( _0_0, _0_0, _0_0, _0_0, 0.2, 0.5, -0.65))
1499
+ _trfX(_ITRF96_, _ETRF96_, epoch=_E(1989),
1500
+ xform=_X( 41.0, 41.0, -49.0, _0_0, _0_0, _0_0, _0_0),
1501
+ rates=_R( _0_0, _0_0, _0_0, _0_0, 0.2, 0.5, -0.65))
1502
+ _trfX(_ITRF94_, _ETRF94_, epoch=_E(1989),
1503
+ xform=_X( 41.0, 41.0, -49.0, _0_0, _0_0, _0_0, _0_0),
1504
+ rates=_R( _0_0, _0_0, _0_0, _0_0, 0.2, 0.5, -0.65))
1505
+ _trfX(_ITRF93_, _ETRF93_, epoch=_E(1989),
1506
+ xform=_X( 19.0, 53.0, -21.0, _0_0, _0_0, _0_0, _0_0),
1507
+ rates=_R( _0_0, _0_0, _0_0, _0_0, 0.32, 0.78, -0.67))
1508
+ _trfX(_ITRF92_, _ETRF92_, epoch=_E(1989),
1509
+ xform=_X( 38.0, 40.0, -37.0, 0.0, 0.0, 0.0, 0.0),
1510
+ rates=_R( _0_0, _0_0, _0_0, _0_0, 0.21, 0.52, -0.68))
1511
+ _trfX(_ITRF91_, _ETRF91_, epoch=_E(1989),
1512
+ xform=_X( 21.0, 25.0, -37.0, _0_0, _0_0, _0_0, _0_0),
1513
+ rates=_R( _0_0, _0_0, _0_0, _0_0, 0.21, 0.52, -0.68))
1514
+ _trfX(_ITRF90_, _ETRF90_, epoch=_E(1989),
1515
+ xform=_X( 19.0, 28.0, -23.0, _0_0, _0_0, _0_0, _0_0),
1516
+ rates=_R( _0_0, _0_0, _0_0, _0_0, 0.11, 0.57, -0.71))
1517
+ _trfX(_ITRF89_, _ETRF89_, epoch=_E(1989),
1518
+ xform=_P_0_0s,
1519
+ rates=_R( _0_0, _0_0, _0_0, _0_0, 0.11, 0.57, -0.71))
1520
+
1521
+ # see Altamimi, Z. U{"EUREF Technical Note 1: Relationship and Transformation between the International and
1522
+ # the European Terrestrial Reference Systems"<https://ERTS89.ENSG.IFN.Fr/pub/EUREF-TN-1-Jan-31-2024.pdf>} Table 2.
1523
+ _trfX(_ITRF2020_, _ETRF2020_, epoch=_E(2015),
1524
+ xform=_X( _0_0, _0_0, _0_0, _0_0, 2.236, 13.494, -19.578),
1525
+ rates=_R( _0_0, _0_0, _0_0, _0_0, 0.086, 0.519, -0.753))
1526
+ _trfX(_ITRF2014_, _ETRF2020_, epoch=_E(2015),
1527
+ xform=_X( 1.4, 0.9, -1.4, 0.42, 2.236, 13.494, -19.578),
1528
+ rates=_R( _0_0, 0.1, -0.2, _0_0, 0.086, 0.519, -0.753))
1529
+ _trfX(_ITRF2008_, _ETRF2020_, epoch=_E(2015),
1530
+ xform=_X( 3.0, 2.8, 0.5, 0.55, 2.236, 13.494, -19.578),
1531
+ rates=_R( _0_0, 0.1, -0.3, 0.03, 0.086, 0.519, -0.753))
1532
+ _trfX(_ITRF2005_, _ETRF2020_, epoch=_E(2015),
1533
+ xform=_X( 5.5, 1.9, -4.2, 1.49, 2.236, 13.494, -19.578),
1534
+ rates=_R( 0.3, 0.1, -0.3, 0.03, 0.086, 0.519, -0.753))
1535
+ _trfX(_ITRF2000_, _ETRF2020_, epoch=_E(2015),
1536
+ xform=_X( 2.6, 2.6, -37.0, 3.09, 2.236, 13.494, -19.578),
1537
+ rates=_R( 0.1, 0.2, -2.1, 0.11, 0.086, 0.519, -0.753))
1538
+ _trfX(_ITRF97_, _ETRF2020_, epoch=_E(2015),
1539
+ xform=_X( 9.3, -2.1, -80.7, 4.82, 2.236, 13.494, -19.218),
1540
+ rates=_R( 0.1, -0.4, -3.5, 0.12, 0.086, 0.519, -0.733))
1541
+ _trfX(_ITRF96_, _ETRF2020_, epoch=_E(2015),
1542
+ xform=_X( 9.3, -2.1, -80.7, 4.82, 2.236, 13.494, -19.218),
1543
+ rates=_R( 0.1, -0.4, -3.5, 0.12, 0.086, 0.519, -0.733))
1544
+ _trfX(_ITRF94_, _ETRF2020_, epoch=_E(2015),
1545
+ xform=_X( 9.3, -2.1, -80.7, 4.82, 2.236, 13.494, -19.218),
1546
+ rates=_R( 0.1, -0.4, -3.5, 0.12, 0.086, 0.519, -0.733))
1547
+ _trfX(_ITRF93_, _ETRF2020_, epoch=_E(2015),
1548
+ xform=_X( -63.0, 3.7, -74.1, 5.31, -1.124, 9.164, -18.828),
1549
+ rates=_R( -2.8, _0_0, -2.7, 0.12, -0.024, 0.329, -0.683))
1550
+ _trfX(_ITRF92_, _ETRF2020_, epoch=_E(2015),
1551
+ xform=_X( 17.3, -0.1, -88.7, 4.11, 2.236, 13.494, -19.218),
1552
+ rates=_R( 0.1, -0.4, -3.5, 0.12, 0.086, 0.519, -0.733))
1553
+ _trfX(_ITRF91_, _ETRF2020_, epoch=_E(2015),
1554
+ xform=_X( 29.3, 13.9, -94.7, 5.51, 2.236, 13.494, -19.218),
1555
+ rates=_R( 0.1, -0.4, -3.5, 0.12, 0.086, 0.519, -0.733))
1556
+ _trfX(_ITRF90_, _ETRF2020_, epoch=_E(2015),
1557
+ xform=_X( 27.3, 9.9, -110.7, 5.81, 2.236, 13.494, -19.218),
1558
+ rates=_R( 0.1, -0.4, -3.5, 0.12, 0.086, 0.519, -0.733))
1559
+ _trfX(_ITRF89_, _ETRF2020_, epoch=_E(2015),
1560
+ xform=_X( 32.3, 33.9, -148.7, 9.21, 2.236, 13.494, -19.218),
1561
+ rates=_R( 0.1, -0.4, -3.5, 0.12, 0.086, 0.519, -0.733))
1562
+ _trfX(_ITRF88_, _ETRF2020_, epoch=_E(2015),
1563
+ xform=_X( 27.3, -2.1, -172.7, 12.31, 2.336, 13.494, -19.218),
1564
+ rates=_R( 0.1, -0.4, -3.5, 0.12, 0.086, 0.519, -0.733))
1565
+
1566
+ # see Altamimi, Z. U{"EUREF Technical Note 1: Relationship and Transformation between the International and
1567
+ # the European Terrestrial Reference Systems"<https://ERTS89.ENSG.IFN.Fr/pub/EUREF-TN-1-Jan-31-2024.pdf>} Table 3.
1568
+ _trfX(_ITRF2020_, _ETRF2014_, epoch=_E(2015),
1569
+ xform=_X( -1.4, -0.9, 1.4, 0.42, 2.21, 13.806, -20.02),
1570
+ rates=_R( _0_0, -0.1, 0.2, _0_0, 0.085, 0.531, -0.77))
1571
+ _trfX(_ITRF2014_, _ETRF2014_, epoch=_E(2015),
1572
+ xform=_X( _0_0, _0_0, _0_0, _0_0, 2.21, 13.806, -20.02),
1573
+ rates=_R( _0_0, _0_0, _0_0, _0_0, 0.085, 0.531, -0.77))
1574
+ _trfX(_ITRF2008_, _ETRF2014_, epoch=_E(2015),
1575
+ xform=_X( -1.6, -1.9, -1.9, -0.13, 2.21, 13.806, -20.02),
1576
+ rates=_R( _0_0, _0_0, 0.1, -0.03, 0.085, 0.531, -0.77))
1577
+ _trfX(_ITRF2005_, _ETRF2014_, epoch=_E(2015),
1578
+ xform=_X( -4.1, -1.0, 2.8, -1.07, 2.21, 13.806, -20.02),
1579
+ rates=_R( -0.3, _0_0, 0.1, -0.03, 0.085, 0.531, -0.77))
1580
+ _trfX(_ITRF2000_, _ETRF2014_, epoch=_E(2015),
1581
+ xform=_X( -1.2, -1.7, 35.6, -2.67, 2.21, 13.806, -20.02),
1582
+ rates=_R( -0.1, -0.1, 1.9, -0.11, 0.085, 0.531, -0.77))
1583
+ _trfX(_ITRF97_, _ETRF2014_, epoch=_E(2015),
1584
+ xform=_X( -7.9, 3.0, 79.3, -4.40, 2.210, 13.806, -20.38),
1585
+ rates=_R( -0.1, 0.5, 3.3, -0.12, 0.085, 0.531, -0.79))
1586
+ _trfX(_ITRF96_, _ETRF2014_, epoch=_E(2015),
1587
+ xform=_X( -7.9, 3.0, 79.3, -4.40, 2.210, 13.806, -20.38),
1588
+ rates=_R( -0.1, 0.5, 3.3, -0.12, 0.085, 0.531, -0.79))
1589
+ _trfX(_ITRF94_, _ETRF2014_, epoch=_E(2015),
1590
+ xform=_X( -7.9, 3.0, 79.3, -4.40, 2.210, 13.806, -20.38),
1591
+ rates=_R( -0.1, 0.5, 3.3, -0.12, 0.085, 0.531, -0.79))
1592
+ _trfX(_ITRF93_, _ETRF2014_, epoch=_E(2015),
1593
+ xform=_X( 64.4, -2.8, 72.7, -4.89, 5.570, 18.136, -20.77),
1594
+ rates=_R( 2.8, 0.1, 2.5, -0.12, 0.195, 0.721, -0.84))
1595
+ _trfX(_ITRF92_, _ETRF2014_, epoch=_E(2015),
1596
+ xform=_X( -15.9, 1.0, 87.3, -3.69, 2.21, 13.806, -20.38),
1597
+ rates=_R( -0.1, 0.5, 3.3, -0.12, 0.085, 0.531, -0.79))
1598
+ _trfX(_ITRF91_, _ETRF2014_, epoch=_E(2015),
1599
+ xform=_X( -27.9, -13.0, 93.3, -5.09, 2.21, 13.806, -20.38),
1600
+ rates=_R( -0.1, 0.5, 3.3, -0.12, 0.085, 0.531, -0.79))
1601
+ _trfX(_ITRF90_, _ETRF2014_, epoch=_E(2015),
1602
+ xform=_X( -25.9, -9.0, 109.3, -5.39, 2.21, 13.806, -20.38),
1603
+ rates=_R( -0.1, 0.5, 3.3, -0.12, 0.085, 0.531, -0.79))
1604
+ _trfX(_ITRF89_, _ETRF2014_, epoch=_E(2015),
1605
+ xform=_X( -30.9, -33.0, 147.3, -8.79, 2.21, 13.806, -20.38),
1606
+ rates=_R( -0.1, 0.5, 3.3, -0.12, 0.085, 0.531, -0.79))
1607
+ _trfX(_ITRF88_, _ETRF2014_, epoch=_E(2015),
1608
+ xform=_X( -25.9, 3.0, 171.3, -11.89, 2.11, 13.806, -20.38),
1609
+ rates=_R( -0.1, 0.5, 3.3, -0.12, 0.085, 0.531, -0.79))
1610
+
1611
+ # see U{Altamimi, Z. "EUREF Technical Note 1: Relationship and Transformation between the International and
1612
+ # the European Terrestrial Reference Systems"<https://ERTS89.ENSG,IFN.Fr/pub/EUREF-TN-1-Jan-31-2024.pdf>} Table 4,
1613
+ # U{Boucher, C. & Altamimi, Z. "Memo: Specifications for reference frame fixing in the analysis of a EUREF GPS
1614
+ # campaign" (2011) <https://ETRS89.ENSG.IGN.Fr/memo-V8.pdf>} and U{Altamimi, Z. "Key results of ITRF2014 and
1615
+ # implication to ETRS89 realization", EUREF2016<https://www.EUREF.EU/symposia/2016SanSebastian/01-02-Altamimi.pdf>}.
1616
+ _trfX(_ITRF2020_, _ETRF2000_, epoch=_E(2015),
1617
+ xform=_X( 53.8, 51.8, -82.2, 2.25, 2.106, 12.74, -20.592),
1618
+ rates=_R( 0.1, _0_0, -1.7, 0.11, 0.081, 0.49, -0.792))
1619
+ # _trfX(_ITRF2014_, _ETRF2000_, epoch=_E(2000),
1620
+ # xform=_X( 53.7, 51.2, -55.1, 1.02, 0.891, 5.39, -8.712),
1621
+ # rates=_R( 0.1, 0.1, -1.9, 0.11, 0.081, 0.49, -0.792))
1622
+ _trfX(_ITRF2014_, _ETRF2000_, epoch=_E(2015),
1623
+ xform=_X( 55.2, 52.7, -83.6, 2.67, 2.106, 12.74, -20.592),
1624
+ rates=_R( 0.1, 0.1, -1.9, 0.11, 0.081, 0.49, -0.792))
1625
+ # _trfX(_ITRF2008_, _ETRF2000_, epoch=_E(2000),
1626
+ # xform=_X( 52.1, 49.3, -58.5, 1.34, 0.891, 5.39, -8.712),
1627
+ # rates=_R( 0.1, 0.1, -1.8, 0.08, 0.081, 0.49, -0.792))
1628
+ _trfX(_ITRF2008_, _ETRF2000_, epoch=_E(2015),
1629
+ xform=_X( 53.6, 50.8, -85.5, 2.54, 2.106, 12.74, -20.592),
1630
+ rates=_R( 0.1, 0.1, -1.8, 0.08, 0.081, 0.49, -0.792))
1631
+ # _trfX(_ITRF2005_, _ETRF2000_, epoch=_E(2000),
1632
+ # xform=_X( 54.1, 50.2, -53.8, 0.4, 0.891, 5.39, -8.712),
1633
+ # rates=_R( -0.2, 0.1, -1.8, 0.08, 0.081, 0.49, -0.792))
1634
+ _trfX(_ITRF2005_, _ETRF2000_, epoch=_E(2015),
1635
+ xform=_X( 51.1, 51.7, -80.8, 1.6, 2.106, 12.74, -20.592),
1636
+ rates=_R( -0.2, 0.1, -1.8, 0.08, 0.081, 0.49, -0.792))
1637
+ # _trfX(_ITRF2000_, _ETRF2000_, epoch=_E(2000),
1638
+ # xform=_X( 54.0, 51.0, -48.0, _0_0, 0.891, 5.39, -8.712),
1639
+ # rates=_R( _0_0, _0_0, _0_0, _0_0, 0.081, 0.49, -0.792))
1640
+ _trfX(_ITRF2000_, _ETRF2000_, epoch=_E(2015),
1641
+ xform=_X( 54.0, 51.0, -48.0, _0_0, 2.106, 12.74, -20.592),
1642
+ rates=_R( _0_0, _0_0, _0_0, _0_0, 0.081, 0.49, -0.792))
1643
+ _trfX(_ITRF97_, _ETRF2000_, epoch=_E(2015),
1644
+ xform=_X( 47.3, 55.7, -4.3, -1.73, 2.106, 12.74, -20.952),
1645
+ rates=_R( _0_0, 0.6, 1.4, -0.01, 0.081, 0.49, -0.812))
1646
+ _trfX(_ITRF96_, _ETRF2000_, epoch=_E(2015),
1647
+ xform=_X( 47.3, 55.7, -4.3, -1.73, 2.106, 12.74, -20.952),
1648
+ rates=_R( _0_0, 0.6, 1.4, -0.01, 0.081, 0.49, -0.812))
1649
+ _trfX(_ITRF94_, _ETRF2000_, epoch=_E(2015),
1650
+ xform=_X( 47.3, 55.7, -4.3, -1.73, 2.106, 12.74, -20.952),
1651
+ rates=_R( _0_0, 0.6, 1.4, -0.01, 0.081, 0.49, -0.812))
1652
+ _trfX(_ITRF93_, _ETRF2000_, epoch=_E(2015),
1653
+ xform=_X( 119.6, 49.9, -10.9, -2.22, 5.466, 17.07, -21.342),
1654
+ rates=_R( 2.9, 0.2, 0.6, -0.01, 0.191, 0.68, -0.862))
1655
+ _trfX(_ITRF92_, _ETRF2000_, epoch=_E(2015),
1656
+ xform=_X( 39.3, 53.7, 3.7, -1.02, 2.106, 12.74, -20.952),
1657
+ rates=_R( _0_0, 0.6, 1.4, -0.01, 0.081, 0.49, -0.812))
1658
+ _trfX(_ITRF91_, _ETRF2000_, epoch=_E(2015),
1659
+ xform=_X( 27.3, 39.7, 9.7, -2.42, 2.106, 12.74, -20.952),
1660
+ rates=_R( _0_0, 0.6, 1.4, -0.01, 0.081, 0.49, -0.812))
1661
+ _trfX(_ITRF90_, _ETRF2000_, epoch=_E(2015),
1662
+ xform=_X( 29.3, 43.7, 25.7, -2.72, 2.106, 12.74, -20.952),
1663
+ rates=_R( _0_0, 0.6, 1.4, -0.01, 0.081, 0.49, -0.812))
1664
+ _trfX(_ITRF89_, _ETRF2000_, epoch=_E(2015),
1665
+ xform=_X( 24.3, 19.7, 63.7, -6.12, 2.106, 12.74, -20.952),
1666
+ rates=_R( _0_0, 0.6, 1.4, -0.01, 0.081, 0.49, -0.812))
1667
+ _trfX(_ITRF88_, _ETRF2000_, epoch=_E(2015),
1668
+ xform=_X( 29.3, 55.7, 87.7, -9.22, 2.006, 12.74, -20.952),
1669
+ rates=_R( _0_0, 0.6, 1.4, -0.01, 0.081, 0.49, -0.812))
1670
+
1671
+ # GDA2020 "Geocentric Datum of Australia 2020 Technical Manual", v1.5, 2020-12-09, Table 3.3 and 3.4
1672
+ # <https://www.ICSM.gov.AU/sites/default/files/2020-12/GDA2020%20Technical%20Manual%20V1.5_4.pdf>
1673
+ # (the GDA2020 xforms are different but the rates are the same as GDA94, further below)
1674
+ _trfX(_ITRF2014_, _GDA2020_, epoch=_E(2020),
1675
+ xform=_P_0_0s,
1676
+ rates=_R( _0_0, _0_0, _0_0, _0_0, 1.50379, 1.18346, 1.20716))
1677
+ _trfX(_ITRF2008_, _GDA2020_, epoch=_E(2020),
1678
+ xform=_X( 13.79, 4.55, 15.22, 2.5, 0.2808, 0.2677, -0.4638),
1679
+ rates=_R( 1.42, 1.34, 0.9, 0.109, 1.5461, 1.182, 1.1551))
1680
+ _trfX(_ITRF2005_, _GDA2020_, epoch=_E(2020),
1681
+ xform=_X( 40.32, -33.85, -16.72, 4.286, -1.2893, -0.8492, -0.3342),
1682
+ rates=_R( 2.25, -0.62, -0.56, 0.294, -1.4707, -1.1443, -1.1701))
1683
+ _trfX(_ITRF2000_, _GDA2020_, epoch=_E(2020),
1684
+ xform=_X(-105.52, 51.58, 231.68, 3.55, 4.2175, 6.3941, 0.8617),
1685
+ rates=_R( -4.66, 3.55, 11.24, 0.249, 1.7454, 1.4868, 1.224))
1686
+
1687
+ # see Table 2 in U{Dawson, J. & Woods, A. "ITRF to GDA94 coordinate transformations", Journal of Applied
1688
+ # Geodesy 4 (2010), 189-199<https://www.ResearchGate.net/publication/258401581_ITRF_to_GDA94_coordinate_transformations>}
1689
+ # (note, sign of rotations for GDA94 reversed as "Australia assumes rotation to be of coordinate axes",
1690
+ # rather than the more conventional "position around the coordinate axes")
1691
+ _trfX(_ITRF2008_, _GDA94_, epoch=_E(1994),
1692
+ xform=_X( -84.68, -19.42, 32.01, 9.71, -0.4254, 2.2578, 2.4015),
1693
+ rates=_R( 1.42, 1.34, 0.9, 0.109, 1.5461, 1.182, 1.1551))
1694
+ _trfX(_ITRF2005_, _GDA94_, epoch=_E(1994),
1695
+ xform=_X( -79.73, -6.86, 38.03, 6.636, 0.0351, -2.1211, -2.1411),
1696
+ rates=_R( 2.25, -0.62, -0.56, 0.294, -1.4707, -1.1443, -1.1701))
1697
+ _trfX(_ITRF2000_, _GDA94_, epoch=_E(1994),
1698
+ xform=_X( -45.91, -29.85, -20.37, 7.07, -1.6705, 0.4594, 1.9356),
1699
+ rates=_R( -4.66, 3.55, 11.24, 0.249, 1.7454, 1.4868, 1.224))
1700
+
1701
+ # see U{Quinsy QPS<https://confluence.QPS.NL/qinsy/files/latest/en/182618383/182618384/1/1579182881000/
1702
+ # ITRF_Transformation_Parameters.xlsx>}, sheets ITRF and NAD83 and Pearson, C. & Snay, R. U{"Introducing
1703
+ # HTDP 3.1 to transform coordinates across time and spatial reference frames"<https://Geodesy.NOAA.gov/
1704
+ # TOOLS/Htdp/Pearson_Snay_2012.pdf> Table 7, 7th column
1705
+ _trfX(_ITRF2008_, _NAD83_, epoch=_E(1997),
1706
+ xform=_X( 993.43, -1903.31, -526.55, 1.71504, -25.91467, -9.42645, -11.59935),
1707
+ rates=_R( 0.79, -0.6, -1.34, -0.10201, -0.06667, 0.75744, 0.05133))
1708
+ # see U{Quinsy QPS<https://confluence.QPS.NL/qinsy/files/latest/en/182618383/182618384/1/1579182881000/
1709
+ # ITRF_Transformation_Parameters.xlsx>}, sheets ITRF and NAD83
1710
+ _trfX(_ITRF2005_, _NAD83_, epoch=_E(1997),
1711
+ xform=_X( 996.3, -1902.4, -521.9, 0.775, -25.915, -9.426, -11.599),
1712
+ rates=_R( 0.5, -0.6, -1.3, -0.10201, -0.06667, 0.75744, 0.05133))
1713
+ # see U{Solar, T. & Snay, R.A. "Transforming Positions and Velocities between the International Terrestrial Reference
1714
+ # Frame of 2000 and North American Datum of 1983" (2004)<https://www.NGS.NOAA.gov/CORS/Articles/SolerSnayASCE.pdf>}
1715
+ _trfX(_ITRF2000_, _NAD83_, epoch=_E(1997), # note NAD83(CORS96)
1716
+ xform=_X( 995.6, -1901.3, -521.5, 0.615, -25.915, -9.426, -11.599),
1717
+ rates=_R( 0.7, -0.7, _0_5, -0.182, -0.06667, 0.75744, 0.05133))
1718
+ _trfX(_ITRF90_, _NAD83_, epoch=_E(1997),
1719
+ xform=_X( 973.0, -1919.2, -482.9, -0.9, -25.79, -9.65, -11.66),
1720
+ rates=_R( _0_0, _0_0, _0_0, _0_0, -0.053, 0.742, 0.032))
1721
+ _trfX(_ITRF90_, _WGS84_, epoch=_E(1984), # coverage
1722
+ xform=_X( 60.0, -517.0, -223.0, -11.0, 18.3, -0.3, 7.0),
1723
+ rates=_P_0_0s)
1724
+
1725
+ # equivalents U{"Transformations Between NAD83 and WGS84"<https://www.NGS.NOAA.gov/CORS/Articles/WGS84NAD83.pdf>}
1726
+ trfXform(_NAD83cors96_, _NAD83_, epoch=_E(1997), xform=_P_0_0s, rates=_P_0_0s)
1727
+ trfXform(_WGS84g1150_, _ITRF2000_, epoch=_E(2004), xform=_P_0_0s, rates=_P_0_0s)
1728
+
1729
+ del _E, _Es, _i, _P, _P_0_0s, _R, _Rs, _X, _Xs
1730
+
1731
+ if __name__ == '__main__':
1732
+
1733
+ def _main():
1734
+ from pygeodesy.basics import _args_kwds_names
1735
+ from pygeodesy.interns import _COLONSPACE_,_COMMA_, _NL_, _NLATvar_, _vs_
1736
+ from pygeodesy.lazily import printf
1737
+ from time import localtime
1738
+
1739
+ D = date2epoch.__name__
1740
+ E = epoch2date.__name__
1741
+ y = localtime()[0]
1742
+ for m in range(1, 13):
1743
+ for d in (1, 15, _mDays[m] - 1, _mDays[m]):
1744
+ f = '%s(%d,%3d,%3d)' % (D, y, m, d)
1745
+ e = date2epoch(y, m, d)
1746
+ t = epoch2date(e)
1747
+ x = NN if t == (y, m, d) else _STAR_
1748
+ e = '%.3f' % (e,)
1749
+ e = '%s, %s(%s)' % (e, E, e)
1750
+ t = '%d,%3d,%3d' % t
1751
+ printf('# %s = %s = %s %s', f, e, t, x)
1752
+
1753
+ # __doc__ of this file, force all into registery
1754
+ def _RFs():
1755
+ yield NN
1756
+ for t in RefFrames.toRepr(all=True).split(_NL_):
1757
+ t = t.strip(_COMMA_)
1758
+ n = t.split(_COLONSPACE_)[0].split(_DOT_)[1]
1759
+ r = RefFrames.get(n)
1760
+ x = len(r.Xforms()), -len(r.Xforms(inverse=True))
1761
+ yield '%s .Xforms=%s' % (t, x)
1762
+
1763
+ printf(_NLATvar_.join(sorted(_RFs())), nt=1)
1764
+
1765
+ X, t = (), 0 # all form
1766
+ for r in RefFrames.values():
1767
+ X += tuple(r._Xto.values())
1768
+ for X in sorted(X):
1769
+ t += 1
1770
+ printf('#%4d %-24s xform=%r', t, X.name, X.xform)
1771
+ printf('#%29s rates=%r', _SPACE_, X.rates)
1772
+
1773
+ t = _args_kwds_names(Transform.__init__)
1774
+ for n in TRFXform7Tuple._Names_:
1775
+ if n not in t:
1776
+ raise AssertionError(_SPACE_(n, _vs_, t))
1777
+
1778
+ _main()
1779
+ del _main
1780
+
1781
+ # **) MIT License
1782
+ #
1783
+ # Copyright (C) 2016-2024 -- mrJean1 at Gmail -- All Rights Reserved.
1784
+ #
1785
+ # Permission is hereby granted, free of charge, to any person obtaining a
1786
+ # copy of this software and associated documentation files (the "Software"),
1787
+ # to deal in the Software without restriction, including without limitation
1788
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
1789
+ # and/or sell copies of the Software, and to permit persons to whom the
1790
+ # Software is furnished to do so, subject to the following conditions:
1791
+ #
1792
+ # The above copyright notice and this permission notice shall be included
1793
+ # in all copies or substantial portions of the Software.
1794
+ #
1795
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1796
+ # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1797
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1798
+ # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
1799
+ # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
1800
+ # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
1801
+ # OTHER DEALINGS IN THE SOFTWARE.
1802
+
1803
+ # % python -m pygeodesy.trf
1804
+ #
1805
+ # date2epoch(2024, 1, 1) = 2024.003, epoch2date(2024.003) = 2024, 1, 1
1806
+ # date2epoch(2024, 1, 15) = 2024.041, epoch2date(2024.041) = 2024, 1, 15
1807
+ # date2epoch(2024, 1, 30) = 2024.082, epoch2date(2024.082) = 2024, 1, 30
1808
+ # date2epoch(2024, 1, 31) = 2024.085, epoch2date(2024.085) = 2024, 1, 31
1809
+ # date2epoch(2024, 2, 1) = 2024.087, epoch2date(2024.087) = 2024, 2, 2 *
1810
+ # date2epoch(2024, 2, 15) = 2024.126, epoch2date(2024.126) = 2024, 2, 16 *
1811
+ # date2epoch(2024, 2, 28) = 2024.161, epoch2date(2024.161) = 2024, 2, 28
1812
+ # date2epoch(2024, 2, 29) = 2024.164, epoch2date(2024.164) = 2024, 3, 1 *
1813
+ # date2epoch(2024, 3, 1) = 2024.167, epoch2date(2024.167) = 2024, 3, 2 *
1814
+ # date2epoch(2024, 3, 15) = 2024.205, epoch2date(2024.205) = 2024, 3, 16 *
1815
+ # date2epoch(2024, 3, 30) = 2024.246, epoch2date(2024.246) = 2024, 3, 31 *
1816
+ # date2epoch(2024, 3, 31) = 2024.249, epoch2date(2024.249) = 2024, 4, 1 *
1817
+ # date2epoch(2024, 4, 1) = 2024.251, epoch2date(2024.251) = 2024, 4, 1
1818
+ # date2epoch(2024, 4, 15) = 2024.290, epoch2date(2024.290) = 2024, 4, 15
1819
+ # date2epoch(2024, 4, 29) = 2024.328, epoch2date(2024.328) = 2024, 4, 29
1820
+ # date2epoch(2024, 4, 30) = 2024.331, epoch2date(2024.331) = 2024, 4, 30
1821
+ # date2epoch(2024, 5, 1) = 2024.333, epoch2date(2024.333) = 2024, 5, 1
1822
+ # date2epoch(2024, 5, 15) = 2024.372, epoch2date(2024.372) = 2024, 5, 15
1823
+ # date2epoch(2024, 5, 30) = 2024.413, epoch2date(2024.413) = 2024, 5, 30
1824
+ # date2epoch(2024, 5, 31) = 2024.415, epoch2date(2024.415) = 2024, 6, 1 *
1825
+ # date2epoch(2024, 6, 1) = 2024.418, epoch2date(2024.418) = 2024, 6, 2 *
1826
+ # date2epoch(2024, 6, 15) = 2024.456, epoch2date(2024.456) = 2024, 6, 16 *
1827
+ # date2epoch(2024, 6, 29) = 2024.495, epoch2date(2024.495) = 2024, 6, 30 *
1828
+ # date2epoch(2024, 6, 30) = 2024.497, epoch2date(2024.497) = 2024, 7, 1 *
1829
+ # date2epoch(2024, 7, 1) = 2024.500, epoch2date(2024.500) = 2024, 7, 1
1830
+ # date2epoch(2024, 7, 15) = 2024.538, epoch2date(2024.538) = 2024, 7, 16 *
1831
+ # date2epoch(2024, 7, 30) = 2024.579, epoch2date(2024.579) = 2024, 7, 30
1832
+ # date2epoch(2024, 7, 31) = 2024.582, epoch2date(2024.582) = 2024, 7, 31
1833
+ # date2epoch(2024, 8, 1) = 2024.585, epoch2date(2024.585) = 2024, 8, 1
1834
+ # date2epoch(2024, 8, 15) = 2024.623, epoch2date(2024.623) = 2024, 8, 15
1835
+ # date2epoch(2024, 8, 30) = 2024.664, epoch2date(2024.664) = 2024, 8, 31 *
1836
+ # date2epoch(2024, 8, 31) = 2024.667, epoch2date(2024.667) = 2024, 9, 1 *
1837
+ # date2epoch(2024, 9, 1) = 2024.669, epoch2date(2024.669) = 2024, 9, 2 *
1838
+ # date2epoch(2024, 9, 15) = 2024.708, epoch2date(2024.708) = 2024, 9, 16 *
1839
+ # date2epoch(2024, 9, 29) = 2024.746, epoch2date(2024.746) = 2024, 9, 30 *
1840
+ # date2epoch(2024, 9, 30) = 2024.749, epoch2date(2024.749) = 2024, 10, 1 *
1841
+ # date2epoch(2024, 10, 1) = 2024.751, epoch2date(2024.751) = 2024, 10, 1
1842
+ # date2epoch(2024, 10, 15) = 2024.790, epoch2date(2024.790) = 2024, 10, 15
1843
+ # date2epoch(2024, 10, 30) = 2024.831, epoch2date(2024.831) = 2024, 10, 30
1844
+ # date2epoch(2024, 10, 31) = 2024.833, epoch2date(2024.833) = 2024, 10, 31
1845
+ # date2epoch(2024, 11, 1) = 2024.836, epoch2date(2024.836) = 2024, 11, 1
1846
+ # date2epoch(2024, 11, 15) = 2024.874, epoch2date(2024.874) = 2024, 11, 15
1847
+ # date2epoch(2024, 11, 29) = 2024.913, epoch2date(2024.913) = 2024, 11, 29
1848
+ # date2epoch(2024, 11, 30) = 2024.915, epoch2date(2024.915) = 2024, 12, 1 *
1849
+ # date2epoch(2024, 12, 1) = 2024.918, epoch2date(2024.918) = 2024, 12, 2 *
1850
+ # date2epoch(2024, 12, 15) = 2024.956, epoch2date(2024.956) = 2024, 12, 16 *
1851
+ # date2epoch(2024, 12, 30) = 2024.997, epoch2date(2024.997) = 2024, 12, 31 *
1852
+ # date2epoch(2024, 12, 31) = 2025.000, epoch2date(2025.000) = 2025, 1, 1 *
1853
+
1854
+ # 1 WGS84g1150@2004xITRF2000 xform=unity(tx=0.0, ty=0.0, tz=0.0, s=0.0, sx=0.0, sy=0.0, sz=0.0)
1855
+ # rates=unity(tx=0.0, ty=0.0, tz=0.0, s=0.0, sx=0.0, sy=0.0, sz=0.0)
1856
+ # 2 NAD83cors96@1997xNAD83 xform=unity(tx=0.0, ty=0.0, tz=0.0, s=0.0, sx=0.0, sy=0.0, sz=0.0)
1857
+ # rates=unity(tx=0.0, ty=0.0, tz=0.0, s=0.0, sx=0.0, sy=0.0, sz=0.0)
1858
+ # 3 ITRF88@2015xETRF2014 xform=xform(tx=-25.9, ty=3.0, tz=171.3, s=-11.89, sx=2.11, sy=13.806, sz=-20.38)
1859
+ # rates=rates(tx=-0.1, ty=0.5, tz=3.3, s=-0.12, sx=0.085, sy=0.531, sz=-0.79)
1860
+ # 4 ITRF89@2015xETRF2000 xform=xform(tx=24.3, ty=19.7, tz=63.7, s=-6.12, sx=2.106, sy=12.74, sz=-20.952)
1861
+ # rates=rates(tx=0.0, ty=0.6, tz=1.4, s=-0.01, sx=0.081, sy=0.49, sz=-0.812)
1862
+ # 5 ITRF89@2015xETRF2014 xform=xform(tx=-30.9, ty=-33.0, tz=147.3, s=-8.79, sx=2.21, sy=13.806, sz=-20.38)
1863
+ # rates=rates(tx=-0.1, ty=0.5, tz=3.3, s=-0.12, sx=0.085, sy=0.531, sz=-0.79)
1864
+ # 6 ITRF89@2015xETRF2020 xform=xform(tx=32.3, ty=33.9, tz=-148.7, s=9.21, sx=2.236, sy=13.494, sz=-19.218)
1865
+ # rates=rates(tx=0.1, ty=-0.4, tz=-3.5, s=0.12, sx=0.086, sy=0.519, sz=-0.733)
1866
+ # 7 ITRF89@1989xETRF89 xform=unity(tx=0.0, ty=0.0, tz=0.0, s=0.0, sx=0.0, sy=0.0, sz=0.0)
1867
+ # rates=rates(tx=0.0, ty=0.0, tz=0.0, s=0.0, sx=0.11, sy=0.57, sz=-0.71)
1868
+ # 8 ITRF90@1984xWGS84 xform=xform(tx=60.0, ty=-517.0, tz=-223.0, s=-11.0, sx=18.3, sy=-0.3, sz=7.0)
1869
+ # rates=unity(tx=0.0, ty=0.0, tz=0.0, s=0.0, sx=0.0, sy=0.0, sz=0.0)
1870
+ # 9 ITRF90@2015xETRF2000 xform=xform(tx=29.3, ty=43.7, tz=25.7, s=-2.72, sx=2.106, sy=12.74, sz=-20.952)
1871
+ # rates=rates(tx=0.0, ty=0.6, tz=1.4, s=-0.01, sx=0.081, sy=0.49, sz=-0.812)
1872
+ # 10 ITRF90@1989xETRF90 xform=xform(tx=19.0, ty=28.0, tz=-23.0, s=0.0, sx=0.0, sy=0.0, sz=0.0)
1873
+ # rates=rates(tx=0.0, ty=0.0, tz=0.0, s=0.0, sx=0.11, sy=0.57, sz=-0.71)
1874
+ # 11 ITRF90@1997xNAD83 xform=xform(tx=973.0, ty=-1919.2, tz=-482.9, s=-0.9, sx=-25.79, sy=-9.65, sz=-11.66)
1875
+ # rates=rates(tx=0.0, ty=0.0, tz=0.0, s=0.0, sx=-0.053, sy=0.742, sz=0.032)
1876
+ # 12 ITRF91@2015xETRF2000 xform=xform(tx=27.3, ty=39.7, tz=9.7, s=-2.42, sx=2.106, sy=12.74, sz=-20.952)
1877
+ # rates=rates(tx=0.0, ty=0.6, tz=1.4, s=-0.01, sx=0.081, sy=0.49, sz=-0.812)
1878
+ # 13 ITRF91@1989xETRF91 xform=xform(tx=21.0, ty=25.0, tz=-37.0, s=0.0, sx=0.0, sy=0.0, sz=0.0)
1879
+ # rates=rates(tx=0.0, ty=0.0, tz=0.0, s=0.0, sx=0.21, sy=0.52, sz=-0.68)
1880
+ # 14 ITRF92@2015xETRF2000 xform=xform(tx=39.3, ty=53.7, tz=3.7, s=-1.02, sx=2.106, sy=12.74, sz=-20.952)
1881
+ # rates=rates(tx=0.0, ty=0.6, tz=1.4, s=-0.01, sx=0.081, sy=0.49, sz=-0.812)
1882
+ # 15 ITRF92@2015xETRF2014 xform=xform(tx=-15.9, ty=1.0, tz=87.3, s=-3.69, sx=2.21, sy=13.806, sz=-20.38)
1883
+ # rates=rates(tx=-0.1, ty=0.5, tz=3.3, s=-0.12, sx=0.085, sy=0.531, sz=-0.79)
1884
+ # 16 ITRF92@2015xETRF2020 xform=xform(tx=17.3, ty=-0.1, tz=-88.7, s=4.11, sx=2.236, sy=13.494, sz=-19.218)
1885
+ # rates=rates(tx=0.1, ty=-0.4, tz=-3.5, s=0.12, sx=0.086, sy=0.519, sz=-0.733)
1886
+ # 17 ITRF92@1989xETRF92 xform=xform(tx=38.0, ty=40.0, tz=-37.0, s=0.0, sx=0.0, sy=0.0, sz=0.0)
1887
+ # rates=rates(tx=0.0, ty=0.0, tz=0.0, s=0.0, sx=0.21, sy=0.52, sz=-0.68)
1888
+ # 18 ITRF93@2015xETRF2000 xform=xform(tx=119.6, ty=49.9, tz=-10.9, s=-2.22, sx=5.466, sy=17.07, sz=-21.342)
1889
+ # rates=rates(tx=2.9, ty=0.2, tz=0.6, s=-0.01, sx=0.191, sy=0.68, sz=-0.862)
1890
+ # 19 ITRF93@2015xETRF2014 xform=xform(tx=64.4, ty=-2.8, tz=72.7, s=-4.89, sx=5.57, sy=18.136, sz=-20.77)
1891
+ # rates=rates(tx=2.8, ty=0.1, tz=2.5, s=-0.12, sx=0.195, sy=0.721, sz=-0.84)
1892
+ # 20 ITRF93@2015xETRF2020 xform=xform(tx=-63.0, ty=3.7, tz=-74.1, s=5.31, sx=-1.124, sy=9.164, sz=-18.828)
1893
+ # rates=rates(tx=-2.8, ty=0.0, tz=-2.7, s=0.12, sx=-0.024, sy=0.329, sz=-0.683)
1894
+ # 21 ITRF93@1989xETRF93 xform=xform(tx=19.0, ty=53.0, tz=-21.0, s=0.0, sx=0.0, sy=0.0, sz=0.0)
1895
+ # rates=rates(tx=0.0, ty=0.0, tz=0.0, s=0.0, sx=0.32, sy=0.78, sz=-0.67)
1896
+ # 22 ITRF94@2015xETRF2000 xform=xform(tx=47.3, ty=55.7, tz=-4.3, s=-1.73, sx=2.106, sy=12.74, sz=-20.952)
1897
+ # rates=rates(tx=0.0, ty=0.6, tz=1.4, s=-0.01, sx=0.081, sy=0.49, sz=-0.812)
1898
+ # 23 ITRF94@2015xETRF2014 xform=xform(tx=-7.9, ty=3.0, tz=79.3, s=-4.4, sx=2.21, sy=13.806, sz=-20.38)
1899
+ # rates=rates(tx=-0.1, ty=0.5, tz=3.3, s=-0.12, sx=0.085, sy=0.531, sz=-0.79)
1900
+ # 24 ITRF94@2015xETRF2020 xform=xform(tx=9.3, ty=-2.1, tz=-80.7, s=4.82, sx=2.236, sy=13.494, sz=-19.218)
1901
+ # rates=rates(tx=0.1, ty=-0.4, tz=-3.5, s=0.12, sx=0.086, sy=0.519, sz=-0.733)
1902
+ # 25 ITRF94@1989xETRF94 xform=xform(tx=41.0, ty=41.0, tz=-49.0, s=0.0, sx=0.0, sy=0.0, sz=0.0)
1903
+ # rates=rates(tx=0.0, ty=0.0, tz=0.0, s=0.0, sx=0.2, sy=0.5, sz=-0.65)
1904
+ # 26 ITRF96@1989xETRF96 xform=xform(tx=41.0, ty=41.0, tz=-49.0, s=0.0, sx=0.0, sy=0.0, sz=0.0)
1905
+ # rates=rates(tx=0.0, ty=0.0, tz=0.0, s=0.0, sx=0.2, sy=0.5, sz=-0.65)
1906
+ # 27 ITRF97@1989xETRF97 xform=xform(tx=41.0, ty=41.0, tz=-49.0, s=0.0, sx=0.0, sy=0.0, sz=0.0)
1907
+ # rates=rates(tx=0.0, ty=0.0, tz=0.0, s=0.0, sx=0.2, sy=0.5, sz=-0.65)
1908
+ # 28 ITRF2000@1994xGDA94 xform=xform(tx=-45.91, ty=-29.85, tz=-20.37, s=7.07, sx=-1.6705, sy=0.4594, sz=1.9356)
1909
+ # rates=rates(tx=-4.66, ty=3.55, tz=11.24, s=0.249, sx=1.7454, sy=1.4868, sz=1.224)
1910
+ # 29 ITRF2000@2015xETRF2000 xform=xform(tx=54.0, ty=51.0, tz=-48.0, s=0.0, sx=2.106, sy=12.74, sz=-20.592)
1911
+ # rates=rates(tx=0.0, ty=0.0, tz=0.0, s=0.0, sx=0.081, sy=0.49, sz=-0.792)
1912
+ # 30 ITRF88@2015xETRF2000 xform=xform(tx=29.3, ty=55.7, tz=87.7, s=-9.22, sx=2.006, sy=12.74, sz=-20.952)
1913
+ # rates=rates(tx=0.0, ty=0.6, tz=1.4, s=-0.01, sx=0.081, sy=0.49, sz=-0.812)
1914
+ # 31 ITRF88@2015xETRF2020 xform=xform(tx=27.3, ty=-2.1, tz=-172.7, s=12.31, sx=2.336, sy=13.494, sz=-19.218)
1915
+ # rates=rates(tx=0.1, ty=-0.4, tz=-3.5, s=0.12, sx=0.086, sy=0.519, sz=-0.733)
1916
+ # 32 ITRF96@2015xETRF2000 xform=xform(tx=47.3, ty=55.7, tz=-4.3, s=-1.73, sx=2.106, sy=12.74, sz=-20.952)
1917
+ # rates=rates(tx=0.0, ty=0.6, tz=1.4, s=-0.01, sx=0.081, sy=0.49, sz=-0.812)
1918
+ # 33 ITRF97@2015xETRF2000 xform=xform(tx=47.3, ty=55.7, tz=-4.3, s=-1.73, sx=2.106, sy=12.74, sz=-20.952)
1919
+ # rates=rates(tx=0.0, ty=0.6, tz=1.4, s=-0.01, sx=0.081, sy=0.49, sz=-0.812)
1920
+ # 34 ITRF2000@2015xETRF2014 xform=xform(tx=-1.2, ty=-1.7, tz=35.6, s=-2.67, sx=2.21, sy=13.806, sz=-20.02)
1921
+ # rates=rates(tx=-0.1, ty=-0.1, tz=1.9, s=-0.11, sx=0.085, sy=0.531, sz=-0.77)
1922
+ # 35 ITRF90@2015xETRF2014 xform=xform(tx=-25.9, ty=-9.0, tz=109.3, s=-5.39, sx=2.21, sy=13.806, sz=-20.38)
1923
+ # rates=rates(tx=-0.1, ty=0.5, tz=3.3, s=-0.12, sx=0.085, sy=0.531, sz=-0.79)
1924
+ # 36 ITRF90@2015xETRF2020 xform=xform(tx=27.3, ty=9.9, tz=-110.7, s=5.81, sx=2.236, sy=13.494, sz=-19.218)
1925
+ # rates=rates(tx=0.1, ty=-0.4, tz=-3.5, s=0.12, sx=0.086, sy=0.519, sz=-0.733)
1926
+ # 37 ITRF91@2015xETRF2014 xform=xform(tx=-27.9, ty=-13.0, tz=93.3, s=-5.09, sx=2.21, sy=13.806, sz=-20.38)
1927
+ # rates=rates(tx=-0.1, ty=0.5, tz=3.3, s=-0.12, sx=0.085, sy=0.531, sz=-0.79)
1928
+ # 38 ITRF96@2015xETRF2014 xform=xform(tx=-7.9, ty=3.0, tz=79.3, s=-4.4, sx=2.21, sy=13.806, sz=-20.38)
1929
+ # rates=rates(tx=-0.1, ty=0.5, tz=3.3, s=-0.12, sx=0.085, sy=0.531, sz=-0.79)
1930
+ # 39 ITRF97@2015xETRF2014 xform=xform(tx=-7.9, ty=3.0, tz=79.3, s=-4.4, sx=2.21, sy=13.806, sz=-20.38)
1931
+ # rates=rates(tx=-0.1, ty=0.5, tz=3.3, s=-0.12, sx=0.085, sy=0.531, sz=-0.79)
1932
+ # 40 ITRF2000@2015xETRF2020 xform=xform(tx=2.6, ty=2.6, tz=-37.0, s=3.09, sx=2.236, sy=13.494, sz=-19.578)
1933
+ # rates=rates(tx=0.1, ty=0.2, tz=-2.1, s=0.11, sx=0.086, sy=0.519, sz=-0.753)
1934
+ # 41 ITRF91@2015xETRF2020 xform=xform(tx=29.3, ty=13.9, tz=-94.7, s=5.51, sx=2.236, sy=13.494, sz=-19.218)
1935
+ # rates=rates(tx=0.1, ty=-0.4, tz=-3.5, s=0.12, sx=0.086, sy=0.519, sz=-0.733)
1936
+ # 42 ITRF96@2015xETRF2020 xform=xform(tx=9.3, ty=-2.1, tz=-80.7, s=4.82, sx=2.236, sy=13.494, sz=-19.218)
1937
+ # rates=rates(tx=0.1, ty=-0.4, tz=-3.5, s=0.12, sx=0.086, sy=0.519, sz=-0.733)
1938
+ # 43 ITRF97@2015xETRF2020 xform=xform(tx=9.3, ty=-2.1, tz=-80.7, s=4.82, sx=2.236, sy=13.494, sz=-19.218)
1939
+ # rates=rates(tx=0.1, ty=-0.4, tz=-3.5, s=0.12, sx=0.086, sy=0.519, sz=-0.733)
1940
+ # 44 ITRF2000@2020xGDA2020 xform=xform(tx=-105.52, ty=51.58, tz=231.68, s=3.55, sx=4.2175, sy=6.3941, sz=0.8617)
1941
+ # rates=rates(tx=-4.66, ty=3.55, tz=11.24, s=0.249, sx=1.7454, sy=1.4868, sz=1.224)
1942
+ # 45 ITRF2000@1988xITRF88 xform=xform(tx=2.47, ty=1.15, tz=-9.79, s=8.95, sx=0.1, sy=0.0, sz=-0.18)
1943
+ # rates=rates(tx=0.0, ty=-0.06, tz=-0.14, s=0.01, sx=0.0, sy=0.0, sz=0.02)
1944
+ # 46 ITRF2000@1988xITRF89 xform=xform(tx=2.97, ty=4.75, tz=-7.39, s=5.85, sx=0.0, sy=0.0, sz=-0.18)
1945
+ # rates=rates(tx=0.0, ty=-0.06, tz=-0.14, s=0.01, sx=0.0, sy=0.0, sz=0.02)
1946
+ # 47 ITRF2000@1988xITRF90 xform=xform(tx=2.47, ty=2.35, tz=-3.59, s=2.45, sx=0.0, sy=0.0, sz=-0.18)
1947
+ # rates=rates(tx=0.0, ty=-0.06, tz=-0.14, s=0.01, sx=0.0, sy=0.0, sz=0.02)
1948
+ # 48 ITRF2000@1988xITRF91 xform=xform(tx=26.7, ty=27.5, tz=-19.9, s=2.15, sx=0.0, sy=0.0, sz=-0.18)
1949
+ # rates=rates(tx=0.0, ty=-0.6, tz=-1.4, s=0.01, sx=0.0, sy=0.0, sz=0.02)
1950
+ # 49 ITRF2000@1988xITRF92 xform=xform(tx=1.47, ty=1.35, tz=-1.39, s=0.75, sx=0.0, sy=0.0, sz=-0.18)
1951
+ # rates=rates(tx=0.0, ty=-0.06, tz=-0.14, s=0.01, sx=0.0, sy=0.0, sz=0.02)
1952
+ # 50 ITRF2000@1988xITRF93 xform=xform(tx=12.7, ty=6.5, tz=-20.9, s=1.95, sx=-0.39, sy=0.8, sz=-1.14)
1953
+ # rates=rates(tx=-2.9, ty=-0.2, tz=-0.6, s=0.01, sx=-0.11, sy=-0.19, sz=0.07)
1954
+ # 51 ITRF2000@1997xITRF94 xform=xform(tx=0.67, ty=0.61, tz=-1.85, s=1.55, sx=0.0, sy=0.0, sz=0.0)
1955
+ # rates=rates(tx=0.0, ty=-0.06, tz=-0.14, s=0.01, sx=0.0, sy=0.0, sz=0.02)
1956
+ # 52 ITRF2000@1997xITRF96 xform=xform(tx=0.67, ty=0.61, tz=-1.85, s=1.55, sx=0.0, sy=0.0, sz=0.0)
1957
+ # rates=rates(tx=0.0, ty=-0.06, tz=-0.14, s=0.01, sx=0.0, sy=0.0, sz=0.02)
1958
+ # 53 ITRF97@1997xITRF96 xform=xform(tx=-2.07, ty=-0.21, tz=9.95, s=-0.93496, sx=0.1267, sy=-0.22355, sz=-0.06065)
1959
+ # rates=rates(tx=0.69, ty=-0.1, tz=1.86, s=-0.19201, sx=0.01347, sy=-0.01514, sz=0.00027)
1960
+ # 54 ITRF2000@1997xITRF97 xform=xform(tx=0.67, ty=0.61, tz=-1.85, s=1.55, sx=0.0, sy=0.0, sz=0.0)
1961
+ # rates=rates(tx=0.0, ty=-0.06, tz=-0.14, s=0.01, sx=0.0, sy=0.0, sz=-0.02)
1962
+ # 55 ITRF2000@1997xNAD83 xform=xform(tx=995.6, ty=-1901.3, tz=-521.5, s=0.615, sx=-25.915, sy=-9.426, sz=-11.599)
1963
+ # rates=rates(tx=0.7, ty=-0.7, tz=0.5, s=-0.182, sx=-0.06667, sy=0.75744, sz=0.05133)
1964
+ # 56 ITRF2005@2015xETRF2000 xform=xform(tx=51.1, ty=51.7, tz=-80.8, s=1.6, sx=2.106, sy=12.74, sz=-20.592)
1965
+ # rates=rates(tx=-0.2, ty=0.1, tz=-1.8, s=0.08, sx=0.081, sy=0.49, sz=-0.792)
1966
+ # 57 ITRF2005@1989xETRF2005 xform=xform(tx=56.0, ty=48.0, tz=-37.0, s=0.0, sx=0.0, sy=0.0, sz=0.0)
1967
+ # rates=rates(tx=0.0, ty=0.0, tz=0.0, s=0.0, sx=0.054, sy=0.518, sz=-0.781)
1968
+ # 58 ITRF2005@1994xGDA94 xform=xform(tx=-79.73, ty=-6.86, tz=38.03, s=6.636, sx=0.0351, sy=-2.1211, sz=-2.1411)
1969
+ # rates=rates(tx=2.25, ty=-0.62, tz=-0.56, s=0.294, sx=-1.4707, sy=-1.1443, sz=-1.1701)
1970
+ # 59 ITRF2005@1997xNAD83 xform=xform(tx=996.3, ty=-1902.4, tz=-521.9, s=0.775, sx=-25.915, sy=-9.426, sz=-11.599)
1971
+ # rates=rates(tx=0.5, ty=-0.6, tz=-1.3, s=-0.10201, sx=-0.06667, sy=0.75744, sz=0.05133)
1972
+ # 60 ITRF2005@2015xETRF2014 xform=xform(tx=-4.1, ty=-1.0, tz=2.8, s=-1.07, sx=2.21, sy=13.806, sz=-20.02)
1973
+ # rates=rates(tx=-0.3, ty=0.0, tz=0.1, s=-0.03, sx=0.085, sy=0.531, sz=-0.77)
1974
+ # 61 ITRF2005@2015xETRF2020 xform=xform(tx=5.5, ty=1.9, tz=-4.2, s=1.49, sx=2.236, sy=13.494, sz=-19.578)
1975
+ # rates=rates(tx=0.3, ty=0.1, tz=-0.3, s=0.03, sx=0.086, sy=0.519, sz=-0.753)
1976
+ # 62 ITRF2005@2020xGDA2020 xform=xform(tx=40.32, ty=-33.85, tz=-16.72, s=4.286, sx=-1.2893, sy=-0.8492, sz=-0.3342)
1977
+ # rates=rates(tx=2.25, ty=-0.62, tz=-0.56, s=0.294, sx=-1.4707, sy=-1.1443, sz=-1.1701)
1978
+ # 63 ITRF2005@2000xITRF2000 xform=xform(tx=0.1, ty=-0.8, tz=-5.8, s=0.4, sx=0.0, sy=0.0, sz=0.0)
1979
+ # rates=rates(tx=-0.2, ty=0.1, tz=-1.8, s=0.08, sx=0.0, sy=0.0, sz=0.0)
1980
+ # 64 ITRF2008@1994xGDA94 xform=xform(tx=-84.68, ty=-19.42, tz=32.01, s=9.71, sx=-0.4254, sy=2.2578, sz=2.4015)
1981
+ # rates=rates(tx=1.42, ty=1.34, tz=0.9, s=0.109, sx=1.5461, sy=1.182, sz=1.1551)
1982
+ # 65 ITRF2008@1997xNAD83 xform=xform(tx=993.43, ty=-1903.31, tz=-526.55, s=1.71504, sx=-25.91467, sy=-9.42645, sz=-11.59935)
1983
+ # rates=rates(tx=0.79, ty=-0.6, tz=-1.34, s=-0.10201, sx=-0.06667, sy=0.75744, sz=0.05133)
1984
+ # 66 ITRF96@1997xNAD83 xform=xform(tx=991.0, ty=-190.72, tz=-512.9, s=0.0, sx=25.79, sy=9.65, sz=11.66)
1985
+ # rates=rates(tx=0.0, ty=0.0, tz=0.0, s=0.0, sx=0.0532, sy=-0.7423, sz=-0.0316)
1986
+ # 67 ITRF2008@2015xETRF2000 xform=xform(tx=53.6, ty=50.8, tz=-85.5, s=2.54, sx=2.106, sy=12.74, sz=-20.592)
1987
+ # rates=rates(tx=0.1, ty=0.1, tz=-1.8, s=0.08, sx=0.081, sy=0.49, sz=-0.792)
1988
+ # 68 ITRF2008@2015xETRF2014 xform=xform(tx=-1.6, ty=-1.9, tz=-1.9, s=-0.13, sx=2.21, sy=13.806, sz=-20.02)
1989
+ # rates=rates(tx=0.0, ty=0.0, tz=0.1, s=-0.03, sx=0.085, sy=0.531, sz=-0.77)
1990
+ # 69 ITRF2008@2015xETRF2020 xform=xform(tx=3.0, ty=2.8, tz=0.5, s=0.55, sx=2.236, sy=13.494, sz=-19.578)
1991
+ # rates=rates(tx=0.0, ty=0.1, tz=-0.3, s=0.03, sx=0.086, sy=0.519, sz=-0.753)
1992
+ # 70 ITRF2008@2020xGDA2020 xform=xform(tx=13.79, ty=4.55, tz=15.22, s=2.5, sx=0.2808, sy=0.2677, sz=-0.4638)
1993
+ # rates=rates(tx=1.42, ty=1.34, tz=0.9, s=0.109, sx=1.5461, sy=1.182, sz=1.1551)
1994
+ # 71 ITRF2008@2000xITRF2000 xform=xform(tx=-1.9, ty=-1.7, tz=-10.5, s=1.34, sx=0.0, sy=0.0, sz=0.0)
1995
+ # rates=rates(tx=0.1, ty=0.1, tz=-1.8, s=0.08, sx=0.0, sy=0.0, sz=0.0)
1996
+ # 72 ITRF2008@2000xITRF88 xform=xform(tx=22.8, ty=2.6, tz=-125.2, s=10.41, sx=0.1, sy=0.0, sz=0.06)
1997
+ # rates=rates(tx=0.1, ty=-0.5, tz=-3.2, s=0.09, sx=0.0, sy=0.0, sz=0.02)
1998
+ # 73 ITRF2008@2000xITRF89 xform=xform(tx=27.8, ty=38.6, tz=-101.2, s=7.31, sx=0.0, sy=0.0, sz=0.06)
1999
+ # rates=rates(tx=0.1, ty=-0.5, tz=-3.2, s=0.09, sx=0.0, sy=0.0, sz=0.02)
2000
+ # 74 ITRF2008@2000xITRF90 xform=xform(tx=22.8, ty=14.6, tz=-63.2, s=3.91, sx=0.0, sy=0.0, sz=0.06)
2001
+ # rates=rates(tx=0.1, ty=-0.5, tz=-3.2, s=0.09, sx=0.0, sy=0.0, sz=0.02)
2002
+ # 75 ITRF2008@2000xITRF91 xform=xform(tx=24.8, ty=18.6, tz=-47.2, s=3.61, sx=0.0, sy=0.0, sz=0.06)
2003
+ # rates=rates(tx=0.1, ty=-0.5, tz=-3.2, s=0.09, sx=0.0, sy=0.0, sz=0.02)
2004
+ # 76 ITRF2008@2000xITRF92 xform=xform(tx=12.8, ty=4.6, tz=-41.2, s=2.21, sx=0.0, sy=0.0, sz=0.06)
2005
+ # rates=rates(tx=0.1, ty=-0.5, tz=-3.2, s=0.09, sx=0.0, sy=0.0, sz=0.02)
2006
+ # 77 ITRF2008@2000xITRF93 xform=xform(tx=-24.0, ty=2.4, tz=-38.6, s=3.41, sx=-1.71, sy=-1.48, sz=-0.3)
2007
+ # rates=rates(tx=-2.8, ty=-0.1, tz=-2.4, s=0.09, sx=-0.11, sy=-0.19, sz=0.07)
2008
+ # 78 ITRF2008@2000xITRF94 xform=xform(tx=4.8, ty=2.6, tz=-33.2, s=2.92, sx=0.0, sy=0.0, sz=0.06)
2009
+ # rates=rates(tx=0.1, ty=-0.5, tz=-3.2, s=0.09, sx=0.0, sy=0.0, sz=0.02)
2010
+ # 79 ITRF2008@2000xITRF96 xform=xform(tx=4.8, ty=2.6, tz=-33.2, s=2.92, sx=0.0, sy=0.0, sz=0.06)
2011
+ # rates=rates(tx=0.1, ty=-0.5, tz=-3.2, s=0.09, sx=0.0, sy=0.0, sz=0.02)
2012
+ # 80 ITRF2008@2000xITRF97 xform=xform(tx=4.8, ty=2.6, tz=-33.2, s=2.92, sx=0.0, sy=0.0, sz=0.06)
2013
+ # rates=rates(tx=0.1, ty=-0.5, tz=-3.2, s=0.09, sx=0.0, sy=0.0, sz=0.02)
2014
+ # 81 ITRF2008@2005xITRF2005 xform=xform(tx=-0.5, ty=-0.9, tz=-4.7, s=0.94, sx=0.0, sy=0.0, sz=0.0)
2015
+ # rates=rates(tx=0.3, ty=0.0, tz=0.0, s=0.0, sx=0.0, sy=0.0, sz=0.0)
2016
+ # 82 ITRF2014@2015xETRF2000 xform=xform(tx=55.2, ty=52.7, tz=-83.6, s=2.67, sx=2.106, sy=12.74, sz=-20.592)
2017
+ # rates=rates(tx=0.1, ty=0.1, tz=-1.9, s=0.11, sx=0.081, sy=0.49, sz=-0.792)
2018
+ # 83 ITRF2014@2015xETRF2014 xform=xform(tx=0.0, ty=0.0, tz=0.0, s=0.0, sx=2.21, sy=13.806, sz=-20.02)
2019
+ # rates=rates(tx=0.0, ty=0.0, tz=0.0, s=0.0, sx=0.085, sy=0.531, sz=-0.77)
2020
+ # 84 ITRF2014@2015xETRF2020 xform=xform(tx=1.4, ty=0.9, tz=-1.4, s=0.42, sx=2.236, sy=13.494, sz=-19.578)
2021
+ # rates=rates(tx=0.0, ty=0.1, tz=-0.2, s=0.0, sx=0.086, sy=0.519, sz=-0.753)
2022
+ # 85 ITRF2014@2020xGDA2020 xform=unity(tx=0.0, ty=0.0, tz=0.0, s=0.0, sx=0.0, sy=0.0, sz=0.0)
2023
+ # rates=rates(tx=0.0, ty=0.0, tz=0.0, s=0.0, sx=1.50379, sy=1.18346, sz=1.20716)
2024
+ # 86 ITRF2014@2010xITRF2000 xform=xform(tx=0.7, ty=1.2, tz=-26.1, s=2.12, sx=0.0, sy=0.0, sz=0.0)
2025
+ # rates=rates(tx=0.1, ty=0.1, tz=-1.9, s=0.11, sx=0.0, sy=0.0, sz=0.0)
2026
+ # 87 ITRF2014@2010xITRF2005 xform=xform(tx=2.6, ty=1.0, tz=-2.3, s=0.92, sx=0.0, sy=0.0, sz=0.0)
2027
+ # rates=rates(tx=0.3, ty=0.0, tz=-0.1, s=0.03, sx=0.0, sy=0.0, sz=0.0)
2028
+ # 88 ITRF2014@2010xITRF2008 xform=xform(tx=1.6, ty=1.9, tz=2.4, s=-0.02, sx=0.0, sy=0.0, sz=0.0)
2029
+ # rates=rates(tx=0.0, ty=0.0, tz=-0.1, s=0.03, sx=0.0, sy=0.0, sz=0.0)
2030
+ # 89 ITRF2014@2010xITRF88 xform=xform(tx=25.4, ty=-0.5, tz=-154.8, s=11.29, sx=0.1, sy=0.0, sz=0.26)
2031
+ # rates=rates(tx=0.1, ty=-0.5, tz=-3.3, s=0.12, sx=0.0, sy=0.0, sz=0.02)
2032
+ # 90 ITRF2014@2010xITRF89 xform=xform(tx=30.4, ty=35.5, tz=-130.8, s=8.19, sx=0.0, sy=0.0, sz=0.26)
2033
+ # rates=rates(tx=0.1, ty=-0.5, tz=-3.3, s=0.12, sx=0.0, sy=0.0, sz=0.02)
2034
+ # 91 ITRF2014@2010xITRF90 xform=xform(tx=25.4, ty=11.5, tz=-92.8, s=4.79, sx=0.0, sy=0.0, sz=0.26)
2035
+ # rates=rates(tx=0.1, ty=-0.5, tz=-3.3, s=0.12, sx=0.0, sy=0.0, sz=0.02)
2036
+ # 92 ITRF2014@2010xITRF91 xform=xform(tx=27.4, ty=15.5, tz=-76.8, s=4.49, sx=0.0, sy=0.0, sz=0.26)
2037
+ # rates=rates(tx=0.1, ty=-0.5, tz=-3.3, s=0.12, sx=0.0, sy=0.0, sz=0.02)
2038
+ # 93 ITRF2014@2010xITRF92 xform=xform(tx=15.4, ty=1.5, tz=-70.8, s=3.09, sx=0.0, sy=0.0, sz=0.26)
2039
+ # rates=rates(tx=0.1, ty=-0.5, tz=-3.3, s=0.12, sx=0.0, sy=0.0, sz=0.02)
2040
+ # 94 ITRF2014@2010xITRF93 xform=xform(tx=-50.4, ty=3.3, tz=-60.2, s=4.29, sx=-2.81, sy=-3.38, sz=0.4)
2041
+ # rates=rates(tx=-2.8, ty=-0.1, tz=-2.5, s=0.12, sx=-0.11, sy=-0.19, sz=0.07)
2042
+ # 95 ITRF2014@2010xITRF94 xform=xform(tx=7.4, ty=-0.5, tz=-62.8, s=3.8, sx=0.0, sy=0.0, sz=0.26)
2043
+ # rates=rates(tx=0.1, ty=-0.5, tz=-3.3, s=0.12, sx=0.0, sy=0.0, sz=0.02)
2044
+ # 96 ITRF2014@2010xITRF96 xform=xform(tx=7.4, ty=-0.5, tz=-62.8, s=3.8, sx=0.0, sy=0.0, sz=0.26)
2045
+ # rates=rates(tx=0.1, ty=-0.5, tz=-3.3, s=0.12, sx=0.0, sy=0.0, sz=0.02)
2046
+ # 97 ITRF2014@2010xITRF97 xform=xform(tx=7.4, ty=-0.5, tz=-62.8, s=3.8, sx=0.0, sy=0.0, sz=0.26)
2047
+ # rates=rates(tx=0.1, ty=-0.5, tz=-3.3, s=0.12, sx=0.0, sy=0.0, sz=0.02)
2048
+ # 98 ITRF2020@2015xETRF2000 xform=xform(tx=53.8, ty=51.8, tz=-82.2, s=2.25, sx=2.106, sy=12.74, sz=-20.592)
2049
+ # rates=rates(tx=0.1, ty=0.0, tz=-1.7, s=0.11, sx=0.081, sy=0.49, sz=-0.792)
2050
+ # 99 ITRF2020@2015xETRF2014 xform=xform(tx=-1.4, ty=-0.9, tz=1.4, s=0.42, sx=2.21, sy=13.806, sz=-20.02)
2051
+ # rates=rates(tx=0.0, ty=-0.1, tz=0.2, s=0.0, sx=0.085, sy=0.531, sz=-0.77)
2052
+ # 100 ITRF2020@2015xETRF2020 xform=xform(tx=0.0, ty=0.0, tz=0.0, s=0.0, sx=2.236, sy=13.494, sz=-19.578)
2053
+ # rates=rates(tx=0.0, ty=0.0, tz=0.0, s=0.0, sx=0.086, sy=0.519, sz=-0.753)
2054
+ # 101 ITRF2020@2015xITRF2000 xform=xform(tx=-0.2, ty=0.8, tz=-34.2, s=2.25, sx=0.0, sy=0.0, sz=0.0)
2055
+ # rates=rates(tx=0.1, ty=0.0, tz=-1.7, s=0.11, sx=0.0, sy=0.0, sz=0.0)
2056
+ # 102 ITRF2020@2015xITRF2005 xform=xform(tx=2.7, ty=0.1, tz=-1.4, s=0.65, sx=0.0, sy=0.0, sz=0.0)
2057
+ # rates=rates(tx=0.3, ty=-0.1, tz=0.1, s=0.03, sx=0.0, sy=0.0, sz=0.0)
2058
+ # 103 ITRF2020@2015xITRF2008 xform=xform(tx=0.2, ty=1.0, tz=3.3, s=-0.29, sx=0.0, sy=0.0, sz=0.0)
2059
+ # rates=rates(tx=0.0, ty=-0.1, tz=0.1, s=0.03, sx=0.0, sy=0.0, sz=0.0)
2060
+ # 104 ITRF2020@2015xITRF2014 xform=xform(tx=-1.4, ty=-0.9, tz=1.4, s=-0.42, sx=0.0, sy=0.0, sz=0.0)
2061
+ # rates=rates(tx=0.0, ty=-0.1, tz=0.2, s=0.0, sx=0.0, sy=0.0, sz=0.0)
2062
+ # 105 ITRF2020@2015xITRF88 xform=xform(tx=24.5, ty=-3.9, tz=-169.9, s=11.47, sx=0.1, sy=0.0, sz=0.36)
2063
+ # rates=rates(tx=0.1, ty=-0.6, tz=-3.1, s=0.12, sx=0.0, sy=0.0, sz=0.02)
2064
+ # 106 ITRF2020@2015xITRF89 xform=xform(tx=29.5, ty=32.1, tz=-145.9, s=8.37, sx=0.0, sy=0.0, sz=0.36)
2065
+ # rates=rates(tx=0.1, ty=-0.6, tz=-3.1, s=0.12, sx=0.0, sy=0.0, sz=0.02)
2066
+ # 107 ITRF2020@2015xITRF90 xform=xform(tx=24.5, ty=8.1, tz=-107.9, s=4.97, sx=0.0, sy=0.0, sz=0.36)
2067
+ # rates=rates(tx=0.1, ty=-0.6, tz=-3.1, s=0.12, sx=0.0, sy=0.0, sz=0.02)
2068
+ # 108 ITRF2020@2015xITRF91 xform=xform(tx=26.5, ty=12.1, tz=-91.9, s=4.67, sx=0.0, sy=0.0, sz=0.36)
2069
+ # rates=rates(tx=0.1, ty=-0.6, tz=-3.1, s=0.12, sx=0.0, sy=0.0, sz=0.02)
2070
+ # 109 ITRF2020@2015xITRF92 xform=xform(tx=14.5, ty=-1.9, tz=-85.9, s=3.27, sx=0.0, sy=0.0, sz=0.36)
2071
+ # rates=rates(tx=0.1, ty=-0.6, tz=-3.1, s=0.12, sx=0.0, sy=0.0, sz=0.02)
2072
+ # 110 ITRF2020@2015xITRF93 xform=xform(tx=-65.8, ty=1.9, tz=-71.3, s=4.47, sx=-3.36, sy=-4.33, sz=0.75)
2073
+ # rates=rates(tx=-2.8, ty=-0.2, tz=-2.3, s=0.12, sx=-0.11, sy=-0.19, sz=0.07)
2074
+ # 111 ITRF2020@2015xITRF94 xform=xform(tx=6.5, ty=-3.9, tz=-77.9, s=3.98, sx=0.0, sy=0.0, sz=0.36)
2075
+ # rates=rates(tx=0.1, ty=-0.6, tz=-3.1, s=0.12, sx=0.0, sy=0.0, sz=0.02)
2076
+ # 112 ITRF2020@2015xITRF96 xform=xform(tx=6.5, ty=-3.9, tz=-77.9, s=3.98, sx=0.0, sy=0.0, sz=0.36)
2077
+ # rates=rates(tx=0.1, ty=-0.6, tz=-3.1, s=0.12, sx=0.0, sy=0.0, sz=0.02)
2078
+ # 113 ITRF2020@2015xITRF97 xform=xform(tx=6.5, ty=-3.9, tz=-77.9, s=3.98, sx=0.0, sy=0.0, sz=0.36)
2079
+ # rates=rates(tx=0.1, ty=-0.6, tz=-3.1, s=0.12, sx=0.0, sy=0.0, sz=0.02)