Coverage for pygeodesy/iters.py : 96%

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 -*-
Iterator classes L{LatLon2PsxyIter} and L{PointsIter} to iterate over iterables, lists, sets, tuples, etc. with optional loop-back to the initial items, skipping of duplicate items and copying of the iterated items. '''
# from pygeodesy.constants import _1_0 # from .utily _ValueError # from pygeodesy.props import property_RO # from .named # from pygeodesy.streprs import Fmt # from .named
'''(INTERNAL) Iterator over items with loop-back and de-duplication.
@see: Luciano Ramalho, "Fluent Python", page 418+, O'Reilly, 2016. '''
'''New iterator over an iterable of B{C{items}}.
@arg items: Iterable (any C{type}). @kwarg loop: Number of loop-back items, also initial enumerate and iterate index (non-negative C{int}). @kwarg dedup: Skip duplicate items (C{bool}). @kwarg Error: Error to raise (L{LenError}). @kwarg name: Optional name (C{str}).
@raise Error: Insufficient number of B{C{items}}. ''' self._Error = Error
# XXX if hasattr(items, 'next') or hasattr(items, '__length_hint__'): # XXX # handle reversed, iter, etc. items types raise RuntimeError # force Error except (RuntimeError, StopIteration): raise self._Error(self.name, self.loop, txt=_too_(_few_))
'''Get the saved copies, if any (C{tuple} or C{list}) and only I{once}. '''
'''Get the de-duplication setting (C{bool}). '''
'''Yield all items, each as a 2-tuple C{(index, item)}.
@kwarg closed: Look back to the first B{C{point(s)}}. @kwarg copies: Make a copy of all B{C{items}} (C{bool}). @kwarg dedup: Set de-duplication in loop-back (C{bool}). ''' for item in self.iterate(closed=closed, copies=copies, dedup=dedup): yield self._indx, item
'''Get the item(s) at the given B{C{index}} or C{slice}.
@raise IndexError: Invalid B{C{index}}, beyond B{C{loop}}. ''' else: except IndexError as x: t = Fmt.SQUARE(self.name, index) raise _IndexError(str(x), txt=t)
def __iter__(self): # PYCHOK no cover '''Make this iterator C{iterable}. ''' # Luciano Ramalho, "Fluent Python", page 421, O'Reilly, 2016. return self.iterate() # XXX or self?
'''Yield all items, each as C{item}.
@kwarg closed: Look back to the first B{C{point(s)}}. @kwarg copies: Make a copy of all B{C{items}} (C{bool}). @kwarg dedup: Set de-duplication in loop-back (C{bool}).
@raise Error: Using C{B{closed}=True} without B{C{loop}}-back. ''' raise self._Error(closed=closed, loop=self.loop)
else: else: # del B{C{items}} reference
while True: else: while True: except StopIteration: self._iter = () # del self._iter, prevent re-iterate
'''Get the number of items seen so far. '''
'''Get the B{C{loop}} setting (C{int}), C{0} for non-loop-back. '''
'''Get the next item. '''
# __next__ # NO __next__ AND __iter__ ... see Ramalho, page 426
'''Return the next item.
@kwarg dedup: Set de-duplication for loop-back (C{bool}). '''
'''Return the next item, regardless.
@arg dedup: Set de-duplication for loop-back (C{bool}). ''' except StopIteration: pass
'''Return the next item, different from the previous one. '''
'''Iterator for C{points} with optional loop-back and copies. '''
'''New L{PointsIter} iterator.
@arg points: C{Iterable} or C{list}, C{sequence}, C{set}, C{tuple}, etc. (C{point}s). @kwarg loop: Number of loop-back points, also initial C{enumerate} and C{iterate} index (non-negative C{int}). @kwarg base: Optional B{C{points}} instance for type checking (C{any}). @kwarg dedup: Skip duplicate points (C{bool}). @kwarg name: Optional name (C{str}).
@raise PointsError: Insufficient number of B{C{points}}.
@raise TypeError: Some B{C{points}} are not B{C{base}}. '''
'''Iterate and yield each point as a 2-tuple C{(index, point)}.
@kwarg closed: Look back to the first B{C{point(s)}}, de-dup'ed (C{bool}). @kwarg copies: Save a copy of all B{C{points}} (C{bool}).
@raise PointsError: Insufficient number of B{C{points}} or using C{B{closed}=True} without B{C{loop}}-back.
@raise TypeError: Some B{C{points}} are not B{C{base}}-compatible. '''
'''Iterate through all B{C{points}} starting at index C{loop}.
@kwarg closed: Look back to the first B{C{point(s)}}, de-dup'ed (C{bool}). @kwarg copies: Save a copy of all B{C{points}} (C{bool}).
@raise PointsError: Insufficient number of B{C{points}} or using C{B{closed}=True} without B{C{loop}}-back.
@raise TypeError: Some B{C{points}} are not B{C{base}}-compatible. ''' else:
raise self._Error(self.name, n, txt=_too_(_few_))
'''Iterate and convert for C{points} with optional loop-back and copies. '''
dedup=False, name=NN): '''New L{LatLon2PsxyIter} iterator.
@note: The C{LatLon} latitude is considered the I{pseudo-y} and longitude the I{pseudo-x} coordinate, like L{LatLon2psxy}.
@arg points: C{Iterable} or C{list}, C{sequence}, C{set}, C{tuple}, etc. (C{LatLon}[]). @kwarg loop: Number of loop-back points, also initial C{enumerate} and C{iterate} index (non-negative C{int}). @kwarg base: Optional B{C{points}} instance for type checking (C{any}). @kwarg wrap: Wrap lat- and longitudes (C{bool}). @kwarg radius: Mean earth radius (C{meter}) for conversion from C{degrees} to C{meter} (or C{radians} if C{B{radius}=1}). @kwarg dedup: Skip duplicate points (C{bool}). @kwarg name: Optional name (C{str}).
@raise PointsError: Insufficient number of B{C{points}}.
@raise TypeError: Some B{C{points}} are not B{C{base}}-compatible. '''
'''Get the point(s) at the given B{C{index}} or C{slice}.
@raise IndexError: Invalid B{C{index}}, beyond B{C{loop}}. ''' return map2(self._point3Tuple, ll) else:
'''Iterate and yield each point as a 2-tuple C{(index, L{Point3Tuple})}.
@kwarg closed: Look back to the first B{C{point(s)}}, de-dup'ed (C{bool}). @kwarg copies: Save a copy of all B{C{points}} (C{bool}).
@raise PointsError: Insufficient number of B{C{points}} or using C{B{closed}=True} without B{C{loop}}-back.
@raise TypeError: Some B{C{points}} are not B{C{base}}-compatible. '''
'''Iterate the B{C{points}} starting at index B{C{loop}} and yield each as a L{Point3Tuple}C{(x, y, ll)}.
@kwarg closed: Loop back to the first B{C{point(s)}}, de-dup'ed (C{bool}). @kwarg copies: Save a copy of all B{C{points}} (C{bool}).
@raise PointsError: Insufficient number of B{C{points}} or using C{B{closed}=True} without B{C{loop}}-back.
@raise TypeError: Some B{C{points}} are not B{C{base}}-compatible. ''' else:
'''(INTERNAL) Create a L{Point3Tuple} for point B{C{ll}}. '''
'''(INTERNAL) Return first and second index of C{range(B{n})}. '''
'''Check for an B{C{Numpy2LatLon}} points wrapper.
@arg obj: The object (any C{type}).
@return: C{True} if B{C{obj}} is an B{C{Numpy2LatLon}} instance, C{False} otherwise. ''' # isinstance(self, (Numpy2LatLon, ...))
'''Check for an B{C{LatLon2psxy}} points wrapper.
@arg obj: The object (any C{type}).
@return: C{True} if B{C{obj}} is an B{C{LatLon2psxy}} instance, C{False} otherwise. ''' # isinstance(self, (LatLon2psxy, ...))
'''Check for an B{C{Tuple2LatLon}} points wrapper.
@arg obj: The object (any).
@return: C{True} if B{C{obj}} is an B{C{Tuple2LatLon}} instance, C{False} otherwise. ''' # isinstance(self, (Tuple2LatLon, ...))
'''Iterate over Numpy2 wrappers or other sequences exceeding the threshold.
@arg obj: Points array, list, sequence, set, etc. (any).
@return: C{True} do, C{False} don't iterate. ''' try: return isNumpy2(obj) or len(obj) > _iterNumpy2len except TypeError: return False
'''Get or set the L{iterNumpy2} threshold.
@kwarg n: Optional, new threshold (C{int}).
@return: Previous threshold (C{int}).
@raise ValueError: Invalid B{C{n}}. ''' global _iterNumpy2len else: raise ValueError except (TypeError, ValueError): raise _ValueError(n=n)
'''Check a path or polygon represented by points.
@arg points: The path or polygon points (C{LatLon}[]) @kwarg closed: Optionally, consider the polygon closed, ignoring any duplicate or closing final B{C{points}} (C{bool}). @kwarg base: Optionally, check all B{C{points}} against this base class, if C{None} don't check. @kwarg Error: Exception to raise (C{ValueError}).
@return: A L{Points2Tuple}C{(number, points)} with the number of points and the points C{list} or C{tuple}.
@raise PointsError: Insufficient number of B{C{points}}.
@raise TypeError: Some B{C{points}} are not B{C{base}} compatible. '''
# remove duplicate or closing final points n -= 1 # XXX following line is unneeded if points # are always indexed as ... i in range(n)
raise Error(points=n, txt=_too_(_few_))
# **) 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. |