Coverage for pygeodesy/nvectorBase.py : 97%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# -*- coding: utf-8 -*-
Classes L{LatLonNvectorBase} for C{n-vectorial} ellipsoidal and spherical C{LatLon}s, class L{NvectorBase} for C{Cartesian}s and function L{sumOf}.
Pure Python implementation of C{n-vector}-based geodesy tools for ellipsoidal earth models, transcoded from JavaScript originals by I{(C) Chris Veness 2005-2016} and published under the same MIT Licence**, see U{Vector-based geodesy <https://www.Movable-Type.co.UK/scripts/latlong-vectors.html>}. '''
# from pygeodesy.datums import _spherical_datum # from .formy _xkwds, _xkwds_pop _bearing_, _coincident_, _COMMASPACE_, \ _distance_, _intersection_, _no_, _NorthPole_, \ _points_, _pole_, _SPACE_, _SouthPole_, \ _1_, _2_, _3_, _2_0 Vector4Tuple
'''Base class for ellipsoidal and spherical C{Nvector}s. '''
'''New n-vector normal to the earth's surface.
@arg x_xyz: X component of vector (C{scalar}) or (3-D) vector (C{Nvector}, L{Vector3d}, L{Vector3Tuple} or L{Vector4Tuple}). @kwarg y: Y component of vector (C{scalar}), ignored if B{C{x_xyz}} is not C{scalar}, otherwise same units as B{C{x_xyz}}. @kwarg z: Z component of vector (C{scalar}), ignored if B{C{x_xyz}} is not C{scalar}, otherwise same units as B{C{x_xyz}}. @kwarg h: Optional height above surface (C{meter}). @kwarg ll: Optional, original latlon (C{LatLon}). @kwarg datum: Optional, I{pass-thru} datum (L{Datum}). @kwarg name: Optional name (C{str}).
@raise TypeError: Non-scalar B{C{x}}, B{C{y}} or B{C{z}} coordinate or B{C{x}} not an C{Nvector}, L{Vector3Tuple} or L{Vector4Tuple} or invalid B{C{datum}}.
@example:
>>> from pygeodesy.sphericalNvector import Nvector >>> v = Nvector(0.5, 0.5, 0.7071, 1) >>> v.toLatLon() # 45.0°N, 045.0°E, +1.00m '''
'''Get the I{pass-thru} datum (C{Datum}) or C{None}. '''
'''Get the ECEF I{class} (L{EcefKarney}), I{lazily}. '''
'''Get the height above surface (C{meter}). '''
'''Set the height above surface.
@arg h: New height (C{meter}).
@raise TypeError: If B{C{h}} invalid.
@raise VectorError: If B{C{h}} invalid. '''
'''Get the height prefix (C{str}). '''
'''Set the height prefix.
@arg H: New height prefix (C{str}). '''
'''Return a string for the height B{C{h}}.
@kwarg prec: Number of (decimal) digits, unstripped (C{int}). @kwarg m: Optional unit of the height (C{str}).
@see: Function L{pygeodesy.hstr}. '''
'''Check whether this n-vector is ellipsoidal (C{bool} or C{None} if unknown). '''
'''Check whether this n-vector is spherical (C{bool} or C{None} if unknown). '''
'''Get the (geodetic) longitude in C{radians} (C{float}). '''
'''Get the (geodetic) latitude in C{degrees} (C{float}). '''
'''Get the (geodetic) lat-, longitude in C{degrees} (L{LatLon2Tuple}C{(lat, lon)}). '''
'''Get the (geodetic) lat-, longitude in C{degrees} and height (L{LatLon3Tuple}C{(lat, lon, height)}). '''
'''Get the lat-, longitude in C{degrees} with height and datum (L{LatLon4Tuple}C{(lat, lon, height, datum)}). ''' return self.latlonheight.to4Tuple(self.datum)
'''Get the (geodetic) longitude in C{degrees} (C{float}). '''
'''Get the (geodetic) latitude in C{radians} (C{float}). '''
'''Get the (geodetic) lat-, longitude in C{radians} (L{PhiLam2Tuple}C{(phi, lam)}). '''
'''Get the (geodetic) lat-, longitude in C{radians} and height (L{PhiLam3Tuple}C{(phi, lam, height)}). '''
'''Get the lat-, longitude in C{radians} with height and datum (L{PhiLam4Tuple}C{(phi, lam, height, datum)}). ''' return self.philamheight.to4Tuple(self.datum)
def to2ab(self): # PYCHOK no cover '''DEPRECATED, use property L{philam}.
@return: A L{PhiLam2Tuple}C{(phi, lam)}. ''' return self.philam
def to3abh(self, height=None): # PYCHOK no cover '''DEPRECATED, use property L{philamheight} or C{philam.to3Tuple(B{height})}.
@kwarg height: Optional height, overriding this n-vector's height (C{meter}).
@return: A L{PhiLam3Tuple}C{(phi, lam, height)}.
@raise ValueError: Invalid B{C{height}}. ''' return self.philamheight if height in (None, self.h) else \ self.philam.to3Tuple(height)
'''Convert this n-vector to C{Nvector}-based cartesian (ECEF) coordinates.
@kwarg h: Optional height, overriding this n-vector's height (C{meter}). @kwarg Cartesian: Optional class to return the (ECEF) coordinates (C{Cartesian}). @kwarg datum: Optional datum (C{Datum}), overriding this datum. @kwarg Cartesian_kwds: Optional, additional B{C{Cartesian}} keyword arguments, ignored if C{B{Cartesian} is None}.
@return: The cartesian (ECEF) coordinates (B{C{Cartesian}}) or if C{B{Cartesian} is None}, an L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)} with C{C} and C{M} if available.
@raise TypeError: Invalid B{C{Cartesian}} or B{C{Cartesian_kwds}} argument.
@raise ValueError: Invalid B{C{h}}.
@example:
>>> v = Nvector(0.5, 0.5, 0.7071) >>> c = v.toCartesian() # [3194434, 3194434, 4487327] >>> p = c.toLatLon() # 45.0°N, 45.0°E '''
# Kenneth Gade eqn 22
else:
def to2ll(self): # PYCHOK no cover '''DEPRECATED, use property L{latlon}.
@return: A L{LatLon2Tuple}C{(lat, lon)}. ''' return self.latlon
def to3llh(self, height=None): # PYCHOK no cover '''DEPRECATED, use property C{latlonheight} or C{latlon.to3Tuple(B{height})}.
@kwarg height: Optional height, overriding this n-vector's height (C{meter}).
@return: A L{LatLon3Tuple}C{(lat, lon, height)}.
@raise ValueError: Invalid B{C{height}}. ''' return self.latlonheight if height in (None, self.h) else \ self.latlon.to3Tuple(height)
'''Convert this n-vector to an C{Nvector}-based geodetic point.
@kwarg height: Optional height, overriding this n-vector's height (C{meter}). @kwarg LatLon: Optional class to return the geodetic point (C{LatLon}) or C{None}. @kwarg datum: Optional, spherical datum (C{Datum}). @kwarg LatLon_kwds: Optional, additional B{C{LatLon}} keyword arguments, ignored if C{B{LatLon} is None}.
@return: The geodetic point (C{LatLon}) or if C{B{LatLon} is None}, an L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)} with C{C} and C{M} if available.
@raise TypeError: Invalid B{C{LatLon}} or B{C{LatLon_kwds}} argument.
@raise ValueError: Invalid B{C{height}}.
@example:
>>> v = Nvector(0.5, 0.5, 0.7071) >>> p = v.toLatLon() # 45.0°N, 45.0°E ''' # use self.Cartesian(Cartesian=None) for better accuracy of the height # than self.Ecef(d).forward(self.lat, self.lon, height=h, M=True) else:
'''Return a string representation of this n-vector.
Height component is only included if non-zero.
@kwarg prec: Number of (decimal) digits, unstripped (C{int}). @kwarg fmt: Enclosing backets format (C{str}). @kwarg sep: Optional separator between components (C{str}).
@return: Comma-separated C{"(x, y, z [, h])"} enclosed in B{C{fmt}} brackets (C{str}).
@example:
>>> Nvector(0.5, 0.5, 0.7071).toStr() # (0.5, 0.5, 0.7071) >>> Nvector(0.5, 0.5, 0.7071, 1).toStr(-3) # (0.500, 0.500, 0.707, +1.00) '''
'''Convert this n-vector to a 3-D vector, I{ignoring the height}.
@kwarg norm: Normalize the 3-D vector (C{bool}).
@return: The (normalized) vector (L{Vector3d}). '''
def to4xyzh(self, h=None): # PYCHOK no cover '''DEPRECATED, use property L{xyzh} or C{xyz.to4Tuple(B{h})}. ''' return self.xyzh if h in (None, self.h) else Vector4Tuple( self.x, self.y, self.z, h, name=self.name)
'''Normalize this n-vector to unit length.
@kwarg ll: Optional, original latlon (C{LatLon}).
@return: Normalized vector (C{Nvector}). '''
'''Get this n-vector's components (L{Vector4Tuple}C{(x, y, z, h)}) '''
'''(INTERNAL) Minimal, low-overhead C{n-vector}. '''
'''(INTERNAL) Base class for n-vector-based ellipsoidal and spherical C{LatLon} classes. '''
'''(INTERNAL) Zap cached attributes if updated.
@see: C{ellipsoidalNvector.LatLon} and C{sphericalNvector.LatLon} for the special case of B{C{_Nv}}. ''' if _Nv._fromll is not None: _Nv._fromll = None self._Nv = None
# def distanceTo(self, other, **kwds): # PYCHOK no cover # '''(INTERNAL) I{Must be overloaded}, see function C{notOverloaded}. # ''' # _MODS.named.notOverloaded(self, other, **kwds)
'''B{Not implemented}, throws a C{NotImplementedError} always. ''' notImplemented(self, radius1, other, radius2, **kwds)
'''Refined class comparison.
@arg other: The other instance (C{LatLonNvectorBase}). @kwarg name_other_up: Overriding C{name=other} and C{up=1} keyword arguments.
@return: The B{C{other}} if compatible.
@raise TypeError: Incompatible B{C{other}} C{type}. '''
'''Convert this point to C{Nvector} components, I{including height}.
@kwarg Nvector_kwds: Optional, additional B{C{Nvector}} keyword arguments, ignored if C{B{Nvector} is None}.
@return: An B{C{Nvector}} or a L{Vector4Tuple}C{(x, y, z, h)} if B{C{Nvector}} is C{None}.
@raise TypeError: Invalid B{C{Nvector}} or B{C{Nvector_kwds}} argument. '''
'''Locate a point given this and an other point and a bearing at this and the other point.
@arg bearing1: Bearing at this point (compass C{degrees360}). @arg other: The other point (C{LatLon}). @arg bearing2: Bearing at the other point (compass C{degrees360}). @kwarg height: Optional height at the triangulated point, overriding the mean height (C{meter}).
@return: Triangulated point (C{LatLon}).
@raise TypeError: Invalid B{C{other}} point.
@raise Valuerror: Points coincide.
@example:
>>> p = LatLon("47°18.228'N","002°34.326'W") # Basse Castouillet >>> q = LatLon("47°18.664'N","002°31.717'W") # Basse Hergo >>> t = p.triangulate(7, q, 295) # 47.323667°N, 002.568501°W' ''' height=height, LatLon=self.classof)
radius=R_M, height=None, useZ=False): '''Locate a point at given distances from this and two other points.
@arg distance1: Distance to this point (C{meter}, same units as B{C{radius}}). @arg point2: Second reference point (C{LatLon}). @arg distance2: Distance to point2 (C{meter}, same units as B{C{radius}}). @arg point3: Third reference point (C{LatLon}). @arg distance3: Distance to point3 (C{meter}, same units as B{C{radius}}). @kwarg radius: Mean earth radius (C{meter}). @kwarg height: Optional height at trilaterated point, overriding the mean height (C{meter}, same units as B{C{radius}}). @kwarg useZ: Include Z component iff non-NaN, non-zero (C{bool}).
@return: Trilaterated point (C{LatLon}).
@raise IntersectionError: No intersection, trilateration failed.
@raise TypeError: Invalid B{C{point2}} or B{C{point3}}.
@raise ValueError: Some B{C{points}} coincide or invalid B{C{distance1}}, B{C{distance2}}, B{C{distance3}} or B{C{radius}}.
@see: U{Trilateration<https://WikiPedia.org/wiki/Trilateration>}, Veness' JavaScript U{Trilateration<https://www.Movable-Type.co.UK/ scripts/latlong-vectors.html>} and method C{LatLon.trilaterate2} of other, non-C{Nvector LatLon} classes. ''' self.others(point2=point2), distance2, self.others(point3=point3), distance3, radius=radius, height=height, useZ=useZ, LatLon=self.classof)
area=False, eps=EPS1, radius=R_M, wrap=False): '''B{Not implemented} for C{B{area}=True} or C{B{wrap}=True} and falls back to method C{trilaterate} otherwise.
@return: A L{Trilaterate5Tuple}C{(min, minPoint, max, maxPoint, n)} with a single trilaterated intersection C{minPoint I{is} maxPoint}, C{min I{is} max} the nearest intersection margin and count C{n = 1}.
@raise IntersectionError: No intersection, trilateration failed.
@raise NotImplementedError: Keyword argument C{B{area}=True} or C{B{wrap}=True} not (yet) supported.
@raise TypeError: Invalid B{C{point2}} or B{C{point3}}.
@raise ValueError: Coincident B{C{points}} or invalid B{C{distance1}}, B{C{distance2}}, B{C{distance3}} or B{C{radius}}. '''
self.others(point3=point3), distance3, radius=radius, height=None, useZ=True, LatLon=self.classof) # ... and handle B{C{eps}} and C{IntersectionError} # like function C{.latlonBase._trilaterate5} t = _SPACE_(_no_(_intersection_), Fmt.PAREN(min.__name__, Fmt.f(d, prec=3))) raise IntersectionError(area=area, eps=eps, wrap=wrap, txt=t)
'''Return the vectorial sum of two or more n-vectors.
@arg nvectors: Vectors to be added (C{Nvector}[]). @kwarg Vector: Optional class for the vectorial sum (C{Nvector}) or C{None}. @kwarg h: Optional height, overriding the mean height (C{meter}). @kwarg Vector_kwds: Optional, additional B{C{Vector}} keyword arguments, ignored if C{B{Vector} is None}.
@return: Vectorial sum (B{C{Vector}}) or a L{Vector4Tuple}C{(x, y, z, h)} if B{C{Vector}} is C{None}.
@raise VectorError: No B{C{nvectors}}. ''' raise VectorError(nvectors=n, txt=MISSING)
else:
**LatLon_LatLon_kwds): # (INTERNAL) Locate a point given two known points and initial # bearings from those points, see C{LatLon.triangulate} above
raise _ValueError(points=point2, txt=_coincident_)
radius=R_M, height=None, useZ=False, **LatLon_LatLon_kwds): # (INTERNAL) Locate a point at given distances from # three other points, see LatLon.triangulate above
raise _ValueError(points=p, txt=_coincident_)
# the following uses x,y coordinate system with origin at n1, x axis n1->n2
# courtesy of U{Carlos Freitas<https://GitHub.com/mrJean1/PyGeodesy/issues/33>} # courtesy of U{AleixDev<https://GitHub.com/mrJean1/PyGeodesy/issues/43>} map1(fabs, distance1, distance2, distance3)) else: h = Height(height)
# no intersection, d < EPS_2 or abs(j) < EPS_2 or z < EPS raise IntersectionError(point1=point1, distance1=distance1, point2=point2, distance2=distance2, point3=point3, distance3=distance3, txt=unstr(t, z=z, useZ=useZ))
# **) MIT License # # Copyright (C) 2016-2022 -- mrJean1 at Gmail -- All Rights Reserved. # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. |