Пример #1
0
def Initialize(credentials=None, opt_url=None):
    """Initialize the EE library.

  If this hasn't been called by the time any object constructor is used,
  it will be called then.  If this is called a second time with a different
  URL, this doesn't do an un-initialization of e.g.: the previously loaded
  Algorithms, but will overwrite them and let point at alternate servers.

  Args:
    credentials: OAuth2 credentials.
    opt_url: The base url for the EarthEngine REST API to connect to.
  """
    data.initialize(credentials, (opt_url + '/api' if opt_url else None),
                    opt_url)
    # Initialize the dynamically loaded functions on the objects that want them.
    ApiFunction.initialize()
    Element.initialize()
    Image.initialize()
    Feature.initialize()
    Collection.initialize()
    ImageCollection.initialize()
    FeatureCollection.initialize()
    Filter.initialize()
    Geometry.initialize()
    List.initialize()
    Number.initialize()
    String.initialize()
    Date.initialize()
    Dictionary.initialize()
    _InitializeGeneratedClasses()
    _InitializeUnboundMethods()
Пример #2
0
def Initialize(credentials=None, opt_url=None):
  """Initialize the EE library.

  If this hasn't been called by the time any object constructor is used,
  it will be called then.  If this is called a second time with a different
  URL, this doesn't do an un-initialization of e.g.: the previously loaded
  Algorithms, but will overwrite them and let point at alternate servers.

  Args:
    credentials: OAuth2 credentials.
    opt_url: The base url for the EarthEngine REST API to connect to.
  """
  data.initialize(credentials, (opt_url + '/api' if opt_url else None), opt_url)
  # Initialize the dynamically loaded functions on the objects that want them.
  ApiFunction.initialize()
  Element.initialize()
  Image.initialize()
  Feature.initialize()
  Collection.initialize()
  ImageCollection.initialize()
  FeatureCollection.initialize()
  Filter.initialize()
  Geometry.initialize()
  List.initialize()
  Number.initialize()
  String.initialize()
  Date.initialize()
  Dictionary.initialize()
  _InitializeGeneratedClasses()
  _InitializeUnboundMethods()
Пример #3
0
def _MakeClass(name):
  """Generates a dynamic API class for a given name."""

  def init(self, *args):
    """Initializer for dynamically created classes.

    Args:
      self: The instance of this class.  Listed to make the linter hush.
      *args: Either a ComputedObject to be promoted to this type, or
             arguments to an algorithm with the same name as this class.

    Returns:
      The new class.
    """
    if isinstance(args[0], ComputedObject) and len(args) == 1:
      result = args[0]
    else:
      result = ApiFunction.call_(name, *args)

    ComputedObject.__init__(self, result.func, result.args)

  properties = {'__init__': init, 'name': lambda self: name}
  new_class = type(str(name), (ComputedObject,), properties)
  ApiFunction.importApi(new_class, name, name)
  return new_class
Пример #4
0
def Initialize(credentials="persistent", opt_url=None):
    """Initialize the EE library.

  If this hasn't been called by the time any object constructor is used,
  it will be called then.  If this is called a second time with a different
  URL, this doesn't do an un-initialization of e.g.: the previously loaded
  Algorithms, but will overwrite them and let point at alternate servers.

  Args:
    credentials: OAuth2 credentials.  'persistent' (default) means use
        credentials already stored in the filesystem, or raise an explanatory
        exception guiding the user to create those credentials.
    opt_url: The base url for the EarthEngine REST API to connect to.
  """
    if credentials == "persistent":
        credentials = _GetPersistentCredentials()
    data.initialize(credentials, (opt_url + "/api" if opt_url else None), opt_url)
    # Initialize the dynamically loaded functions on the objects that want them.
    ApiFunction.initialize()
    Element.initialize()
    Image.initialize()
    Feature.initialize()
    Collection.initialize()
    ImageCollection.initialize()
    FeatureCollection.initialize()
    Filter.initialize()
    Geometry.initialize()
    List.initialize()
    Number.initialize()
    String.initialize()
    Date.initialize()
    Dictionary.initialize()
    Terrain.initialize()
    _InitializeGeneratedClasses()
    _InitializeUnboundMethods()
