Esempio n. 1
0
  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)
Esempio n. 2
0
    def set(self, *args):
        """Overrides one or more metadata properties of an Element.

    Args:
      *args: Either a dictionary of properties, or a vararg sequence of
          properties, e.g. key1, value1, key2, value2, ...

    Returns:
      The element with the specified properties overridden.
    """
        # TODO(user): Remove fallback once Element.set() is live.
        result = self
        if len(args) == 1:
            properties = args[0]
            if not isinstance(properties,
                              (dict, computedobject.ComputedObject)):
                raise ee_exception.EEException(
                    'Element.set() requires a dictionary.')

            # Try to be smart about interpreting the argument.
            if (isinstance(properties, dict)
                    and properties.keys() == ['properties']
                    and isinstance(properties['properties'], dict)):
                # Looks like a call with keyword parameters. Extract them.
                properties = properties['properties']
            try:
                for key, value in properties.iteritems():
                    result = apifunction.ApiFunction.call_(
                        'Element.set', result, key, value)
            except ee_exception.EEException:
                # No Element.set() defined yet. Use Feature.set().
                result = apifunction.ApiFunction.call_('Feature.set', result,
                                                       properties)
        else:
            # Interpret as key1, value1, key2, value2, ...
            if len(args) % 2 != 0:
                raise ee_exception.EEException(
                    'When Element.set() is passed multiple arguments, there '
                    'must be an even number of them.')
            try:
                for i in range(0, len(args), 2):
                    key = args[i]
                    value = args[i + 1]
                    result = apifunction.ApiFunction.call_(
                        'Element.set', result, key, value)
            except ee_exception.EEException:
                # No Element.set() defined yet. Use Feature.set().
                properties = {}
                for i in range(0, len(args), 2):
                    key = args[i]
                    value = args[i + 1]
                    properties[key] = value
                result = apifunction.ApiFunction.call_('Feature.set', result,
                                                       properties)

        # Manually cast the result to an image.
        return self._cast(result)
Esempio n. 3
0
    def set(self, *args):
        """Overrides one or more metadata properties of an Element.

    Args:
      *args: Either a dictionary of properties, or a vararg sequence of
          properties, e.g. key1, value1, key2, value2, ...

    Returns:
      The element with the specified properties overridden.
    """
        if len(args) == 1:
            properties = args[0]

            # If this is a keyword call, unwrap it.
            if (isinstance(properties, dict)
                    and properties.keys() == ['properties']
                    and isinstance(properties['properties'],
                                   (dict, computedobject.ComputedObject))):
                # Looks like a call with keyword parameters. Extract them.
                properties = properties['properties']

            if isinstance(properties, dict):
                # Still a plain object. Extract its keys. Setting the keys separately
                # allows filter propagation.
                result = self
                for key, value in properties.iteritems():
                    result = apifunction.ApiFunction.call_(
                        'Element.set', result, key, value)
            elif (isinstance(properties, computedobject.ComputedObject) and
                  apifunction.ApiFunction.lookupInternal('Element.setMulti')):
                # A computed dictionary. Can't set each key separately.
                result = apifunction.ApiFunction.call_('Element.setMulti',
                                                       self, properties)
            else:
                raise ee_exception.EEException(
                    'When Element.set() is passed one argument, '
                    'it must be a dictionary.')
        else:
            # Interpret as key1, value1, key2, value2, ...
            if len(args) % 2 != 0:
                raise ee_exception.EEException(
                    'When Element.set() is passed multiple arguments, there '
                    'must be an even number of them.')
            result = self
            for i in range(0, len(args), 2):
                key = args[i]
                value = args[i + 1]
                result = apifunction.ApiFunction.call_('Element.set', result,
                                                       key, value)

        # Manually cast the result to an image.
        return self._cast(result)
