def __init__(self, args=None, version=None): """Constructs an Earth Engine image. Args: args: This constructor accepts a variety of arguments: - A string - an EarthEngine asset id, - A string and a number - an EarthEngine asset id and version, - A number - creates a constant image, - An EEArray - creates a constant array image, - A list - creates an image out of each element of the array and combines them into a single image, - An ee.Image - returns the argument, - Nothing - results in an empty transparent image. version: An optional asset version. Raises: EEException: if passed something other than the above. """ self.initialize() if version is not None: if ee_types.isString(args) and ee_types.isNumber(version): # An ID and version. super(Image, self).__init__( apifunction.ApiFunction.lookup('Image.load'), {'id': args, 'version': version}) else: raise ee_exception.EEException( 'If version is specified, the arg to Image() must be a string. ' 'Received: %s' % (args,)) return if ee_types.isNumber(args): # A constant image. super(Image, self).__init__( apifunction.ApiFunction.lookup('Image.constant'), {'value': args}) elif ee_types.isString(args): # An ID. super(Image, self).__init__( apifunction.ApiFunction.lookup('Image.load'), {'id': args}) elif isinstance(args, (list, tuple)): # Make an image out of each element. image = Image.combine_([Image(i) for i in args]) super(Image, self).__init__(image.func, image.args) elif isinstance(args, computedobject.ComputedObject): if args.name() == 'Array': # A constant array image. super(Image, self).__init__( apifunction.ApiFunction.lookup('Image.constant'), {'value': args}) else: # A custom object to reinterpret as an Image. super(Image, self).__init__(args.func, args.args, args.varName) elif args is None: super(Image, self).__init__( apifunction.ApiFunction.lookup('Image.mask'), {'image': Image(0), 'mask': Image(0)}) else: raise ee_exception.EEException( 'Unrecognized argument type to convert to an Image: %s' % args)
def select(self, opt_selectors=None, opt_names=None, *args): """Selects bands from an image. Can be called in one of two ways: - Passed any number of non-list arguments. All of these will be interpreted as band selectors. These can be band names, regexes, or numeric indices. E.g. selected = image.select('a', 'b', 3, 'd'); - Passed two lists. The first will be used as band selectors and the second as new names for the selected bands. The number of new names must match the number of selected bands. E.g. selected = image.select(['a', 4], ['newA', 'newB']); Args: opt_selectors: An array of names, regexes or numeric indices specifying the bands to select. opt_names: An array of strings specifying the new names for the selected bands. *args: Selector elements as varargs. Returns: An image with the selected bands. """ if opt_selectors is not None: args = list(args) if opt_names is not None: args.insert(0, opt_names) args.insert(0, opt_selectors) algorithm_args = { 'input': self, 'bandSelectors': args[0] if args else [], } if args: # If the user didn't pass an array as the first argument, assume # that everything in the arguments array is actually a selector. if (len(args) > 2 or ee_types.isString(args[0]) or ee_types.isNumber(args[0])): # Varargs inputs. selectors = args # Verify we didn't get anything unexpected. for selector in selectors: if (not ee_types.isString(selector) and not ee_types.isNumber(selector) and not isinstance(selector, computedobject.ComputedObject)): raise ee_exception.EEException( 'Illegal argument to select(): ' + selector) algorithm_args['bandSelectors'] = selectors elif len(args) > 1: algorithm_args['newNames'] = args[1] return apifunction.ApiFunction.apply_('Image.select', algorithm_args)
def select(self, selectors, opt_names=None, *args): """Select bands from an image. This is an override to the normal Image.select function to allow varargs specification of selectors. Args: selectors: An array of names, regexes or numeric indices specifying the bands to select. opt_names: An array of strings specifying the new names for the selected bands. If supplied, the length must match the number of bands selected. *args: Selector elements as varargs. Returns: An image with the selected bands. """ arguments = { 'input': self, 'bandSelectors': selectors, } if (isinstance(selectors, (basestring, int, long)) or ee_types.isString(selectors) or ee_types.isNumber(selectors)): # Varargs inputs. selectors = [selectors] if opt_names is not None: selectors.append(opt_names) opt_names = None selectors.extend(args) arguments['bandSelectors'] = selectors if opt_names: arguments['newNames'] = opt_names return apifunction.ApiFunction.apply_('Image.select', arguments)
def __init__(self, args): """ImageCollection constructor. Args: args: ImageCollections can be constructed from the following arguments: 1) A string: assumed to be the name of a collection, 2) An array of images, or anything that can be used to construct an image. 3) A single image. 5) A computed object - reinterpreted as a collection. Raises: EEException: if passed something other than the above. """ self.initialize() # Wrap single images in an array. if isinstance(args, image.Image): args = [args] if ee_types.isString(args): # An ID. super(ImageCollection, self).__init__(apifunction.ApiFunction.lookup("ImageCollection.load"), {"id": args}) elif isinstance(args, (list, tuple)): # A list of images. super(ImageCollection, self).__init__( apifunction.ApiFunction.lookup("ImageCollection.fromImages"), {"images": [image.Image(i) for i in args]} ) elif isinstance(args, computedobject.ComputedObject): # A custom object to reinterpret as a ImageCollection. super(ImageCollection, self).__init__(args.func, args.args, args.varName) else: raise ee_exception.EEException("Unrecognized argument type to convert to a ImageCollection: %s" % args)
def __init__(self, args, opt_column=None): """Constructs a collection features. Args: args: constructor argument. One of: 1) A string - assumed to be the name of a collection. 2) A number - assumed to be the ID of a Fusion Table. 3) A geometry. 4) A feature. 5) An array of features. 6) A computed object - reinterpreted as a collection. opt_column: The name of the geometry column to use. Only useful with the string or number constructor arguments. Raises: EEException: if passed something other than the above. """ self.initialize() # Wrap geometries with features. if isinstance(args, geometry.Geometry): args = feature.Feature(args) # Wrap single features in an array. if isinstance(args, feature.Feature): args = [args] if ee_types.isNumber(args) or ee_types.isString(args): # An ID. actual_args = {'tableId': args} if opt_column: actual_args['geometryColumn'] = opt_column super(FeatureCollection, self).__init__( apifunction.ApiFunction.lookup('Collection.loadTable'), actual_args) elif isinstance(args, (list, tuple)): # A list of features. super(FeatureCollection, self).__init__( apifunction.ApiFunction.lookup('Collection'), { 'features': [feature.Feature(i) for i in args] }) elif isinstance(args, ee_list.List): # A computed list of features. super(FeatureCollection, self).__init__( apifunction.ApiFunction.lookup('Collection'), { 'features': args }) elif isinstance(args, computedobject.ComputedObject): # A custom object to reinterpret as a FeatureCollection. super(FeatureCollection, self).__init__( args.func, args.args, args.varName) else: raise ee_exception.EEException( 'Unrecognized argument type to convert to a FeatureCollection: %s' % args)
def __init__(self, args, opt_column=None): """Constructs a collection features. Args: args: constructor argument. One of: 1) A string - assumed to be the name of a collection. 2) A number - assumed to be the ID of a Fusion Table. 3) A geometry. 4) A feature. 5) An array of features. 6) A computed object - reinterpreted as a collection. opt_column: The name of the geometry column to use. Only useful with the string or number constructor arguments. Raises: EEException: if passed something other than the above. """ self.initialize() # Wrap geometries with features. if isinstance(args, geometry.Geometry): args = feature.Feature(args) # Wrap single features in an array. if isinstance(args, feature.Feature): args = [args] if ee_types.isNumber(args) or ee_types.isString(args): # An ID. actual_args = {'tableId': args} if opt_column: actual_args['geometryColumn'] = opt_column super(FeatureCollection, self).__init__( apifunction.ApiFunction.lookup('Collection.loadTable'), actual_args) elif isinstance(args, (list, tuple)): # A list of features. super(FeatureCollection, self).__init__( apifunction.ApiFunction.lookup('Collection'), {'features': [feature.Feature(i) for i in args]}) elif isinstance(args, ee_list.List): # A computed list of features. super(FeatureCollection, self).__init__(apifunction.ApiFunction.lookup('Collection'), {'features': args}) elif isinstance(args, computedobject.ComputedObject): # A custom object to reinterpret as a FeatureCollection. super(FeatureCollection, self).__init__(args.func, args.args, args.varName) else: raise ee_exception.EEException( 'Unrecognized argument type to convert to a FeatureCollection: %s' % args)
def __init__(self, args): """ImageCollection constructor. Args: args: ImageCollections can be constructed from the following arguments: 1) A string: assumed to be the name of a collection, 2) An array of images, or anything that can be used to construct an image. 3) A single image. 5) A computed object - reinterpreted as a collection. Raises: EEException: if passed something other than the above. """ self.initialize() # Wrap single images in an array. if isinstance(args, image.Image): args = [args] if ee_types.isString(args): # An ID. super(ImageCollection, self).__init__( apifunction.ApiFunction.lookup('ImageCollection.load'), {'id': args}) elif isinstance(args, (list, tuple)): # A list of images. super(ImageCollection, self).__init__( apifunction.ApiFunction.lookup('ImageCollection.fromImages'), {'images': [image.Image(i) for i in args]}) elif isinstance(args, ee_list.List): # A computed list of images. super(ImageCollection, self).__init__( apifunction.ApiFunction.lookup('ImageCollection.fromImages'), {'images': args}) elif isinstance(args, computedobject.ComputedObject): # A custom object to reinterpret as a ImageCollection. super(ImageCollection, self).__init__(args.func, args.args, args.varName) else: raise ee_exception.EEException( 'Unrecognized argument type to convert to a ImageCollection: %s' % args)
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
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
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
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
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