Пример #5
0
def _MakeClass(name):
    """Generates a dynamic API class for a given name."""
    def init(self, *args):
        """Initializer for dynamically created classes.

    Args:
      self: The instance of this class.  Listed to make the linter hush.
      *args: Either a ComputedObject to be promoted to this type, or
             arguments to an algorithm with the same name as this class.

    Returns:
      The new class.
    """
        klass = globals()[name]
        onlyOneArg = (len(args) == 1)
        # Are we trying to cast something that's already of the right class?
        if onlyOneArg and isinstance(args[0], klass):
            result = args[0]
        else:
            # Decide whether to call a server-side constructor or just do a
            # client-side cast.
            ctor = ApiFunction.lookupInternal(name)
            firstArgIsPrimitive = not isinstance(args[0], ComputedObject)
            shouldUseConstructor = False
            if ctor:
                if not onlyOneArg:
                    # Can't client-cast multiple arguments.
                    shouldUseConstructor = True
                elif firstArgIsPrimitive:
                    # Can't cast a primitive.
                    shouldUseConstructor = True
                elif args[0].func != ctor:
                    # We haven't already called the constructor on this object.
                    shouldUseConstructor = True

        # Apply our decision.
        if shouldUseConstructor:
            # Call ctor manually to avoid having promote() called on the output.
            ComputedObject.__init__(self, ctor,
                                    ctor.promoteArgs(ctor.nameArgs(args)))
        else:
            # Just cast and hope for the best.
            if not onlyOneArg:
                # We don't know what to do with multiple args.
                raise EEException('Too many arguments for ee.%s(): %s' %
                                  (name, args))
            elif firstArgIsPrimitive:
                # Can't cast a primitive.
                raise EEException(
                    'Invalid argument for ee.%s(): %s.  Must be a ComputedObject.'
                    % (name, args))
            else:
                result = args[0]
            ComputedObject.__init__(self, result.func, result.args,
                                    result.varName)

    properties = {'__init__': init, 'name': lambda self: name}
    new_class = type(str(name), (ComputedObject, ), properties)
    ApiFunction.importApi(new_class, name, name)
    return new_class
Пример #6
0
def _MakeClass(name):
  """Generates a dynamic API class for a given name."""

  def init(self, *args):
    """Initializer for dynamically created classes.

    Args:
      self: The instance of this class.  Listed to make the linter hush.
      *args: Either a ComputedObject to be promoted to this type, or
             arguments to an algorithm with the same name as this class.

    Returns:
      The new class.
    """
    klass = globals()[name]
    onlyOneArg = (len(args) == 1)
    # Are we trying to cast something that's already of the right class?
    if onlyOneArg and isinstance(args[0], klass):
      result = args[0]
    else:
      # Decide whether to call a server-side constructor or just do a
      # client-side cast.
      ctor = ApiFunction.lookupInternal(name)
      firstArgIsPrimitive = not isinstance(args[0], ComputedObject)
      shouldUseConstructor = False
      if ctor:
        if not onlyOneArg:
          # Can't client-cast multiple arguments.
          shouldUseConstructor = True
        elif firstArgIsPrimitive:
          # Can't cast a primitive.
          shouldUseConstructor = True
        elif args[0].func != ctor:
          # We haven't already called the constructor on this object.
          shouldUseConstructor = True

    # Apply our decision.
    if shouldUseConstructor:
      # Call ctor manually to avoid having promote() called on the output.
      ComputedObject.__init__(self, ctor, ctor.promoteArgs(ctor.nameArgs(args)))
    else:
      # Just cast and hope for the best.
      if not onlyOneArg:
        # We don't know what to do with multiple args.
        raise EEException(
            'Too many arguments for ee.%s(): %s' % (name, args))
      elif firstArgIsPrimitive:
        # Can't cast a primitive.
        raise EEException(
            'Invalid argument for ee.%s(): %s.  Must be a ComputedObject.' %
            (name, args))
      else:
        result = args[0]
      ComputedObject.__init__(self, result.func, result.args, result.varName)

  properties = {'__init__': init, 'name': lambda self: name}
  new_class = type(str(name), (ComputedObject,), properties)
  ApiFunction.importApi(new_class, name, name)
  return new_class
Пример #7
0
def _ResetGeneratedClasses():
    """Remove the dynamic classes."""
    global _generatedClasses

    for name in _generatedClasses:
        ApiFunction.clearApi(globals()[name])
        del globals()[name]
    _generatedClasses = []
    # Warning: we're passing all of globals() into registerClasses.
    # This is a) pass by reference, and b) a lot more stuff.
    types._registerClasses(globals())  # pylint: disable=protected-access