Esempio n. 4
0
    def __init__(self, date, opt_tz=None):
        """Construct a date.

    This sends all inputs (except another Date) through the Date function.

    This constuctor accepts the following args:
      1) A bare date.
      2) An ISO string
      3) A integer number of milliseconds since the epoch.
      4) A ComputedObject.

    Args:
      date: The date to wrap.
      opt_tz: An optional timezone, only useable with a string date.
    """
        self.initialize()

        func = apifunction.ApiFunction('Date')
        args = None
        varName = None
        if isinstance(date, datetime.datetime):
            args = {
                'value':
                math.floor(serializer.DatetimeToMicroseconds(date) / 1000)
            }
        elif types.isNumber(date):
            args = {'value': date}
        elif isinstance(date, basestring):
            args = {'value': date}
            if opt_tz:
                if isinstance(opt_tz, basestring):
                    args['timeZone'] = opt_tz
                else:
                    raise ee_exception.EEException(
                        'Invalid argument specified for ee.Date(..., opt_tz): %s'
                        % date)
        elif isinstance(date, computedobject.ComputedObject):
            if date.func and date.func.getSignature()['returns'] == 'Date':
                # If it's a call that's already returning a Date, just cast.
                func = date.func
                args = date.args
                varName = date.varName
            else:
                args = {'value': date}
        else:
            raise ee_exception.EEException(
                'Invalid argument specified for ee.Date(): %s' % date)

        super(Date, self).__init__(func, args, varName)
Esempio n. 5
0
    def map(self, algorithm):
        """Maps an algorithm over a list.

    Args:
      algorithm: The operation to map over the list.  A Python function that
          receives an object returns one. The function is called only once
          and the result is captured as a description, so it cannot perform
          imperative operations or rely on external state.

    Returns:
      The mapped list.

    Raises:
      ee_exception.EEException: if algorithm is not a function.
    """
        if not callable(algorithm):
            raise ee_exception.EEException(
                'Can\'t map non-callable object: %s' % algorithm)
        signature = {
            'name': '',
            'returns': 'Object',
            'args': [{
                'name': None,
                'type': 'Object',
            }]
        }
        return self._cast(
            apifunction.ApiFunction.apply_(
                'List.map', {
                    'list':
                    self,
                    'baseAlgorithm':
                    customfunction.CustomFunction(signature, algorithm)
                }))
Esempio n. 6
0
  def mapInternal(self, cls, algorithm):
    """Maps an algorithm over a collection.

    Args:
      cls: The collection elements' type (class).
      algorithm: The operation to map over the images or features of the
          collection, a Python function that receives an image or features and
          returns one. The function is called only once and the result is
          captured as a description, so it cannot perform imperative operations
          or rely on external state.

    Returns:
      The mapped collection.

    Raises:
      ee_exception.EEException: if algorithm is not a function.
    """
    if not callable(algorithm):
      raise ee_exception.EEException(
          'Can\'t map non-callable object: %s' % algorithm)
    signature = {
        'name': '',
        'returns': 'Object',
        'args': [{
            'name': None,
            'type': ee_types.classToName(cls)
        }]
    }
    return self._cast(apifunction.ApiFunction.apply_('Collection.map', {
        'collection': self,
        'baseAlgorithm': customfunction.CustomFunction(signature, algorithm)
    }))
Esempio n. 7
0
    def getThumbURL(self, params=None):
        """Get a thumbnail URL for this image.

    Args:
      params: Parameters identical to getMapId, plus, optionally:
          size - (a number or pair of numbers in format WIDTHxHEIGHT) Maximum
            dimensions of the thumbnail to render, in pixels. If only one number
            is passed, it is used as the maximum, and the other dimension is
            computed by proportional scaling.
          region - (E,S,W,N or GeoJSON) Geospatial region of the image
            to render. By default, the whole image.
          format - (string) Either 'png' or 'jpg'.

    Returns:
      A URL to download a thumbnail the specified image.

    Raises:
      EEException: If the region parameter is not an array or GeoJSON object.
    """
        request = params or {}
        request['image'] = self.serialize()
        if request.has_key('region'):
            if (isinstance(request['region'], dict)
                    or isinstance(request['region'], list)):
                request['region'] = json.dumps(request['region'])
            elif not isinstance(request['region'], str):
                raise ee_exception.EEException(
                    'The region parameter must be an array or a GeoJSON object.'
                )
        return data.makeThumbUrl(data.getThumbId(request))
