diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml index 972c62e81..0b2f96554 100644 --- a/.github/workflows/ci-tests.yml +++ b/.github/workflows/ci-tests.yml @@ -7,10 +7,12 @@ on: [ jobs: build: - name: "python ${{ matrix.python-version }} tests" - runs-on: ubuntu-latest + name: "Python ${{ matrix.python-version }} tests on ${{ matrix.os }}" + runs-on: ${{ matrix.os }} strategy: + fail-fast: false matrix: + os: [ubuntu-latest] python-version: [ "3.7", "3.8", @@ -19,6 +21,11 @@ jobs: "3.11", "3.12", ] + include: + - os: macos-latest + python-version: "3.11" + - os: windows-latest + python-version: "3.11" steps: - uses: actions/checkout@v3 - name: Set up Python diff --git a/javascript/build/ee_api_js.js b/javascript/build/ee_api_js.js index b9ac89267..7674ad579 100644 --- a/javascript/build/ee_api_js.js +++ b/javascript/build/ee_api_js.js @@ -454,7 +454,7 @@ Na(p,f[m]))});return b?b(l):l};return this.callback?(vj(d,null,function(f,l){ret wj.prototype.send=function(a,b){var c=[a.B+" "+a.path+" HTTP/1.1"];c.push("Content-Type: application/json; charset=utf-8");var d=yj();null!=d&&c.push("Authorization: "+d);a=a.body?JSON.stringify(a.body):"";return[c.join("\r\n")+"\r\n\r\n"+a,b]}; var zj=function(a,b,c){a=n(b.split("--"+a.split("; boundary=")[1]));for(b=a.next();!b.done;b=a.next())if(b=b.value.split("\r\n\r\n"),!(3>b.length)){var d=b[0].match(/\r\nContent-ID: ]*)>/)[1],e=Number(b[1].match(/^HTTP\S*\s(\d+)\s/)[1]);c(d,e,b.slice(2).join("\r\n\r\n"))}},tj=function(){var a=Aj.replace(/\/api$/,"");return"window"in r&&!a.match(/^https?:\/\/content-/)?a.replace(/^(https?:\/\/)(.*\.googleapis\.com)$/,"$1content-$2"):a},Cj=function(a,b,c){var d=[];a&&(d=d.concat(Bj)); b&&d.push("https://www.googleapis.com/auth/devstorage.read_write");a=d=d.concat(c);c=b=0;for(var e={};cg)break;A++}return Xj(C.status,function(I){try{return C.getResponseHeader(I)}catch(ea){return null}},C.responseText,l,void 0,e,d,f)},Vj=function(a,b,c,d,e,g,f){var l=0,m={url:a,method:c,content:d,headers:e},p=Pj,v=null!=g?g:10; m.callback=function(A){A=A.target;if(429==A.getStatus()&&la.y||a.y>=1< 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. @@ -138,7 +120,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. @@ -452,12 +434,11 @@ 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), - "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. + 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. - 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: @@ -482,13 +463,10 @@ 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. Note that this is - ignored if the format is "ZIPPED_GEO_TIFF" or - "ZIPPED_GEO_TIFF_PER_BAND". + band-level transformations will be ignored. - format: the download format. One of: - "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). + "ZIPPED_GEO_TIFF" (GeoTIFF file(s) wrapped in a zip file, default), + "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. @@ -535,8 +513,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'. @@ -694,7 +672,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: @@ -752,7 +730,6 @@ 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: @@ -762,7 +739,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: @@ -779,3 +756,21 @@ 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/pyproject.toml b/python/pyproject.toml index a4cfe1061..13c5b9dfc 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "earthengine-api" -version = "0.1.403" +version = "0.1.404" description = "Earth Engine Python API" requires-python = ">=3.7" keywords = [