Skip to content

Commit

Permalink
refactor: replace all the dates methods (#115)
Browse files Browse the repository at this point in the history
  • Loading branch information
12rambau committed Sep 14, 2023
2 parents fe4c5f1 + 2128022 commit 3b0d1ab
Show file tree
Hide file tree
Showing 8 changed files with 231 additions and 324 deletions.
78 changes: 78 additions & 0 deletions geetools/DateRange.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
"""Extra tools for the ``ee.DateRange`` class."""
from __future__ import annotations

from typing import Union

import ee

from .accessors import geetools_accessor


@geetools_accessor(ee.DateRange)
class DateRange:
"""Toolbox for the ``ee.DateRange`` class."""

def __init__(self, obj: ee.DateRange):
"""Initialize the DateRange class."""
self._obj = obj

def split(
self,
interval: Union[int, ee.Number],
unit: str = "day",
) -> ee.List:
"""Convert a ``ee.DateRange`` to a list of ``ee.DateRange``.
The DateRange will be split in multiple DateRanges of the specified interval and Unit.
For example "1", "day". if the end date is not included the last dateRange length will be adapted.
Parameters:
interval: The interval to split the DateRange
unit: The unit to split the DateRange. One of: ``second``, ``minute``, ``hour``, ``day``, ``month``, ``year``.
Returns:
The list of DateRanges
Examples:
.. jupyter-execute::
import ee, geetools
ee.Initialize()
d = ee.DateRange('2020-01-01', '2020-01-31').geetools.split(1, 'day')
d.getInfo()
"""
interval = ee.Number(interval).toInt().multiply(self._unitMillis(unit))
start, end = self._obj.start().millis(), self._obj.end().millis()

timestampList = ee.List.sequence(start, end, interval)
timestampList = timestampList.add(ee.Number(end).toFloat()).distinct()

indexList = ee.List.sequence(0, timestampList.size().subtract(2))

return indexList.map(
lambda i: ee.DateRange(
timestampList.get(i), timestampList.get(ee.Number(i).add(1))
)
)

@classmethod
def _check_unit(cls, unit: str) -> None:
"""Check if the unit is valid."""
if unit not in (units := ["second", "minute", "hour", "day", "month", "year"]):
raise ValueError(f"unit must be one of: {','.join(units)}")

@classmethod
def _unitMillis(cls, unit: str) -> ee.Number:
"""Get the milliseconds of a unit."""
cls._check_unit(unit)
millis = {
"second": 1000,
"minute": 1000 * 60,
"hour": 1000 * 60 * 60,
"day": 1000 * 60 * 60 * 24,
"month": 1000 * 60 * 60 * 24 * 30,
"year": 1000 * 60 * 60 * 24 * 365,
}
return ee.Number(millis[unit])
40 changes: 40 additions & 0 deletions geetools/Image.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""Toolbox for the ``ee.Image`` class."""
from __future__ import annotations

import ee

from .accessors import geetools_accessor


@geetools_accessor(ee.Image)
class Image:
"""Toolbox for the ``ee.Image`` class."""

def __init__(self, obj: ee.Image):
"""Initialize the Image class."""
self._obj = obj

def addDate(self) -> ee.Image:
"""Add a band with the date of the image in the provided format.
The date is stored as a Timestamp in millisecond in a band date.
Returns:
The image with the date band added.
Examples:
.. jupyter-execute::
import ee, geetools
ee.Initialize()
image = ee.Image('COPERNICUS/S2_SR_HARMONIZED/20200101T100319_20200101T100321_T32TQM')
image = image.geetools.addDate()
date = image.select('date')
value = date.reduceRegion(ee.Reducer.first()).get("date")
ee.Date(value).format('YYYY-MM-dd').getInfo()
"""
return self._obj.addBands(
ee.Image.constant(self._obj.date().millis()).rename("date")
)
2 changes: 2 additions & 0 deletions geetools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@
# then we extend all the other classes
from .Array import Array # noqa: F401
from .Date import Date # noqa: F401
from .DateRange import DateRange # noqa: F401
from .Dictionary import Dictionary # noqa: F401
from .Filter import Filter # noqa: F401
from .Float import Float
from .Image import Image # noqa: F401
from .Integer import Integer
from .List import List # noqa: F401
from .Number import Number # noqa: F401
Expand Down
26 changes: 26 additions & 0 deletions geetools/tools/_deprecated_date.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,29 @@ def fromDOY(year, doy):
def isLeap(date):
"""Check if a date is leap."""
return ee.Date(date).geetools.isLeap()


@deprecated(version="1.0.0", reason="Use ee.DateRange.geetools.split instead")
def daterangeList(start, end, interval, unit):
"""Divide a range that goes from start_date to end_date into many."""
return ee.DateRange(start, end).geetools.split(interval, unit)


@deprecated(version="1.0.0", reason="Use ee.DateRange.geetools.split instead")
def daterangeIntervals(
start,
end,
interval=1,
unit="month",
date_range=(1, 1),
date_range_unit="day",
direction="backward",
):
"""Divide a range that goes from start_date to end_date into many."""
return ee.DateRange(start, end).geetools.split(interval, unit)


@deprecated(version="1.0.0", reason="Use ee.Image.geetools.addDate instead")
def makeDateBand(image, format="YMMdd", bandname="date"):
"""Add a band name to the image."""
return ee.Image(image).geetools.addDate()

0 comments on commit 3b0d1ab

Please sign in to comment.