Esempio n. 8
0
 def type(self):
     """Returns the GeoJSON type of the geometry."""
     if self.func:
         raise ee_exception.EEException(
             'Can\'t get the type of a computed geometry to GeoJSON. '
             'Use getInfo() instead.')
     return self._type
Esempio n. 9
0
    def __init__(self, string):
        """Construct a string wrapper.

    This constuctor accepts the following args:
      1) A bare string.
      2) A ComputedObject returning a string.

    Args:
      string: The string to wrap.
    """
        self.initialize()

        if isinstance(string, basestring):
            super(String, self).__init__(None, None)
        elif isinstance(string, computedobject.ComputedObject):
            if string.func and string.func.getSignature(
            )['returns'] == 'String':
                # If it's a call that's already returning a String, just cast.
                super(String, self).__init__(string.func, string.args,
                                             string.varName)
            else:
                super(String, self).__init__(apifunction.ApiFunction('String'),
                                             {'input': string})
        else:
            raise ee_exception.EEException(
                'Invalid argument specified for ee.String(): %s' % string)
        self._string = string
Esempio n. 10
0
 def toGeoJSONString(self):
     """Returns a GeoJSON string representation of the geometry."""
     if self.func:
         raise ee_exception.EEException(
             'Can\'t convert a computed geometry to GeoJSON. '
             'Use getInfo() instead.')
     return json.dumps(self.toGeoJSON())
Esempio n. 11
0
    def metadata_(name, operator, value):
        """Filter on metadata. This is deprecated.

    Args:
      name: The property name to filter on.
      operator: The type of comparison. One of:
          "equals", "less_than", "greater_than", "contains", "begins_with",
          "ends_with", or any of these prefixed with "not_".
      value: The value to compare against.

    Returns:
      The new filter.
    """
        operator = operator.lower()

        # Check for negated filters.
        negated = False
        if operator.startswith('not_'):
            negated = True
            operator = operator[4:]

        # Convert the operator to a function.
        if operator not in _FUNCTION_NAMES:
            raise ee_exception.EEException('Unknown filtering operator: %s' %
                                           operator)
        func_name = 'Filter.' + _FUNCTION_NAMES[operator]
        new_filter = apifunction.ApiFunction.call_(func_name, name, value)

        return new_filter.Not() if negated else new_filter
Esempio n. 12
0
    def Point(coords=_UNSPECIFIED, proj=_UNSPECIFIED, *args, **kwargs):
        """Constructs an ee.Geometry describing a point.

    Args:
      coords: A list of two [x,y] coordinates in the given projection.
      proj: The projection of this geometry, or EPSG:4326 if unspecified.
      *args: For convenience, varargs may be used when all arguments are
          numbers. This allows creating EPSG:4326 points, e.g.
          ee.Geometry.Point(lng, lat).
      **kwargs: Keyword args that accept "lon" and "lat" for backward-
          compatibility.

    Returns:
      An ee.Geometry describing a point.
    """
        init = Geometry._parseArgs(
            'Point', 1,
            Geometry._GetSpecifiedArgs((coords, proj) + args, ('lon', 'lat'),
                                       **kwargs))
        if not isinstance(init, computedobject.ComputedObject):
            xy = init['coordinates']
            if not isinstance(xy, (list, tuple)) or len(xy) != 2:
                raise ee_exception.EEException(
                    'The Geometry.Point constructor requires 2 coordinates.')
        return Geometry(init)
