Coverage for pybelbg / __pygeodesy.py: 96%

91 statements  

« prev     ^ index     » next       coverage.py v7.14.0, created at 2026-07-29 15:24 -0400

1 

2# -*- coding: utf-8 -*- 

3 

4u'''(INTERNAL) C{pybelbg} access to some private C{pygeodesy} attributes. 

5''' 

6import os.path as os_path 

7import sys # PYCHOK used! 

8 

9_missing_ = 'missing' # PYCHOK used! 

10_requires = '26.7.27' # in README.rst, requirements.txt, setup.py 

11 

12 

13def _PyGeodesy_dir(requires): 

14 # Adjust sys.path to enable import pygeodesy 

15 d = None 

16 try: 

17 from pygeodesy import version as _v 

18 except ImportError: 

19 _v = _missing_ 

20 # PYTHONPATH=.../PyBeLBG for development ONLY 

21 p = os_path.abspath(__file__) 

22 p = os_path.dirname(p) # pybelbg_abspath 

23 p = os_path.dirname(p) # PyBeLBG 

24 p = os_path.dirname(p) # ../ 

25 g = os_path.join(p, 'PyGeodesy') 

26 if g != p and g not in sys.path: 

27 sys.path.insert(0, g) 

28 try: 

29 from pygeodesy import version as _v # PYCHOK redef 

30 d = g 

31 except ImportError: 

32 pass 

33# finally: 

34# try: 

35# sys.path.remove(g) 

36# except ValueError: 

37# pass 

38 

39 def _t(v): 

40 return tuple(map(int, v.split('.'))) # _DOT_ 

41 

42 if _v == _missing_ or _t(_v) < _t(requires): 

43 _v = ' %s, need %s or newer' % (_v, requires) 

44 raise ImportError('pygeodesy' + _v) 

45 

46 return d # or None 

47 

48_PyGeodesy_dir = _PyGeodesy_dir(_requires) # PYCHOK path or None 

49 

50from pygeodesy.basics import _xinstanceof, _xsubclassof # noqa: F401 

51from pygeodesy.constants import (_1_0, _3600_0, # noqa: F401 

52 _isNAN, _isNAN0) # noqa: F401 

53from pygeodesy.ellipsoidalBase import LatLonEllipsoidalBase as _LLEB # noqa: F401 

54from pygeodesy.errors import _ValueError, _xkwds # noqa: F401 

55from pygeodesy.internals import machine, _secs2str, _versions # noqa: F401 

56from pygeodesy.interns import (_COMMA_, _DASH_, _easting_, # noqa: F401 

57 _H_, _height_, _lat_, _lon_, _N_, # noqa: F401 

58 _name_, _northing_, _SPACE_) # noqa: F401 

59from pygeodesy.lazily import _ALL_DOCS, _ALL_OTHER, _FOR_DOCS # noqa: F401 

60from pygeodesy.named import _NamedBase, _NamedTuple, _Pass # noqa: F401 

61from pygeodesy.namedTuples import (EasNor2Tuple, LatLon2Tuple, PhiLam2Tuple, 

62 _isinside, _resize4) 

63from pygeodesy.streprs import Fmt # noqa: F401 

64 

65from pygeodesy import (Datums, Easting, Height, Lamd, Lat, Lon, Meter, 

66 NAN, Northing, Phid, Property_RO) 

67 

68 

69class BeLBGError(_ValueError): 

70 '''Error raised for C{pybelbg}, C{hBG18}, unzip and other issues. 

71 ''' 

72 pass 

73 

74 

75class BeLBG7Tuple(_NamedTuple): 

76 '''7-Tuple C{(easting, northing, H, lat, lon, height, beLBG)} with I{local} 

77 Belgian C{easting}, C{northing} and orthometric height C{H}, geodetic C{lat}, 

78 C{lon} and ellipsoidal C{height} and C{beLBG} the C{Be*LBG} instance with 

79 C{lat} and C{lon} in C{degrees} and with C{easting}, C{northing}, C{H} and 

80 C{height} in C{meter}, conventionally. 

81 ''' 

82 _Names_ = (_easting_, _northing_, _H_, _lat_, _lon_, _height_, 'beLBG') 

83 _Units_ = ( Easting, Northing, Height, Lat, Lon, Height, _Pass) 

84 

85 @Property_RO 

86 def datum(self): 

87 '''Get the C{beLBG}'s datum (C{Datum}). 

88 ''' 

89 return self.beLBG.datum # PYCHOK beLBG 

90 

91# def diff(self, other, datum=None, **name): 

92# '''Return the difference between this and an C{other} C{BeLBG7Tuple}. 

93# 

94# @kwarg datum: Datum C{diff} (C{Datum}, None or NAN). 

95# @kwarg name: Optional name (C{str}). 

96# 

97# @return: An L{BeLBG7Tuple} with the C{fabs(diff)} for each item, 