Пример #8
0
def _ResetGeneratedClasses():
    """Remove the dynamic classes."""
    global _generatedClasses

    for name in _generatedClasses:
        ApiFunction.clearApi(globals()[name])
        del globals()[name]
    _generatedClasses = []
    # Warning: we're passing all of globals() into registerClasses.
    # This is a) pass by reference, and b) a lot more stuff.
    types._registerClasses(globals())  # pylint: disable=protected-access
Пример #9
0
def _InitializeUnboundMethods():
    # Sort the items by length, so parents get created before children.
    items = ApiFunction.unboundFunctions().items()
    items.sort(key=lambda x: len(x[0]))

    for name, func in items:
        signature = func.getSignature()
        if signature.get("hidden", False):
            continue

        # Create nested objects as needed.
        name_parts = name.split(".")
        target = Algorithms
        while len(name_parts) > 1:
            first = name_parts[0]
            if not hasattr(target, first):
                setattr(target, first, _AlgorithmsContainer())
            target = getattr(target, first)
            name_parts = name_parts[1:]

        # Attach the function.
        # We need a copy of the function to attach properties.
        def GenerateFunction(f):
            return lambda *args, **kwargs: f.call(*args, **kwargs)  # pylint: disable=unnecessary-lambda

        bound = GenerateFunction(func)
        bound.signature = signature
        bound.__doc__ = str(func)
        setattr(target, name_parts[0], bound)
Пример #10
0
def Reset():
  """Reset the library. Useful for re-initializing to a different server."""
  data.reset()
  ApiFunction.reset()
  Image.reset()
  Feature.reset()
  Collection.reset()
  ImageCollection.reset()
  FeatureCollection.reset()
  Filter.reset()
  Geometry.reset()
  Number.reset()
  String.reset()
  _ResetGeneratedClasses()
  global Algorithms
  Algorithms = _AlgorithmsContainer()
Пример #11
0
def _InitializeUnboundMethods():
    # Sort the items by length, so parents get created before children.
    items = ApiFunction.unboundFunctions().items()
    items.sort(key=lambda x: len(x[0]))

    for name, func in items:
        signature = func.getSignature()
        if signature.get('hidden', False):
            continue

        # Create nested objects as needed.
        name_parts = name.split('.')
        target = Algorithms
        while len(name_parts) > 1:
            first = name_parts[0]
            if not hasattr(target, first):
                setattr(target, first, _AlgorithmsContainer())
            target = getattr(target, first)
            name_parts = name_parts[1:]

        # Attach the function.
        # We need a copy of the function to attach properties.
        def GenerateFunction(f):
            return lambda *args, **kwargs: f.call(*args, **kwargs)  # pylint: disable=unnecessary-lambda

        bound = GenerateFunction(func)
        bound.signature = signature
        bound.__doc__ = str(func)
        setattr(target, name_parts[0], bound)
Пример #12
0
def Reset():
  """Reset the library. Useful for re-initializing to a different server."""
  data.reset()
  ApiFunction.reset()
  Element.reset()
  Image.reset()
  Feature.reset()
  Collection.reset()
  ImageCollection.reset()
  FeatureCollection.reset()
  Filter.reset()
  Geometry.reset()
  Number.reset()
  String.reset()
  _ResetGeneratedClasses()
  global Algorithms
  Algorithms = _AlgorithmsContainer()
Пример #13
0
def _MakeClass(name):
  """Generates a dynamic API class for a given name."""

  def init(self, *args):
    """Initializer for dynamically created classes.

    Args:
      self: The instance of this class.  Listed to make the linter hush.
      *args: Either a ComputedObject to be promoted to this type, or
             arguments to an algorithm with the same name as this class.

    Returns:
      The new class.
    """
    if isinstance(args[0], ComputedObject) and len(args) == 1:
      result = args[0]
    else:
      result = ApiFunction.call_(name, *args)

    ComputedObject.__init__(self, result.func, result.args)

  new_class = type(str(name), (ComputedObject,), {'__init__': init})
  ApiFunction.importApi(new_class, name, name)
  return new_class
Пример #14
0
def apply(func, named_args):  # pylint: disable=redefined-builtin
    """Call a function with a dictionary of named arguments.

  Args:
    func: The function to call. Either an ee.Function object or the name of
        an API function.
    named_args: A dictionary of arguments to the function.

  Returns:
    A ComputedObject representing the called function. If the signature
    specifies a recognized return type, the returned value will be cast
    to that type.
  """
    if isinstance(func, basestring):
        func = ApiFunction.lookup(func)
    return func.apply(named_args)