Esempio n. 13
0
def send_(path, params, opt_method='POST', opt_raw=False):
    """Send an API call.

  Args:
    path: The API endpoint to call.
    params: The call parameters.
    opt_method: The HTTPRequest method (GET or POST).
    opt_raw: Whether the data should be returned raw, without attempting
        to decode it as JSON.

  Returns:
    The data object returned by the API call.

  Raises:
    EEException: For malformed requests or errors from the server.
  """
    # Make sure we never perform API calls before initialization.
    initialize()

    if _profile_hook:
        params = params.copy()
        params['profiling'] = '1'

    url = _api_base_url + path
    payload = urllib.urlencode(params)
    http = httplib2.Http(timeout=int(_deadline_ms / 1000) or None)

    headers = {}
    if _credentials:
        http = _credentials.authorize(http)

    if opt_method == 'GET':
        url = url + ('&' if '?' in url else '?') + payload
        payload = None
    elif opt_method == 'POST':
        headers['Content-type'] = 'application/x-www-form-urlencoded'
    else:
        raise ee_exception.EEException('Unexpected request method: ' +
                                       opt_method)

    try:
        response, content = http.request(url,
                                         method=opt_method,
                                         body=payload,
                                         headers=headers)
    except httplib2.HttpLib2Error, e:
        raise ee_exception.EEException('Unexpected HTTP error: %s' % e.message)
Esempio n. 14
0
    def toGeoJSON(self):
        """Returns a GeoJSON representation of the geometry."""
        if self.func:
            raise ee_exception.EEException(
                'Can\'t convert a computed geometry to GeoJSON. '
                'Use getInfo() instead.')

        return self.encode()
Esempio n. 15
0
    def _makeGeometry(nesting, opt_coordinates=()):
        """Check that the given geometry has the specified level of nesting.

    If the user passed a list of points to one of the Geometry functions,
    then geometry will not be used and the coordinates in opt_coordinates
    will be processed instead.  This is to allow calls such as:
    Polygon(1,2,3,4,5,6) and Polygon([[[1,2],[3,4],[5,6]]])

    Args:
      nesting: The expected level of array nesting.
      opt_coordinates: A list of all the coordinates to decode.

    Returns:
      The processed geometry.

    Raises:
      EEException: if the nesting level of the arrays isn't supported.
    """
        if nesting < 2 or nesting > 4:
            raise ee_exception.EEException('Unexpected nesting level.')

        # Handle a list of points.
        if (len(opt_coordinates) == 1 and isinstance(opt_coordinates[0],
                                                     (list, tuple))):
            geometry = opt_coordinates[0]
        else:
            geometry = Geometry._coordinatesToLine(opt_coordinates)

        # Make sure the number of nesting levels is correct.
        item = geometry
        count = 0
        while isinstance(item, (list, tuple)):
            item = item[0] if item else None
            count += 1

        while count < nesting:
            geometry = [geometry]
            count += 1

        if Geometry._isValidCoordinates(geometry) != nesting:
            raise ee_exception.EEException('Invalid geometry.')

        # Empty arrays should not be wrapped.
        if list(geometry) in ([[]], [()]): geometry = []

        return geometry
