|
| 1 | +> **⚠️ Breaking Change in v0.1.0** |
| 2 | +> |
| 3 | +> A major refactor was released in v0.1.0, introducing breaking changes to the Xee API. In most cases, existing code written for pre-v0.1.0 versions will require updates to remain compatible. |
| 4 | +> |
| 5 | +> - See the [Migration Guide](docs/migration-guide-v0.1.0.md) for details on updating your code. |
| 6 | +> - If you need more time to migrate, you can pin your environment to the latest pre-v0.1.0 release. |
| 7 | +
|
1 | 8 | # Xee: Xarray + Google Earth Engine |
2 | 9 |
|
3 | 10 |  |
4 | 11 |
|
5 | | -_An Xarray extension for Google Earth Engine._ |
| 12 | +Xee is an Xarray backend for Google Earth Engine. Open `ee.Image` / `ee.ImageCollection` objects as lazy `xarray.Dataset`s and analyze petabyte‑scale Earth data with the scientific Python stack. |
6 | 13 |
|
7 | 14 | [](https://pypi.python.org/pypi/xee) |
8 | 15 | [](https://pepy.tech/project/xee) |
9 | | -[](https://github.com/conda-forge/xee-feedstock) |
| 16 | +[](https://github.com/conda-forge/xee-feedstock) |
11 | 17 | [](https://anaconda.org/conda-forge/xee) |
12 | | -[](https://anaconda.org/conda-forge/xee) |
14 | | - |
15 | | -## How to use |
| 18 | +[](https://anaconda.org/conda-forge/xee) |
16 | 19 |
|
17 | | -Install with pip: |
| 20 | +## Install |
18 | 21 |
|
19 | | -```shell |
| 22 | +```bash |
20 | 23 | pip install --upgrade xee |
21 | 24 | ``` |
22 | 25 |
|
23 | | -Install with conda: |
| 26 | +or |
24 | 27 |
|
25 | | -```shell |
| 28 | +```bash |
26 | 29 | conda install -c conda-forge xee |
27 | 30 | ``` |
28 | 31 |
|
29 | | -Then, authenticate Earth Engine: |
30 | | - |
31 | | -```shell |
32 | | -earthengine authenticate --quiet |
33 | | -``` |
34 | | - |
35 | | -Now, in your Python environment, make the following imports: |
| 32 | +## Minimal example |
36 | 33 |
|
37 | 34 | ```python |
38 | 35 | import ee |
39 | | -import xarray |
40 | | -``` |
41 | | - |
42 | | -Next, specify your EE-registered cloud project ID and initialize the EE client |
43 | | -with the high volume API: |
44 | | - |
45 | | -```python |
46 | | -ee.Initialize( |
47 | | - project='my-project-id', |
48 | | - opt_url='https://earthengine-highvolume.googleapis.com') |
49 | | -``` |
50 | | - |
51 | | -Open any Earth Engine ImageCollection by specifying the Xarray engine as `'ee'`: |
52 | | - |
53 | | -```python |
54 | | -ds = xarray.open_dataset('ee://ECMWF/ERA5_LAND/HOURLY', engine='ee') |
55 | | -``` |
56 | | - |
57 | | -Open all bands in a specific projection (not the Xee default): |
58 | | - |
59 | | -```python |
60 | | -ds = xarray.open_dataset('ee://ECMWF/ERA5_LAND/HOURLY', engine='ee', |
61 | | - crs='EPSG:4326', scale=0.25) |
62 | | -``` |
63 | | - |
64 | | -Open an ImageCollection (maybe, with EE-side filtering or processing): |
65 | | - |
66 | | -```python |
67 | | -ic = ee.ImageCollection('ECMWF/ERA5_LAND/HOURLY').filterDate( |
68 | | - '1992-10-05', '1993-03-31') |
69 | | -ds = xarray.open_dataset(ic, engine='ee', crs='EPSG:4326', scale=0.25) |
70 | | -``` |
71 | | - |
72 | | -Open an ImageCollection with a specific EE projection or geometry: |
73 | | - |
74 | | -```python |
75 | | -ic = ee.ImageCollection('ECMWF/ERA5_LAND/HOURLY').filterDate( |
76 | | - '1992-10-05', '1993-03-31') |
77 | | -leg1 = ee.Geometry.Rectangle(113.33, -43.63, 153.56, -10.66) |
78 | | -ds = xarray.open_dataset( |
79 | | - ic, |
80 | | - engine='ee', |
81 | | - projection=ic.first().select(0).projection(), |
82 | | - geometry=leg1 |
83 | | -) |
84 | | -``` |
85 | | - |
86 | | -Open multiple ImageCollections into one `xarray.Dataset`, all with the same |
87 | | -projection: |
| 36 | +import xarray as xr |
| 37 | +from xee import helpers |
88 | 38 |
|
89 | | -```python |
90 | | -ds = xarray.open_mfdataset( |
91 | | - ['ee://ECMWF/ERA5_LAND/HOURLY', 'ee://NASA/GDDP-CMIP6'], |
92 | | - engine='ee', crs='EPSG:4326', scale=0.25) |
93 | | -``` |
94 | | - |
95 | | -Open a single Image by passing it to an ImageCollection: |
96 | | - |
97 | | -```python |
98 | | -i = ee.ImageCollection(ee.Image('LANDSAT/LC08/C02/T1_TOA/LC08_044034_20140318')) |
99 | | -ds = xarray.open_dataset(i, engine='ee') |
100 | | -``` |
| 39 | +# Authenticate once (on a persistent machine): |
| 40 | +# earthengine authenticate |
101 | 41 |
|
102 | | -Open any Earth Engine ImageCollection to match an existing transform: |
| 42 | +project = 'PROJECT-ID' # Set your Earth Engine registered Google Cloud project ID |
| 43 | +# Initialize (high‑volume endpoint recommended for reading stored collections) |
| 44 | +ee.Initialize(project=project, opt_url='https://earthengine-highvolume.googleapis.com') |
103 | 45 |
|
104 | | -```python |
105 | | -raster = rioxarray.open_rasterio(...) # assume crs + transform is set |
106 | | -ds = xr.open_dataset( |
107 | | - 'ee://ECMWF/ERA5_LAND/HOURLY', |
108 | | - engine='ee', |
109 | | - geometry=tuple(raster.rio.bounds()), # must be in EPSG:4326 |
110 | | - projection=ee.Projection( |
111 | | - crs=str(raster.rio.crs), transform=raster.rio.transform()[:6] |
112 | | - ), |
113 | | -) |
| 46 | +# Open a dataset by matching its native grid |
| 47 | +ic = ee.ImageCollection('ECMWF/ERA5_LAND/MONTHLY_AGGR') |
| 48 | +grid = helpers.extract_grid_params(ic) |
| 49 | +ds = xr.open_dataset(ic, engine='ee', **grid) |
| 50 | +print(ds) |
114 | 51 | ``` |
115 | 52 |
|
116 | | -See [examples](https://github.com/google/Xee/tree/main/examples) or |
117 | | -[docs](https://github.com/google/Xee/tree/main/docs) for more uses and |
118 | | -integrations. |
119 | | - |
120 | | -## Getting help |
| 53 | +Next steps: |
121 | 54 |
|
122 | | -If you encounter issues using Xee, you can: |
| 55 | +- Quickstart: docs/quickstart.md |
| 56 | +- Concepts (grid params, CRS, orientation): docs/concepts.md |
| 57 | +- User Guide (workflows): docs/guide.md |
123 | 58 |
|
124 | | -1. Open a new or add to an existing [Xee discussion |
125 | | - topic](https://github.com/google/Xee/discussions) |
126 | | -2. Open an [Xee issue](https://github.com/google/Xee/issues). To increase the |
127 | | - likelihood of the issue being resolved, use this [template Colab |
128 | | - notebook](https://colab.research.google.com/drive/1vAgfAPhKGJd4G9ZUOzciqZ7MbqJjlMLR) |
129 | | - to create a reproducible script. |
| 59 | +## Features |
130 | 60 |
|
131 | | -## How to run integration tests |
| 61 | +- Lazy, parallel pixel retrieval through Earth Engine |
| 62 | +- Flexible output grid definition (fixed resolution or fixed shape) |
| 63 | +- CF-friendly dimension order: `[time, y, x]` |
| 64 | +- Plays nicely with Xarray, Dask, and friends |
132 | 65 |
|
133 | | -The Xee integration tests only pass on Xee branches (no forks). Please run the |
134 | | -integration tests locally before sending a PR. To run the tests locally, |
135 | | -authenticate using `earthengine authenticate` and run the following: |
| 66 | +## Community & Support |
136 | 67 |
|
137 | | -```bash |
138 | | -python -m unittest xee/ext_integration_test.py |
139 | | -``` |
| 68 | +- Discussions: https://github.com/google/Xee/discussions |
| 69 | +- Issues: https://github.com/google/Xee/issues |
140 | 70 |
|
141 | | -or |
| 71 | +## Contributing |
142 | 72 |
|
143 | | -```bash |
144 | | -python -m pytest xee/ext_integration_test.py |
145 | | -``` |
| 73 | +See docs/contributing.md and sign the required CLA. |
146 | 74 |
|
147 | 75 | ## License |
148 | 76 |
|
149 | | -This is not an official Google product. |
150 | | - |
151 | | -``` |
152 | | -Copyright 2023 Google LLC |
| 77 | +[Apache 2.0](LICENSE) |
153 | 78 |
|
154 | | -Licensed under the Apache License, Version 2.0 (the "License"); |
155 | | -you may not use this file except in compliance with the License. |
156 | | -You may obtain a copy of the License at |
| 79 | +`SPDX-License-Identifier: Apache-2.0` |
157 | 80 |
|
158 | | - https://www.apache.org/licenses/LICENSE-2.0 |
| 81 | +This is not an official Google product. |
159 | 82 |
|
160 | | -Unless required by applicable law or agreed to in writing, software |
161 | | -distributed under the License is distributed on an "AS IS" BASIS, |
162 | | -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
163 | | -See the License for the specific language governing permissions and |
164 | | -limitations under the License. |
165 | | -``` |
0 commit comments