Пример #15
0
def apply(func, named_args):  # pylint: disable=redefined-builtin
    """Call a function with a dictionary of named arguments.

  Args:
    func: The function to call. Either an ee.Function object or the name of
        an API function.
    named_args: A dictionary of arguments to the function.

  Returns:
    A ComputedObject representing the called function. If the signature
    specifies a recognized return type, the returned value will be cast
    to that type.
  """
    if isinstance(func, basestring):
        func = ApiFunction.lookup(func)
    return func.apply(named_args)
Пример #16
0
def call(func, *args, **kwargs):
    """Invoke the given algorithm with the specified args.

  Args:
    func: The function to call. Either an ee.Function object or the name of
        an API function.
    *args: The positional arguments to pass to the function.
    **kwargs: The named arguments to pass to the function.

  Returns:
    A ComputedObject representing the called function. If the signature
    specifies a recognized return type, the returned value will be cast
    to that type.
  """
    if isinstance(func, basestring):
        func = ApiFunction.lookup(func)
    return func.call(*args, **kwargs)
Пример #17
0
  def init(self, *args):
    """Initializer for dynamically created classes.

    Args:
      self: The instance of this class.  Listed to make the linter hush.
      *args: Either a ComputedObject to be promoted to this type, or
             arguments to an algorithm with the same name as this class.

    Returns:
      The new class.
    """
    if isinstance(args[0], ComputedObject) and len(args) == 1:
      result = args[0]
    else:
      result = ApiFunction.call_(name, *args)

    ComputedObject.__init__(self, result.func, result.args)
Пример #18
0
  def init(self, *args):
    """Initializer for dynamically created classes.

    Args:
      self: The instance of this class.  Listed to make the linter hush.
      *args: Either a ComputedObject to be promoted to this type, or
             arguments to an algorithm with the same name as this class.

    Returns:
      The new class.
    """
    if isinstance(args[0], ComputedObject) and len(args) == 1:
      result = args[0]
    else:
      result = ApiFunction.call_(name, *args)

    ComputedObject.__init__(self, result.func, result.args)
Пример #19
0
def call(func, *args, **kwargs):
    """Invoke the given algorithm with the specified args.

  Args:
    func: The function to call. Either an ee.Function object or the name of
        an API function.
    *args: The positional arguments to pass to the function.
    **kwargs: The named arguments to pass to the function.

  Returns:
    A ComputedObject representing the called function. If the signature
    specifies a recognized return type, the returned value will be cast
    to that type.
  """
    if isinstance(func, basestring):
        func = ApiFunction.lookup(func)
    return func.call(*args, **kwargs)
Пример #20
0
def _InitializeGeneratedClasses():
  """Generate classes for extra types that appear in the web API."""
  signatures = ApiFunction.allSignatures()
  # Collect the first part of all function names.
  names = set([name.split('.')[0] for name in signatures])
  # Collect the return types of all functions.
  returns = set([signatures[sig]['returns'] for sig in signatures])

  want = [name for name in names.intersection(returns) if name not in globals()]

  for name in want:
    globals()[name] = _MakeClass(name)
    _generatedClasses.append(name)
    ApiFunction._bound_signatures.add(name)  # pylint: disable=protected-access

  # Warning: we're passing all of globals() into registerClasses.
  # This is a) pass by reference, and b) a lot more stuff.
  types._registerClasses(globals())     # pylint: disable=protected-access
Пример #21
0
def _InitializeGeneratedClasses():
    """Generate classes for extra types that appear in the web API."""
    signatures = ApiFunction.allSignatures()
    # Collect the first part of all function names.
    names = set([name.split(".")[0] for name in signatures])
    # Collect the return types of all functions.
    returns = set([signatures[sig]["returns"] for sig in signatures])

    want = [name for name in names.intersection(returns) if name not in globals()]

    for name in want:
        globals()[name] = _MakeClass(name)
        _generatedClasses.append(name)
        ApiFunction._bound_signatures.add(name)  # pylint: disable=protected-access

    # Warning: we're passing all of globals() into registerClasses.
    # This is a) pass by reference, and b) a lot more stuff.
    types._registerClasses(globals())  # pylint: disable=protected-access