Esempio n. 16
0
    def Rectangle(coords=_UNSPECIFIED,
                  proj=_UNSPECIFIED,
                  geodesic=_UNSPECIFIED,
                  maxError=_UNSPECIFIED,
                  evenOdd=_UNSPECIFIED,
                  *args,
                  **kwargs):
        """Constructs an ee.Geometry describing a rectangular polygon.

    Args:
      coords: The minimum and maximum corners of the rectangle, as a list of
          two points each in the format of GeoJSON 'Point' coordinates, or a
          list of two ee.Geometry describing a point, or a list of four
          numbers in the order xMin, yMin, xMax, yMax.
      proj: The projection of this geometry. If unspecified, the default is the
          projection of the input ee.Geometry, or EPSG:4326 if there are no
          ee.Geometry inputs.
      geodesic: If false, edges are straight in the projection. If true, edges
          are curved to follow the shortest path on the surface of the Earth.
          The default is the geodesic state of the inputs, or true if the
          inputs are numbers.
      maxError: Max error when input geometry must be reprojected to an
          explicitly requested result projection or geodesic state.
      evenOdd: If true, polygon interiors will be determined by the even/odd
          rule, where a point is inside if it crosses an odd number of edges to
          reach a point at infinity. Otherwise polygons use the left-inside
          rule, where interiors are on the left side of the shell's edges when
          walking the vertices in the given order. If unspecified, defaults to
          True.
      *args: For convenience, varargs may be used when all arguments are
          numbers. This allows creating EPSG:4326 Polygons given exactly four
          coordinates, e.g.
          ee.Geometry.Rectangle(minLng, minLat, maxLng, maxLat).
      **kwargs: Keyword args that accept "xlo", "ylo", "xhi" and "yhi" for
          backward-compatibility.

    Returns:
      An ee.Geometry describing a rectangular polygon.
    """
        init = Geometry._parseArgs(
            'Rectangle', 2,
            Geometry._GetSpecifiedArgs(
                (coords, proj, geodesic, maxError, evenOdd) + args,
                ('xlo', 'ylo', 'xhi', 'yhi'), **kwargs))
        if not isinstance(init, computedobject.ComputedObject):
            # GeoJSON does not have a Rectangle type, so expand to a Polygon.
            xy = init['coordinates']
            if not isinstance(xy, (list, tuple)) or len(xy) != 2:
                raise ee_exception.EEException(
                    'The Geometry.Rectangle constructor requires 2 points or 4 '
                    'coordinates.')
            x1 = xy[0][0]
            y1 = xy[0][1]
            x2 = xy[1][0]
            y2 = xy[1][1]
            init['coordinates'] = [[[x1, y2], [x1, y1], [x2, y1], [x2, y2]]]
            init['type'] = 'Polygon'
        return Geometry(init)
Esempio n. 17
0
    def _fixDepth(depth, coords):
        """Fixes the depth of the given coordinates.

    Checks that each element has the expected depth as all other elements
    at that depth.

    Args:
      depth: The desired depth.
      coords: The coordinates to fix.

    Returns:
      The fixed coordinates, with the deepest elements at the requested depth.

    Raises:
      EEException: if the depth is invalid and could not be fixed.
    """
        if depth < 1 or depth > 4:
            raise ee_exception.EEException('Unexpected nesting level.')

        # Handle a list of numbers.
        if all(isinstance(i, numbers.Number) for i in coords):
            coords = Geometry._coordinatesToLine(coords)

        # Make sure the number of nesting levels is correct.
        item = coords
        count = 0
        while isinstance(item, (list, tuple)):
            item = item[0] if item else None
            count += 1
        while count < depth:
            coords = [coords]
            count += 1

        if Geometry._isValidCoordinates(coords) != depth:
            raise ee_exception.EEException('Invalid geometry.')

        # Empty arrays should not be wrapped.
        item = coords
        while isinstance(item, (list, tuple)) and len(item) == 1:
            item = item[0]
        if isinstance(item, (list, tuple)) and not item:
            return []

        return coords
