def lengths(a, close=False, prn=False): """Calls `e_leng` to calculate lengths for many types of nested objects. This would include object arrays, list of lists and similar constructs. Each part is considered separately. Parameters ---------- a : array-like An array like sequence of points that are assumed to make up lengths or perimeters of geometries close : boolean True, computes the closed-loop length for polylines and check to ensure polygons have duplicate first and last points. prn : boolean True, prints the output as well as returning the result Notes ----- e_leng is required by this function. Make sure you ensure that you are aware of the `close` parameter. Returns ------- A list with total length and segment lengths, for multipoint sequences. """ def _prn_(a_s): """optional result printing""" hdr = "{!s:<12} {}\n".format("Tot. Length", "Seg. Length") r = ["{:12.3f} {!r:}".format(*a_s[i]) for i in range(len(a_s))] print(hdr + "\n".join(r)) # # a = np.asarray(a).squeeze() if isinstance(a, (list, tuple)): return sum([e_leng(i) for i in a]) if a.dtype == 'O': # tmp = [np.asarray(i).squeeze() for i in a] # a_s = [e_leng(i, close) for i in tmp] tmp = pieces(a) # ---- did some fixing a_s = sum([e_leng(i, close)[0] for i in tmp]) if prn: _prn_(a_s) return a_s if len(a.dtype) == 1: a = _reshape_(a) if len(a.dtype) > 1: a = _reshape_(a) if isinstance(a, (list, tuple)): return [e_leng(i, close) for i in a] if a.ndim == 2: a = a.reshape((1,) + a.shape) a_s = [e_leng(i, close) for i in a] if prn: _prn_(a_s) return a_s
def centroids(a): """batch centroids (ie centroid_) """ a = np.asarray(a) if a.dtype == 'O': tmp = [_reshape_(i) for i in a] return np.asarray([centroid_(i) for i in tmp]) if len(a.dtype) >= 1: a = _reshape_(a) if a.ndim == 2: a = a.reshape((1,) + a.shape) c = np.asarray([centroid_(i) for i in a]).squeeze() return c
def centers(a, remove_dup=True): """batch centres (ie center_) """ a = np.asarray(a) if a.dtype == 'O': tmp = [_reshape_(i) for i in a] return np.asarray([center_(i, remove_dup) for i in tmp]) if len(a.dtype) >= 1: a = _reshape_(a) if a.ndim == 2: a = a.reshape((1,) + a.shape) c = np.asarray([center_(i, remove_dup) for i in a]).squeeze() return c
def areas(a): """Calls e_area to calculate areas for many types of nested objects. This would include object arrays, list of lists and similar constructs. Each part is considered separately. Returns ------- A list with one or more areas. """ def _e_area(a): """mini e_area with a twist, shoelace formula using einsum""" x0, y1 = (a.T)[:, 1:] x1, y0 = (a.T)[:, :-1] e0 = np.einsum('...i,...i->...i', x0, y0) e1 = np.einsum('...i,...i->...i', x1, y1) return np.nansum((e0-e1)*0.5) # # a = np.asarray(a).squeeze() if isinstance(a, (list, tuple)): a = np.asarray(a) if a.dtype == 'O': tmp = pieces(a) # ---- did some fixing return sum([_e_area(i) for i in tmp]) if len(a.dtype) >= 1: a = _reshape_(a) if a.ndim == 2: has_nan = np.any(np.isnan(a[:, 0])) if has_nan: tmp = _nan_sp_(a) return sum([_e_area(i) for i in tmp]) a = a.reshape((1,) + a.shape) a_s = np.array(sum([_e_area(i) for i in a])) return a_s
def min_(a): """Array minimums. No `finite_check`. See Note above """ a = _reshape_(a) if (a.dtype.kind == 'O') or (len(a.shape) > 2): mins = np.asanyarray([np.nanmin(i, axis=0) for i in a]) else: mins = np.nanmin(a, axis=0) return mins
def extent_(a): """Array extent values. Only 2D extent is returned, Z extent not covered. """ a = _reshape_(a) if isinstance(a, (list, tuple)): a = np.asanyarray(a) if (a.dtype.kind == 'O') or (len(a.shape) > 2): mins = min_(a) maxs = max_(a) ret = np.hstack((mins, maxs)) else: L, B = min_(a)[:2] R, T = max_(a)[:2] ret = np.asarray([L, B, R, T]) return ret