def period(self): """ Return the combined period datetime tuple. """ periods = filter_none([x.period for x in self.args]) if len(periods) == 0: return None elif len(periods) == 1: return periods[0] # multiple periods: return the joined period return min([p[0] for p in periods]), max([p[1] for p in periods])
def extent(self): """ Boundingbox of combined contents in WGS84 projection. """ extents = filter_none([x.extent for x in self.args]) if len(extents) == 0: return None elif len(extents) == 1: return extents[0] # multiple extents: return the joined box x1 = min([e[0] for e in extents]) y1 = min([e[1] for e in extents]) x2 = max([e[2] for e in extents]) y2 = max([e[3] for e in extents]) return x1, y1, x2, y2
def geometry(self): """Combined geometry in the projection of the first store geometry. """ geometries = filter_none([x.geometry for x in self.args]) if len(geometries) == 0: return elif len(geometries) == 1: return geometries[0] result = geometries[0] sr = result.GetSpatialReference() for geometry in geometries[1:]: if not geometry.GetSpatialReference().IsSame(sr): geometry = geometry.Clone() geometry.TransformTo(sr) result = result.Union(geometry) return result
def process(process_kwargs, *args): # plan for merging combine_mode = process_kwargs["combine_mode"] mode = process_kwargs.get("mode", None) if combine_mode == "simple": # simple mode, return the result right away if len(args) == 0: return None else: return args[0] elif combine_mode == "by_time" and mode == "time": sorted_times = Group._unique_times(args) # check if single band result required start, stop = process_kwargs["start"], process_kwargs["stop"] if stop is None and len(sorted_times) > 1: index = Group._nearest_index(sorted_times, start) sorted_times = sorted_times[index:index + 1] return {"time": sorted_times} elif combine_mode == "by_time" and mode in ["meta", "vals"]: # split the data and time results, skipping None n = int(len(args) // 2) # assume that we have None at the same positions multi, times = filter_none(args[:n]), filter_none(args[n:]) if len(multi) == 0: return None if mode == "vals": return Group._merge_vals_by_time(multi, times, process_kwargs) elif mode == "meta": return Group._merge_meta_by_time(multi, times, process_kwargs) elif combine_mode == "by_bands" and mode == "time": # start and stop are aligned so we can compute the times here start = process_kwargs["start"] stop = process_kwargs["stop"] delta = process_kwargs["timedelta"] length = (stop - start).total_seconds() // delta.total_seconds() length = int(length) + 1 # the result includes the last frame return {"time": [start + i * delta for i in range(int(length))]} elif combine_mode == "by_bands" and mode in ["meta", "vals"]: # list the data and bands results, skipping None multi = [] bands = [] for data, _bands in zip(args, process_kwargs["bands"]): if data is None: continue multi.append(data) bands.append(_bands) if len(multi) == 0: return None if mode == "vals": dtype = process_kwargs["dtype"] return Group._merge_vals_by_bands(multi, bands, dtype) elif mode == "meta": return Group._merge_meta_by_bands(multi, bands) else: raise ValueError("Unknown combine_mode / mode combination")
def _unique_times(multi): times = filter_none([data.get("time", None) for data in multi]) return sorted(set(itertools.chain(*times)))