Пример #22
0
def _InitializeGeneratedClasses():
  """Generate classes for extra types that appear in the web API."""
  signatures = ApiFunction.allSignatures()
  # Collect the first part of any function names that contain a '.'.
  names = set([name.split('.')[0] for name in signatures if '.' in name])
  # Collect the return types of all functions.
  returns = set([signatures[sig]['returns'] for sig in signatures])
  # We generate classes for all return types that match algorithms names TYPE.x
  # excluding those already handled by the client library, and those
  # explicitly blacklisted.
  blacklist = ['List']
  want = [name for name in names.intersection(returns)
          if name not in globals() and name not in blacklist]

  for name in want:
    globals()[name] = _MakeClass(name)
    _generatedClasses.append(name)

  # Warning: we're passing all of globals() into registerClasses.
  # This is a) pass by reference, and b) a lot more stuff.
  types._registerClasses(globals())     # pylint: disable=protected-access
Пример #23
0
def _InitializeGeneratedClasses():
  """Generate classes for extra types that appear in the web API."""
  signatures = ApiFunction.allSignatures()
  # Collect the first part of all function names.
  names = set([name.split('.')[0] for name in signatures])
  # Collect the return types of all functions.
  returns = set([signatures[sig]['returns'] for sig in signatures])
  # We generate classes for all return types that match algorithms names TYPE.x
  # excluding those already handled by the client library, and those
  # explicitly blacklisted.
  blacklist = ['List']
  want = [name for name in names.intersection(returns)
          if name not in globals() and name not in blacklist]

  for name in want:
    globals()[name] = _MakeClass(name)
    _generatedClasses.append(name)

  # Warning: we're passing all of globals() into registerClasses.
  # This is a) pass by reference, and b) a lot more stuff.
  types._registerClasses(globals())     # pylint: disable=protected-access
Пример #24
0
def _Promote(arg, klass):
    """Wrap an argument in an object of the specified class.

  This is used to e.g.: promote numbers or strings to Images and arrays
  to Collections.

  Args:
    arg: The object to promote.
    klass: The expected type.

  Returns:
    The argument promoted if the class is recognized, otherwise the
    original argument.
  """
    if arg is None:
        return arg

    if klass == 'Image':
        return Image(arg)
    elif klass == 'Feature':
        if isinstance(arg, Collection):
            # TODO(user): Decide whether we want to leave this in. It can be
            #              quite dangerous on large collections.
            return ApiFunction.call_(
                'Feature', ApiFunction.call_('Collection.geometry', arg))
        else:
            return Feature(arg)
    elif klass == 'Element':
        if isinstance(arg, Element):
            # Already an Element.
            return arg
        elif isinstance(arg, Geometry):
            # Geometries get promoted to Features.
            return Feature(arg)
        elif isinstance(arg, ComputedObject):
            # Try a cast.
            return Element(arg.func, arg.args, arg.varName)
        else:
            # No way to convert.
            raise EEException('Cannot convert %s to Element.' % arg)
    elif klass == 'Geometry':
        if isinstance(arg, Collection):
            return ApiFunction.call_('Collection.geometry', arg)
        else:
            return Geometry(arg)
    elif klass in ('FeatureCollection', 'Collection'):
        # For now Collection is synonymous with FeatureCollection.
        if isinstance(arg, Collection):
            return arg
        else:
            return FeatureCollection(arg)
    elif klass == 'ImageCollection':
        return ImageCollection(arg)
    elif klass == 'Filter':
        return Filter(arg)
    elif klass == 'Algorithm':
        if isinstance(arg, basestring):
            # An API function name.
            return ApiFunction.lookup(arg)
        elif callable(arg):
            # A native function that needs to be wrapped.
            args_count = len(inspect.getargspec(arg).args)
            return CustomFunction.create(arg, 'Object',
                                         ['Object'] * args_count)
        elif isinstance(arg, Encodable):
            # An ee.Function or a computed function like the return value of
            # Image.parseExpression().
            return arg
        else:
            raise EEException('Argument is not a function: %s' % arg)
    elif klass == 'Dictionary':
        if isinstance(arg, dict):
            return arg
        else:
            return Dictionary(arg)
    elif klass == 'String':
        if (types.isString(arg) or isinstance(arg, ComputedObject)
                or isinstance(arg, String)):
            return String(arg)
        else:
            return arg
    elif klass == 'List':
        return List(arg)
    elif klass in ('Number', 'Float', 'Long', 'Integer', 'Short', 'Byte'):
        return Number(arg)
    elif klass in globals():
        cls = globals()[klass]
        ctor = ApiFunction.lookupInternal(klass)
        # Handle dynamically created classes.
        if isinstance(arg, cls):
            # Return unchanged.
            return arg
        elif ctor:
            # The client-side constructor will call the server-side constructor.
            return cls(arg)
        elif isinstance(arg, basestring):
            if hasattr(cls, arg):
                # arg is the name of a method in klass.
                return getattr(cls, arg)()
            else:
                raise EEException('Unknown algorithm: %s.%s' % (klass, arg))
        else:
            # Client-side cast.
            return cls(arg)
    else:
        return arg
