mirror of
https://github.com/google/earthengine-api.git
synced 2025-12-08 19:26:12 +00:00
368 lines
10 KiB
Python
368 lines
10 KiB
Python
"""A wrapper for dictionaries."""
|
|
from __future__ import annotations
|
|
|
|
from typing import Any, Union
|
|
|
|
from ee import _arg_types
|
|
from ee import _utils
|
|
from ee import apifunction
|
|
from ee import computedobject
|
|
from ee import ee_array
|
|
from ee import ee_list
|
|
from ee import ee_number
|
|
from ee import ee_string
|
|
from ee import geometry
|
|
from ee import image
|
|
|
|
# bool, float, and int are automatically converted to ee.String for keys.
|
|
_EeKeyType = Union[bool, float, int, str, computedobject.ComputedObject]
|
|
# TODO: Make a better type for a list of keys.
|
|
_EeKeyListType = Any
|
|
# TODO: Make a better type for a list of strings.
|
|
# Or is this the same as _EeKeyListType?
|
|
_StringListType = Union[Any, computedobject.ComputedObject]
|
|
|
|
|
|
class Dictionary(computedobject.ComputedObject):
|
|
"""An object to represent dictionaries."""
|
|
|
|
_dictionary: dict[Any, Any] | None
|
|
|
|
_initialized = False
|
|
|
|
# Tell pytype to not complain about dynamic attributes.
|
|
_HAS_DYNAMIC_ATTRIBUTES = True
|
|
|
|
def __init__(self, arg: _arg_types.Dictionary | None = None):
|
|
"""Construct a dictionary.
|
|
|
|
Args:
|
|
arg: This constructor accepts the following args:
|
|
1) Another dictionary.
|
|
2) A list of key/value pairs.
|
|
3) A null or no argument (producing an empty dictionary)
|
|
"""
|
|
self.initialize()
|
|
|
|
if isinstance(arg, dict):
|
|
super().__init__(None, None)
|
|
self._dictionary = arg
|
|
else:
|
|
self._dictionary = None
|
|
if self.is_func_returning_same(arg):
|
|
# If it's a call that's already returning a Dictionary, just cast.
|
|
assert isinstance(arg, computedobject.ComputedObject)
|
|
super().__init__(arg.func, arg.args, arg.varName)
|
|
else:
|
|
# Delegate everything else to the server-side constructor.
|
|
super().__init__(apifunction.ApiFunction(self.name()), {'input': arg})
|
|
|
|
@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 'Dictionary'
|
|
|
|
@_utils.accept_opt_prefix('opt_encoder')
|
|
def encode(self, encoder=None):
|
|
if self._dictionary is not None:
|
|
return encoder(self._dictionary)
|
|
else:
|
|
return super().encode(encoder)
|
|
|
|
@_utils.accept_opt_prefix('opt_encoder')
|
|
def encode_cloud_value(self, encoder=None):
|
|
if self._dictionary is not None:
|
|
return {'valueReference': encoder(self._dictionary)}
|
|
else:
|
|
return super().encode_cloud_value(encoder)
|
|
|
|
def combine(
|
|
self,
|
|
second: _arg_types.Dictionary,
|
|
overwrite: _arg_types.Bool | None = None,
|
|
) -> Dictionary:
|
|
"""Combines two dictionaries.
|
|
|
|
In the case of duplicate key names, the output will contain the value of the
|
|
second dictionary unless overwrite is false. Null values in both
|
|
dictionaries are ignored / removed.
|
|
|
|
Args:
|
|
second: The other dictionary to merge in.
|
|
overwrite: If true, this keeps the value of the original dictionary.
|
|
Defaults to true.
|
|
|
|
Returns:
|
|
An ee.Dictionary.
|
|
"""
|
|
|
|
return apifunction.ApiFunction.call_(
|
|
self.name() + '.combine', self, second, overwrite
|
|
)
|
|
|
|
def contains(self, key: _arg_types.String) -> computedobject.ComputedObject:
|
|
"""Returns true if the dictionary contains the given key.
|
|
|
|
Args:
|
|
key: A string to look for in the dictionary.
|
|
|
|
Returns:
|
|
An ee.Boolean.
|
|
"""
|
|
|
|
return apifunction.ApiFunction.call_(self.name() + '.contains', self, key)
|
|
|
|
# TODO: keys should be a _StringListType.
|
|
@staticmethod
|
|
def fromLists(keys: _arg_types.List, values: _arg_types.List) -> Dictionary:
|
|
"""Returns a dictionary from two parallel lists of keys and values.
|
|
|
|
Args:
|
|
keys: A list of keys.
|
|
values: A list of values.
|
|
"""
|
|
|
|
return apifunction.ApiFunction.call_('Dictionary.fromLists', keys, values)
|
|
|
|
def get(
|
|
self,
|
|
key: _EeKeyType,
|
|
# pylint: disable-next=invalid-name
|
|
defaultValue: _arg_types.Any | None = None,
|
|
) -> computedobject.ComputedObject:
|
|
"""Extracts a named value from a dictionary.
|
|
|
|
If the dictionary does not contain the given key, then defaultValue is
|
|
returned, unless it is null.
|
|
|
|
Args:
|
|
key: A string to look for in the dictionary.
|
|
defaultValue: The value to return if the key is not found.
|
|
|
|
Returns:
|
|
Returns an ee.ComputedObject.
|
|
"""
|
|
|
|
return apifunction.ApiFunction.call_(
|
|
self.name() + '.get', self, key, defaultValue
|
|
)
|
|
|
|
def getArray(self, key: _EeKeyType) -> ee_array.Array:
|
|
"""Extracts a named array value from a dictionary.
|
|
|
|
Args:
|
|
key: A string to look for in the dictionary.
|
|
|
|
Returns:
|
|
An ee.Array.
|
|
"""
|
|
|
|
return apifunction.ApiFunction.call_(self.name() + '.getArray', self, key)
|
|
|
|
def getGeometry(self, key: _EeKeyType) -> geometry.Geometry:
|
|
"""Extracts a named geometry value from a dictionary.
|
|
|
|
Args:
|
|
key: A string to look for in the dictionary.
|
|
|
|
Returns:
|
|
An ee.Geometry.
|
|
"""
|
|
|
|
return apifunction.ApiFunction.call_(
|
|
self.name() + '.getGeometry', self, key
|
|
)
|
|
|
|
def getNumber(self, key: _EeKeyType) -> ee_number.Number:
|
|
"""Extracts a named number value from a dictionary.
|
|
|
|
Args:
|
|
key: A string to look for in the dictionary.
|
|
|
|
Returns:
|
|
An ee.Number.
|
|
"""
|
|
|
|
return apifunction.ApiFunction.call_(self.name() + '.getNumber', self, key)
|
|
|
|
def getString(self, key: _EeKeyType) -> ee_string.String:
|
|
"""Extracts a named string value from a dictionary.
|
|
|
|
Args:
|
|
key: A string to look for in the dictionary.
|
|
|
|
Returns:
|
|
An ee.String.
|
|
"""
|
|
|
|
return apifunction.ApiFunction.call_(self.name() + '.getString', self, key)
|
|
|
|
def keys(self) -> ee_list.List:
|
|
"""Retrieve the keys of a dictionary as a list."""
|
|
|
|
return apifunction.ApiFunction.call_(self.name() + '.keys', self)
|
|
|
|
# pylint: disable-next=invalid-name
|
|
def map(self, baseAlgorithm: _arg_types.Any) -> Dictionary:
|
|
"""Map an algorithm over a dictionary.
|
|
|
|
The algorithm is expected to take 2 arguments, a key from the existing
|
|
dictionary and the value it corresponds to, and return a new value for the
|
|
given key. If the algorithm returns null, the key is dropped.
|
|
|
|
Args:
|
|
baseAlgorithm: A function taking key, value and returning the new value.
|
|
|
|
Returns:
|
|
An ee.Dictionary with new values for each key.
|
|
"""
|
|
|
|
return apifunction.ApiFunction.call_(
|
|
self.name() + '.map', self, baseAlgorithm
|
|
)
|
|
|
|
def remove(
|
|
self,
|
|
selectors: _arg_types.Any,
|
|
# pylint: disable-next=invalid-name
|
|
ignoreMissing: _arg_types.Bool | None = None,
|
|
) -> Dictionary:
|
|
"""Returns a dictionary with the specified keys removed.
|
|
|
|
Args:
|
|
selectors: A list of key names or regular expressions of key names to
|
|
remove.
|
|
ignoreMissing: Ignore selectors that don't match at least 1 key. Defaults
|
|
to false.
|
|
|
|
Returns:
|
|
An ee.Dictionary.
|
|
"""
|
|
|
|
return apifunction.ApiFunction.call_(
|
|
self.name() + '.remove', self, selectors, ignoreMissing
|
|
)
|
|
|
|
# TODO: Make a tighter method signature.
|
|
# pylint: disable-next=g-doc-args
|
|
def rename(self, *args, **kwargs) -> Dictionary:
|
|
"""Rename elements in a dictionary.
|
|
|
|
Args:
|
|
from: A list of keys to be renamed.
|
|
to: A list of the new names for the keys listed in the 'from' parameter.
|
|
Must have the same length as the 'from' list.
|
|
overwrite: Allow overwriting existing properties with the same name.
|
|
|
|
Returns:
|
|
An ee.Dictionary.
|
|
"""
|
|
|
|
return apifunction.ApiFunction.call_(
|
|
self.name() + '.rename', self, *args, **kwargs
|
|
)
|
|
|
|
def select(
|
|
self,
|
|
selectors: _arg_types.Any,
|
|
# pylint: disable-next=invalid-name
|
|
ignoreMissing: _arg_types.Bool | None = None,
|
|
) -> Dictionary:
|
|
"""Returns a dictionary with only the specified keys.
|
|
|
|
Args:
|
|
selectors: A list of keys or regular expressions to select.
|
|
ignoreMissing: Ignore selectors that don't match at least 1 key.
|
|
Defaults to false.
|
|
|
|
Returns:
|
|
An ee.Dictionary.
|
|
"""
|
|
|
|
return apifunction.ApiFunction.call_(
|
|
self.name() + '.select', self, selectors, ignoreMissing
|
|
)
|
|
|
|
def set(self, key: _EeKeyType, value: _arg_types.Any) -> Dictionary:
|
|
"""Set a value in a dictionary.
|
|
|
|
Args:
|
|
key: A string for where to set the value. Does not need to already exist.
|
|
value: The value to set for the key.
|
|
|
|
Returns:
|
|
An ee.Dictionary.
|
|
"""
|
|
|
|
return apifunction.ApiFunction.call_(self.name() + '.set', self, key, value)
|
|
|
|
def size(self) -> ee_number.Number:
|
|
"""Returns the number of entries in a dictionary."""
|
|
|
|
return apifunction.ApiFunction.call_(self.name() + '.size', self)
|
|
|
|
def toArray(
|
|
self,
|
|
keys: _EeKeyListType | None = None,
|
|
axis: _arg_types.Integer | None = None,
|
|
) -> ee_array.Array:
|
|
"""Returns numeric values of a dictionary as an array.
|
|
|
|
If no keys are specified, all values are returned in the natural ordering of
|
|
the dictionary's keys. The default 'axis' is 0.
|
|
|
|
Args:
|
|
keys: An optional list of keys to subselect.
|
|
axis: How to interpret values that are ee.Arrays. Defaults to 0.
|
|
|
|
Returns:
|
|
An ee.Array.
|
|
"""
|
|
|
|
return apifunction.ApiFunction.call_(
|
|
self.name() + '.toArray', self, keys, axis
|
|
)
|
|
|
|
def toImage(self, names: _arg_types.Any | None = None) -> image.Image:
|
|
"""Creates an image of constants from values in a dictionary.
|
|
|
|
The bands of the image are ordered and named according to the names
|
|
argument. If no names are specified, the bands are sorted
|
|
alpha-numerically.
|
|
|
|
Args:
|
|
names: The order of the output bands.
|
|
|
|
Returns:
|
|
An ee.Image.
|
|
"""
|
|
|
|
return apifunction.ApiFunction.call_(self.name() + '.toImage', self, names)
|
|
|
|
def values(self, keys: _EeKeyListType | None = None) -> ee_list.List:
|
|
"""Returns the values of a dictionary as a list.
|
|
|
|
If no keys are specified, all values are returned in the natural ordering of
|
|
the dictionary's keys.
|
|
|
|
Args:
|
|
keys: An optional list of keys to subselect.
|
|
|
|
Returns:
|
|
An ee.Array.
|
|
"""
|
|
|
|
return apifunction.ApiFunction.call_(self.name() + '.values', self, keys)
|