"""A wrapper for ErrorMargins.""" from __future__ import annotations from typing import Any, Dict, Optional from ee import _arg_types from ee import apifunction from ee import computedobject class ErrorMargin(computedobject.ComputedObject): """An object to represent an Earth Engine ErrorMargin. Examples: # Construct a variety of error margins. ee.ErrorMargin(0) # unit: meters, value: 0 ee.ErrorMargin(1) # unit: meters, value: 1 # Negative margin yields a positive value. ee.ErrorMargin(-1) # unit: meters, value: 1 # A very large error margin does not quite trigger infinite, which is 2.0e7. ee.ErrorMargin(1.99e7) # unit: meters, value: 19900000 # Values >= 2.0e7 are turned into an 'infinite'. ee.ErrorMargin(2e7) # unit: infinite # High precision for 'meters' (< 0.001) results in an error. ee.ErrorMargin(0.0009, 'meters') # Being explicit about the units of the error margin. ee.ErrorMargin(1, 'meters') # unit: meters, value: 1 ee.ErrorMargin(1, 'projected') # unit: projected, value: 1 ee.ErrorMargin(1, 'infinite') # unit: infinite ee.ErrorMargin(value=2, unit='meters') # unit: meters, value: 2 """ _initialized: bool = False def __init__( self, value: Optional[_arg_types.Number] = None, unit: Optional[_arg_types.String] = None, ): """Creates a ErrorMargin wrapper. Args: value: The maximum error value allowed by the margin. Ignored if the unit is 'infinite'. unit: The unit of this margin: 'meters', 'projected', or 'infinite'. When specifying 'infinite', 'value' is ignored. Defaults to 'meters'. """ self.initialize() if isinstance(value, computedobject.ComputedObject): if self.is_func_returning_same(value): if unit is not None: raise TypeError('unit must be None if value is an ErrorMargin') # If it is a call that is already returning a ErrorMargin, just cast. super().__init__(value.func, value.args, value.varName) return if value is None and not ( # TODO(user): Make the computed object check look for a ee.String or # a function that returns a string. unit == 'infinite' or isinstance(unit, computedobject.ComputedObject) ): raise TypeError('value must be provided if unit is not infinite') args: Dict[str, Any] = {} if value is not None: args['value'] = value if unit is not None: args['unit'] = unit func = apifunction.ApiFunction(self.name()) super().__init__(func, func.promoteArgs(args)) @classmethod def initialize(cls) -> None: """Imports API functions to this class.""" if not cls._initialized: apifunction.ApiFunction.importApi(cls, cls.name(), cls.name()) cls._initialized = True @classmethod def reset(cls) -> None: """Removes imported API functions from this class.""" apifunction.ApiFunction.clearApi(cls) cls._initialized = False @staticmethod def name() -> str: return 'ErrorMargin'