Пример #25
0
def _Promote(arg, klass):
    """Wrap an argument in an object of the specified class.

  This is used to e.g.: promote numbers or strings to Images and arrays
  to Collections.

  Args:
    arg: The object to promote.
    klass: The expected type.

  Returns:
    The argument promoted if the class is recognized, otherwise the
    original argument.
  """
    if arg is None:
        return arg

    if klass == "Image":
        return Image(arg)
    elif klass == "Feature":
        if isinstance(arg, Collection):
            # TODO(user): Decide whether we want to leave this in. It can be
            #              quite dangerous on large collections.
            return ApiFunction.call_("Feature", ApiFunction.call_("Collection.geometry", arg))
        else:
            return Feature(arg)
    elif klass == "Element":
        if isinstance(arg, Element):
            # Already an Element.
            return arg
        elif isinstance(arg, Geometry):
            # Geometries get promoted to Features.
            return Feature(arg)
        elif isinstance(arg, ComputedObject):
            # Try a cast.
            return Element(arg.func, arg.args, arg.varName)
        else:
            # No way to convert.
            raise EEException("Cannot convert %s to Element." % arg)
    elif klass == "Geometry":
        if isinstance(arg, Collection):
            return ApiFunction.call_("Collection.geometry", arg)
        else:
            return Geometry(arg)
    elif klass in ("FeatureCollection", "Collection"):
        # For now Collection is synonymous with FeatureCollection.
        if isinstance(arg, Collection):
            return arg
        else:
            return FeatureCollection(arg)
    elif klass == "ImageCollection":
        return ImageCollection(arg)
    elif klass == "Filter":
        return Filter(arg)
    elif klass == "Algorithm":
        if isinstance(arg, basestring):
            # An API function name.
            return ApiFunction.lookup(arg)
        elif callable(arg):
            # A native function that needs to be wrapped.
            args_count = len(inspect.getargspec(arg).args)
            return CustomFunction.create(arg, "Object", ["Object"] * args_count)
        elif isinstance(arg, Encodable):
            # An ee.Function or a computed function like the return value of
            # Image.parseExpression().
            return arg
        else:
            raise EEException("Argument is not a function: %s" % arg)
    elif klass == "Dictionary":
        if isinstance(arg, dict):
            return arg
        else:
            return Dictionary(arg)
    elif klass == "String":
        if types.isString(arg) or isinstance(arg, ComputedObject) or isinstance(arg, String):
            return String(arg)
        else:
            return arg
    elif klass == "List":
        return List(arg)
    elif klass in ("Number", "Float", "Long", "Integer", "Short", "Byte"):
        return Number(arg)
    elif klass in globals():
        cls = globals()[klass]
        ctor = ApiFunction.lookupInternal(klass)
        # Handle dynamically created classes.
        if isinstance(arg, cls):
            # Return unchanged.
            return arg
        elif ctor:
            # The client-side constructor will call the server-side constructor.
            return cls(arg)
        elif isinstance(arg, basestring):
            if hasattr(cls, arg):
                # arg is the name of a method in klass.
                return getattr(cls, arg)()
            else:
                raise EEException("Unknown algorithm: %s.%s" % (klass, arg))
        else:
            # Client-side cast.
            return cls(arg)
    else:
        return arg