98# except C{datum} as B{C{datum}}. 

99# ''' 

100# def _diff(a, b): 

101# try: 

102# return fabs(a - b) 

103# except TypeError: 

104# return datum 

105# 

106# _xinstanceof(BeLBG7Tuple, other=other) 

107# t = map2(_diff, self, other) 

108# return BeLBG7Tuple(t, **name) 

109 

110 @Property_RO 

111 def eastingnorthing(self): 

112 '''Get easting and northing (L{EasNor2Tuple}C{(easting, northing)}). 

113 ''' 

114 return EasNor2Tuple(self.easting, self.northing, name=self.name) 

115 

116 @Property_RO 

117 def eastingnorthingHeight(self): 

118 '''Get easting, northing and orthometric height (L{EasNorH3Tuple}C{(easting, northing, H)}). 

119 ''' 

120 return EasNorH3Tuple(self.easting, self.northing, self.H, name=self.name) 

121 

122 @Property_RO 

123 def lam(self): 

124 '''Get the longitude (B{C{radians}}). 

125 ''' 

126 return Lamd(self.lon) # PYCHOK lon 

127 

128 @Property_RO 

129 def latlon(self): 

130 '''Get the lat-, longitude in C{degrees} (L{LatLon2Tuple}C{(lat, lon)}). 

131 ''' 

132 return LatLon2Tuple(self.lat, self.lon, name=self.name) 

133 

134 @Property_RO 

135 def latlonheight(self): 

136 '''Get the lat-, longitude in C{degrees} and height (L{LatLon3Tuple}C{(lat, lon, height)}). 

137 ''' 

138 return self.latlon.to3Tuple(self.height) 

139 

140 @Property_RO 

141 def latlonheightdatum(self): 

142 '''Get the lat-, longitude in C{degrees} with height and datum (L{LatLon4Tuple}C{(lat, lon, height, datum)}). 

143 ''' 

144 return self.latlonheight.to4Tuple(self.datum) 

145 

146 @Property_RO 

147 def latlonNgeoid(self): 

148 '''Get the lat-, longitude in C{degrees} and geoid height (L{LatLonN3Tuple}C{(lat, lon, N)}). 

149 ''' 

150 return LatLonN3Tuple(self.lat, self.lon, self.N, name=self.name) 

151 

152 @Property_RO 

153 def N(self): 

154 '''Get the geoid height C{N} (C{meter}, conventionally). 

155 ''' 

156 N = self.height - self.H 

157 return NAN if _isNAN(N) else Height(N=N) 

158 

159 @Property_RO 

160 def phi(self): 

161 '''Get the latitude (B{C{radians}}). 

162 ''' 

163 return Phid(self.lat) # PYCHOK lat 

164 

165 @Property_RO 

166 def philam(self): 

167 '''Get the lat- and longitude in C{radians} (L{PhiLam2Tuple}C{(phi, lam)}). 

168 ''' 

169 return PhiLam2Tuple(self.phi, self.lam, name=self.name) # PYCHOK lam, phi 

170 

171 @Property_RO 

172 def philamheight(self): 

173 '''Get the lat-, longitude in C{radians} and height (L{PhiLam3Tuple}C{(phi, lam, height)}). 

174 ''' 

175 return self.philam.to3Tuple(self.height) # PYCHOK height 

176 

177 @Property_RO 

178 def philamheightdatum(self): 

179 '''Get the lat-, longitude in C{radians} with height and datum (L{PhiLamn4Tuple}C{(phi, lam, height, datum)}). 

180 ''' 

181 return self.philamheight.to4Tuple(self.datum) 

182 

183# def toDatum(self, datum2, name=NN): 

184# '''Convert this C{lat}, C{lon} and C{height} to B{C{datum2}}. 

185# 

186# @arg datum2: Datum to convert I{to} (L{Datum}). 

187# @kwarg name: Optional name (C{str}), overriding this name. 

188# 

189# @return: An L{BeLBG7Tuple} with transformed C{lat}, C{lon} and C{height} 

190# or this L{BeLBG7Tuple} if this.datum is B{C{datum2}}. 

191# ''' 

192# _xinstanceof(Datum, datum2=datum2) 

193# if self.datum is datum2 or self.datum == datum2: # PYCHOK datum 

194# return self 

195# g = self.toLatLon(_LLEB).toDatum(datum2) 

196# h = NAN if _isNAN(self.height) else g.height # PYCHOK preserve height NAN 

197# return self.dup(lat=g.lat, lon=g.lon, datum=g.datum, height=h, 

198# name=name or self.name) 

199 

200# def toLatLon(self, LatLon, **LatLon_kwds): 

201# '''Return this C{lat}, C{lon}, C{datum} and C{height} as B{C{LatLon}}. 

202# 