Esempio n. 18
0
    def _makeGeometry(geometry, nesting, opt_coordinates=()):
        """Check that the given geometry has the specified level of nesting.

    If the user passed a list of points to one of the Geometry functions,
    then geometry will not be used and the coordinates in opt_coordinates
    will be processed instead.  This is to allow calls such as:
    Polygon(1,2,3,4,5,6) and Polygon([[[1,2],[3,4],[5,6]]])

    Args:
      geometry: The geometry to check.
      nesting: The expected level of array nesting.
      opt_coordinates: A list of extra coordinates to decode.

    Returns:
      The processed geometry.

    Raises:
      EEException: if the nesting level of the arrays isn't supported.
    """
        if nesting < 2 or nesting > 4:
            raise ee_exception.EEException('Unexpected nesting level.')

        # Handle a list of points.
        if isinstance(geometry, numbers.Number) and opt_coordinates:
            coordinates = [geometry]
            coordinates.extend(opt_coordinates)
            geometry = Geometry._coordinatesToLine(coordinates)

        # Make sure the number of nesting levels is correct.
        item = geometry
        count = 0
        while isinstance(item, list) or isinstance(item, tuple):
            item = item[0]
            count += 1

        while count < nesting:
            geometry = [geometry]
            count += 1

        if Geometry._isValidCoordinates(geometry) != nesting:
            raise ee_exception.EEException('Invalid geometry.')

        return geometry
Esempio n. 19
0
    def __init__(self, geom, opt_properties=None):
        """Creates a feature a geometry or computed object.

    Features can be constructed from one of the following arguments plus an
    optional dictionary of properties:
      1) An ee.Geometry.
      2) A GeoJSON Geometry.
      3) A GeoJSON Feature.
      4) A computed object - reinterpreted as a geometry if properties
         are specified, and as a feature if they aren't.

    Args:
      geom: A geometry or feature.
      opt_properties: A dictionary of metadata properties. If the first
          parameter is a Feature (instead of a geometry), this is unused.

    Raises:
      EEException: if the given geometry isn't valid.
    """
        if isinstance(geom, Feature):
            if opt_properties is not None:
                raise ee_exception.EEException(
                    'Can\'t create Feature out of a Feature and properties.')
            # A pre-constructed Feature. Copy.
            super(Feature, self).__init__(geom.func, geom.args)
            return

        self.initialize()

        feature_constructor = apifunction.ApiFunction.lookup('Feature')
        if geom is None or isinstance(geom, geometry.Geometry):
            # A geometry object.
            super(Feature, self).__init__(feature_constructor, {
                'geometry': geom,
                'metadata': opt_properties or None
            })
        elif isinstance(geom, computedobject.ComputedObject):
            # A custom object to reinterpret as a Feature.
            super(Feature, self).__init__(geom.func, geom.args)
        elif isinstance(geom, dict) and geom.get('type') == 'Feature':
            # Try to convert a GeoJSON Feature.
            super(Feature, self).__init__(
                feature_constructor, {
                    'geometry': geometry.Geometry(geom.get('geometry', None)),
                    'metadata': geom.get('properties', None)
                })
        else:
            # Try to convert the geometry arg to a Geometry, in the hopes of it
            # turning out to be GeoJSON.
            super(Feature, self).__init__(
                feature_constructor, {
                    'geometry': geometry.Geometry(geom),
                    'metadata': opt_properties or None
                })
Esempio n. 20
0
    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)
Esempio n. 21
0
    def __init__(self, opt_filter=None):
        """Construct a filter.

    This constuctor accepts the following args:
      1) Another filter.
      2) An array of filters (which are implicitly ANDed together).
      3) A ComputedObject returning a filter. Users shouldn't be making these;
         they're produced by the generator functions below.

    Args:
      opt_filter: Optional filter to add.
    """
        self.initialize()

        if isinstance(opt_filter, (list, tuple)):
            if not opt_filter:
                raise ee_exception.EEException(
                    'Empty list specified for ee.Filter().')
            elif len(opt_filter) == 1:
                opt_filter = opt_filter[0]
            else:
                self._filter = tuple(opt_filter)
                super(Filter, self).__init__(
                    apifunction.ApiFunction.lookup('Filter.and'),
                    {'filters': self._filter})
                return

        if isinstance(opt_filter, computedobject.ComputedObject):
            super(Filter, self).__init__(opt_filter.func, opt_filter.args,
                                         opt_filter.varName)
            self._filter = (opt_filter, )
        elif opt_filter is None:
            # A silly call with no arguments left for backward-compatibility.
            # Encoding such a filter is expected to fail, but it can be composed
            # by calling the various methods that end up in _append().
            super(Filter, self).__init__(None, None)
            self._filter = ()
        else:
            raise ee_exception.EEException(
                'Invalid argument specified for ee.Filter(): %s' % opt_filter)