Пример #26
0
def _Promote(arg, klass):
  """Wrap an argument in an object of the specified class.

  This is used to e.g.: promote numbers or strings to Images and arrays
  to Collections.

  Args:
    arg: The object to promote.
    klass: The expected type.

  Returns:
    The argument promoted if the class is recognized, otherwise the
    original argument.
  """
  if arg is None:
    return arg

  if klass == 'Image':
    return Image(arg)
  elif klass == 'ImageCollection':
    return ImageCollection(arg)
  elif klass in ('Feature', 'EEObject'):
    if isinstance(arg, Collection):
      # TODO(user): Decide whether we want to leave this in. It can be
      #              quite dangerous on large collections.
      return ApiFunction.call_(
          'Feature', ApiFunction.call_('Collection.geometry', arg))
    elif klass == 'EEObject' and isinstance(arg, Image):
      # An Image is already an EEObject.
      return arg
    else:
      return Feature(arg)
  elif klass == 'Geometry':
    if isinstance(arg, Collection):
      return ApiFunction.call_('Collection.geometry', arg)
    else:
      return Geometry(arg)
  elif klass in ('FeatureCollection', 'EECollection', 'Collection'):
    if isinstance(arg, Collection):
      return arg
    else:
      return FeatureCollection(arg)
  elif klass == 'Filter':
    return Filter(arg)
  elif klass == 'ErrorMargin' and isinstance(arg, numbers.Number):
    return ApiFunction.call_('ErrorMargin', arg, 'meters')
  elif klass == 'Algorithm' and isinstance(arg, basestring):
    return ApiFunction.lookup(arg)
  elif klass == 'Date':
    if isinstance(arg, basestring):
      try:
        import dateutil.parser    # pylint: disable=g-import-not-at-top
      except ImportError:
        raise EEException(
            'Conversion of strings to dates requires the dateutil library.')
      else:
        return dateutil.parser.parse(arg)
    elif isinstance(arg, numbers.Number):
      return datetime.datetime.fromtimestamp(arg / 1000)
    elif isinstance(arg, ComputedObject):
      # Bypass promotion of this and do it directly.
      func = ApiFunction.lookup('Date')
      return ComputedObject(func, func.promoteArgs(func.nameArgs([arg])))
    else:
      return arg
  elif klass == 'Dictionary':
    if klass not in globals():
      # No dictionary class defined.
      return arg
    cls = globals()[klass]
    if isinstance(arg, cls):
      return arg
    elif isinstance(arg, ComputedObject):
      return cls(arg)
    else:
      # Can't promote non-ComputedObjects up to Dictionary; no constructor.
      return arg
  elif klass == 'String':
    if (types.isString(arg) or
        isinstance(arg, ComputedObject) or
        isinstance(arg, String) or
        types.isVarOfType(arg, String)):
      return String(arg)
    else:
      return arg
  elif klass in globals():
    cls = globals()[klass]
    # Handle dynamically created classes.
    if isinstance(arg, cls):
      return arg
    elif isinstance(arg, basestring):
      if not hasattr(cls, arg):
        raise EEException('Unknown algorithm: %s.%s' % (klass, arg))
      return getattr(cls, arg)()
    else:
      return cls(arg)
  else:
    return arg
Пример #27
0
def _Promote(arg, klass):
  """Wrap an argument in an object of the specified class.

  This is used to e.g.: promote numbers or strings to Images and arrays
  to Collections.

  Args:
    arg: The object to promote.
    klass: The expected type.

  Returns:
    The argument promoted if the class is recognized, otherwise the
    original argument.
  """
  if arg is None:
    return arg

  if klass == 'Image':
    return Image(arg)
  elif klass == 'Feature':
    if isinstance(arg, Collection):
      # TODO(user): Decide whether we want to leave this in. It can be
      #              quite dangerous on large collections.
      return ApiFunction.call_(
          'Feature', ApiFunction.call_('Collection.geometry', arg))
    else:
      return Feature(arg)
  elif klass in ('Element', 'EEObject'):
    # TODO(user): Remove EEObject once the server is updated.
    if isinstance(arg, Element):
      # Already an EEObject.
      return arg
    elif isinstance(arg, ComputedObject):
      # Try a cast.
      return Element(arg.func, arg.args, arg.varName)
    else:
      # No way to convert.
      raise EEException('Cannot convert %s to Element.' % arg)
  elif klass == 'Geometry':
    if isinstance(arg, Collection):
      return ApiFunction.call_('Collection.geometry', arg)
    else:
      return Geometry(arg)
  elif klass in ('FeatureCollection', 'Collection'):
    # For now Collection is synonymous with FeatureCollection.
    if isinstance(arg, Collection):
      return arg
    else:
      return FeatureCollection(arg)
  elif klass == 'ImageCollection':
    return ImageCollection(arg)
  elif klass == 'Filter':
    return Filter(arg)
  elif klass == 'Algorithm' and isinstance(arg, basestring):
    return ApiFunction.lookup(arg)
  elif klass == 'Dictionary':
    if isinstance(arg, dict):
      return arg
    else:
      return Dictionary(arg)
  elif klass == 'String':
    if (types.isString(arg) or
        isinstance(arg, ComputedObject) or
        isinstance(arg, String)):
      return String(arg)
    else:
      return arg
  elif klass == 'List':
    return List(arg)
  elif klass in ('Number', 'Float', 'Long', 'Integer', 'Short', 'Byte'):
    return Number(arg)
  elif klass in globals():
    cls = globals()[klass]
    ctor = ApiFunction.lookupInternal(klass)
    # Handle dynamically created classes.
    if isinstance(arg, cls):
      # Return unchanged.
      return arg
    elif ctor:
      # The client-side constructor will call the server-side constructor.
      return cls(arg)
    elif isinstance(arg, basestring):
      if hasattr(cls, arg):
        # arg is the name of a method in klass.
        return getattr(cls, arg)()
      else:
        raise EEException('Unknown algorithm: %s.%s' % (klass, arg))
    else:
      # Client-side cast.
      return cls(arg)
  else:
    return arg
