Source code for openeo_udf.api.collection_base

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""OpenEO Python UDF interface"""

import pandas
from typing import Optional, List, Dict
from openeo_udf.api.spatial_extent import SpatialExtent


__license__ = "Apache License, Version 2.0"
__author__     = "Soeren Gebbert"
__copyright__  = "Copyright 2018, Soeren Gebbert"
__maintainer__ = "Soeren Gebbert"
__email__      = "soerengebbert@googlemail.com"


[docs]class CollectionBase: """This is the base class for raster and vector collection tiles. It implements start time, end time and spatial extent handling. Some basic tests: >>> extent = SpatialExtent(top=100, bottom=0, right=100, left=0, height=10, width=10) >>> coll = CollectionBase(id="test", extent=extent) >>> print(coll) id: test extent: top: 100 bottom: 0 right: 100 left: 0 height: 10 width: 10 start_times: None end_times: None >>> import pandas >>> extent = SpatialExtent(top=100, bottom=0, right=100, left=0, height=10, width=10) >>> dates = [pandas.Timestamp('2012-05-01')] >>> starts = pandas.DatetimeIndex(dates) >>> dates = [pandas.Timestamp('2012-05-02')] >>> ends = pandas.DatetimeIndex(dates) >>> rdc = CollectionBase(id="test", extent=extent, ... start_times=starts, end_times=ends) >>> "extent" in rdc.extent_to_dict() True >>> rdc.extent_to_dict()["extent"]["left"] == 0 True >>> rdc.extent_to_dict()["extent"]["right"] == 100 True >>> rdc.extent_to_dict()["extent"]["top"] == 100 True >>> rdc.extent_to_dict()["extent"]["bottom"] == 0 True >>> rdc.extent_to_dict()["extent"]["height"] == 10 True >>> rdc.extent_to_dict()["extent"]["width"] == 10 True >>> import json >>> json.dumps(rdc.start_times_to_dict()) '{"start_times": ["2012-05-01T00:00:00"]}' >>> json.dumps(rdc.end_times_to_dict()) '{"end_times": ["2012-05-02T00:00:00"]}' >>> ct = CollectionBase(id="test") >>> ct.set_extent_from_dict({"top": 53, "bottom": 50, "right": 30, "left": 24, "height": 0.01, "width": 0.01}) >>> ct.set_start_times_from_list(["2012-05-01T00:00:00"]) >>> ct.set_end_times_from_list(["2012-05-02T00:00:00"]) >>> print(ct) id: test extent: top: 53 bottom: 50 right: 30 left: 24 height: 0.01 width: 0.01 start_times: DatetimeIndex(['2012-05-01'], dtype='datetime64[ns]', freq=None) end_times: DatetimeIndex(['2012-05-02'], dtype='datetime64[ns]', freq=None) """ def __init__(self, id: str, extent: Optional[SpatialExtent]=None, start_times: Optional[pandas.DatetimeIndex]=None, end_times: Optional[pandas.DatetimeIndex]=None): """Constructor of the base class for tile of a collection Args: id: The unique id of the raster collection tile extent: The spatial extent with resolution information, must be of type SpatialExtent start_times: The pandas.DateTimeIndex vector with start times for each spatial x,y slice end_times: The pandas.DateTimeIndex vector with end times for each spatial x,y slice, if no end times are defined, then time instances are assumed not intervals """ self.id = id self._extent: Optional[SpatialExtent] = None self._start_times: Optional[pandas.DatetimeIndex] = None self._end_times: Optional[pandas.DatetimeIndex] = None self._data: List = None self.set_extent(extent=extent) self.set_start_times(start_times=start_times) self.set_end_times(end_times=end_times)
[docs] def check_data_with_time(self): """Check if the start and end date vectors have the same size as the data """ if self._data is not None and self.start_times is not None: if len(self.start_times) != len(self._data): raise Exception("The size of the start times vector just be equal " "to the size of data") if self._data is not None and self.end_times is not None: if len(self.end_times) != len(self._data): raise Exception("The size of the end times vector just be equal " "to the size of data")
def __str__(self) -> str: return "id: %(id)s\n" \ "extent: %(extent)s\n" \ "start_times: %(start_times)s\n" \ "end_times: %(end_times)s"%{"id":self.id, "extent":self.extent, "start_times":self.start_times, "end_times":self.end_times}
[docs] def get_start_times(self) -> Optional[pandas.DatetimeIndex]: """Returns the start time vector Returns: pandas.DatetimeIndex: Start time vector """ return self._start_times
[docs] def set_start_times(self, start_times: Optional[pandas.DatetimeIndex]): """Set the start times vector Args: start_times (pandas.DatetimeIndex): The start times vector """ if start_times is None: return if isinstance(start_times, pandas.DatetimeIndex) is False: raise Exception("The start times vector mus be of type pandas.DatetimeIndex") self._start_times = start_times
[docs] def get_end_times(self) -> Optional[pandas.DatetimeIndex]: """Returns the end time vector Returns: pandas.DatetimeIndex: End time vector """ return self._end_times
[docs] def set_end_times(self, end_times: Optional[pandas.DatetimeIndex]): """Set the end times vector Args: end_times (pandas.DatetimeIndex): The end times vector """ if end_times is None: return if isinstance(end_times, pandas.DatetimeIndex) is False: raise Exception("The start times vector mus be of type pandas.DatetimeIndex") self._end_times = end_times
[docs] def get_extent(self) -> SpatialExtent: """Return the spatial extent Returns: SpatialExtent: The spatial extent """ return self._extent
[docs] def set_extent(self, extent: SpatialExtent): """Set the spatial extent Args: extent (SpatialExtent): The spatial extent with resolution information, must be of type SpatialExtent """ if extent is None: return if isinstance(extent, SpatialExtent) is False: raise Exception("extent mus be of type SpatialExtent") self._extent = extent
start_times = property(fget=get_start_times, fset=set_start_times) end_times = property(fget=get_end_times, fset=set_end_times) extent = property(fget=get_extent, fset=set_extent)
[docs] def extent_to_dict(self) -> Dict: """Convert the extent into a dictionary representation that can be converted to JSON Returns: dict: The spatial extent """ return self._extent.to_dict()
[docs] def start_times_to_dict(self) -> Dict: """Convert the start times vector into a dictionary representation that can be converted to JSON Returns: dict: The start times vector """ return dict(start_times=[t.isoformat() for t in self._start_times])
[docs] def end_times_to_dict(self) -> Dict: """Convert the end times vector into a dictionary representation that can be converted to JSON Returns: dict: The end times vector """ return dict(end_times=[t.isoformat() for t in self._end_times])
[docs] def set_extent_from_dict(self, extent: Dict): """Set the spatial extent from a dictionary Args: extent (dict): The dictionary with the layout of the JSON SpatialExtent definition """ self.set_extent(SpatialExtent.from_dict(extent))
[docs] def set_start_times_from_list(self, start_times: Dict): """Set the start times vector from a dictionary Args: start_times (dict): The dictionary with the layout of the JSON start times vector definition """ self.set_start_times(pandas.DatetimeIndex(start_times))
[docs] def set_end_times_from_list(self, end_times: Dict): """Set the end times vector from a dictionary Args: end_times (dict): The dictionary with the layout of the JSON end times vector definition """ self.set_end_times(pandas.DatetimeIndex(end_times))
if __name__ == "__main__": import doctest doctest.testmod()