Esempio n. 22
0
    def promoteArgs(self, args):
        """Promotes arguments to their types based on the function's signature.

    Verifies that all required arguments are provided and no unknown arguments
    are present.

    Args:
      args: A dictionary of keyword arguments to the function.

    Returns:
      A dictionary of promoted arguments.

    Raises:
      EEException: If unrecognized arguments are passed or required ones are
          missing.
    """
        specs = self.getSignature()['args']

        # Promote all recognized args.
        promoted_args = {}
        known = set()
        for spec in specs:
            name = spec['name']
            if name in args:
                promoted_args[name] = Function._promoter(
                    args[name], spec['type'])
            elif not spec.get('optional'):
                raise ee_exception.EEException(
                    'Required argument (%s) missing to function: %s' %
                    (name, self))
            known.add(name)

        # Check for unknown arguments.
        unknown = set(args.keys()).difference(known)
        if unknown:
            raise ee_exception.EEException(
                'Unrecognized arguments %s to function: %s' % (unknown, self))

        return promoted_args
Esempio n. 23
0
  def filter(self, new_filter):
    """Apply a filter to this collection.

    Args:
      new_filter: Filter to add to this collection.

    Returns:
      The filtered collection object.
    """
    if not new_filter:
      raise ee_exception.EEException('Empty filters.')
    return self._cast(apifunction.ApiFunction.call_(
        'Collection.filter', self, new_filter))
Esempio n. 24
0
    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)
Esempio n. 25
0
    def lookup(cls, name):
        """Looks up an API function by name.

    Args:
      name: The name of the function to get.

    Returns:
      The requested ApiFunction.
    """
        result = cls.lookupInternal(name)
        if not name:
            raise ee_exception.EEException(
                'Unknown built-in function name: %s' % name)
        return result
Esempio n. 26
0
  def lookup(cls, name):
    """Looks up an API function by name.

    Args:
      name: The name of the function to get.

    Returns:
      The requested ApiFunction.
    """
    cls.initialize()
    if name not in cls._api:
      raise ee_exception.EEException(
          'Unknown built-in function name: %s' % name)
    return cls._api[name]
Esempio n. 27
0
    def nameArgs(self, args, extra_keyword_args=None):
        """Converts a list of positional arguments to a map of keyword arguments.

    Uses the function's signature for argument names. Note that this does not
    check whether the array contains enough arguments to satisfy the call.

    Args:
      args: Positional arguments to the function.
      extra_keyword_args: Optional named arguments to add.

    Returns:
      Keyword arguments to the function.

    Raises:
      EEException: If conflicting arguments or too many of them are supplied.
    """
        specs = self.getSignature()['args']

        # Handle positional arguments.
        if len(specs) < len(args):
            raise ee_exception.EEException(
                'Too many (%d) arguments to function: %s' % (len(args), self))
        named_args = dict([(spec['name'], value)
                           for spec, value in zip(specs, args)])

        # Handle keyword arguments.
        if extra_keyword_args:
            for name in extra_keyword_args:
                if name in named_args:
                    raise ee_exception.EEException(
                        'Argument %s specified as both positional and '
                        'keyword to function: %s' % (name, self))
                named_args[name] = extra_keyword_args[name]
            # Unrecognized arguments are checked in promoteArgs().

        return named_args