203# @arg LatLon: An ellipsoidal C{LatLon} class (C{pygeodesy.ellipsoidal*}). 

204# @kwarg LatLon_kwds: Optional, additional B{C{LatLon}} keyword arguments. 

205# 

206# @return: An B{C{LatLon}} instance. 

207# 

208# @raise TypeError: B{C{LatLon}} not ellipsoidal or an other issue. 

209# ''' 

210# _xsubclassof(_LLEB, LatLon=LatLon) 

211# h = _isNAN0(self.height) # PYCHOK height 

212# kwds = _xkwds(LatLon_kwds, name=self.name, height=h) 

213# return LatLon(self.lat, self.lon, datum=self.datum, **kwds) # PYCHOK datum 

214 

215# @Property_RO 

216# def xy(self): 

217# '''Get the I{local} easting, northing) coordinates (L{Vector2Tuple}C{(x, y)}). 

218# ''' 

219# return Vector2Tuple(self.easting, self.northing, name=self.name) 

220 

221# @Property_RO 

222# def xyz(self): 

223# '''Get the I{local} easting, northing and (orthometric) height (L{Vector3Tuple}C{(x, y, z)}). 

224# ''' 

225# return Vector3Tuple(self.easting, self.northing, self.H, name=self.name) 

226 

227 

228class EasNorH3Tuple(_NamedTuple): 

229 '''3-Tuple C{(easting, northing, H)}, all in C{meter}, conventionally 

230 with orthometric height C{H}. 

231 ''' 

232 _Names_ = EasNor2Tuple._Names_ + (_H_,) 

233 _Units_ = EasNor2Tuple._Units_ + (Height,) 

234 

235 

236class LatLonN3Tuple(_NamedTuple): # XXX move to pygeodesy 

237 '''3-tuple C{(lat, lon, N)} with geoid height C{N} in C{meter}, conventionally. 

238 ''' 

239 _Names_ = (_lat_, _lon_, _N_) 

240 _Units_ = ( Lat, Lon, Height) 

241 

242 

243class Lb4Tuple(_NamedTuple): 

244 '''4-Tuple C{(minE, minN, maxE, maxN)} with local C{Lambert} lower-left 

245 C{(minE, minN)} and upper-right C{(maxE, maxN)} bounds in C{meter}, 

246 conventionally. 

247 ''' 

248 _Names_ = ('minE', 'minN', 'maxE', 'maxN') 

249 _Units_ = ( Easting, Northing, Easting, Northing) 

250 

251 def isinside(self, easting, northing, eps=0): 

252 '''Are B{C{easting}} and B{C{northing}} inside these C{Lambert} bounds? 

253 

254 @arg easting: Easting (C{meter}). 

255 @arg northing: Northing (C{meter}). 

256 @kwarg eps: Over-/undersize the C{Lb} bounds (C{meter}). 

257 

258 @return: C{False} if B{C{easting}} or B{C{northing}} is outsize 

259 these C{Lb} bounds or C{NAN}, C{True} otherwise. 

260 ''' 

261 z = Meter(eps=eps) if eps else 0 

262 return _isinside(Easting(easting), Northing(northing), z, self) 

263 

264 def resize(self, eps): 

265 '''Get these C{Lambert} bounds, over- or undersized by C{B{eps}}. 

266 

267 @arg eps: In- or decrease (C{meter}). 

268 

269 @return: An L{Lb4Tuple}C{(minE, minN, maxE, maxN)} with all 

270 4 bounds resized. 

271 ''' 

272 return _resize4(self, Meter(eps=eps)) 

273 

274 

275def _all_OTHER(*objs): # PYCHOK shared 

276 # collect all __all__ lists or tuples 

277 _all = _ALL_OTHER(*objs) 

278 _all__all__.extend(_all) 

279 return _all 

280 

281_all__all__ = [] # PYCHOK in .__init__ 

282 

283__all__ = _all_OTHER(machine, BeLBGError, BeLBG7Tuple, Datums, 

284 EasNorH3Tuple, LatLonN3Tuple, Lb4Tuple) 

285__version__ = '26.07.29' 

286 

287# **) MIT License 

288# 

289# Copyright (C) 2026-2026 -- mrJean1 at Gmail -- All Rights Reserved. 

290# 

291# Permission is hereby granted, free of charge, to any person obtaining a 

292# copy of this software and associated documentation files (the "Software"), 

293# to deal in the Software without restriction, including without limitation 

294# the rights to use, copy, modify, merge, publish, distribute, sublicense, 

295# and/or sell copies of the Software, and to permit persons to whom the 

296# Software is furnished to do so, subject to the following conditions: 

297# 

298# The above copyright notice and this permission notice shall be included 

299# in all copies or substantial portions of the Software. 

300# 

301# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 

302# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 

303# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 

304# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 

305# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 

306# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 

307# OTHER DEALINGS IN THE SOFTWARE.