Пример #28
0
def _Promote(arg, klass):
  """Wrap an argument in an object of the specified class.

  This is used to e.g.: promote numbers or strings to Images and arrays
  to Collections.

  Args:
    arg: The object to promote.
    klass: The expected type.

  Returns:
    The argument promoted if the class is recognized, otherwise the
    original argument.
  """
  if arg is None:
    return arg

  if klass == 'Image':
    return Image(arg)
  elif klass == 'Feature':
    if isinstance(arg, Collection):
      # TODO(user): Decide whether we want to leave this in. It can be
      #              quite dangerous on large collections.
      return ApiFunction.call_(
          'Feature', ApiFunction.call_('Collection.geometry', arg))
    else:
      return Feature(arg)
  elif klass in ('Element', 'EEObject'):
    # TODO(user): Remove EEObject once the server is updated.
    if isinstance(arg, Element):
      # Already an EEObject.
      return arg
    elif isinstance(arg, ComputedObject):
      # Try a cast.
      return Element(arg.func, arg.args)
    else:
      # No way to convert.
      raise EEException('Cannot convert %s to Element.' % arg)
  elif klass == 'Geometry':
    if isinstance(arg, Collection):
      return ApiFunction.call_('Collection.geometry', arg)
    else:
      return Geometry(arg)
  elif klass in ('FeatureCollection', 'Collection'):
    # For now Collection is synonymous with FeatureCollection.
    if isinstance(arg, Collection):
      return arg
    else:
      return FeatureCollection(arg)
  elif klass == 'ImageCollection':
    return ImageCollection(arg)
  elif klass == 'Filter':
    return Filter(arg)
  elif klass == 'Algorithm' and isinstance(arg, basestring):
    return ApiFunction.lookup(arg)
  elif klass == 'Date':
    if isinstance(arg, basestring):
      try:
        import dateutil.parser    # pylint: disable=g-import-not-at-top
      except ImportError:
        raise EEException(
            'Conversion of strings to dates requires the dateutil library.')
      else:
        return dateutil.parser.parse(arg)
    elif isinstance(arg, numbers.Number):
      return datetime.datetime.fromtimestamp(arg / 1000)
    elif isinstance(arg, ComputedObject):
      # Bypass promotion of this and do it directly.
      func = ApiFunction.lookup('Date')
      return ComputedObject(func, func.promoteArgs(func.nameArgs([arg])))
    else:
      return arg
  elif klass == 'Dictionary':
    if klass not in globals():
      # No dictionary class defined.
      return arg
    cls = globals()[klass]
    if isinstance(arg, cls):
      return arg
    elif isinstance(arg, ComputedObject):
      return cls(arg)
    else:
      # Can't promote non-ComputedObjects up to Dictionary; no constructor.
      return arg
  elif klass == 'String':
    if (types.isString(arg) or
        isinstance(arg, ComputedObject) or
        isinstance(arg, String) or
        types.isVarOfType(arg, String)):
      return String(arg)
    else:
      return arg
  elif klass in globals():
    cls = globals()[klass]
    # Handle dynamically created classes.
    if isinstance(arg, cls):
      return arg
    elif isinstance(arg, basestring):
      if not hasattr(cls, arg):
        raise EEException('Unknown algorithm: %s.%s' % (klass, arg))
      return getattr(cls, arg)()
    else:
      return cls(arg)
  else:
    return arg