Esempio n. 28
0
    def _parseArgs(ctor_name, depth, args):
        """Parses arguments into a GeoJSON dictionary or a ComputedObject.

    Args:
      ctor_name: The name of the constructor to use.
      depth: The nesting depth at which points are found.
      args: The array of values to test.

    Returns:
      If the arguments are simple, a GeoJSON object describing the geometry.
      Otherwise a ComputedObject calling the appropriate constructor.
    """
        result = {}
        keys = ['coordinates', 'crs', 'geodesic', 'maxError', 'evenOdd']

        if all(ee_types.isNumber(i) for i in args):
            # All numbers, so convert them to a true array.
            result['coordinates'] = args
        else:
            # Parse parameters by position.
            if len(args) > len(keys):
                raise ee_exception.EEException(
                    'Geometry constructor given extra arguments.')
            for key, arg in zip(keys, args):
                if arg is not None:
                    result[key] = arg

        # Standardize the coordinates and test if they are simple enough for
        # client-side initialization.
        if (Geometry._hasServerValue(result['coordinates'])
                or result.get('crs') is not None
                or result.get('geodesic') is not None
                or result.get('maxError') is not None):
            # Some arguments cannot be handled in the client, so make a server call.
            # Note we don't declare a default evenOdd value, so the server can infer
            # a default based on the projection.
            server_name = 'GeometryConstructors.' + ctor_name
            return apifunction.ApiFunction.lookup(server_name).apply(result)
        else:
            # Everything can be handled here, so check the depth and init this object.
            result['type'] = ctor_name
            result['coordinates'] = Geometry._fixDepth(depth,
                                                       result['coordinates'])
            # Enable evenOdd by default for any kind of polygon.
            if ('evenOdd' not in result
                    and ctor_name in ['Polygon', 'Rectangle', 'MultiPolygon']):
                result['evenOdd'] = True
            return result
Esempio n. 29
0
 def _GetSerializedRegion(region):
     """Converts a region parameter to serialized form, if it isn't already."""
     region_error = ee_exception.EEException(
         'Invalid format for region property. '
         'See Export.image() documentation for more details.')
     if isinstance(region, basestring):
         try:
             region = json.loads(region)
         except:
             raise region_error
     try:
         geometry.Geometry.LineString(region)
     except:  # pylint: disable=bare-except
         try:
             geometry.Geometry.Polygon(region)
         except:
             raise region_error
     return json.dumps(region)
Esempio n. 30
0
def _ConvertToServerParams(configDict, eeElementKey, destination):
    """Converts an export configuration to server friendly parameters.

  Note that configDict is changed in place and not returned.

  Args:
    configDict: The configuration dictionary to be converted.
    eeElementKey: The key used to access the EE element.
    destination: The destination to export to.
  """
    del configDict[eeElementKey]
    if 'kwargs' in configDict:
        configDict.update(configDict['kwargs'])
        del configDict['kwargs']

    if 'crsTransform' in configDict:
        configDict['crs_transform'] = configDict.pop('crsTransform')

    if destination is Task.ExportDestination.GCS:
        if 'bucket' in configDict:
            configDict['outputBucket'] = configDict.pop('bucket')

        if 'fileNamePrefix' in configDict:
            if 'outputPrefix' not in configDict:
                configDict['outputPrefix'] = configDict.pop('fileNamePrefix')
            else:
                del configDict['fileNamePrefix']

        # Only used with Export.map
        if 'path' in configDict:
            configDict['outputPrefix'] = configDict.pop('path')
    elif destination is Task.ExportDestination.DRIVE:
        if 'folder' in configDict:
            configDict['driveFolder'] = configDict.pop('folder')

        if 'fileNamePrefix' in configDict:
            if 'driveFileNamePrefix' not in configDict:
                configDict['driveFileNamePrefix'] = configDict.pop(
                    'fileNamePrefix')
            else:
                del configDict['fileNamePrefix']
    elif destination is not Task.ExportDestination.ASSET:
        raise ee_exception.EEException('Unknown export destination.')