diff --git a/python/ee/__init__.py b/python/ee/__init__.py index e389292a5..d1ae2d00e 100644 --- a/python/ee/__init__.py +++ b/python/ee/__init__.py @@ -62,7 +62,7 @@ # Tell pytype not to worry about dynamic attributes. _HAS_DYNAMIC_ATTRIBUTES = True -# A list of autogenerated class names added by _InitializeGenerateClasses. +# A list of autogenerated class names added by _InitializeGeneratedClasses. _generatedClasses: ListType[str] = [] NO_PROJECT_EXCEPTION = ('ee.Initialize: no project found. Call with project=' diff --git a/python/ee/_cloud_api_utils.py b/python/ee/_cloud_api_utils.py index 986fed564..a808616f4 100644 --- a/python/ee/_cloud_api_utils.py +++ b/python/ee/_cloud_api_utils.py @@ -75,6 +75,8 @@ def request( # pylint: disable=invalid-name except requests.exceptions.ChunkedEncodingError as encoding_error: # This is not a one-to-one match, but it's close enough. raise ConnectionError(encoding_error) from encoding_error + except requests.exceptions.Timeout as timeout_error: + raise TimeoutError(timeout_error) from timeout_error headers = dict(response.headers) headers['status'] = response.status_code content = response.content diff --git a/python/ee/apitestcase.py b/python/ee/apitestcase.py index 404167bf9..f0b78ca2d 100644 --- a/python/ee/apitestcase.py +++ b/python/ee/apitestcase.py @@ -70,6 +70,8 @@ def InitializeApi(self, should_mock: bool = True): ee.data.getDownloadId = self._MockDownloadUrl ee.data.getThumbId = self._MockThumbUrl ee.data.getTableDownloadId = self._MockTableDownload + # pylint: disable-next=protected-access + ee.deprecation._FetchDataCatalogStac = self._MockFetchDataCatalogStac ee.Initialize(None, '') # We are mocking the url here so the unit tests are happy. @@ -96,6 +98,9 @@ def _MockTableDownload(self, params: Dict[str, Any]) -> Dict[str, str]: self.last_table_call = {'url': '/table', 'data': params} return {'docid': '5', 'token': '6'} + def _MockFetchDataCatalogStac(self) -> Dict[str, Any]: + return {} + def _GenerateCloudApiResource(mock_http: Any, raw: Any) -> discovery.Resource: """Returns a Cloud API resource for testing.""" diff --git a/python/ee/batch.py b/python/ee/batch.py index 9b2c501f3..41bd86902 100644 --- a/python/ee/batch.py +++ b/python/ee/batch.py @@ -812,7 +812,7 @@ def toBigQuery( description: Human-readable name of the task. table: The fully-qualifed BigQuery destination table with "project_id.dataset_id.table_id" format. - overwrite: [Not yet supported.] Whether the existing table should be + overwrite: Whether the existing table should be overwritten by the results of this export. The `overwrite` and `append` parameters cannot be `true` simultaneously. The export fails if the table already exists and both diff --git a/python/ee/data.py b/python/ee/data.py index 10ed26ab6..4353bc8e1 100644 --- a/python/ee/data.py +++ b/python/ee/data.py @@ -1256,11 +1256,12 @@ def getDownloadId(params: Dict[str, Any]) -> Dict[str, str]: possible values: image - The image to download. - name: a base name to use when constructing filenames. Only applicable - when format is "ZIPPED_GEO_TIFF" (default) or filePerBand is true. - Defaults to the image id (or "download" for computed images) when - format is "ZIPPED_GEO_TIFF" or filePerBand is true, otherwise a - random character string is generated. Band names are appended when - filePerBand is true. + when format is "ZIPPED_GEO_TIFF" (default), + "ZIPPED_GEO_TIFF_PER_BAND", or filePerBand is true. Defaults to the + image id (or "download" for computed images) when format is + "ZIPPED_GEO_TIFF", "ZIPPED_GEO_TIFF_PER_BAND", or filePerBand is + true, otherwise a random character string is generated. Band names + are appended when filePerBand is true. - bands: a description of the bands to download. Must be an array of band names or an array of dictionaries, each with the following keys: @@ -1285,10 +1286,13 @@ def getDownloadId(params: Dict[str, Any]) -> Dict[str, str]: and crs_transform are specified. - filePerBand: whether to produce a separate GeoTIFF per band (boolean). Defaults to true. If false, a single GeoTIFF is produced and all - band-level transformations will be ignored. + band-level transformations will be ignored. Note that this is + ignored if the format is "ZIPPED_GEO_TIFF" or + "ZIPPED_GEO_TIFF_PER_BAND". - format: the download format. One of: - "ZIPPED_GEO_TIFF" (GeoTIFF file(s) wrapped in a zip file, default), - "GEO_TIFF" (GeoTIFF file), "NPY" (NumPy binary format). + "ZIPPED_GEO_TIFF" (GeoTIFF file wrapped in a zip file, default), + "ZIPPED_GEO_TIFF_PER_BAND" (Multiple GeoTIFF files wrapped in a + zip file), "GEO_TIFF" (GeoTIFF file), "NPY" (NumPy binary format). If "GEO_TIFF" or "NPY", filePerBand and all band-level transformations will be ignored. Loading a NumPy output results in a structured array. @@ -2102,8 +2106,7 @@ def setAssetAcl(assetId: str, aclUpdate: Union[str, Dict[str, Any]]) -> None: Args: assetId: The ID of the asset to set the ACL on. - aclUpdate: The updated ACL for the asset. Must be formatted like the - value returned by getAssetAcl but without "owners". + aclUpdate: The updated ACL. """ # The ACL may be a string by the time it gets to us. Sigh. if isinstance(aclUpdate, str): diff --git a/python/ee/deprecation.py b/python/ee/deprecation.py index 2b05f43a6..ad74279db 100644 --- a/python/ee/deprecation.py +++ b/python/ee/deprecation.py @@ -193,7 +193,9 @@ def _IssueAssetDeprecationWarning(asset: DeprecatedAsset) -> None: ) removal_date = asset.removal_date if removal_date: - formatted_date = removal_date.strftime('%B %-d, %Y') + # %d gives a zero-padded day. Remove the leading zero. %-d is incompatible + # with Windows. + formatted_date = removal_date.strftime('%B %d, %Y').replace(' 0', ' ') warning = warning + f' by {formatted_date}.' else: warning = warning + '.' diff --git a/python/ee/image.py b/python/ee/image.py index 4f0cf81ae..5a987fdb8 100644 --- a/python/ee/image.py +++ b/python/ee/image.py @@ -21,6 +21,20 @@ from ee import geometry +def _parse_dimensions(dimensions: Any) -> Sequence[Any]: + """Parses a dimensions specification into a one or two element list.""" + if ee_types.isNumber(dimensions): + return [dimensions] + elif isinstance(dimensions, str): + # Unpack WIDTHxHEIGHT + return [int(x) for x in dimensions.split('x')] + elif isinstance(dimensions, (list, tuple)) and 1 <= len(dimensions) <= 2: + return dimensions + + raise ee_exception.EEException( + 'Invalid dimensions {}.'.format(dimensions)) + + class Image(element.Element): """An object to represent an Earth Engine image.""" @@ -105,6 +119,10 @@ def reset(cls) -> None: apifunction.ApiFunction.clearApi(cls) cls._initialized = False + @staticmethod + def name() -> str: + return 'Image' + # pylint: disable-next=useless-parent-delegation def getInfo(self) -> Optional[Any]: """Fetch and return information about this image. @@ -120,7 +138,7 @@ def getMapId(self, vis_params: Optional[Any] = None) -> Dict[str, Any]: """Fetch and return a map ID dictionary, suitable for use in a Map overlay. Args: - vis_params: The visualization parameters. See ee.data.getMapId. + vis_params: The visualization parameters. See ee.data.getMapId. Returns: A map ID dictionary as described in ee.data.getMapId. @@ -434,11 +452,12 @@ def getDownloadURL(self, params: Optional[Dict[str, Any]] = None) -> str: params: An object containing download options with the following possible values: - name: a base name to use when constructing filenames. Only applicable - when format is "ZIPPED_GEO_TIFF" (default) or filePerBand is true. - Defaults to the image id (or "download" for computed images) when - format is "ZIPPED_GEO_TIFF" or filePerBand is true, otherwise a - random character string is generated. Band names are appended when - filePerBand is true. + when format is "ZIPPED_GEO_TIFF" (default), + "ZIPPED_GEO_TIFF_PER_BAND" or filePerBand is true. Defaults to the + image id (or "download" for computed images) when format is + "ZIPPED_GEO_TIFF", "ZIPPED_GEO_TIFF_PER_BAND", or filePerBand is + true, otherwise a random character string is generated. Band names + are appended when filePerBand is true. - bands: a description of the bands to download. Must be an array of band names or an array of dictionaries, each with the following keys: @@ -463,10 +482,13 @@ def getDownloadURL(self, params: Optional[Dict[str, Any]] = None) -> str: and crs_transform are specified. - filePerBand: whether to produce a separate GeoTIFF per band (boolean). Defaults to true. If false, a single GeoTIFF is produced and all - band-level transformations will be ignored. + band-level transformations will be ignored. Note that this is + ignored if the format is "ZIPPED_GEO_TIFF" or + "ZIPPED_GEO_TIFF_PER_BAND". - format: the download format. One of: - "ZIPPED_GEO_TIFF" (GeoTIFF file(s) wrapped in a zip file, default), - "GEO_TIFF" (GeoTIFF file), "NPY" (NumPy binary format). + "ZIPPED_GEO_TIFF" (GeoTIFF file wrapped in a zip file, default), + "ZIPPED_GEO_TIFF_PER_BAND" (Multiple GeoTIFF files wrapped in a + zip file), "GEO_TIFF" (GeoTIFF file), "NPY" (NumPy binary format). If "GEO_TIFF" or "NPY", filePerBand and all band-level transformations will be ignored. Loading a NumPy output results in a structured array. @@ -513,8 +535,8 @@ def getThumbURL(self, params: Optional[Dict[str, Any]] = None) -> str: computed by proportional scaling. region - (ee.Geometry, GeoJSON, list of numbers, list of points) Geospatial region of the image to render. By default, the whole - image. If given a list of min lon, min lat, max lon, max lat, - a planar rectangle is created. If given a list of points a + image. If given a list of min lon, min lat, max lon, max lat, + a planar rectangle is created. If given a list of points a planar polygon is created. format - (string) Either 'png' or 'jpg'. @@ -672,7 +694,7 @@ def expression(self, expression: Any, map_: Optional[Any] = None) -> Image: accessed like image.band_name or image[0]. Both b() and image[] allow multiple arguments, to specify multiple bands, - such as b(1, 'name', 3). Calling b() with no arguments, or using a variable + such as b(1, 'name', 3). Calling b() with no arguments, or using a variable by itself, returns all bands of the image. Args: @@ -730,6 +752,7 @@ def clip(self, clip_geometry: Any) -> Image: clip_geometry = geometry.Geometry(clip_geometry) except ee_exception.EEException: pass # Not an ee.Geometry or GeoJSON. Just pass it along. + return apifunction.ApiFunction.call_('Image.clip', self, clip_geometry) def rename(self, names: Any, *args) -> Image: @@ -739,7 +762,7 @@ def rename(self, names: Any, *args) -> Image: Args: names: An array of strings specifying the new names for the - bands. Must exactly match the number of bands in the image. + bands. Must exactly match the number of bands in the image. *args: Band names as varargs. Returns: @@ -756,21 +779,3 @@ def rename(self, names: Any, *args) -> Image: 'names': names } return apifunction.ApiFunction.apply_('Image.rename', algorithm_args) - - @staticmethod - def name() -> str: - return 'Image' - - -def _parse_dimensions(dimensions: Any) -> Sequence[Any]: - """Parses a dimensions specification into a one or two element list.""" - if ee_types.isNumber(dimensions): - return [dimensions] - elif isinstance(dimensions, str): - # Unpack WIDTHxHEIGHT - return [int(x) for x in dimensions.split('x')] - elif isinstance(dimensions, (list, tuple)) and 1 <= len(dimensions) <= 2: - return dimensions - - raise ee_exception.EEException( - 'Invalid dimensions {}.'.format(dimensions)) diff --git a/python/ee/tests/deprecation_test.py b/python/ee/tests/deprecation_test.py index bc01dd94d..08c338e6c 100644 --- a/python/ee/tests/deprecation_test.py +++ b/python/ee/tests/deprecation_test.py @@ -4,7 +4,6 @@ import contextlib from typing import Any, Dict import warnings -import unittest from absl.testing import parameterized @@ -48,6 +47,20 @@ 'gee:replacement_id': 'replacement_id', 'gee:removal_date': '2024-07-01T00:00:00Z', }, + { + 'href': 'https://example.test/two_digit_date.json', + 'title': 'two_digit_date', + 'deprecated': True, + 'gee:replacement_id': 'replacement_id', + 'gee:removal_date': '2024-01-31T00:00:00Z', + }, + { + 'href': 'https://example.test/invalid_date.json', + 'title': 'invalid_date', + 'deprecated': True, + 'gee:replacement_id': 'replacement_id', + 'gee:removal_date': '20240131', + }, { 'href': 'https://example.test/learn_more_url_only.json', 'title': 'learn_more_url_only', @@ -83,6 +96,15 @@ r'Attention required for date_only! You are using a deprecated asset.\n' r'To ensure continued functionality, please update it by July 1, 2024.' ), + 'two_digit_date': ( + r'Attention required for two_digit_date! You are using a deprecated' + r' asset.\nTo ensure continued functionality, please update it by' + r' January 31, 2024.' + ), + 'invalid_date': ( + r'Attention required for invalid_date! You are using a deprecated' + r' asset.\nTo ensure continued functionality, please update it\.' + ), 'learn_more_url_only': ( r'Attention required for learn_more_url_only! You are using a' r' deprecated asset.\nTo ensure continued functionality, please update' @@ -123,38 +145,28 @@ def test_no_warnings_thrown_second_arg(self): with self.assertDoesNotWarn(): FakeClass().some_function('some-value', 'valid-asset') - @unittest.skip('Does not work on github') - @parameterized.named_parameters( - ('deprecated_asset', 'deprecated_asset'), - ('date_and_learn_more', 'date_and_learn_more'), - ('date_only', 'date_only'), - ('learn_more_url_only', 'learn_more_url_only'), - ) + @parameterized.named_parameters((k, k) for k in _EXPECTED_WARNINGS.keys()) def test_warning_thrown_args_init(self, asset_id: str): with self.assertWarnsRegex( DeprecationWarning, _EXPECTED_WARNINGS[asset_id] ): FakeClass(asset_id, 'some-value') - @unittest.skip('Does not work on github') def test_warning_thrown_args_instance_method(self): asset = 'deprecated_asset' with self.assertWarnsRegex(DeprecationWarning, _EXPECTED_WARNINGS[asset]): FakeClass().some_function('some-value', asset) - @unittest.skip('Does not work on github') def test_warning_thrown_kwargs_init(self): asset = 'deprecated_asset' with self.assertWarnsRegex(DeprecationWarning, _EXPECTED_WARNINGS[asset]): FakeClass(arg1=asset) - @unittest.skip('Does not work on github') def test_warning_thrown_kwargs_instance_method(self): asset = 'deprecated_asset' with self.assertWarnsRegex(DeprecationWarning, _EXPECTED_WARNINGS[asset]): FakeClass().some_function(arg2=asset) - @unittest.skip('Does not work on github') def test_same_warning_not_thrown(self): # Verifies the same warning message is not thrown twice. asset = 'deprecated_asset' diff --git a/python/ee/tests/image_test.py b/python/ee/tests/image_test.py index 034e15033..a5920907c 100644 --- a/python/ee/tests/image_test.py +++ b/python/ee/tests/image_test.py @@ -12,6 +12,9 @@ from ee import ee_exception from ee import serializer +EPSG_3857 = 'EPSG:3857' +EPSG_4326 = 'EPSG:4326' + # ee.Image('a').serialize() IMAGE = { 'functionInvocationValue': { @@ -283,7 +286,7 @@ def test_thumb_with_dimensions_region_crs(self): url = self.base_image.getThumbURL({ 'dimensions': [13, 42], 'region': self.geo_json, - 'crs': 'EPSG:4326', + 'crs': EPSG_4326, }) self.assertEqual('None/%s/thumbName:getPixels' % _cloud_api_utils.VERSION, @@ -294,7 +297,7 @@ def test_thumb_with_dimensions_region_crs(self): kwargs['body']['expression'], serializer.encode( self.base_image.setDefaultProjection( - crs='EPSG:4326', crsTransform=[1, 0, 0, 0, -1, 0] + crs=EPSG_4326, crsTransform=[1, 0, 0, 0, -1, 0] ).clipToBoundsAndScale( geometry=ee.Geometry(self.geo_json, geodesic=False), width=13, @@ -1371,21 +1374,21 @@ def test_ceil(self): self.assertEqual(expect, result) def test_change_proj(self): - src_proj = 'EPSG:3857' - dst_proj = 'EPSG:4326' + src_proj = EPSG_3857 + dst_proj = EPSG_4326 expect = make_expression_graph({ 'arguments': { 'input': IMAGE, 'srcProj': { 'functionInvocationValue': { 'functionName': 'Projection', - 'arguments': {'crs': {'constantValue': 'EPSG:3857'}}, + 'arguments': {'crs': {'constantValue': EPSG_3857}}, } }, 'dstProj': { 'functionInvocationValue': { 'functionName': 'Projection', - 'arguments': {'crs': {'constantValue': 'EPSG:4326'}}, + 'arguments': {'crs': {'constantValue': EPSG_4326}}, } }, }, @@ -1444,6 +1447,3306 @@ def test_classify(self): result = json.loads(expression.serialize()) self.assertEqual(expect, result) + def test_clip(self): + point = ee.Geometry.Point([1, 2]) + expect = make_expression_graph({ + 'arguments': { + 'input': IMAGE, + 'geometry': { + 'functionInvocationValue': { + 'functionName': 'GeometryConstructors.Point', + 'arguments': {'coordinates': {'constantValue': [1, 2]}}, + } + }, + }, + 'functionName': 'Image.clip', + }) + expression = ee.Image('a').clip(point) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').clip(clip_geometry=point) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_clip_to_bounds_and_scale(self): + point = ee.Geometry.Point([1, 2]) + width = 3 + height = 4 + max_dimension = 5 + scale = 6 + expect = make_expression_graph({ + 'arguments': { + 'input': IMAGE, + 'geometry': { + 'functionInvocationValue': { + 'functionName': 'GeometryConstructors.Point', + 'arguments': {'coordinates': {'constantValue': [1, 2]}}, + } + }, + 'width': {'constantValue': width}, + 'height': {'constantValue': height}, + 'maxDimension': {'constantValue': max_dimension}, + 'scale': {'constantValue': scale}, + }, + 'functionName': 'Image.clipToBoundsAndScale', + }) + expression = ee.Image('a').clipToBoundsAndScale( + point, width, height, max_dimension, scale + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').clipToBoundsAndScale( + geometry=point, + width=width, + height=height, + maxDimension=max_dimension, + scale=scale, + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_clip_to_collection(self): + featurecollection = ee.FeatureCollection(ee.Feature(None)) + expect = make_expression_graph({ + 'arguments': { + 'input': IMAGE, + 'collection': { + 'functionInvocationValue': { + 'functionName': 'Collection', + 'arguments': { + 'features': { + 'arrayValue': { + 'values': [{ + 'functionInvocationValue': { + 'functionName': 'Feature', + 'arguments': {}, + } + }] + } + } + }, + } + }, + }, + 'functionName': 'Image.clipToCollection', + }) + expression = ee.Image('a').clipToCollection(featurecollection) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').clipToCollection(collection=featurecollection) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_cluster(self): + clusterer = ee.Clusterer.wekaCobweb() + output_name = 'output name' + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'clusterer': { + 'functionInvocationValue': { + 'functionName': 'Clusterer.wekaCobweb', + 'arguments': {}, + } + }, + 'outputName': {'constantValue': output_name}, + }, + 'functionName': 'Image.cluster', + }) + expression = ee.Image('a').cluster(clusterer, output_name) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').cluster( + clusterer=clusterer, outputName=output_name + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_connected_components(self): + connectedness = ee.Kernel.square(1) + max_size = 2 + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'connectedness': { + 'functionInvocationValue': { + 'functionName': 'Kernel.square', + 'arguments': {'radius': {'constantValue': 1}}, + } + }, + 'maxSize': {'constantValue': max_size}, + }, + 'functionName': 'Image.connectedComponents', + }) + expression = ee.Image('a').connectedComponents(connectedness, max_size) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').connectedComponents( + connectedness=connectedness, maxSize=max_size + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_connected_pixel_count(self): + max_size = 1 + eight_connected = True + expect = make_expression_graph({ + 'arguments': { + 'input': IMAGE, + 'maxSize': {'constantValue': max_size}, + 'eightConnected': {'constantValue': eight_connected}, + }, + 'functionName': 'Image.connectedPixelCount', + }) + expression = ee.Image('a').connectedPixelCount(max_size, eight_connected) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').connectedPixelCount( + maxSize=max_size, eightConnected=eight_connected + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_constant(self): + value = 1 + expect = make_expression_graph({ + 'arguments': { + 'value': {'constantValue': value}, + }, + 'functionName': 'Image.constant', + }) + expression = ee.Image('a').constant(value) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image.constant(value=value) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_convolve(self): + kernel = ee.Kernel.square(1) + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'kernel': { + 'functionInvocationValue': { + 'functionName': 'Kernel.square', + 'arguments': {'radius': {'constantValue': 1}}, + } + }, + }, + 'functionName': 'Image.convolve', + }) + expression = ee.Image('a').convolve(kernel) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').convolve(kernel=kernel) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_copy_properties(self): + source = ee.Image('b') + properties = ['c', 'd'] + exclude = ['e', 'f'] + expect = make_expression_graph({ + 'arguments': { + 'destination': IMAGE, + 'source': IMAGE_B, + 'properties': {'constantValue': properties}, + 'exclude': {'constantValue': exclude}, + }, + 'functionName': 'Image.copyProperties', + }) + expression = ee.Image('a').copyProperties(source, properties, exclude) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').copyProperties( + source=source, properties=properties, exclude=exclude + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_cos(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.cos', + }) + expression = ee.Image('a').cos() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_cosh(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.cosh', + }) + expression = ee.Image('a').cosh() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_cumulative_cost(self): + source = 'b' + max_distance = 2 + geodetic_distance = 3 + expect = make_expression_graph({ + 'arguments': { + 'cost': IMAGE, + 'source': IMAGE_B, + 'maxDistance': {'constantValue': max_distance}, + 'geodeticDistance': {'constantValue': geodetic_distance}, + }, + 'functionName': 'Image.cumulativeCost', + }) + expression = ee.Image('a').cumulativeCost( + source, max_distance, geodetic_distance + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').cumulativeCost( + source=source, + maxDistance=max_distance, + geodeticDistance=geodetic_distance, + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_date(self): + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + }, + 'functionName': 'Image.date', + }) + expression = ee.Image('a').date() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_derivative(self): + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + }, + 'functionName': 'Image.derivative', + }) + expression = ee.Image('a').derivative() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_digamma(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.digamma', + }) + expression = ee.Image('a').digamma() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_directional_distance_transform(self): + angle = 1 + max_distance = 2 + label_band = 'label band' + expect = make_expression_graph({ + 'arguments': { + 'source': IMAGE, + 'angle': {'constantValue': angle}, + 'maxDistance': {'constantValue': max_distance}, + 'labelBand': {'constantValue': label_band}, + }, + 'functionName': 'Image.directionalDistanceTransform', + }) + expression = ee.Image('a').directionalDistanceTransform( + angle, max_distance, label_band + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').directionalDistanceTransform( + angle=angle, maxDistance=max_distance, labelBand=label_band + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_displace(self): + displacement = 'b' + mode = 'bilinear' + max_offset = 1 + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'displacement': IMAGE_B, + 'mode': {'constantValue': mode}, + 'maxOffset': {'constantValue': max_offset}, + }, + 'functionName': 'Image.displace', + }) + expression = ee.Image('a').displace(displacement, mode, max_offset) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').displace( + displacement=displacement, mode=mode, maxOffset=max_offset + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_displacement(self): + reference_image = 'b' + max_offset = 1 + projection = EPSG_4326 + patch_width = 2 + stiffness = 3 + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'referenceImage': IMAGE_B, + 'maxOffset': {'constantValue': max_offset}, + 'projection': { + 'functionInvocationValue': { + 'functionName': 'Projection', + 'arguments': {'crs': {'constantValue': projection}}, + } + }, + 'patchWidth': {'constantValue': patch_width}, + 'stiffness': {'constantValue': stiffness}, + }, + 'functionName': 'Image.displacement', + }) + expression = ee.Image('a').displacement( + reference_image, max_offset, projection, patch_width, stiffness + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').displacement( + referenceImage=reference_image, + maxOffset=max_offset, + projection=projection, + patchWidth=patch_width, + stiffness=stiffness, + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_distance(self): + kernel = ee.Kernel.square(1) + skip_masked = True + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'kernel': { + 'functionInvocationValue': { + 'functionName': 'Kernel.square', + 'arguments': {'radius': {'constantValue': 1}}, + } + }, + 'skipMasked': {'constantValue': skip_masked}, + }, + 'functionName': 'Image.distance', + }) + expression = ee.Image('a').distance(kernel, skip_masked) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').distance(kernel=kernel, skipMasked=skip_masked) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_divide(self): + image2 = 'b' + expect = make_expression_graph({ + 'arguments': { + 'image1': IMAGE, + 'image2': IMAGE_B, + }, + 'functionName': 'Image.divide', + }) + expression = ee.Image('a').divide(image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').divide(image2=image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_double(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.double', + }) + expression = ee.Image('a').double() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_entropy(self): + kernel = ee.Kernel.square(1) + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'kernel': { + 'functionInvocationValue': { + 'functionName': 'Kernel.square', + 'arguments': {'radius': {'constantValue': 1}}, + } + }, + }, + 'functionName': 'Image.entropy', + }) + expression = ee.Image('a').entropy(kernel) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').entropy(kernel=kernel) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_eq(self): + image2 = 'b' + expect = make_expression_graph({ + 'arguments': { + 'image1': IMAGE, + 'image2': IMAGE_B, + }, + 'functionName': 'Image.eq', + }) + expression = ee.Image('a').eq(image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').eq(image2=image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_erf(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.erf', + }) + expression = ee.Image('a').erf() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_erf_inv(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.erfInv', + }) + expression = ee.Image('a').erfInv() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_erfc(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.erfc', + }) + expression = ee.Image('a').erfc() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_erfc_inv(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.erfcInv', + }) + expression = ee.Image('a').erfcInv() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_exp(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.exp', + }) + expression = ee.Image('a').exp() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_fast_distance_transform(self): + neighborhood = 1 + units = 'pixels' + metric = 'manhattan' + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'neighborhood': {'constantValue': neighborhood}, + 'units': {'constantValue': units}, + 'metric': {'constantValue': metric}, + }, + 'functionName': 'Image.fastDistanceTransform', + }) + expression = ee.Image('a').fastDistanceTransform( + neighborhood, units, metric + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').fastDistanceTransform( + neighborhood=neighborhood, units=units, metric=metric + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_first(self): + image2 = 'b' + expect = make_expression_graph({ + 'arguments': { + 'image1': IMAGE, + 'image2': IMAGE_B, + }, + 'functionName': 'Image.first', + }) + expression = ee.Image('a').first(image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').first(image2=image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_first_non_zero(self): + image2 = 'b' + expect = make_expression_graph({ + 'arguments': { + 'image1': IMAGE, + 'image2': IMAGE_B, + }, + 'functionName': 'Image.firstNonZero', + }) + expression = ee.Image('a').firstNonZero(image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').firstNonZero(image2=image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_float(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.float', + }) + expression = ee.Image('a').float() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_floor(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.floor', + }) + expression = ee.Image('a').floor() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_focal_max(self): + radius = 1 + kernel_type = 'plus' + units = 'meters' + iterations = 2 + kernel = ee.Kernel.square(1) + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'radius': {'constantValue': radius}, + 'kernelType': {'constantValue': kernel_type}, + 'units': {'constantValue': units}, + 'iterations': {'constantValue': iterations}, + 'kernel': { + 'functionInvocationValue': { + 'functionName': 'Kernel.square', + 'arguments': {'radius': {'constantValue': 1}}, + } + }, + }, + 'functionName': 'Image.focalMax', + }) + expression = ee.Image('a').focalMax( + radius, kernel_type, units, iterations, kernel + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').focalMax( + radius=radius, + kernelType=kernel_type, + units=units, + iterations=iterations, + kernel=kernel, + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_focal_mean(self): + radius = 1 + kernel_type = 'plus' + units = 'meters' + iterations = 2 + kernel = ee.Kernel.square(1) + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'radius': {'constantValue': radius}, + 'kernelType': {'constantValue': kernel_type}, + 'units': {'constantValue': units}, + 'iterations': {'constantValue': iterations}, + 'kernel': { + 'functionInvocationValue': { + 'functionName': 'Kernel.square', + 'arguments': {'radius': {'constantValue': 1}}, + } + }, + }, + 'functionName': 'Image.focalMean', + }) + expression = ee.Image('a').focalMean( + radius, kernel_type, units, iterations, kernel + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').focalMean( + radius=radius, + kernelType=kernel_type, + units=units, + iterations=iterations, + kernel=kernel, + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_focal_median(self): + radius = 1 + kernel_type = 'plus' + units = 'meters' + iterations = 2 + kernel = ee.Kernel.square(1) + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'radius': {'constantValue': radius}, + 'kernelType': {'constantValue': kernel_type}, + 'units': {'constantValue': units}, + 'iterations': {'constantValue': iterations}, + 'kernel': { + 'functionInvocationValue': { + 'functionName': 'Kernel.square', + 'arguments': {'radius': {'constantValue': 1}}, + } + }, + }, + 'functionName': 'Image.focalMedian', + }) + expression = ee.Image('a').focalMedian( + radius, kernel_type, units, iterations, kernel + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').focalMedian( + radius=radius, + kernelType=kernel_type, + units=units, + iterations=iterations, + kernel=kernel, + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_focal_min(self): + radius = 1 + kernel_type = 'plus' + units = 'meters' + iterations = 2 + kernel = ee.Kernel.square(1) + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'radius': {'constantValue': radius}, + 'kernelType': {'constantValue': kernel_type}, + 'units': {'constantValue': units}, + 'iterations': {'constantValue': iterations}, + 'kernel': { + 'functionInvocationValue': { + 'functionName': 'Kernel.square', + 'arguments': {'radius': {'constantValue': 1}}, + } + }, + }, + 'functionName': 'Image.focalMin', + }) + expression = ee.Image('a').focalMin( + radius, kernel_type, units, iterations, kernel + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').focalMin( + radius=radius, + kernelType=kernel_type, + units=units, + iterations=iterations, + kernel=kernel, + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_focal_mode(self): + radius = 1 + kernel_type = 'plus' + units = 'meters' + iterations = 2 + kernel = ee.Kernel.square(1) + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'radius': {'constantValue': radius}, + 'kernelType': {'constantValue': kernel_type}, + 'units': {'constantValue': units}, + 'iterations': {'constantValue': iterations}, + 'kernel': { + 'functionInvocationValue': { + 'functionName': 'Kernel.square', + 'arguments': {'radius': {'constantValue': 1}}, + } + }, + }, + 'functionName': 'Image.focalMode', + }) + expression = ee.Image('a').focalMode( + radius, kernel_type, units, iterations, kernel + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').focalMode( + radius=radius, + kernelType=kernel_type, + units=units, + iterations=iterations, + kernel=kernel, + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_gamma(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.gamma', + }) + expression = ee.Image('a').gamma() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_gammainc(self): + image2 = 'b' + expect = make_expression_graph({ + 'arguments': { + 'image1': IMAGE, + 'image2': IMAGE_B, + }, + 'functionName': 'Image.gammainc', + }) + expression = ee.Image('a').gammainc(image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').gammainc(image2=image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_geometry(self): + max_error = 1 + proj = EPSG_4326 + geodesics = True + expect = make_expression_graph({ + 'arguments': { + 'feature': IMAGE, + 'maxError': { + 'functionInvocationValue': { + 'functionName': 'ErrorMargin', + 'arguments': {'value': {'constantValue': 1}}, + } + }, + 'proj': { + 'functionInvocationValue': { + 'functionName': 'Projection', + 'arguments': {'crs': {'constantValue': proj}}, + } + }, + 'geodesics': {'constantValue': geodesics}, + }, + 'functionName': 'Image.geometry', + }) + expression = ee.Image('a').geometry(max_error, proj, geodesics) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').geometry( + maxError=max_error, proj=proj, geodesics=geodesics + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_glcm_texture(self): + size = 1 + kernel = ee.Kernel.square(1) + average = True + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'size': {'constantValue': size}, + 'kernel': { + 'functionInvocationValue': { + 'functionName': 'Kernel.square', + 'arguments': {'radius': {'constantValue': 1}}, + } + }, + 'average': {'constantValue': average}, + }, + 'functionName': 'Image.glcmTexture', + }) + expression = ee.Image('a').glcmTexture(size, kernel, average) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').glcmTexture( + size=size, kernel=kernel, average=average + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_gradient(self): + expect = make_expression_graph({ + 'arguments': { + 'input': IMAGE, + }, + 'functionName': 'Image.gradient', + }) + expression = ee.Image('a').gradient() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_gt(self): + image2 = 'b' + expect = make_expression_graph({ + 'arguments': { + 'image1': IMAGE, + 'image2': IMAGE_B, + }, + 'functionName': 'Image.gt', + }) + expression = ee.Image('a').gt(image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').gt(image2=image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_gte(self): + image2 = 'b' + expect = make_expression_graph({ + 'arguments': { + 'image1': IMAGE, + 'image2': IMAGE_B, + }, + 'functionName': 'Image.gte', + }) + expression = ee.Image('a').gte(image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').gte(image2=image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_hers_descriptor(self): + selectors = ['b', 'c'] + buckets = 1 + peak_width_scale = 2 + expect = make_expression_graph({ + 'arguments': { + 'element': IMAGE, + 'selectors': {'constantValue': selectors}, + 'buckets': {'constantValue': buckets}, + 'peakWidthScale': {'constantValue': peak_width_scale}, + }, + 'functionName': 'Image.hersDescriptor', + }) + expression = ee.Image('a').hersDescriptor( + selectors, buckets, peak_width_scale + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').hersDescriptor( + selectors=selectors, buckets=buckets, peakWidthScale=peak_width_scale + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_hers_feature(self): + reference = {'b': 'c'} + peak_width_scale = 1 + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'reference': {'constantValue': reference}, + 'peakWidthScale': {'constantValue': peak_width_scale}, + }, + 'functionName': 'Image.hersFeature', + }) + expression = ee.Image('a').hersFeature(reference, peak_width_scale) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').hersFeature( + reference=reference, peakWidthScale=peak_width_scale + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_hers_image(self): + image2 = 'b' + radius = 1 + buckets = 2 + peak_width_scale = 3 + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'image2': IMAGE_B, + 'radius': {'constantValue': radius}, + 'buckets': {'constantValue': buckets}, + 'peakWidthScale': {'constantValue': peak_width_scale}, + }, + 'functionName': 'Image.hersImage', + }) + expression = ee.Image('a').hersImage( + image2, radius, buckets, peak_width_scale + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').hersImage( + image2=image2, + radius=radius, + buckets=buckets, + peakWidthScale=peak_width_scale, + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_hsv_to_rgb(self): + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + }, + 'functionName': 'Image.hsvToRgb', + }) + expression = ee.Image('a').hsvToRgb() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_hypot(self): + image2 = 'b' + expect = make_expression_graph({ + 'arguments': { + 'image1': IMAGE, + 'image2': IMAGE_B, + }, + 'functionName': 'Image.hypot', + }) + expression = ee.Image('a').hypot(image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').hypot(image2=image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_id(self): + expect = make_expression_graph({ + 'arguments': { + 'element': IMAGE, + }, + 'functionName': 'Image.id', + }) + expression = ee.Image('a').id() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_int(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.int', + }) + expression = ee.Image('a').int() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_int16(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.int16', + }) + expression = ee.Image('a').int16() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_int32(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.int32', + }) + expression = ee.Image('a').int32() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_int64(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.int64', + }) + expression = ee.Image('a').int64() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_int8(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.int8', + }) + expression = ee.Image('a').int8() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_interpolate(self): + x = [1, 2] + y = [3, 4] + behavior = 'clamp' + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'x': {'constantValue': x}, + 'y': {'constantValue': y}, + 'behavior': {'constantValue': behavior}, + }, + 'functionName': 'Image.interpolate', + }) + expression = ee.Image('a').interpolate(x, y, behavior) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').interpolate(x=x, y=y, behavior=behavior) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_lanczos(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.lanczos', + }) + expression = ee.Image('a').lanczos() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_left_shift(self): + image2 = 'b' + expect = make_expression_graph({ + 'arguments': { + 'image1': IMAGE, + 'image2': IMAGE_B, + }, + 'functionName': 'Image.leftShift', + }) + expression = ee.Image('a').leftShift(image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').leftShift(image2=image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_link_collection(self): + image_collection = ee.ImageCollection('b') + linked_bands = 'a band' + linked_properties = 'a property' + match_property_name = 'a match property name' + expect = make_expression_graph({ + 'arguments': { + 'input': IMAGE, + 'imageCollection': { + 'functionInvocationValue': { + 'functionName': 'ImageCollection.load', + 'arguments': {'id': {'constantValue': 'b'}}, + } + }, + 'linkedBands': {'constantValue': linked_bands}, + 'linkedProperties': {'constantValue': linked_properties}, + 'matchPropertyName': {'constantValue': match_property_name}, + }, + 'functionName': 'Image.linkCollection', + }) + expression = ee.Image('a').linkCollection( + image_collection, linked_bands, linked_properties, match_property_name + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').linkCollection( + imageCollection=image_collection, + linkedBands=linked_bands, + linkedProperties=linked_properties, + matchPropertyName=match_property_name, + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_load(self): + asset_id = 'a' + version = 1 + expect = make_expression_graph({ + 'arguments': { + 'id': {'constantValue': asset_id}, + 'version': {'constantValue': version}, + }, + 'functionName': 'Image.load', + }) + expression = ee.Image.load(asset_id, version) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image.load(id=asset_id, version=version) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_load_geotiff(self): + uri = 'a' + expect = make_expression_graph({ + 'arguments': { + 'uri': {'constantValue': uri}, + }, + 'functionName': 'Image.loadGeoTIFF', + }) + expression = ee.Image.loadGeoTIFF(uri) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').loadGeoTIFF(uri=uri) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_log(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.log', + }) + expression = ee.Image('a').log() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_log10(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.log10', + }) + expression = ee.Image('a').log10() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_long(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.long', + }) + expression = ee.Image('a').long() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_lt(self): + image2 = 'b' + expect = make_expression_graph({ + 'arguments': { + 'image1': IMAGE, + 'image2': IMAGE_B, + }, + 'functionName': 'Image.lt', + }) + expression = ee.Image('a').lt(image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').lt(image2=image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_lte(self): + image2 = 'b' + expect = make_expression_graph({ + 'arguments': { + 'image1': IMAGE, + 'image2': IMAGE_B, + }, + 'functionName': 'Image.lte', + }) + expression = ee.Image('a').lte(image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').lte(image2=image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_mask(self): + mask = 'b' + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'mask': IMAGE_B, + }, + 'functionName': 'Image.mask', + }) + expression = ee.Image('a').mask(mask) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').mask(mask=mask) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_matrix_cholesky_decomposition(self): + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + }, + 'functionName': 'Image.matrixCholeskyDecomposition', + }) + expression = ee.Image('a').matrixCholeskyDecomposition() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_matrix_determinant(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.matrixDeterminant', + }) + expression = ee.Image('a').matrixDeterminant() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_matrix_diagonal(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.matrixDiagonal', + }) + expression = ee.Image('a').matrixDiagonal() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_matrix_fnorm(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.matrixFnorm', + }) + expression = ee.Image('a').matrixFnorm() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_matrix_identity(self): + size = 1 + expect = make_expression_graph({ + 'arguments': { + 'size': {'constantValue': size}, + }, + 'functionName': 'Image.matrixIdentity', + }) + expression = ee.Image.matrixIdentity(size) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_matrix_inverse(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.matrixInverse', + }) + expression = ee.Image('a').matrixInverse() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_matrix_lu_decomposition(self): + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + }, + 'functionName': 'Image.matrixLUDecomposition', + }) + expression = ee.Image('a').matrixLUDecomposition() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_matrix_multiply(self): + image2 = 'b' + expect = make_expression_graph({ + 'arguments': { + 'image1': IMAGE, + 'image2': IMAGE_B, + }, + 'functionName': 'Image.matrixMultiply', + }) + expression = ee.Image('a').matrixMultiply(image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').matrixMultiply(image2=image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_matrix_pseudo_inverse(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.matrixPseudoInverse', + }) + expression = ee.Image('a').matrixPseudoInverse() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_matrix_qr_decomposition(self): + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + }, + 'functionName': 'Image.matrixQRDecomposition', + }) + expression = ee.Image('a').matrixQRDecomposition() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_matrix_singular_value_decomposition(self): + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + }, + 'functionName': 'Image.matrixSingularValueDecomposition', + }) + expression = ee.Image('a').matrixSingularValueDecomposition() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_matrix_solve(self): + image2 = 'b' + expect = make_expression_graph({ + 'arguments': { + 'image1': IMAGE, + 'image2': IMAGE_B, + }, + 'functionName': 'Image.matrixSolve', + }) + expression = ee.Image('a').matrixSolve(image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').matrixSolve(image2=image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_matrix_to_diag(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.matrixToDiag', + }) + expression = ee.Image('a').matrixToDiag() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_matrix_trace(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.matrixTrace', + }) + expression = ee.Image('a').matrixTrace() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_matrix_transpose(self): + axis1 = 1 + axis2 = 2 + expect = make_expression_graph({ + 'arguments': { + 'input': IMAGE, + 'axis1': {'constantValue': axis1}, + 'axis2': {'constantValue': axis2}, + }, + 'functionName': 'Image.matrixTranspose', + }) + expression = ee.Image('a').matrixTranspose(axis1, axis2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').matrixTranspose(axis1=axis1, axis2=axis2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_max(self): + image2 = 'b' + expect = make_expression_graph({ + 'arguments': { + 'image1': IMAGE, + 'image2': IMAGE_B, + }, + 'functionName': 'Image.max', + }) + expression = ee.Image('a').max(image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').max(image2=image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_medial_axis(self): + neighborhood = 1 + units = 'pixels' + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'neighborhood': {'constantValue': neighborhood}, + 'units': {'constantValue': units}, + }, + 'functionName': 'Image.medialAxis', + }) + expression = ee.Image('a').medialAxis(neighborhood, units) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').medialAxis( + neighborhood=neighborhood, units=units + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_metadata(self): + property = 'a property' + name = 'a name' + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'property': {'constantValue': property}, + 'name': {'constantValue': name}, + }, + 'functionName': 'Image.metadata', + }) + expression = ee.Image('a').metadata(property, name) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').metadata(property=property, name=name) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_min(self): + image2 = 'b' + expect = make_expression_graph({ + 'arguments': { + 'image1': IMAGE, + 'image2': IMAGE_B, + }, + 'functionName': 'Image.min', + }) + expression = ee.Image('a').min(image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').min(image2=image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_mod(self): + image2 = 'b' + expect = make_expression_graph({ + 'arguments': { + 'image1': IMAGE, + 'image2': IMAGE_B, + }, + 'functionName': 'Image.mod', + }) + expression = ee.Image('a').mod(image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').mod(image2=image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_multiply(self): + image2 = 'b' + expect = make_expression_graph({ + 'arguments': { + 'image1': IMAGE, + 'image2': IMAGE_B, + }, + 'functionName': 'Image.multiply', + }) + expression = ee.Image('a').multiply(image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').multiply(image2=image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_neighborhood_to_array(self): + kernel = ee.Kernel.square(1) + default_value = 1 + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'kernel': { + 'functionInvocationValue': { + 'functionName': 'Kernel.square', + 'arguments': {'radius': {'constantValue': 1}}, + } + }, + 'defaultValue': {'constantValue': default_value}, + }, + 'functionName': 'Image.neighborhoodToArray', + }) + expression = ee.Image('a').neighborhoodToArray(kernel, default_value) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').neighborhoodToArray( + kernel=kernel, defaultValue=default_value + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_neighborhood_to_bands(self): + kernel = ee.Kernel.square(1) + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'kernel': { + 'functionInvocationValue': { + 'functionName': 'Kernel.square', + 'arguments': {'radius': {'constantValue': 1}}, + } + }, + }, + 'functionName': 'Image.neighborhoodToBands', + }) + expression = ee.Image('a').neighborhoodToBands(kernel) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').neighborhoodToBands(kernel=kernel) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_neq(self): + image2 = 'b' + expect = make_expression_graph({ + 'arguments': { + 'image1': IMAGE, + 'image2': IMAGE_B, + }, + 'functionName': 'Image.neq', + }) + expression = ee.Image('a').neq(image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').neq(image2=image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_normalized_difference(self): + band_names = ['b', 'c'] + expect = make_expression_graph({ + 'arguments': { + 'input': IMAGE, + 'bandNames': {'constantValue': band_names}, + }, + 'functionName': 'Image.normalizedDifference', + }) + expression = ee.Image('a').normalizedDifference(band_names) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').normalizedDifference(bandNames=band_names) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_not(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.not', + }) + expression = ee.Image('a').Not() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_or(self): + image2 = 'b' + expect = make_expression_graph({ + 'arguments': { + 'image1': IMAGE, + 'image2': IMAGE_B, + }, + 'functionName': 'Image.or', + }) + expression = ee.Image('a').Or(image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').Or(image2=image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_paint(self): + featurecollection = ee.FeatureCollection('b') + color = 'cadetblue' + width = 1 + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'featureCollection': { + 'functionInvocationValue': { + 'functionName': 'Collection.loadTable', + 'arguments': {'tableId': {'constantValue': 'b'}}, + } + }, + 'color': {'constantValue': color}, + 'width': {'constantValue': width}, + }, + 'functionName': 'Image.paint', + }) + expression = ee.Image('a').paint(featurecollection, color, width) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').paint( + featureCollection=featurecollection, color=color, width=width + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_pixel_coordinates(self): + projection = EPSG_4326 + expect = make_expression_graph({ + 'arguments': { + 'projection': { + 'functionInvocationValue': { + 'functionName': 'Projection', + 'arguments': {'crs': {'constantValue': projection}}, + } + } + }, + 'functionName': 'Image.pixelCoordinates', + }) + expression = ee.Image('a').pixelCoordinates(projection) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').pixelCoordinates(projection=projection) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_polynomial(self): + coefficients = [1, 2] + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'coefficients': {'constantValue': coefficients}, + }, + 'functionName': 'Image.polynomial', + }) + expression = ee.Image('a').polynomial(coefficients) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').polynomial(coefficients=coefficients) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_pow(self): + image2 = 'b' + expect = make_expression_graph({ + 'arguments': { + 'image1': IMAGE, + 'image2': IMAGE_B, + }, + 'functionName': 'Image.pow', + }) + expression = ee.Image('a').pow(image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').pow(image2=image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_projection(self): + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + }, + 'functionName': 'Image.projection', + }) + expression = ee.Image('a').projection() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_random(self): + seed = 1 + distribution = 'normal' + expect = make_expression_graph({ + 'arguments': { + 'seed': {'constantValue': seed}, + 'distribution': {'constantValue': distribution}, + }, + 'functionName': 'Image.random', + }) + expression = ee.Image.random(seed, distribution) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image().random(seed=seed, distribution=distribution) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_random_visualizer(self): + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + }, + 'functionName': 'Image.randomVisualizer', + }) + expression = ee.Image('a').randomVisualizer() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_reduce(self): + reducer = ee.Reducer.sum() + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'reducer': { + 'functionInvocationValue': { + 'functionName': 'Reducer.sum', + 'arguments': {}, + } + }, + }, + 'functionName': 'Image.reduce', + }) + expression = ee.Image('a').reduce(reducer) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').reduce(reducer=reducer) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_reduce_connected_components(self): + reducer = ee.Reducer.sum() + label_band = 'b' + max_size = 1 + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'reducer': { + 'functionInvocationValue': { + 'functionName': 'Reducer.sum', + 'arguments': {}, + } + }, + 'labelBand': {'constantValue': label_band}, + 'maxSize': {'constantValue': max_size}, + }, + 'functionName': 'Image.reduceConnectedComponents', + }) + expression = ee.Image('a').reduceConnectedComponents( + reducer, label_band, max_size + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').reduceConnectedComponents( + reducer=reducer, labelBand=label_band, maxSize=max_size + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_reduce_neighborhood(self): + reducer = ee.Reducer.sum() + kernel = ee.Kernel.square(1) + input_weight = 'mask' + skip_masked = True + optimization = 'boxcar' + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'reducer': { + 'functionInvocationValue': { + 'functionName': 'Reducer.sum', + 'arguments': {}, + } + }, + 'kernel': { + 'functionInvocationValue': { + 'functionName': 'Kernel.square', + 'arguments': {'radius': {'constantValue': 1}}, + } + }, + 'inputWeight': {'constantValue': input_weight}, + 'skipMasked': {'constantValue': skip_masked}, + 'optimization': {'constantValue': optimization}, + }, + 'functionName': 'Image.reduceNeighborhood', + }) + expression = ee.Image('a').reduceNeighborhood( + reducer, kernel, input_weight, skip_masked, optimization + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').reduceNeighborhood( + reducer=reducer, + kernel=kernel, + inputWeight=input_weight, + skipMasked=skip_masked, + optimization=optimization, + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_reduce_region(self): + reducer = ee.Reducer.sum() + geometry = ee.Geometry.Point([1, 2]) + scale = 1 + crs = EPSG_4326 + crs_transform = [3, 4, 5, 6, 7, 8] + best_effort = True + max_pixels = 9 + tile_scale = 10 + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'reducer': { + 'functionInvocationValue': { + 'functionName': 'Reducer.sum', + 'arguments': {}, + } + }, + 'geometry': { + 'functionInvocationValue': { + 'functionName': 'GeometryConstructors.Point', + 'arguments': {'coordinates': {'constantValue': [1, 2]}}, + } + }, + 'scale': {'constantValue': scale}, + 'crs': { + 'functionInvocationValue': { + 'functionName': 'Projection', + 'arguments': {'crs': {'constantValue': crs}}, + } + }, + 'crsTransform': {'constantValue': crs_transform}, + 'bestEffort': {'constantValue': best_effort}, + 'maxPixels': {'constantValue': max_pixels}, + 'tileScale': {'constantValue': tile_scale}, + }, + 'functionName': 'Image.reduceRegion', + }) + expression = ee.Image('a').reduceRegion( + reducer, + geometry, + scale, + crs, + crs_transform, + best_effort, + max_pixels, + tile_scale, + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').reduceRegion( + reducer=reducer, + geometry=geometry, + scale=scale, + crs=crs, + crsTransform=crs_transform, + bestEffort=best_effort, + maxPixels=max_pixels, + tileScale=tile_scale, + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_reduce_regions(self): + reducer = ee.Reducer.sum() + featurecollection = ee.FeatureCollection(ee.Feature(None)) + scale = 1 + crs = EPSG_4326 + crs_transform = [3, 4, 5, 6, 7, 8] + tile_scale = 10 + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'collection': { + 'functionInvocationValue': { + 'functionName': 'Collection', + 'arguments': { + 'features': { + 'arrayValue': { + 'values': [{ + 'functionInvocationValue': { + 'functionName': 'Feature', + 'arguments': {}, + } + }] + } + } + }, + } + }, + 'reducer': { + 'functionInvocationValue': { + 'functionName': 'Reducer.sum', + 'arguments': {}, + } + }, + 'scale': {'constantValue': scale}, + 'crs': { + 'functionInvocationValue': { + 'functionName': 'Projection', + 'arguments': {'crs': {'constantValue': crs}}, + } + }, + 'crsTransform': {'constantValue': crs_transform}, + 'tileScale': {'constantValue': tile_scale}, + }, + 'functionName': 'Image.reduceRegions', + }) + expression = ee.Image('a').reduceRegions( + featurecollection, reducer, scale, crs, crs_transform, tile_scale + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').reduceRegions( + collection=featurecollection, + reducer=reducer, + scale=scale, + crs=crs, + crsTransform=crs_transform, + tileScale=tile_scale, + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_reduce_resolution(self): + reducer = ee.Reducer.sum() + best_effort = True + max_pixels = 1 + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'reducer': { + 'functionInvocationValue': { + 'functionName': 'Reducer.sum', + 'arguments': {}, + } + }, + 'bestEffort': {'constantValue': best_effort}, + 'maxPixels': {'constantValue': max_pixels}, + }, + 'functionName': 'Image.reduceResolution', + }) + expression = ee.Image('a').reduceResolution( + reducer, best_effort, max_pixels + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').reduceResolution( + reducer=reducer, bestEffort=best_effort, maxPixels=max_pixels + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_reduce_to_vectors(self): + reducer = ee.Reducer.sum() + geometry = ee.Geometry.Point([1, 2]) + scale = 3 + geometry_type = 'bb' + eight_connected = True + label_property = 'a label property' + crs = EPSG_4326 + crs_transform = [4, 5, 6, 7, 8, 9] + best_effort = True + max_pixels = 10 + tile_scale = 11 + geometry_in_native_projection = True + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'reducer': { + 'functionInvocationValue': { + 'functionName': 'Reducer.sum', + 'arguments': {}, + } + }, + 'geometry': { + 'functionInvocationValue': { + 'functionName': 'GeometryConstructors.Point', + 'arguments': {'coordinates': {'constantValue': [1, 2]}}, + } + }, + 'scale': {'constantValue': scale}, + 'geometryType': {'constantValue': geometry_type}, + 'eightConnected': {'constantValue': eight_connected}, + 'labelProperty': {'constantValue': label_property}, + 'crs': { + 'functionInvocationValue': { + 'functionName': 'Projection', + 'arguments': {'crs': {'constantValue': crs}}, + } + }, + 'crsTransform': {'constantValue': crs_transform}, + 'bestEffort': {'constantValue': best_effort}, + 'maxPixels': {'constantValue': max_pixels}, + 'tileScale': {'constantValue': tile_scale}, + 'geometryInNativeProjection': { + 'constantValue': geometry_in_native_projection + }, + }, + 'functionName': 'Image.reduceToVectors', + }) + expression = ee.Image('a').reduceToVectors( + reducer, + geometry, + scale, + geometry_type, + eight_connected, + label_property, + crs, + crs_transform, + best_effort, + max_pixels, + tile_scale, + geometry_in_native_projection, + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').reduceToVectors( + reducer=reducer, + geometry=geometry, + scale=scale, + geometryType=geometry_type, + eightConnected=eight_connected, + labelProperty=label_property, + crs=crs, + crsTransform=crs_transform, + bestEffort=best_effort, + maxPixels=max_pixels, + tileScale=tile_scale, + geometryInNativeProjection=geometry_in_native_projection, + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_regexp_rename(self): + regex = 'a regex' + replacement = 'a replacement' + all = True + expect = make_expression_graph({ + 'arguments': { + 'input': IMAGE, + 'regex': {'constantValue': regex}, + 'replacement': {'constantValue': replacement}, + 'all': {'constantValue': all}, + }, + 'functionName': 'Image.regexpRename', + }) + expression = ee.Image('a').regexpRename(regex, replacement, all) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').regexpRename( + regex=regex, replacement=replacement, all=all + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_register(self): + reference_image = 'b' + max_offset = 1 + patch_width = 2 + stiffness = 3 + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'referenceImage': IMAGE_B, + 'maxOffset': {'constantValue': max_offset}, + 'patchWidth': {'constantValue': patch_width}, + 'stiffness': {'constantValue': stiffness}, + }, + 'functionName': 'Image.register', + }) + expression = ee.Image('a').register( + reference_image, max_offset, patch_width, stiffness + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').register( + referenceImage=reference_image, + maxOffset=max_offset, + patchWidth=patch_width, + stiffness=stiffness, + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_remap(self): + # `from` is a reserved word. + from_list = [1, 2] + to = [3, 4] + default_value = 5 + band_name = 'a band name' + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'from': {'constantValue': from_list}, + 'to': {'constantValue': to}, + 'defaultValue': {'constantValue': default_value}, + 'bandName': {'constantValue': band_name}, + }, + 'functionName': 'Image.remap', + }) + expression = ee.Image('a').remap(from_list, to, default_value, band_name) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').remap( + to=to, + defaultValue=default_value, + bandName=band_name, + **{'from': from_list} + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_rename(self): + names = ['b', 'c'] + expect = make_expression_graph({ + 'arguments': { + 'input': IMAGE, + 'names': {'constantValue': names}, + }, + 'functionName': 'Image.rename', + }) + expression = ee.Image('a').rename(names) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + # var_args, so no kwargs + + def test_reproject(self): + crs = EPSG_4326 + crs_transform = [1, 2, 3, 4, 5, 6] + scale = 7 + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'crs': { + 'functionInvocationValue': { + 'functionName': 'Projection', + 'arguments': {'crs': {'constantValue': crs}}, + } + }, + 'crsTransform': {'constantValue': crs_transform}, + 'scale': {'constantValue': scale}, + }, + 'functionName': 'Image.reproject', + }) + expression = ee.Image('a').reproject(crs, crs_transform, scale) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').reproject( + crs=crs, crsTransform=crs_transform, scale=scale + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_resample(self): + mode = 'bicubic' + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'mode': {'constantValue': mode}, + }, + 'functionName': 'Image.resample', + }) + expression = ee.Image('a').resample(mode) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').resample(mode=mode) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_rgb_to_hsv(self): + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + }, + 'functionName': 'Image.rgbToHsv', + }) + expression = ee.Image('a').rgbToHsv() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_right_shift(self): + image2 = 'b' + expect = make_expression_graph({ + 'arguments': { + 'image1': IMAGE, + 'image2': IMAGE_B, + }, + 'functionName': 'Image.rightShift', + }) + expression = ee.Image('a').rightShift(image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').rightShift(image2=image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_round(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.round', + }) + expression = ee.Image('a').round() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_rsed_transform(self): + neighborhood = 1 + units = 'pixels' + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'neighborhood': {'constantValue': neighborhood}, + 'units': {'constantValue': units}, + }, + 'functionName': 'Image.rsedTransform', + }) + expression = ee.Image('a').rsedTransform(neighborhood, units) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').rsedTransform( + neighborhood=neighborhood, units=units + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_sample(self): + region = ee.Geometry.Point([1, 2]) + scale = 3 + projection = EPSG_4326 + factor = 4 + num_pixels = 5 + seed = 6 + drop_nulls = True + tile_scale = 7 + geometries = False + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'region': { + 'functionInvocationValue': { + 'functionName': 'GeometryConstructors.Point', + 'arguments': {'coordinates': {'constantValue': [1, 2]}}, + } + }, + 'scale': {'constantValue': scale}, + 'projection': { + 'functionInvocationValue': { + 'functionName': 'Projection', + 'arguments': {'crs': {'constantValue': projection}}, + } + }, + 'factor': {'constantValue': factor}, + 'numPixels': {'constantValue': num_pixels}, + 'seed': {'constantValue': seed}, + 'dropNulls': {'constantValue': drop_nulls}, + 'tileScale': {'constantValue': tile_scale}, + 'geometries': {'constantValue': geometries}, + }, + 'functionName': 'Image.sample', + }) + expression = ee.Image('a').sample( + region, + scale, + projection, + factor, + num_pixels, + seed, + drop_nulls, + tile_scale, + geometries, + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').sample( + region=region, + scale=scale, + projection=projection, + factor=factor, + numPixels=num_pixels, + seed=seed, + dropNulls=drop_nulls, + tileScale=tile_scale, + geometries=geometries, + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_sample_rectangle(self): + point = [1, 2] + region = ee.Geometry.Point(point) + properties = ['b', 'c'] + default_value = 3 + default_array_value = [4, 5] + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'region': { + 'functionInvocationValue': { + 'functionName': 'GeometryConstructors.Point', + 'arguments': {'coordinates': {'constantValue': point}}, + } + }, + 'properties': {'constantValue': properties}, + 'defaultValue': {'constantValue': default_value}, + 'defaultArrayValue': { + 'functionInvocationValue': { + 'functionName': 'Array', + 'arguments': { + 'values': {'constantValue': default_array_value} + }, + } + }, + }, + 'functionName': 'Image.sampleRectangle', + }) + expression = ee.Image('a').sampleRectangle( + region, properties, default_value, default_array_value + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').sampleRectangle( + region=region, + properties=properties, + defaultValue=default_value, + defaultArrayValue=default_array_value, + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_sample_regions(self): + featurecollection = ee.FeatureCollection(ee.Feature(None)) + properties = ['b', 'c'] + scale = 3 + projection = EPSG_4326 + tile_scale = 4 + geometries = False + + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'collection': { + 'functionInvocationValue': { + 'functionName': 'Collection', + 'arguments': { + 'features': { + 'arrayValue': { + 'values': [{ + 'functionInvocationValue': { + 'functionName': 'Feature', + 'arguments': {}, + } + }] + } + } + }, + } + }, + 'geometries': {'constantValue': geometries}, + 'projection': { + 'functionInvocationValue': { + 'functionName': 'Projection', + 'arguments': {'crs': {'constantValue': projection}}, + } + }, + 'properties': {'constantValue': properties}, + 'scale': {'constantValue': scale}, + 'tileScale': {'constantValue': tile_scale}, + }, + 'functionName': 'Image.sampleRegions', + }) + expression = ee.Image('a').sampleRegions( + featurecollection, properties, scale, projection, tile_scale, geometries + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').sampleRegions( + collection=featurecollection, + properties=properties, + scale=scale, + projection=projection, + tileScale=tile_scale, + geometries=geometries, + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_select(self): + band_selectors = ['b', 'c'] + new_names = ['d', 'e'] + expect = make_expression_graph({ + 'arguments': { + 'input': IMAGE, + 'bandSelectors': {'constantValue': band_selectors}, + 'newNames': {'constantValue': new_names}, + }, + 'functionName': 'Image.select', + }) + expression = ee.Image('a').select(band_selectors, new_names) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + # var_args, so now kwargs. + + def test_self_mask(self): + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + }, + 'functionName': 'Image.selfMask', + }) + expression = ee.Image('a').selfMask() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_set_default_projection(self): + crs = EPSG_4326 + crs_transform = [1, 2, 3, 4, 5, 6] + scale = 7 + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'crs': { + 'functionInvocationValue': { + 'functionName': 'Projection', + 'arguments': {'crs': {'constantValue': crs}}, + } + }, + 'crsTransform': {'constantValue': crs_transform}, + 'scale': {'constantValue': scale}, + }, + 'functionName': 'Image.setDefaultProjection', + }) + expression = ee.Image('a').setDefaultProjection(crs, crs_transform, scale) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').setDefaultProjection( + crs=crs, crsTransform=crs_transform, scale=scale + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_short(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.short', + }) + expression = ee.Image('a').short() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_signum(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.signum', + }) + expression = ee.Image('a').signum() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_sin(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.sin', + }) + expression = ee.Image('a').sin() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_sinh(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.sinh', + }) + expression = ee.Image('a').sinh() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_sld_style(self): + sld_xml = 'some xml' + expect = make_expression_graph({ + 'arguments': { + 'input': IMAGE, + 'sldXml': {'constantValue': sld_xml}, + }, + 'functionName': 'Image.sldStyle', + }) + expression = ee.Image('a').sldStyle(sld_xml) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').sldStyle(sldXml=sld_xml) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_slice(self): + start = 1 + end = 2 + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'start': {'constantValue': start}, + 'end': {'constantValue': end}, + }, + 'functionName': 'Image.slice', + }) + expression = ee.Image('a').slice(start, end) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').slice(start=start, end=end) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_spectral_dilation(self): + metric = 'sid' + kernel = ee.Kernel.square(1) + use_centroid = True + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'metric': {'constantValue': metric}, + 'kernel': { + 'functionInvocationValue': { + 'functionName': 'Kernel.square', + 'arguments': {'radius': {'constantValue': 1}}, + } + }, + 'useCentroid': {'constantValue': use_centroid}, + }, + 'functionName': 'Image.spectralDilation', + }) + expression = ee.Image('a').spectralDilation(metric, kernel, use_centroid) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').spectralDilation( + metric=metric, kernel=kernel, useCentroid=use_centroid + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_spectral_distance(self): + image2 = 'b' + metric = 'emd' + expect = make_expression_graph({ + 'arguments': { + 'image1': IMAGE, + 'image2': IMAGE_B, + 'metric': {'constantValue': metric}, + }, + 'functionName': 'Image.spectralDistance', + }) + expression = ee.Image('a').spectralDistance(image2, metric) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').spectralDistance(image2=image2, metric=metric) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_spectral_erosion(self): + metric = 'sid' + kernel = ee.Kernel.square(1) + use_centroid = True + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'metric': {'constantValue': metric}, + 'kernel': { + 'functionInvocationValue': { + 'functionName': 'Kernel.square', + 'arguments': {'radius': {'constantValue': 1}}, + } + }, + 'useCentroid': {'constantValue': use_centroid}, + }, + 'functionName': 'Image.spectralErosion', + }) + expression = ee.Image('a').spectralErosion(metric, kernel, use_centroid) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').spectralErosion( + metric=metric, kernel=kernel, useCentroid=use_centroid + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_spectral_gradient(self): + metric = 'sid' + kernel = ee.Kernel.square(1) + use_centroid = True + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'metric': {'constantValue': metric}, + 'kernel': { + 'functionInvocationValue': { + 'functionName': 'Kernel.square', + 'arguments': {'radius': {'constantValue': 1}}, + } + }, + 'useCentroid': {'constantValue': use_centroid}, + }, + 'functionName': 'Image.spectralGradient', + }) + expression = ee.Image('a').spectralGradient(metric, kernel, use_centroid) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').spectralGradient( + metric=metric, kernel=kernel, useCentroid=use_centroid + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_sqrt(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.sqrt', + }) + expression = ee.Image('a').sqrt() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_stratified_sample(self): + num_points = 1 + class_band = 'band' + point = [7, 8] + region = ee.Geometry.Point(point) + scale = 2 + projection = EPSG_4326 + seed = 3 + class_values = ['b', 'c'] + class_points = [4, 5] + drop_nulls = False + tile_scale = 6 + geometries = True + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'numPoints': {'constantValue': num_points}, + 'classBand': {'constantValue': class_band}, + 'region': { + 'functionInvocationValue': { + 'functionName': 'GeometryConstructors.Point', + 'arguments': {'coordinates': {'constantValue': point}}, + } + }, + 'scale': {'constantValue': scale}, + 'projection': { + 'functionInvocationValue': { + 'functionName': 'Projection', + 'arguments': {'crs': {'constantValue': projection}}, + } + }, + 'seed': {'constantValue': seed}, + 'classValues': {'constantValue': class_values}, + 'classPoints': {'constantValue': class_points}, + 'dropNulls': {'constantValue': drop_nulls}, + 'tileScale': {'constantValue': tile_scale}, + 'geometries': {'constantValue': geometries}, + }, + 'functionName': 'Image.stratifiedSample', + }) + expression = ee.Image('a').stratifiedSample( + num_points, + class_band, + region, + scale, + projection, + seed, + class_values, + class_points, + drop_nulls, + tile_scale, + geometries, + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').stratifiedSample( + numPoints=num_points, + classBand=class_band, + region=region, + scale=scale, + projection=projection, + seed=seed, + classValues=class_values, + classPoints=class_points, + dropNulls=drop_nulls, + tileScale=tile_scale, + geometries=geometries, + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_subtract(self): + image2 = 'b' + expect = make_expression_graph({ + 'arguments': { + 'image1': IMAGE, + 'image2': IMAGE_B, + }, + 'functionName': 'Image.subtract', + }) + expression = ee.Image('a').subtract(image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').subtract(image2=image2) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_tan(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.tan', + }) + expression = ee.Image('a').tan() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_tanh(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.tanh', + }) + expression = ee.Image('a').tanh() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_to_array(self): + axis = 1 + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'axis': {'constantValue': axis}, + }, + 'functionName': 'Image.toArray', + }) + expression = ee.Image('a').toArray(axis) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').toArray(axis=axis) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_to_byte(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.toByte', + }) + expression = ee.Image('a').toByte() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_to_double(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.toDouble', + }) + expression = ee.Image('a').toDouble() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_to_float(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.toFloat', + }) + expression = ee.Image('a').toFloat() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_to_int(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.toInt', + }) + expression = ee.Image('a').toInt() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_to_int16(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.toInt16', + }) + expression = ee.Image('a').toInt16() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_to_int32(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.toInt32', + }) + expression = ee.Image('a').toInt32() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_to_int64(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.toInt64', + }) + expression = ee.Image('a').toInt64() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_to_int8(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.toInt8', + }) + expression = ee.Image('a').toInt8() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_to_long(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.toLong', + }) + expression = ee.Image('a').toLong() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_to_short(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.toShort', + }) + expression = ee.Image('a').toShort() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_to_uint16(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.toUint16', + }) + expression = ee.Image('a').toUint16() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_to_uint32(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.toUint32', + }) + expression = ee.Image('a').toUint32() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_to_uint8(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.toUint8', + }) + expression = ee.Image('a').toUint8() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_translate(self): + x = 1 + y = 2 + units = 'pixels' + proj = EPSG_4326 + expect = make_expression_graph({ + 'arguments': { + 'input': IMAGE, + 'x': {'constantValue': x}, + 'y': {'constantValue': y}, + 'units': {'constantValue': units}, + 'proj': { + 'functionInvocationValue': { + 'functionName': 'Projection', + 'arguments': {'crs': {'constantValue': proj}}, + } + }, + }, + 'functionName': 'Image.translate', + }) + expression = ee.Image('a').translate(x, y, units, proj) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').translate(x=x, y=y, units=units, proj=proj) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_trigamma(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.trigamma', + }) + expression = ee.Image('a').trigamma() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_uint16(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.uint16', + }) + expression = ee.Image('a').uint16() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_uint32(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.uint32', + }) + expression = ee.Image('a').uint32() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_uint8(self): + expect = make_expression_graph({ + 'arguments': { + 'value': IMAGE, + }, + 'functionName': 'Image.uint8', + }) + expression = ee.Image('a').uint8() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_unit_scale(self): + low = 1 + high = 2 + expect = make_expression_graph({ + 'arguments': { + 'input': IMAGE, + 'low': {'constantValue': low}, + 'high': {'constantValue': high}, + }, + 'functionName': 'Image.unitScale', + }) + expression = ee.Image('a').unitScale(low, high) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').unitScale(low=low, high=high) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_unmask(self): + value = 'b' + same_footprint = True + expect = make_expression_graph({ + 'arguments': { + 'input': IMAGE, + 'value': IMAGE_B, + 'sameFootprint': {'constantValue': same_footprint}, + }, + 'functionName': 'Image.unmask', + }) + expression = ee.Image('a').unmask(value, same_footprint) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').unmask(value=value, sameFootprint=same_footprint) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_unmix(self): + endmembers = ['b', 'c'] + sum_to_one = False + non_negative = True + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'endmembers': {'constantValue': endmembers}, + 'nonNegative': {'constantValue': non_negative}, + 'sumToOne': {'constantValue': sum_to_one}, + }, + 'functionName': 'Image.unmix', + }) + expression = ee.Image('a').unmix(endmembers, sum_to_one, non_negative) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').unmix( + endmembers=endmembers, sumToOne=sum_to_one, nonNegative=non_negative + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_update_mask(self): + mask = 'b' + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'mask': IMAGE_B, + }, + 'functionName': 'Image.updateMask', + }) + expression = ee.Image('a').updateMask(mask) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').updateMask(mask=mask) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_visualize(self): + bands = ['b', 'c'] + gain = [1, 2] + bias = [3, 4] + min_values = [5, 6] + max_values = [7, 8] + gamma = [9, 10] + opacity = 11 + palette = ['red', 'blue'] + force_rgb_output = True + + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + 'bands': {'constantValue': bands}, + 'gain': {'constantValue': gain}, + 'bias': {'constantValue': bias}, + 'min': {'constantValue': min_values}, + 'max': {'constantValue': max_values}, + 'gamma': {'constantValue': gamma}, + 'opacity': {'constantValue': opacity}, + 'palette': {'constantValue': palette}, + 'forceRgbOutput': {'constantValue': force_rgb_output}, + }, + 'functionName': 'Image.visualize', + }) + + expression = ee.Image('a').visualize( + bands, + gain, + bias, + min_values, + max_values, + gamma, + opacity, + palette, + force_rgb_output, + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').visualize( + bands=bands, + gain=gain, + bias=bias, + min=min_values, + max=max_values, + gamma=gamma, + opacity=opacity, + palette=palette, + forceRgbOutput=force_rgb_output, + ) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_where(self): + test = 'b' + value = 'c' + expect = make_expression_graph({ + 'arguments': { + 'input': IMAGE, + 'test': IMAGE_B, + 'value': IMAGE_C, + }, + 'functionName': 'Image.where', + }) + expression = ee.Image('a').where(test, value) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + expression = ee.Image('a').where(test=test, value=value) + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + + def test_zero_crossing(self): + expect = make_expression_graph({ + 'arguments': { + 'image': IMAGE, + }, + 'functionName': 'Image.zeroCrossing', + }) + expression = ee.Image('a').zeroCrossing() + result = json.loads(expression.serialize()) + self.assertEqual(expect, result) + if __name__ == '__main__': unittest.main()