├── .devcontainer └── devcontainer.json ├── .github └── workflows │ ├── prerelease.yaml │ ├── release.yaml │ └── unit.yaml ├── .gitignore ├── .pre-commit-config.yaml ├── .readthedocs.yaml ├── AUTHORS.rst ├── CONTRIBUTING.rst ├── LICENSE ├── README.rst ├── RELEASE.rst ├── docs ├── _extension │ ├── api_admonition.py │ └── docstring.py ├── _static │ ├── banner.html │ ├── custom-icon.js │ ├── custom.css │ ├── logo.png │ ├── logo.svg │ ├── long-logo.png │ ├── switcher.json │ ├── usage │ │ └── plot │ │ │ └── index │ │ │ ├── histogram.png │ │ │ └── hydroshed.png │ └── we-need-you.jpg ├── _templates │ └── python │ │ ├── class.rst │ │ ├── function.rst │ │ ├── method.rst │ │ └── module.rst ├── conf.py ├── index.rst ├── setup │ ├── author.rst │ ├── contribute.rst │ ├── index.rst │ ├── inspiration.rst │ ├── install.rst │ ├── layout.rst │ ├── license.rst │ ├── migration.rst │ ├── pattern.rst │ └── quickstart.rst └── usage │ ├── asset.ipynb │ ├── export.ipynb │ ├── index.rst │ ├── plot │ ├── index.rst │ ├── map-featurecollection.ipynb │ ├── map-image.ipynb │ ├── plot-featurecollection.ipynb │ ├── plot-image.ipynb │ └── plot-imagecollection.ipynb │ ├── profile.ipynb │ ├── reduce.ipynb │ └── template.ipynb ├── geetools ├── __init__.py ├── _deprecated_algorithms.py ├── _deprecated_composite.py ├── accessors.py ├── ee_array.py ├── ee_asset.py ├── ee_authenticate.py ├── ee_computed_object.py ├── ee_date.py ├── ee_date_range.py ├── ee_dictionary.py ├── ee_export.py ├── ee_feature.py ├── ee_feature_collection.py ├── ee_filter.py ├── ee_geometry.py ├── ee_image.py ├── ee_image_collection.py ├── ee_initialize.py ├── ee_join.py ├── ee_list.py ├── ee_number.py ├── ee_profiler.py ├── ee_string.py ├── tools │ ├── __init__.py │ └── _deprecated_imagecollection.py └── utils.py ├── notebooks ├── algorithms │ ├── brdf.ipynb │ ├── distance_to_mask.ipynb │ ├── euclidean_distance.ipynb │ ├── harmonize.ipynb │ ├── mask_cover.ipynb │ └── pansharpen.ipynb ├── cloud_mask │ └── cloud_masking.ipynb ├── collection │ └── joinByProperty.ipynb ├── composite │ ├── closest_date.ipynb │ ├── medoid.ipynb │ └── medoid_score.ipynb ├── date │ ├── dayRangeIntervals.ipynb │ └── since_epoch.ipynb ├── geometry │ ├── .ipynb_checkpoints │ │ └── getRegion-checkpoint.ipynb │ └── getRegion.ipynb ├── image │ ├── addConstantBand.ipynb │ ├── addSuffix_addPrefix.ipynb │ ├── bufferMask.ipynb │ ├── clipToCollection.ipynb │ ├── distributions.ipynb │ ├── parametrize.ipynb │ ├── removeBands.ipynb │ ├── renameDict.ipynb │ ├── renamePattern.ipynb │ └── toGrid.ipynb └── imagecollection │ ├── distributions.ipynb │ ├── mosaicSameDay.ipynb │ └── parametrizeProperty.ipynb ├── noxfile.py ├── pyproject.toml └── tests ├── __init__.py ├── conftest.py ├── test_Array.py ├── test_Asset.py ├── test_Asset ├── test_glob.yml ├── test_iterdir.yml ├── test_iterdir_recursive.yml ├── test_parents.yml ├── test_rglob.yml └── test_rmdir_recursive_dry_run.yml ├── test_ComputedObect.py ├── test_Date.py ├── test_DateRange.py ├── test_Dictionary.py ├── test_Dictionary ├── test_to_table_any.yml ├── test_to_table_dict.yml └── test_to_table_list.yml ├── test_Export.py ├── test_Feature.py ├── test_Feature ├── serialized_test_remove_properties.yml ├── serialized_test_to_feature_collection.yml ├── test_remove_properties.yml └── test_to_feature_collection.yml ├── test_FeatureCollection.py ├── test_FeatureCollection ├── serialized_test_by_features.yml ├── serialized_test_by_features_with_id.yml ├── serialized_test_by_features_with_properties.yml ├── serialized_test_by_properties.yml ├── serialized_test_by_properties_with_id.yml ├── serialized_test_by_properties_with_properties.yml ├── serialized_test_from_geo_interface.yml ├── serialized_test_from_geo_interface_from_dict.yml ├── serialized_test_to_dictionary.yml ├── test_by_features.yml ├── test_by_features_with_id.yml ├── test_by_features_with_properties.yml ├── test_by_properties.yml ├── test_by_properties_with_id.yml ├── test_by_properties_with_properties.yml ├── test_deprecated_merge.yml ├── test_from_geo_interface.yml ├── test_from_geo_interface_from_dict.yml ├── test_merge_geometries.yml ├── test_plot.png ├── test_plot_by_features_bar.png ├── test_plot_by_features_donut.png ├── test_plot_by_features_pie.png ├── test_plot_by_features_scatter.png ├── test_plot_by_features_stacked.png ├── test_plot_by_properties_area.png ├── test_plot_by_properties_bar.png ├── test_plot_by_properties_plot.png ├── test_plot_hist.png ├── test_plot_with_boundaries.png ├── test_plot_with_cmap.png ├── test_plot_with_property.png └── test_to_dictionary.yml ├── test_Filter.py ├── test_Float.py ├── test_Geometry.py ├── test_Geometry └── test_deprecated_polygon.npz ├── test_Image.py ├── test_Image ├── serialized_test_class_mask.yml ├── serialized_test_class_to_bands.yml ├── test_add_date.csv ├── test_add_date_format.csv ├── test_add_prefix_to_all.yml ├── test_add_prefix_to_selected.yml ├── test_add_suffix_to_all.yml ├── test_add_suffix_to_selected.yml ├── test_class_mask.png ├── test_class_to_bands.png ├── test_clip_on_collection_bands.yml ├── test_clip_on_collection_property.yml ├── test_clip_on_collection_without_properties_bands.yml ├── test_clip_on_collection_without_properties_property.yml ├── test_default_spectral_indices.csv ├── test_deprecated_distance_to_mask.csv ├── test_deprecated_euclidian_distance.csv ├── test_distance.csv ├── test_distance_to_mask.csv ├── test_doy_to_date.csv ├── test_doy_to_date_with_band.csv ├── test_doy_to_date_with_format.csv ├── test_full.csv ├── test_full_like.csv ├── test_full_like_with_mask.csv ├── test_full_with_lists.csv ├── test_full_with_name.csv ├── test_full_with_value.csv ├── test_gauss.csv ├── test_gauss_with_band.csv ├── test_get_scale_params.yml ├── test_get_values.csv ├── test_get_values_with_scale.csv ├── test_histogram_match.csv ├── test_interpolate_bands.csv ├── test_islet_mask.png ├── test_mask_S2_clouds.csv ├── test_merge.yml ├── test_negative_clip.csv ├── test_pan_sharpen.csv ├── test_plot.png ├── test_plot_by_bands_area.png ├── test_plot_by_bands_bar.png ├── test_plot_by_bands_donut.png ├── test_plot_by_bands_pie.png ├── test_plot_by_bands_plot.png ├── test_plot_by_regions_bar.png ├── test_plot_by_regions_barh.png ├── test_plot_by_regions_stacked.png ├── test_plot_hist.png ├── test_plot_one_band.png ├── test_plot_one_band_cmap.png ├── test_plot_with_crs.png ├── test_plot_with_fc.png ├── test_prefix.yml ├── test_preprocess.csv ├── test_reduce_bands.csv ├── test_reduce_bands_with_bands.csv ├── test_reduce_bands_with_name.csv ├── test_remove.yml ├── test_remove_properties.yml ├── test_rename.yml ├── test_scale_and_offset.csv ├── test_suffix.yml ├── test_tasseled_cap.csv └── test_to_grid.npz ├── test_ImageCollection.py ├── test_ImageCollection ├── serialized_test_deprecated_composite_by_month.yml ├── serialized_test_deprecated_composite_regular_intervals.yml ├── serialized_test_deprecated_reduce_day_intervals.yml ├── serialized_test_deprecated_reduce_equal_interval.yml ├── serialized_test_reduce_interval.yml ├── serialized_test_reduce_interval_properties.yml ├── serialized_test_reduce_interval_with_multi_output_reducer.yml ├── serialized_test_reduce_interval_with_reducer.yml ├── serialized_test_reduce_interval_without_original_names.yml ├── serialized_test_reduce_regions_by_date_property.yml ├── serialized_test_reduce_regions_by_dates.yml ├── serialized_test_reduce_regions_by_doy.yml ├── serialized_test_sort_many_asc_asc.yml ├── serialized_test_sort_many_asc_desc.yml ├── serialized_test_sort_many_default.yml ├── serialized_test_sort_many_desc_desc.yml ├── serialized_test_sort_many_missing_asc.yml ├── test_aggregate_array.yml ├── test_aggregate_array_with_properties.yml ├── test_append.yml ├── test_closest_date.csv ├── test_closest_s2_sr.yml ├── test_collection_mask.csv ├── test_deprecated_closest_date.csv ├── test_deprecated_composite_by_month.csv ├── test_deprecated_composite_by_month.yml ├── test_deprecated_composite_regular_intervals.csv ├── test_deprecated_composite_regular_intervals.yml ├── test_deprecated_fill_with_last.csv ├── test_deprecated_medoid.csv ├── test_deprecated_mosaic_same_day.csv ├── test_deprecated_reduce_day_intervals.csv ├── test_deprecated_reduce_day_intervals.yml ├── test_deprecated_reduce_equal_interval.csv ├── test_deprecated_reduce_equal_interval.yml ├── test_get_citation.yml ├── test_get_doi.yml ├── test_get_offset_params.yml ├── test_get_scale_params.yml ├── test_iloc.csv ├── test_integral.csv ├── test_mask_s2.yml ├── test_mask_s2_sr.csv ├── test_medoid.csv ├── test_outliers.csv ├── test_outliers_with_bands.csv ├── test_outliers_with_drop.csv ├── test_outliers_with_sigma.csv ├── test_pan_sharpen.csv ├── test_plot_dates_by_bands.png ├── test_plot_dates_by_regions.png ├── test_plot_doy_by_bands.png ├── test_plot_doy_by_regions.png ├── test_plot_doy_by_seasons.png ├── test_plot_doy_by_years.png ├── test_preprocess.csv ├── test_reduce_interval.yml ├── test_reduce_interval_properties.yml ├── test_reduce_interval_with_multi_output_reducer.yml ├── test_reduce_interval_with_reducer.yml ├── test_reduce_interval_without_original_names.yml ├── test_reduce_region_by_date_property.yml ├── test_reduce_region_by_dates.yml ├── test_reduce_region_by_doy.yml ├── test_reduce_regions_by_date_property.yml ├── test_reduce_regions_by_dates.yml ├── test_reduce_regions_by_doy.yml ├── test_scale_and_offset.csv ├── test_sort_many_asc_asc.yml ├── test_sort_many_asc_desc.yml ├── test_sort_many_default.yml ├── test_sort_many_desc_desc.yml ├── test_sort_many_missing_asc.yml ├── test_spectral_indices.csv ├── test_tasseled_cap.csv ├── test_to_xarray.yml ├── test_validPixel.csv └── test_valid_pixels.csv ├── test_Integer.py ├── test_Join.py ├── test_Join ├── serialized_test_by_property.yml ├── serialized_test_by_property_outer.yml ├── test_by_property.yml ├── test_by_property_outer.yml └── test_deprecated_join.yml ├── test_List.py ├── test_List ├── serialized_test_chunked_even.yml ├── serialized_test_chunked_odd.yml ├── serialized_test_complement_with_different_type.yml ├── serialized_test_complement_with_same_type.yml ├── serialized_test_delete.yml ├── serialized_test_intersection_with_different_type.yml ├── serialized_test_intersection_with_same_type.yml ├── serialized_test_product_with_different_type.yml ├── serialized_test_product_with_same_type.yml ├── serialized_test_replace_many.yml ├── serialized_test_union_with_duplicate.yml ├── serialized_test_union_without_dupplicates.yml ├── serialized_test_zip.yml ├── test_chunked_even.yml ├── test_chunked_odd.yml ├── test_complement_with_different_type.yml ├── test_complement_with_same_type.yml ├── test_delete.yml ├── test_intersection_with_different_type.yml ├── test_intersection_with_same_type.yml ├── test_product_with_different_type.yml ├── test_product_with_same_type.yml ├── test_replace_many.yml ├── test_to_strings.yml ├── test_union_with_duplicate.yml ├── test_union_without_dupplicates.yml └── test_zip.yml ├── test_Number.py ├── test_Profiler.py ├── test_String.py ├── test_batch └── test_utils.py ├── test_deprecated.py └── test_deprecated ├── test_deprecated_cast_image.yml ├── test_merge_geometry.yml └── test_tobands.yml /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Python 3", 3 | "image": "mcr.microsoft.com/devcontainers/python:1-3.11-bullseye", 4 | "features": { 5 | "ghcr.io/devcontainers-contrib/features/nox:2": {}, 6 | "ghcr.io/devcontainers-contrib/features/pre-commit:2": {}, 7 | "ghcr.io/rocker-org/devcontainer-features/pandoc:1": {} 8 | }, 9 | "postCreateCommand": "pre-commit install" 10 | } 11 | -------------------------------------------------------------------------------- /.github/workflows/prerelease.yaml: -------------------------------------------------------------------------------- 1 | name: Schedule 2 | 3 | on: 4 | schedule: 5 | # Runs every Sunday at 18:00 (UTC time) 6 | - cron: "0 18 * * 0" 7 | workflow_dispatch: 8 | 9 | env: 10 | EARTHENGINE_SERVICE_ACCOUNT: ${{ secrets.EARTHENGINE_SERVICE_ACCOUNT }} 11 | EARTHENGINE_PROJECT: ${{ secrets.EARTHENGINE_PROJECT }} 12 | 13 | jobs: 14 | prerelease: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v4 18 | - name: Set up Python 3.11 19 | uses: actions/setup-python@v5 20 | with: 21 | python-version: "3.11" 22 | - name: Install dependencies 23 | run: pip install .[test] 24 | - name: Install EE pre-release 25 | run: pip install --pre --upgrade --force-reinstall earthengine-api 26 | - name: test with pytest 27 | run: pytest --color=yes tests 28 | -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | workflow_dispatch: 5 | release: 6 | types: [created] 7 | 8 | jobs: 9 | deploy: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v3 14 | #- uses: ./.github/workflows/unit.yaml 15 | - uses: actions/setup-python@v4 16 | with: 17 | python-version: "3.10" 18 | - name: Install dependencies 19 | run: pip install twine build nox 20 | - name: Build and publish 21 | env: 22 | TWINE_USERNAME: __token__ 23 | TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} 24 | run: | 25 | python -m build 26 | twine upload dist/* 27 | -------------------------------------------------------------------------------- /.github/workflows/unit.yaml: -------------------------------------------------------------------------------- 1 | name: Unit 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | workflow_dispatch: 9 | 10 | env: 11 | EARTHENGINE_SERVICE_ACCOUNT: ${{ secrets.EARTHENGINE_SERVICE_ACCOUNT }} 12 | EARTHENGINE_PROJECT: ${{ secrets.EARTHENGINE_PROJECT }} 13 | 14 | jobs: 15 | lint: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v4 19 | - uses: actions/setup-python@v5 20 | with: 21 | python-version: "3.13" 22 | - uses: pre-commit/action@v3.0.1 23 | 24 | mypy: 25 | runs-on: ubuntu-latest 26 | steps: 27 | - uses: actions/checkout@v4 28 | - uses: actions/setup-python@v5 29 | with: 30 | python-version: "3.13" 31 | - name: Install nox 32 | run: pip install nox 33 | - name: run mypy checks 34 | run: nox -s mypy 35 | 36 | docs: 37 | needs: [lint] 38 | runs-on: ubuntu-latest 39 | steps: 40 | - uses: actions/checkout@v4 41 | - uses: 12rambau/setup-pandoc@test 42 | - uses: actions/setup-python@v5 43 | with: 44 | python-version: "3.13" 45 | - name: Install nox 46 | run: pip install nox 47 | - name: build static docs 48 | run: nox -s docs 49 | 50 | build: 51 | needs: [lint, mypy] 52 | strategy: 53 | fail-fast: false 54 | matrix: 55 | os: [ubuntu-latest] 56 | # dropping 3.12 for now because of https://github.com/r-earthengine/ee_extra/issues/56 57 | python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] 58 | include: 59 | - os: macos-latest # macos test 60 | python-version: "3.12" 61 | - os: windows-latest # windows test 62 | python-version: "3.12" 63 | runs-on: ${{ matrix.os }} 64 | steps: 65 | - uses: actions/checkout@v4 66 | - name: Set up Python ${{ matrix.python-version }} 67 | uses: actions/setup-python@v5 68 | with: 69 | python-version: ${{ matrix.python-version }} 70 | - name: Install nox 71 | run: pip install nox 72 | - name: test with pytest 73 | run: nox -s ci-test 74 | - name: assess dead fixtures 75 | if: ${{ matrix.python-version == '3.13' }} 76 | shell: bash 77 | run: nox -s dead-fixtures 78 | - uses: actions/upload-artifact@v4 79 | if: ${{ matrix.python-version == '3.13' }} 80 | with: 81 | name: coverage 82 | path: coverage.xml 83 | 84 | coverage: 85 | needs: [build] 86 | runs-on: ubuntu-latest 87 | steps: 88 | - uses: actions/checkout@v4 89 | - uses: actions/download-artifact@v4 90 | with: 91 | name: coverage 92 | - name: codecov 93 | uses: codecov/codecov-action@v5 94 | with: 95 | token: ${{ secrets.CODECOV_TOKEN }} 96 | verbose: true 97 | fail_ci_if_error: true 98 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | docs/autoapi/ 74 | warnings.txt 75 | 76 | # PyBuilder 77 | .pybuilder/ 78 | target/ 79 | 80 | # Jupyter Notebook 81 | .ipynb_checkpoints 82 | 83 | # IPython 84 | profile_default/ 85 | ipython_config.py 86 | 87 | # pyenv 88 | # For a library or package, you might want to ignore these files since the code is 89 | # intended to run in multiple environments; otherwise, check them in: 90 | # .python-version 91 | 92 | # pipenv 93 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 94 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 95 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 96 | # install all needed dependencies. 97 | #Pipfile.lock 98 | 99 | # uv 100 | uv.lock 101 | 102 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 103 | __pypackages__/ 104 | 105 | # Celery stuff 106 | celerybeat-schedule 107 | celerybeat.pid 108 | 109 | # SageMath parsed files 110 | *.sage.py 111 | 112 | # Environments 113 | .env 114 | .venv 115 | env/ 116 | venv/ 117 | ENV/ 118 | env.bak/ 119 | venv.bak/ 120 | 121 | # Spyder project settings 122 | .spyderproject 123 | .spyproject 124 | 125 | # Rope project settings 126 | .ropeproject 127 | 128 | # mkdocs documentation 129 | /site 130 | 131 | # mypy 132 | .mypy_cache/ 133 | .dmypy.json 134 | dmypy.json 135 | 136 | # Pyre type checker 137 | .pyre/ 138 | 139 | # pytype static type analyzer 140 | .pytype/ 141 | 142 | # Cython debug symbols 143 | cython_debug/ 144 | 145 | # vscode config 146 | .vscode/ 147 | 148 | # JetBrains config 149 | .idea/ 150 | 151 | # sandbox Notebook 152 | sandbox.ipynb 153 | test.ipynb 154 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | default_install_hook_types: [pre-commit, commit-msg] 2 | 3 | repos: 4 | - repo: "https://github.com/psf/black" 5 | rev: "22.3.0" 6 | hooks: 7 | - id: black 8 | stages: [pre-commit] 9 | 10 | - repo: "https://github.com/commitizen-tools/commitizen" 11 | rev: "v2.18.0" 12 | hooks: 13 | - id: commitizen 14 | stages: [commit-msg] 15 | 16 | - repo: "https://github.com/pre-commit/mirrors-prettier" 17 | rev: "v2.7.1" 18 | hooks: 19 | - id: prettier 20 | stages: [pre-commit] 21 | exclude: tests\/test_.+\. 22 | 23 | - repo: https://github.com/charliermarsh/ruff-pre-commit 24 | rev: "v0.0.215" 25 | hooks: 26 | - id: ruff 27 | stages: [pre-commit] 28 | 29 | # - repo: https://github.com/PyCQA/doc8 30 | # rev: "v1.1.1" 31 | # hooks: 32 | # - id: doc8 33 | # stages: [pre-commit] 34 | 35 | - repo: https://github.com/codespell-project/codespell 36 | rev: v2.4.1 37 | hooks: 38 | - id: codespell 39 | stages: [pre-commit] 40 | additional_dependencies: 41 | - tomli 42 | 43 | # waiting for https://github.com/gee-community/geetools/issues/337 44 | # so notebooks can again be executed from the documentation 45 | - repo: "https://github.com/kynan/nbstripout" 46 | rev: "0.5.0" 47 | hooks: 48 | - id: nbstripout 49 | stages: [pre-commit] 50 | -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 2 | 3 | version: 2 4 | 5 | build: 6 | os: ubuntu-22.04 7 | tools: 8 | python: "3.10" 9 | 10 | sphinx: 11 | configuration: docs/conf.py 12 | 13 | python: 14 | install: 15 | - method: pip 16 | path: . 17 | extra_requirements: 18 | - doc 19 | -------------------------------------------------------------------------------- /AUTHORS.rst: -------------------------------------------------------------------------------- 1 | Thanks goes to these wonderful people (`emoji key `_): 2 | 3 | .. raw:: html 4 | 5 | 6 | 7 | 8 | 14 | 20 | 26 | 27 | 28 | 34 | 40 | 46 | 47 | 48 | 54 | 60 | 61 | 62 |
9 | 10 | fitoprincipe
11 | Rodrigo E. Principe 12 |
13 |
15 | 16 | 12rambau
17 | Pierrick Rambaud 18 |
19 |
21 | 22 | MarcCoru
23 | Marc Rußwurm 24 |
25 |
29 | 30 | hubert-crea
31 | hubert-crea 32 |
33 |
35 | 36 | samsammurphy
37 | Sam Murphy 38 |
39 |
41 | 42 | lumbric
43 | lumbric 44 |
45 |
49 | 50 | emmanuel-ferdman
51 | emmanuel-ferdman 52 |
53 |
55 | 56 | framunoz
57 | Francisco Muñoz 58 |
59 |
63 | 64 | This project follows the `all-contributors `_ specification. 65 | 66 | Contributions of any kind are welcome! 67 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Rodrigo E. Principe 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /RELEASE.rst: -------------------------------------------------------------------------------- 1 | Release instructions 2 | ==================== 3 | 4 | This page contains the steps to make a release and some helpful resources to get you started. 5 | 6 | Create an issue and copy/paste the steps below to release a new version. Close the issue when it is done. 7 | 8 | These steps should be taken in order to create a new release! 9 | 10 | .. code-block:: md 11 | 12 | **Double check for quality-control** 13 | 14 | - [ ] There are no [open issues with a `impact: block-release` label](https://github.com/gee-community/geetools/labels/impact%3A%20block-release) 15 | 16 | **Prepare the codebase for a new version** 17 | 18 | - [ ] Bump a new version using `commitizen`. use the `--pre-release` flag if it's a **release candidate**. 19 | - [ ] Push the RLS commit `git push upstream main` 20 | - [ ] If a **release candidate** is needed, tick this box when we're now ready for a full release. 21 | 22 | **Make the release** 23 | 24 | - [ ] [Start a new GitHub release](https://github.com/gee-community/geetools/releases/new) 25 | - Call the release the current version, e.g. `v0.2.0` 26 | - In the **`Choose a Tag:`** dropdown, type in the release name (e.g., `v0.2.0`) and click "Create new tag" 27 | - In the **`Target:`** dropdown, pin it to the release commit that you've just pushed. 28 | - Generate the automatic release notes, eventually manually specify the previous version (useful when several release candidate have been made) 29 | - [ ] Confirm that the release completed 30 | - [The `publish` github action job](https://github.com/gee-community/geetools/actions/workflows/release.yaml) has completed successfully in the [actions tab](https://github.com/gee-community/geetools/actions). 31 | - [The PyPI version is updated](https://pypi.org/project/geetools/) 32 | - [ ] Hide the previous patch version build in the RDT interface if needed. 33 | - [ ] Celebrate, you're done! 34 | 35 | Taken from [the release checklist](https://github.com/gee-community/geetools/blob/main/RELEASE.rst). 36 | -------------------------------------------------------------------------------- /docs/_extension/api_admonition.py: -------------------------------------------------------------------------------- 1 | """A directive to generate an API admonition.""" 2 | from __future__ import annotations 3 | 4 | from docutils import nodes 5 | from docutils.parsers.rst import directives 6 | from docutils.parsers.rst.directives.admonitions import BaseAdmonition 7 | from sphinx.application import Sphinx 8 | from sphinx.util import logging 9 | from sphinx.util.docutils import SphinxDirective 10 | from sphinx.writers.html5 import HTML5Translator 11 | 12 | logger = logging.getLogger(__name__) 13 | 14 | 15 | class api_node(nodes.Admonition, nodes.Element): 16 | pass 17 | 18 | 19 | def visit_api_node(self: HTML5Translator, node: api_node) -> None: 20 | self.visit_admonition(node) 21 | 22 | 23 | def depart_api_node(self: HTML5Translator, node: api_node) -> None: 24 | self.depart_admonition(node) 25 | 26 | 27 | class APIAdmonitionDirective(BaseAdmonition, SphinxDirective): 28 | """An API entry, displayed (if configured) in the form of an admonition.""" 29 | 30 | node_class = api_node 31 | has_content = True 32 | required_arguments = 0 33 | optional_arguments = 0 34 | final_argument_whitespace = False 35 | option_spec = { 36 | "class": directives.class_option, 37 | "name": directives.unchanged, 38 | } 39 | 40 | def run(self) -> list[nodes.Node]: 41 | if not self.options.get("class"): 42 | self.options["class"] = ["admonition-api"] 43 | 44 | (api,) = super().run() 45 | if isinstance(api, nodes.system_message): 46 | return [api] 47 | elif isinstance(api, api_node): 48 | api.insert(0, nodes.title(text="See API")) 49 | api["docname"] = self.env.docname 50 | self.add_name(api) 51 | self.set_source_info(api) 52 | self.state.document.note_explicit_target(api) 53 | return [api] 54 | else: 55 | raise RuntimeError # never reached here 56 | 57 | 58 | def setup(app: Sphinx) -> dict[str, object]: 59 | """Add custom configuration to sphinx app. 60 | 61 | Args: 62 | app: the Sphinx application 63 | 64 | Returns: 65 | the 2 parallel parameters set to ``True``. 66 | """ 67 | app.add_directive("api", APIAdmonitionDirective) 68 | app.add_node(api_node, html=(visit_api_node, depart_api_node)) 69 | 70 | return { 71 | "parallel_read_safe": True, 72 | "parallel_write_safe": True, 73 | } 74 | -------------------------------------------------------------------------------- /docs/_extension/docstring.py: -------------------------------------------------------------------------------- 1 | """A docstring role to read the docstring from a Python method.""" 2 | from __future__ import annotations 3 | 4 | import inspect 5 | from functools import reduce 6 | 7 | import ee 8 | from docutils import nodes 9 | from sphinx.application import Sphinx 10 | from sphinx.util import logging 11 | from sphinx.util.docutils import SphinxRole 12 | 13 | import geetools # noqa: F401 14 | 15 | logger = logging.getLogger(__name__) 16 | 17 | 18 | class DocstringRole(SphinxRole): 19 | """The docstring role interpreter.""" 20 | 21 | def run(self) -> tuple[list[nodes.Node], list[str]]: 22 | """Setup the role in the builder context.""" 23 | # retrieve the environment from the node members 24 | env = self.inliner.document.settings.env 25 | builder = env.app.builder 26 | current_doc = self.env.docname 27 | 28 | # extract the members we try to reach from the ee lib 29 | members = self.text.split(".")[1:] 30 | 31 | # reach the final object using getattr. It will allow us to access the complete information 32 | # of the object (docstring, qualname, name, source module) 33 | try: 34 | o = reduce(getattr, members, ee) 35 | modules = inspect.getmodule(o).__name__.split(".") 36 | except Exception as e: 37 | logger.warning(f"Failed to retrieve {members}: {e}") 38 | return [nodes.Text(f"{self.text} not found")], [] 39 | 40 | # create the docstring node 41 | docstring = nodes.Text(f": {o.__doc__.splitlines()[0]}") 42 | 43 | # create a complete link to the object using the url and the name of the object 44 | target_doc = f"autoapi/{'/'.join(modules)}/{o.__qualname__}" 45 | refuri = builder.get_relative_uri(current_doc, target_doc) 46 | inline_node = nodes.literal(members[-1], members[-1], classes=["py", "py-meth"]) 47 | link = nodes.reference("", "", inline_node, internal=True, refuri=refuri) 48 | 49 | return [link, docstring], [] 50 | 51 | 52 | def setup(app: Sphinx) -> dict[str, object]: 53 | """Add custom configuration to sphinx application.""" 54 | app.add_role("docstring", DocstringRole()) 55 | 56 | return { 57 | "parallel_read_safe": True, 58 | "parallel_write_safe": True, 59 | } 60 | -------------------------------------------------------------------------------- /docs/_static/banner.html: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /docs/_static/custom-icon.js: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Set a custom icon for pypi as it's not available in the fa built-in brands 3 | */ 4 | FontAwesome.library.add( 5 | (faListOldStyle = { 6 | prefix: "fa-custom", 7 | iconName: "conda", 8 | icon: [ 9 | 24, // viewBox width 10 | 24, // viewBox height 11 | [], // ligature 12 | "e001", // unicode codepoint - private use area 13 | "M12.045.033a12.181 12.182 0 00-1.361.078 17.512 17.513 0 011.813 1.433l.48.438-.465.45a15.047 15.048 0 00-1.126 1.205l-.178.215a8.527 8.527 0 01.86-.05 8.154 8.155 0 11-4.286 15.149 15.764 15.765 0 01-1.841.106h-.86a21.847 21.848 0 00.264 2.866 11.966 11.967 0 106.7-21.89zM8.17.678a12.181 12.182 0 00-2.624 1.275 15.506 15.507 0 011.813.43A18.551 18.552 0 018.17.678zM9.423.75a16.237 16.238 0 00-.995 1.998 16.15 16.152 0 011.605.66 6.98 6.98 0 01.43-.509c.234-.286.472-.559.716-.817A15.047 15.048 0 009.423.75zM4.68 2.949a14.969 14.97 0 000 2.336c.587-.065 1.196-.1 1.812-.107a16.617 16.617 0 01.48-1.748 16.48 16.481 0 00-2.292-.481zM3.62 3.5A11.938 11.938 0 001.762 5.88a17.004 17.004 0 011.877-.444A17.39 17.391 0 013.62 3.5zm4.406.287c-.143.437-.265.888-.38 1.347a8.255 8.255 0 011.67-.803c-.423-.2-.845-.38-1.29-.544zM6.3 6.216a14.051 14.052 0 00-1.555.108c.064.523.157 1.038.272 1.554a8.39 8.391 0 011.283-1.662zm-2.55.137a15.313 15.313 0 00-2.602.716h-.078v.079a17.104 17.105 0 001.267 2.544l.043.071.072-.049a16.309 16.31 0 011.734-1.083l.057-.035V8.54a16.867 16.868 0 01-.408-2.094v-.092zM.644 8.095l-.063.2A11.844 11.845 0 000 11.655v.209l.143-.152a17.706 17.707 0 011.584-1.447l.057-.043-.043-.064a16.18 16.18 0 01-1.025-1.87zm3.77 1.253l-.18.1c-.465.273-.93.573-1.375.889l-.065.05.05.064c.309.437.645.867.996 1.276l.137.165v-.208a8.176 8.176 0 01.364-2.15zM2.2 10.853l-.072.05a16.574 16.574 0 00-1.813 1.734l-.058.058.066.057a15.449 15.45 0 001.991 1.483l.072.05.043-.08a16.738 16.74 0 011.053-1.64v-.05l-.043-.05a16.99 16.99 0 01-1.19-1.54zm1.855 2.071l-.121.172a15.363 15.363 0 00-.917 1.433l-.043.072.071.043a16.61 16.61 0 001.562.766l.193.086-.086-.193a8.04 8.04 0 01-.66-2.172zm-3.976.48v.2a11.758 11.759 0 00.946 3.326l.078.186.072-.194a16.215 16.216 0 01.845-2l.057-.063-.064-.043a17.197 17.198 0 01-1.776-1.284zm2.543 1.805l-.035.08a15.764 15.765 0 00-.983 2.479v.08h.086a16.15 16.152 0 002.688.5l.072.007v-.086a17.562 17.563 0 01.164-2.056v-.065H4.55a16.266 16.266 0 01-1.849-.896zm2.544 1.169v.114a17.254 17.255 0 00-.151 1.828v.078h.931c.287 0 .624.014.946 0h.209l-.166-.129a8.011 8.011 0 01-1.64-1.834zm-3.29 2.1l.115.172a11.988 11.988 0 002.502 2.737l.157.129v-.201a22.578 22.58 0 01-.2-2.336v-.071h-.072a16.23 16.23 0 01-2.3-.387z", // svg path (https://simpleicons.org/icons/anaconda.svg) 14 | ], 15 | }) 16 | ); 17 | -------------------------------------------------------------------------------- /docs/_static/custom.css: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * add dollar sign in console code-block 3 | */ 4 | div.highlight-console pre span.go::before { 5 | content: "$"; 6 | margin-right: 10px; 7 | margin-left: 5px; 8 | } 9 | 10 | /******************************************************************************* 11 | * Create a custom api admonition 12 | */ 13 | div.admonition.admonition-api > .admonition-title::after { 14 | content: "\f121"; /* the fa-code icon */ 15 | } 16 | 17 | /******************************************************************************* 18 | * custom sizing 19 | */ 20 | .bd-main .bd-content .bd-article-container { 21 | max-width: 100%; /* default is 60em */ 22 | } 23 | 24 | .bd-page-width { 25 | max-width: 110rem; /* default is 88rem */ 26 | } 27 | 28 | /******************************************************************************* 29 | * custom article footer rendering 30 | */ 31 | footer.bd-footer-article { 32 | background-color: transparent; 33 | border-top: 1px solid var(--pst-color-border); 34 | margin-top: 2em; 35 | } 36 | 37 | .bd-footer-article .footer-article-items { 38 | flex-direction: row; 39 | } 40 | 41 | .bd-footer-article .footer-article-items .footer-article-item { 42 | flex-grow: 1; 43 | } 44 | 45 | .bd-footer-article .last-updated { 46 | color: var(--pst-color-text-muted); 47 | text-align: right; 48 | } 49 | -------------------------------------------------------------------------------- /docs/_static/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/docs/_static/logo.png -------------------------------------------------------------------------------- /docs/_static/long-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/docs/_static/long-logo.png -------------------------------------------------------------------------------- /docs/_static/switcher.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "version": "dev", 4 | "url": "https://geetools.readthedocs.io/en/latest/" 5 | }, 6 | { 7 | "name": "1.5.1 (stable)", 8 | "version": "v1.5.1", 9 | "url": "https://geetools.readthedocs.io/en/stable/", 10 | "preferred": true 11 | }, 12 | { 13 | "name": "1.4.0", 14 | "version": "v1.4.0", 15 | "url": "https://geetools.readthedocs.io/en/v1.4.0/" 16 | }, 17 | { 18 | "name": "1.3.1", 19 | "version": "v1.3.1", 20 | "url": "https://geetools.readthedocs.io/en/v1.3.1/" 21 | }, 22 | { 23 | "name": "1.2.2", 24 | "version": "v1.2.2", 25 | "url": "https://geetools.readthedocs.io/en/v1.2.2/" 26 | }, 27 | { 28 | "name": "1.1.0", 29 | "version": "v1.1.0", 30 | "url": "https://geetools.readthedocs.io/en/v1.1.0/" 31 | } 32 | ] 33 | -------------------------------------------------------------------------------- /docs/_static/usage/plot/index/histogram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/docs/_static/usage/plot/index/histogram.png -------------------------------------------------------------------------------- /docs/_static/usage/plot/index/hydroshed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/docs/_static/usage/plot/index/hydroshed.png -------------------------------------------------------------------------------- /docs/_static/we-need-you.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/docs/_static/we-need-you.jpg -------------------------------------------------------------------------------- /docs/_templates/python/class.rst: -------------------------------------------------------------------------------- 1 | {% if obj.display %} 2 | {% if is_own_page %} 3 | :html_theme.sidebar_secondary.remove: 4 | 5 | {{ obj.id.split(".")[-1] }} 6 | {{ "=" * obj.id.split(".")[-1] | length }} 7 | 8 | {% endif %} 9 | {% set visible_children = obj.children|selectattr("display")|list %} 10 | {% set own_page_children = visible_children|selectattr("type", "in", own_page_types)|list %} 11 | {% if is_own_page and own_page_children %} 12 | .. toctree:: 13 | :hidden: 14 | 15 | {% for child in own_page_children %} 16 | {{ child.include_path }} 17 | {% endfor %} 18 | 19 | {% endif %} 20 | .. py:{{ obj.type }}:: {% if is_own_page %}{{ obj.id }}{% else %}{{ obj.short_name }}{% endif %}{% if obj.args %}({{ obj.args }}){% endif %} 21 | 22 | {% for (args, return_annotation) in obj.overloads %} 23 | {{ " " * (obj.type | length) }} {{ obj.short_name }}{% if args %}({{ args }}){% endif %} 24 | 25 | {% endfor %} 26 | {% if obj.bases %} 27 | {% if "show-inheritance" in autoapi_options %} 28 | 29 | Bases: {% for base in obj.bases %}{{ base|link_objs }}{% if not loop.last %}, {% endif %}{% endfor %} 30 | {% endif %} 31 | 32 | 33 | {% if "show-inheritance-diagram" in autoapi_options and obj.bases != ["object"] %} 34 | .. autoapi-inheritance-diagram:: {{ obj.obj["full_name"] }} 35 | :parts: 1 36 | {% if "private-members" in autoapi_options %} 37 | :private-bases: 38 | {% endif %} 39 | 40 | {% endif %} 41 | {% endif %} 42 | {% if obj.docstring %} 43 | 44 | {{ obj.docstring|indent(3) }} 45 | {% endif %} 46 | {% for obj_item in visible_children %} 47 | {% if obj_item.type not in own_page_types %} 48 | 49 | {{ obj_item.render()|indent(3) }} 50 | {% endif %} 51 | {% endfor %} 52 | {% if is_own_page and own_page_children %} 53 | {% set visible_attributes = own_page_children|selectattr("type", "in", ("attribute", "property"))|list %} 54 | {% if visible_attributes %} 55 | Attributes 56 | ---------- 57 | 58 | .. autoapisummary:: 59 | 60 | {% for attribute in visible_attributes %} 61 | {{ attribute.id }} 62 | {% endfor %} 63 | 64 | 65 | {% endif %} 66 | {% set visible_exceptions = own_page_children|selectattr("type", "equalto", "exception")|list %} 67 | {% if visible_exceptions %} 68 | Exceptions 69 | ---------- 70 | 71 | .. autoapisummary:: 72 | 73 | {% for exception in visible_exceptions %} 74 | {{ exception.id }} 75 | {% endfor %} 76 | 77 | 78 | {% endif %} 79 | {% set visible_classes = own_page_children|selectattr("type", "equalto", "class")|list %} 80 | {% if visible_classes %} 81 | Classes 82 | ------- 83 | 84 | .. autoapisummary:: 85 | 86 | {% for klass in visible_classes %} 87 | {{ klass.id }} 88 | {% endfor %} 89 | 90 | 91 | {% endif %} 92 | {% set visible_methods = own_page_children|selectattr("type", "equalto", "method")|list %} 93 | {% if visible_methods %} 94 | Methods 95 | ------- 96 | 97 | .. autoapisummary:: 98 | 99 | {% for method in visible_methods %} 100 | {{ method.id }} 101 | {% endfor %} 102 | 103 | 104 | {% endif %} 105 | {% endif %} 106 | {% endif %} -------------------------------------------------------------------------------- /docs/_templates/python/function.rst: -------------------------------------------------------------------------------- 1 | {% if obj.display %} 2 | {% if is_own_page %} 3 | :html_theme.sidebar_secondary.remove: 4 | 5 | {{ obj.id.split(".")[-1] }} 6 | {{ "=" * obj.id.split(".")[-1] | length }} 7 | 8 | {% endif %} 9 | .. py:function:: {% if is_own_page %}{{ obj.id }}{% else %}{{ obj.short_name }}{% endif %}({{ obj.args }}){% if obj.return_annotation is not none %} -> {{ obj.return_annotation }}{% endif %} 10 | {% for (args, return_annotation) in obj.overloads %} 11 | 12 | {%+ if is_own_page %}{{ obj.id }}{% else %}{{ obj.short_name }}{% endif %}({{ args }}){% if return_annotation is not none %} -> {{ return_annotation }}{% endif %} 13 | {% endfor %} 14 | {% for property in obj.properties %} 15 | 16 | :{{ property }}: 17 | {% endfor %} 18 | 19 | {% if obj.docstring %} 20 | 21 | {{ obj.docstring|indent(3) }} 22 | {% endif %} 23 | {% endif %} -------------------------------------------------------------------------------- /docs/_templates/python/method.rst: -------------------------------------------------------------------------------- 1 | {% if obj.display %} 2 | {% if is_own_page %} 3 | :html_theme.sidebar_secondary.remove: 4 | 5 | {{ obj.id.split(".")[-1] }} 6 | {{ "=" * obj.id.split(".")[-1] | length }} 7 | 8 | {% endif %} 9 | .. py:method:: {% if is_own_page %}{{ obj.id }}{% else %}{{ obj.short_name }}{% endif %}({{ obj.args }}){% if obj.return_annotation is not none %} -> {{ obj.return_annotation }}{% endif %} 10 | {% for (args, return_annotation) in obj.overloads %} 11 | 12 | {%+ if is_own_page %}{{ obj.id }}{% else %}{{ obj.short_name }}{% endif %}({{ args }}){% if return_annotation is not none %} -> {{ return_annotation }}{% endif %} 13 | {% endfor %} 14 | {% for property in obj.properties %} 15 | 16 | :{{ property }}: 17 | {% endfor %} 18 | 19 | {% if obj.docstring %} 20 | 21 | {{ obj.docstring|indent(3) }} 22 | {% endif %} 23 | {% endif %} -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | :html_theme.sidebar_secondary.remove: 2 | 3 | 4 | geetools 5 | ======== 6 | 7 | .. toctree:: 8 | :hidden: 9 | 10 | setup/index 11 | usage/index 12 | Reference 13 | Changelogs 14 | earth-engine API 15 | 16 | Overview 17 | -------- 18 | 19 | .. image:: _static/logo.png 20 | :width: 20% 21 | :align: right 22 | :class: dark-light 23 | 24 | `Google Earth Engine `__ is a cloud-based service for geospatial processing of vector and raster data. The Earth Engine platform has a `JavaScript and a Python API `__ with different methods to process geospatial objects. 25 | 26 | The **geetools** package extends the Google Earth Engine Python API with pre-processing and processing tools for the most used satellite platforms by adding utility methods for different Earth Engine Objects that are friendly with the Python method chaining using the ``geetools`` namespace. 27 | 28 | content 29 | ------- 30 | 31 | .. grid:: 1 2 3 3 32 | 33 | .. grid-item:: 34 | 35 | .. card:: :icon:`fa-solid fa-chart-simple` plot 36 | :link: usage/plot/index.html 37 | 38 | Display EE objects directly as static plots. 39 | 40 | .. grid-item:: 41 | 42 | .. card:: :icon:`fa-solid fa-folder` asset 43 | :link: usage/asset.html 44 | 45 | Manage your assets as a object-oriented file system. 46 | 47 | .. grid-item:: 48 | 49 | .. card:: :icon:`fa-solid fa-images` export ImageCollections 50 | :link: usage/export.html 51 | 52 | Useful wrapper to export ImageCollections as simply as Images. 53 | 54 | .. grid-item:: 55 | 56 | .. card:: :icon:`fa-solid fa-handshake-angle` Contribute 57 | :link: setup/contribute.html 58 | 59 | Help us improve the lib. 60 | 61 | Why using it ? 62 | -------------- 63 | 64 | New utility methods and constructors are added to most of the GEE classes. They can be simple wrapper for repetitive tasks, complex algorithm or mandatory preprocessing steps. The goal is to make the code more fluid and easy to read for researchers, students and analysts. 65 | 66 | The package design is mostly performing server-side computation making it also very friendly with commercial users of Earth Engine. 67 | 68 | This small example wrapping of the excellent ``ee_extra`` package functionalities shows how to preprocess sentinel 2 data in 5 lines of code: 69 | 70 | .. code-block:: python 71 | 72 | import ee 73 | import geetools #noqa: F401 74 | import pygaul # another gee-community package to access FAO GAUl 2015 dataset 75 | 76 | # we assume you are already authenticated to GEE 77 | ee.Initialize.geetools.from_account("toto") # yes we also support multi users 78 | 79 | amazonas = pygaul.Items(name="Amazonas").centroid() 80 | 81 | S2 = ( 82 | ee.ImageCollection('COPERNICUS/S2_SR') 83 | .filterBounds(point) 84 | .geetools.closest('2020-10-15') # Extended (pre-processing) 85 | .geetools.maskClouds(prob = 70) # Extended (pre-processing) 86 | .geetools.scaleAndOffset() # Extended (pre-processing) 87 | .geetools.spectralIndices(['NDVI','NDWI','BAIS2'])) # Extended (processing) 88 | 89 | -------------------------------------------------------------------------------- /docs/setup/author.rst: -------------------------------------------------------------------------------- 1 | Authors 2 | ======= 3 | 4 | .. include:: ../../AUTHORS.rst -------------------------------------------------------------------------------- /docs/setup/contribute.rst: -------------------------------------------------------------------------------- 1 | Contributing workflow 2 | ===================== 3 | 4 | .. include:: ../../CONTRIBUTING.rst 5 | :start-line: 3 6 | -------------------------------------------------------------------------------- /docs/setup/index.rst: -------------------------------------------------------------------------------- 1 | Setup 2 | ===== 3 | 4 | Overview 5 | -------- 6 | 7 | The User Guide covers all of **geetools** by topic area. The :doc:`quickstart` page is a good place to start if you are new to the package or just want to refresh your memory. The :doc:`layout` page provides a high-level overview of the package's layout, and the :doc:`pattern` page provides a high-level overview of the package's design decsisions. 8 | 9 | The use of the package requires a basic understanding of the **Python** programming language and the **GEE Python API**. Users brand-new to Earth Engine should refer to the `Google documentation `__ first. 10 | 11 | Further hands-on example of specific tasks can be found in the :doc:`../usage/index` section. and for the most advance user please refe to the :doc:`../autoapi/index` section for a complete description of each individual functionality. 12 | 13 | Refactoring 14 | ----------- 15 | 16 | Since version v1.0.0, the package has been drastically modified to adopt the extension pattern (see :doc:`pattern` for more information). Many functions have also bee dropped or fully refactored to improve overall performances, and to make the package more consistent and easy to use. For more information about the miregation process please refer to the :doc:`migration` page. 17 | 18 | .. important:: 19 | 20 | The refactoring process is not finished yet, we will progressively reintegrate all the methods in the new pattern and add many cool functionalities. If any of your previous is not working anymore and the :doc:`migration` page did not provided any solution, please open an issue in the `GitHub repository `__. 21 | 22 | .. toctree:: 23 | :hidden: 24 | :caption: Get started 25 | 26 | install 27 | quickstart 28 | layout 29 | 30 | .. toctree:: 31 | :hidden: 32 | :caption: Extension Layout 33 | 34 | pattern 35 | migration 36 | inspiration 37 | 38 | .. toctree:: 39 | :hidden: 40 | :caption: Contributor guide 41 | 42 | contribute 43 | author 44 | license 45 | 46 | 47 | -------------------------------------------------------------------------------- /docs/setup/inspiration.rst: -------------------------------------------------------------------------------- 1 | Acknowledgment 2 | ============== 3 | 4 | This project was inspired by other very cool initiatives and we would like to acknowledge them here. 5 | 6 | xarray 7 | ------ 8 | 9 | the `xarray `__ lib is a great lib to handle n-dimensional data and has very well documented the use of the extension pattern. Without their guidances, `documentation `__ and `sphinx-extention `__, this project would have not been possible. 10 | 11 | eemont 12 | ------ 13 | 14 | the `eemont `__ lib has already implemented the extension pattern and allow the users to perform many different operations from preprocessing to extra construction methods. We loved some of them so much that we rewired within **geetools** every method available in `ee_extra `__. 15 | 16 | Our implementations diverge on 2 main points: 17 | 18 | - We decided to be more careful with the extensions and avoid adding them directly after the ``earthengine-api`` objects. We preferred to follow ``xarray`` recommendation and create systematically a ``geetools`` intermediate member to notify to the user that no, these methods are not from the vanilla ``earthengine-api`` but from the ``geetools`` lib. 19 | 20 | - We decided not to reimplement the Python magic methods. Now that EarthEngine is a commercial product, the users need to always be in control of what is performed server-side and what is performed client-side. We believe that spercharging magic method (although they allow cool things as ``ee.Image(1) + ee.image(2)``) make it even more confusing for new users to understand what is performed server-side and what is performed client-side. That's why all our method are using camel case naming convention and only return ``ee.ComputedObject``. Few exceptions are made for converters and plotting method that are forced to run an interactive ``getInfo()`` but they use snake case convention to notify their user and have a disclaimer in the docstring. 21 | -------------------------------------------------------------------------------- /docs/setup/install.rst: -------------------------------------------------------------------------------- 1 | Installation instructions 2 | ========================= 3 | 4 | The package is a pure python package, installation is thus very straight forward. 5 | 6 | pypi 7 | ---- 8 | 9 | the python package is available on `pypi `__ and can be installed it using ``pip``: 10 | 11 | .. code-block:: console 12 | 13 | pip install geetools 14 | 15 | conda 16 | ----- 17 | 18 | The python package is available on `conda `__ and can be installed using ``conda`` and the ``conda-forge`` channel: 19 | 20 | .. code-block:: console 21 | 22 | conda install -c conda-forge geetools 23 | 24 | from source 25 | ----------- 26 | 27 | You can also install the package from source. First clone the repository: 28 | 29 | .. code-block:: console 30 | 31 | git clone https://github.com/gee-community/geetools.git 32 | 33 | Then, navigate to the folder and install the package using pip: 34 | 35 | .. code-block:: console 36 | 37 | cd geetools 38 | pip install . 39 | 40 | Multiple version of the package requirements are available and are specifically important for local development. 41 | See the :doc:`contribute` page for more information. 42 | 43 | -------------------------------------------------------------------------------- /docs/setup/license.rst: -------------------------------------------------------------------------------- 1 | License 2 | ======= 3 | 4 | .. include:: ../../LICENSE -------------------------------------------------------------------------------- /docs/setup/migration.rst: -------------------------------------------------------------------------------- 1 | Upgrade from v0 to v1 2 | ===================== 3 | 4 | in v1 **geetoold** has fully embraced the extension pattern and has revamped most of it's functionalities. 5 | This page will gather the changes that you need to make to your code to upgrade from v0 to v1. 6 | 7 | The lib is following a deprecation cycle of several month so no function has been directly removed. 8 | They will simply raised a deprecation warning and provide some suggestion on the potential replacement. 9 | 10 | None the less, as previous implementation was leading to internal issues such as circular imports, it is recommended to update your code to the new pattern as soon as possible to avoid any future breakage. 11 | 12 | .. warning:: 13 | 14 | This documentation is gathering problems faced by the community and the solutions that were found. 15 | If you have a problem that is not listed here, please open an item in our `issue tracker `__. 16 | 17 | 18 | Import the modules 19 | ------------------ 20 | 21 | If in the previous implementation, most of the modules were brought back to the main ``__init.py`` which was causing circular import issues. 22 | In v1 the internal structure was revisited and some modules are no longer accecible from ``geetools``. 23 | 24 | A v0 implementation would look like this: 25 | 26 | .. code-block:: python 27 | 28 | import ee 29 | from geetools.tools import geometry 30 | 31 | image = ee.Image(ee.ImageCollection('COPERNICUS/S2').first()) 32 | tools.geometry.getRegion(image) 33 | 34 | It will raise an error as the "tools" file has been replaced by a "_deprecated_tools" one. 35 | 36 | Now to run the same code you should do: 37 | 38 | .. code-block:: python 39 | 40 | import ee 41 | from geetools import tools 42 | 43 | image = ee.Image(ee.ImageCollection('COPERNICUS/S2').first()) 44 | tools.geometry.getRegion(image) 45 | 46 | This will simply raise a deprecation warning and will work as expected. 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /docs/setup/quickstart.rst: -------------------------------------------------------------------------------- 1 | Quickstart 2 | ========== 3 | 4 | 5 | 6 | An extension ? 7 | -------------- 8 | 9 | **geetools** is an extension package. It means that it cannot be used without the **Google Earth Engine Python API** but also that you don't need to call it explicitly to use all the methods and functions available. 10 | 11 | To summarize, these functions are added to GEE objects inside a member called ``geetools``. 12 | 13 | The first step is as always to authenticate to GEE and import the **geetools** package. 14 | 15 | .. code-block:: python 16 | 17 | import ee 18 | import geetools #noqa: F401 19 | 20 | ee.Initialize() 21 | 22 | At this stage all the methods of the package have been added to the ``ee`` objects. You can use them as if they were part of the original API in the ``geetools`` member. 23 | 24 | The following example will use the ``truncate`` method to truncate a number to a given number of decimals. 25 | 26 | .. code-block:: python 27 | :emphasize-lines: 2, 5 28 | 29 | import ee 30 | import geetools #noqa: F401 31 | 32 | number = ee.Number(3.14159265359) 33 | truncated = number.geetools.truncate(2) 34 | truncated.getInfo() 35 | 36 | Real life example 37 | ----------------- 38 | 39 | This small example shows how **geetools** is wrapping the excellent ``ee_extra`` package functionalities to preprocess sentinel 2 data in 5 lines of code: 40 | 41 | .. code-block:: python 42 | 43 | import ee 44 | import geetools #noqa: F401 45 | import pygaul # another gee-community package to access FAO GAUl 2015 dataset 46 | 47 | # we assume you are already authenticated to GEE 48 | ee.Initialize.geetools.from_account("toto") # yes we also support multi users 49 | 50 | amazonas = pygaul.Items(name="Amazonas").centroid() 51 | 52 | S2 = ( 53 | ee.ImageCollection('COPERNICUS/S2_SR') 54 | .filterBounds(point) 55 | .geetools.closest('2020-10-15') # Extended (pre-processing) 56 | .geetools.maskClouds(prob = 70) # Extended (pre-processing) 57 | .geetools.scaleAndOffset() # Extended (pre-processing) 58 | .geetools.spectralIndices(['NDVI','NDWI','BAIS2'])) # Extended (processing) 59 | 60 | More examples of more complex and meaningful analysis can be found in the :doc:`../usage/index` gallery. 61 | 62 | F401 ? 63 | ------ 64 | 65 | In Python it's recommended to clean you code using automatic tools like ``flake8``, ``ruff``, ``isort``...etc 66 | 67 | These tool will raise an error if you import a package and don't use it, it's the ``F401`` error. In some tools the erroring lines can be deleted from the file. This will break your code as even if the **geetools** package is never called it's required to import it to extend the ``ee`` package. 68 | 69 | The ``#noqa: F401`` comment is used to avoid the linter to raise an error when the package is imported but not used. It is not mandatory if you don't use linters but it is a good practice to keep your code clean. 70 | 71 | .. note:: 72 | 73 | as per flake8 `documentation `__: 74 | 75 | F401: A module has been imported but is not used anywhere in the file. The module should either be used or the import should be removed. 76 | -------------------------------------------------------------------------------- /docs/usage/index.rst: -------------------------------------------------------------------------------- 1 | Guides 2 | ====== 3 | 4 | Overview 5 | -------- 6 | 7 | This section gathered many real life examples of the Lib usage gathered by the community. 8 | If you think your workflow should be shared please open a PR and follow the contribution guildelines shared in the next section. 9 | 10 | .. warning:: 11 | 12 | The example gallery is a work in progress as the library was recently refactored. 13 | All contributions are welcolmed! 14 | 15 | Add a new example 16 | ----------------- 17 | 18 | .. image:: /_static/we-need-you.jpg 19 | :alt: We need you! 20 | :align: center 21 | 22 | Currently most of the examples built by `@Rodrigo `__ are still using the old implementation of the library. 23 | They should be transformed into modern example and moved from the old `notebook `__ folder to the new `example `__ one to be displayed in our doc. 24 | 25 | The examples are regular notebook files that are interpreted by the ``myst-nb`` lib and displayed in the doc, clicking on the :guilabel:`open in colab` button will open a colab notebook with the code ready to be executed and the :guilabel:`view source` will bring you back to github. 26 | 27 | To add a new example, you can use the `example template `__ and replace things with your code. 28 | 29 | Adapt the code of the 2 first buttons to your file so users can lunch it in collab and view the source in github. 30 | 31 | .. code-block:: md 32 | 33 | [![github](https://img.shields.io/badge/-see%20sources-white?logo=github&labelColor=555)](https://github.com/gee-community/geetools/blob/main/docs/usage/template.ipynb) 34 | [![colab](https://img.shields.io/badge/-open%20in%20colab-blue?logo=googlecolab&labelColor=555)](https://colab.research.google.com/github/gee-community/geetools/blob/main/docs/usage/template.ipynb) 35 | 36 | 37 | Then you can open a PR with the new file and it will be reviewed and merged. 38 | 39 | .. toctree:: 40 | :hidden: 41 | 42 | template 43 | export 44 | plot/index 45 | asset 46 | profile 47 | reduce -------------------------------------------------------------------------------- /docs/usage/template.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# example Template" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": null, 13 | "metadata": { 14 | "tags": [ 15 | "remove-cell" 16 | ] 17 | }, 18 | "outputs": [], 19 | "source": [ 20 | "import ee, geetools\n", 21 | "from geetools.utils import initialize_documentation\n", 22 | "\n", 23 | "initialize_documentation()" 24 | ] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "[![github](https://img.shields.io/badge/-see%20sources-white?logo=github&labelColor=555)](https://github.com/gee-community/geetools/blob/main/docs/usage/template.ipynb)\n", 31 | "[![colab](https://img.shields.io/badge/-open%20in%20colab-blue?logo=googlecolab&labelColor=555)](https://colab.research.google.com/github/gee-community/geetools/blob/main/docs/usage/template.ipynb)" 32 | ] 33 | }, 34 | { 35 | "cell_type": "markdown", 36 | "metadata": {}, 37 | "source": [ 38 | "## Set up environement\n", 39 | "\n", 40 | "Install all the required libs if necessary and perform the import statements upstream." 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": null, 46 | "metadata": {}, 47 | "outputs": [], 48 | "source": [ 49 | "# uncomment if installation of libs is necessary\n", 50 | "# !pip install earthengine-api geetools" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": null, 56 | "metadata": {}, 57 | "outputs": [], 58 | "source": [ 59 | "import ee\n", 60 | "import geetools #noqa: F401" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": null, 66 | "metadata": {}, 67 | "outputs": [], 68 | "source": [ 69 | "# uncomment if authetication to GEE is needed\n", 70 | "# ee.Authenticate()" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": null, 76 | "metadata": {}, 77 | "outputs": [], 78 | "source": [ 79 | "# uncomment if initialization is required\n", 80 | "# ee.Initialize()" 81 | ] 82 | }, 83 | { 84 | "cell_type": "markdown", 85 | "metadata": {}, 86 | "source": [ 87 | "## Truncate a number\n", 88 | "\n", 89 | "This template is demonstrating how to truncate a EE number to a given number of decimal places." 90 | ] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "execution_count": null, 95 | "metadata": {}, 96 | "outputs": [], 97 | "source": [ 98 | "# initialize your GEE object\n", 99 | "pi = 3.14159265359\n", 100 | "ee_pi = ee.Number(pi)\n", 101 | "ee_pi.getInfo()" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": null, 107 | "metadata": {}, 108 | "outputs": [], 109 | "source": [ 110 | "# truncate the number to 3 decimals directly in GEE\n", 111 | "ee_pi_truncated = ee_pi.geetools.truncate(3)\n", 112 | "ee_pi_truncated.getInfo()" 113 | ] 114 | } 115 | ], 116 | "metadata": { 117 | "language_info": { 118 | "name": "python" 119 | } 120 | }, 121 | "nbformat": 4, 122 | "nbformat_minor": 2 123 | } 124 | -------------------------------------------------------------------------------- /geetools/__init__.py: -------------------------------------------------------------------------------- 1 | """A toolbox to use with Google Earth Engine Python API. 2 | 3 | The ``geetools`` package extends the Google Earth Engine Python API with pre-processing and 4 | processing tools for the most used satellite platforms by adding utility methods for different Earth 5 | Engine Objects that are friendly with the Python method chaining using the geetools namespace. 6 | """ 7 | import ee 8 | 9 | # import the accessor namespace 10 | from .accessors import geetools 11 | 12 | # it needs to be imported first as it's the mother class 13 | from .ee_computed_object import * 14 | 15 | # reproduce older structure of the lib (deprecated) 16 | # will be removed along the deprecation cycle 17 | from . import _deprecated_algorithms as algorithms 18 | from . import _deprecated_composite as composite 19 | from .tools import imagecollection 20 | 21 | # then we extend all the other classes 22 | from .ee_asset import Asset 23 | from .ee_date import DateAccessor 24 | from .ee_dictionary import DictionaryAccessor 25 | from .ee_feature import FeatureAccessor 26 | from .ee_feature_collection import FeatureCollectionAccessor 27 | from .ee_filter import FilterAccessor 28 | from .ee_geometry import GeometryAccessor 29 | from .ee_image import ImageAccessor 30 | from .ee_join import JoinAccessor 31 | from .ee_list import ListAccessor 32 | from .ee_number import NumberAccessor 33 | from .ee_string import StringAccessor 34 | from .ee_image_collection import ImageCollectionAccessor 35 | from .ee_initialize import InitializeAccessor 36 | from .ee_authenticate import AuthenticateAccessor 37 | from .ee_array import ArrayAccessor 38 | from .ee_date_range import DateRangeAccessor 39 | from .ee_export import ExportAccessor 40 | from .ee_profiler import Profiler 41 | 42 | __title__ = "geetools" 43 | __summary__ = "A set of useful tools to use with Google Earth Engine Python" "API" 44 | __uri__ = "http://geetools.readthedocs.io" 45 | __version__ = "1.16.0" 46 | 47 | __author__ = "Rodrigo E. Principe" 48 | __email__ = "fitoprincipe82@gmail.com" 49 | 50 | __license__ = "MIT" 51 | __copyright__ = "2017 Rodrigo E. Principe" 52 | -------------------------------------------------------------------------------- /geetools/_deprecated_algorithms.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | """Module holding misc algorithms.""" 3 | 4 | import ee 5 | import ee.data 6 | from deprecated.sphinx import deprecated 7 | 8 | 9 | @deprecated(version="1.4.0", reason="Use ee.Image.geetools.distanceToMask instead.") 10 | def distanceToMask( 11 | image, 12 | mask, 13 | kernel=None, 14 | radius=1000, 15 | unit="meters", 16 | scale=None, 17 | geometry=None, 18 | band_name="distance_to_mask", 19 | normalize=False, 20 | ): 21 | """Compute the distance to the mask in meters.""" 22 | return ( 23 | ee.Image(image) 24 | .geetools.distanceToMask(mask, radius=radius, band_name=band_name) 25 | .select(band_name) 26 | ) 27 | 28 | 29 | @deprecated(version="1.5.0", reason="Use ee.Image.geetools.maskCover instead.") 30 | def maskCover( 31 | image, 32 | geometry=None, 33 | scale=None, 34 | property_name="MASK_COVER", 35 | crs=None, 36 | crsTransform=None, 37 | bestEffort=False, 38 | maxPixels=1e13, 39 | tileScale=1, 40 | ): 41 | """Percentage of masked pixels (masked/total * 100) as an Image property.""" 42 | return ee.Image(image).geetools.maskCover() 43 | 44 | 45 | @deprecated(version="1.5.0", reason="Use ee.Image.geetools.distance instead.") 46 | def euclideanDistance(image1, image2, bands=None, discard_zeros=False, name="distance"): 47 | """Compute the Euclidean distance between two images.""" 48 | return ee.Image(image1).geetools.distance(image2) 49 | 50 | 51 | @deprecated(version="1.4.0", reason="It's included in the ee_extra bindings.") 52 | def pansharpenKernel(image, pan, rgb=None, kernel=None): 53 | """Compute the per-pixel means of the unsharpened bands.""" 54 | raise NotImplementedError("This function is deprecated. Use the one in ee_extra.") 55 | 56 | 57 | @deprecated(version="1.4.0", reason="It's included in the ee_extra bindings.") 58 | def pansharpenIhsFusion(image, pan=None, rgb=None): 59 | """HSV-based Pan-Sharpening.""" 60 | raise NotImplementedError("This function is deprecated. Use the one in ee_extra.") 61 | -------------------------------------------------------------------------------- /geetools/_deprecated_composite.py: -------------------------------------------------------------------------------- 1 | """Module holding tools for creating composites.""" 2 | 3 | import ee 4 | from deprecated.sphinx import deprecated 5 | 6 | 7 | @deprecated(version="1.5.0", reason="Only used to build the medoid composite.") 8 | def medoidScore(collection, bands=None, discard_zeros=False, bandname="sumdist", normalize=True): 9 | """Compute a score to reflect 'how far' is from the medoid.""" 10 | raise NotImplementedError( 11 | "This method was only used to build the medoid composite. " 12 | "The medoid composite is still available in the lib." 13 | ) 14 | 15 | 16 | @deprecated(version="1.5.0", reason="Use ee.imageCollection.geetools.medoid instead") 17 | def medoid(collection, bands=None, discard_zeros=False): 18 | """Medoid Composite. Adapted from https://www.mdpi.com/2072-4292/5/12/6481.""" 19 | return ee.ImageCollection(collection).geetools.medoid() 20 | 21 | 22 | @deprecated(version="1.5.0", reason="Use ee.ImageCollection.geetools.closestDate instead") 23 | def closestDate(col, clip_to_first=False): 24 | """Make a composite in which masked pixels are filled with the last available pixel.""" 25 | return ee.ImageCollection(col).geetools.closestDate() 26 | 27 | 28 | @deprecated(version="1.5.0", reason="Use ee.ImageCollection.geetools.reduceInterval instead") 29 | def compositeRegularIntervals( 30 | collection, 31 | interval=1, 32 | unit="month", 33 | date_range=(1, 0), 34 | date_range_unit="month", 35 | direction="backward", 36 | start=None, 37 | end=None, 38 | composite_function=None, 39 | composite_args=None, 40 | composite_kwargs=None, 41 | ): 42 | """Make a composite at regular intervals parsing a composite.""" 43 | return ee.ImageCollection(collection).geetools.reduceInterval(unit=unit) 44 | 45 | 46 | @deprecated(version="1.5.0", reason="Use ee.ImageCollection.geetools.reduceInterval instead") 47 | def compositeByMonth( 48 | collection, composite_function=None, composite_args=None, composite_kwargs=None 49 | ): 50 | """Make a composite at regular intervals parsing a composite.""" 51 | return ee.ImageCollection(collection).geetools.reduceInterval(unit="month") 52 | 53 | 54 | @deprecated(version="1.4.0", reason="Use the vanilla Earth Engine API") 55 | def max(collection, band=None): 56 | """Make a max composite using the specified band.""" 57 | return collection.max() 58 | -------------------------------------------------------------------------------- /geetools/accessors.py: -------------------------------------------------------------------------------- 1 | """Generic accessor to add extra function to the base GEE API classes.""" 2 | from __future__ import annotations 3 | 4 | from typing import Callable 5 | 6 | import ee 7 | 8 | 9 | def register_class_accessor(klass: type, name: str) -> Callable: 10 | """Create an accessor through the provided namespace to a given class. 11 | 12 | Parameters: 13 | klass: The class to set the accessor to. 14 | name: The name of the accessor namespace 15 | 16 | Returns: 17 | The accessor function to the class. 18 | """ 19 | 20 | def decorator(accessor: Callable) -> object: 21 | class ClassAccessor: 22 | def __init__(self, name: str, accessor: Callable): 23 | self.name, self.accessor = name, accessor 24 | 25 | def __get__(self, obj: object, *args) -> object: 26 | return self.accessor(obj) 27 | 28 | # check if the accessor already exists for this class 29 | if hasattr(klass, name): 30 | raise AttributeError(f"Accessor {name} already exists for {klass}") 31 | 32 | # register the accessor to the class 33 | setattr(klass, name, ClassAccessor(name, accessor)) 34 | 35 | return accessor 36 | 37 | return decorator 38 | 39 | 40 | def register_function_accessor(func: Callable, name: str) -> Callable: 41 | """Add an Accessor class to function through the provided namespace. 42 | 43 | Parameters: 44 | func: The function to set the accessor to. 45 | name: The name of the accessor namespace. 46 | 47 | Returns: 48 | The accessor function to the function. 49 | """ 50 | 51 | def decorator(accessor: Callable) -> object: 52 | 53 | # check if the accessor already exists for this class 54 | if hasattr(func, name): 55 | raise AttributeError(f"Member {name} already exists for {func}") 56 | else: 57 | setattr(func, name, accessor()) 58 | 59 | return accessor 60 | 61 | return decorator 62 | 63 | 64 | # this private method should not be exposed to end user as it perform 0 checks it can overwrite 65 | # existing methods/class/member. Only used in the lib for the Computed object as the method need 66 | # to be shared by every other child of the class. 67 | def _register_extention(obj: object) -> Callable: 68 | """Add the function to any object.""" 69 | return lambda f: (setattr(obj, f.__name__, f) or f) # type: ignore 70 | 71 | 72 | # create a geetools namespace that can be use directly on the ee module 73 | 74 | 75 | @_register_extention(ee) 76 | class geetools: 77 | """Namespace class for the geetools library.""" 78 | 79 | def __init__(self): 80 | """The geetools namespace cannot be instantiated.""" 81 | raise AttributeError("Cannot instantiate geetools") 82 | -------------------------------------------------------------------------------- /geetools/ee_array.py: -------------------------------------------------------------------------------- 1 | """Extra methods for the :py:class:`ee.Array` class.""" 2 | from __future__ import annotations 3 | 4 | import ee 5 | 6 | from .accessors import register_class_accessor 7 | 8 | 9 | @register_class_accessor(ee.Array, "geetools") 10 | class ArrayAccessor: 11 | """Toolbox for the :py:class:`ee.Array` class.""" 12 | 13 | def __init__(self, obj: ee.Array): 14 | """Initialize the Array class.""" 15 | self._obj = obj 16 | 17 | def full( 18 | self, 19 | width: float | int | ee.Number, 20 | height: float | int | ee.Number, 21 | value: float | int | ee.Number, 22 | ) -> ee.Array: 23 | """Create an :py:class:`ee.Array` with the given dimensions, initialized to the given value. 24 | 25 | Parameters: 26 | width: The width of the array. 27 | height: The height of the array. 28 | value: The value to initialize the array with. 29 | 30 | Returns: 31 | An array with the given dimensions, initialized to the given value. 32 | 33 | Examples: 34 | .. jupyter-execute:: 35 | 36 | import ee, geetools 37 | from geetools.utils import initialize_documentation 38 | 39 | initialize_documentation() 40 | 41 | array = ee.Array.geetools.full(3, 3, 1) 42 | array.getInfo() 43 | """ 44 | width, height = ee.Number(width).toInt(), ee.Number(height).toInt() 45 | return ee.Array(ee.List.repeat(ee.List.repeat(value, width), height)) 46 | 47 | def set( 48 | self, 49 | x: int | ee.Number, 50 | y: int | ee.Number, 51 | value: float | int | ee.Number, 52 | ) -> ee.Array: 53 | """Set the value of a cell in an array. 54 | 55 | Parameters: 56 | x: The x coordinate of the cell. 57 | y: The y coordinate of the cell. 58 | value: The value to set the cell to. 59 | 60 | Returns: 61 | The array with the cell set to the given value. 62 | 63 | Examples: 64 | .. jupyter-execute:: 65 | 66 | import ee, geetools 67 | from geetools.utils import initialize_documentation 68 | 69 | initialize_documentation() 70 | 71 | array = ee.Array.geetools.full(3, 3, 1) 72 | array = array.geetools.set(1, 1, 0) 73 | array.getInfo() 74 | """ 75 | xPos, yPos = ee.Number(x).toInt(), ee.Number(y).toInt() 76 | row = ee.List(self._obj.toList().get(yPos)).set(xPos, ee.Number(value)) 77 | return ee.Array(self._obj.toList().set(yPos, row)) 78 | -------------------------------------------------------------------------------- /geetools/ee_date_range.py: -------------------------------------------------------------------------------- 1 | """Extra tools for the :py:class:`ee.DateRange` class.""" 2 | from __future__ import annotations 3 | 4 | import ee 5 | 6 | from .accessors import register_class_accessor 7 | 8 | 9 | @register_class_accessor(ee.DateRange, "geetools") 10 | class DateRangeAccessor: 11 | """Toolbox for the :py:class:`ee.DateRange` class.""" 12 | 13 | def __init__(self, obj: ee.DateRange): 14 | """Initialize the DateRange class.""" 15 | self._obj = obj 16 | 17 | # -- date range operations ------------------------------------------------- 18 | def split(self, interval: int | ee.Number, unit: str = "day") -> ee.List: 19 | """Convert a :py:class:`ee.DateRange` to a list of :py:class:`ee.DateRange`. 20 | 21 | The DateRange will be split in multiple DateRanges of the specified interval and Unit. 22 | For example "1", "day". if the end date is not included the last dateRange length will be adapted. 23 | 24 | Parameters: 25 | interval: The interval to split the DateRange 26 | unit: The unit to split the DateRange. One of: ``second``, ``minute``, ``hour``, ``day``, ``month``, ``year``. 27 | 28 | Returns: 29 | The list of DateRanges 30 | 31 | Examples: 32 | .. jupyter-execute:: 33 | 34 | import ee, geetools 35 | from geetools.utils import initialize_documentation 36 | 37 | initialize_documentation() 38 | 39 | dateList = ee.DateRange('2020-01-01', '2020-01-31').geetools.split(1, 'day') 40 | dateList.getInfo() 41 | """ 42 | self.check_unit(unit) 43 | interval = ee.Number(interval).toInt().multiply(self.unitMillis(unit)) 44 | start, end = self._obj.start().millis(), self._obj.end().millis() 45 | 46 | timestampList = ee.List.sequence(start, end, interval) 47 | timestampList = timestampList.add(ee.Number(end).toFloat()).distinct() 48 | indexList = ee.List.sequence(0, timestampList.size().subtract(2)) 49 | 50 | return indexList.map( 51 | lambda i: ee.DateRange(timestampList.get(i), timestampList.get(ee.Number(i).add(1))) 52 | ) 53 | 54 | # -- utils ----------------------------------------------------------------- 55 | @staticmethod 56 | def check_unit(unit: str) -> None: 57 | """Check if the unit is valid.""" 58 | if unit not in (units := ["second", "minute", "hour", "day", "month", "year"]): 59 | raise ValueError(f"unit must be one of: {','.join(units)}") 60 | 61 | @staticmethod 62 | def unitMillis(unit: str) -> ee.Number: 63 | """Get the milliseconds of a unit. 64 | 65 | Parameters: 66 | unit: The unit to get the milliseconds. One of: ``second``, ``minute``, ``hour``, ``day``, ``month``, ``year``. 67 | 68 | Returns: 69 | The number of milliseconds in the unit 70 | """ 71 | millis = { 72 | "second": 1000, 73 | "minute": 1000 * 60, 74 | "hour": 1000 * 60 * 60, 75 | "day": 1000 * 60 * 60 * 24, 76 | "month": 1000 * 60 * 60 * 24 * 30, 77 | "year": 1000 * 60 * 60 * 24 * 365, 78 | } 79 | return ee.Number(millis[unit]) 80 | -------------------------------------------------------------------------------- /geetools/ee_feature.py: -------------------------------------------------------------------------------- 1 | """Toolbox for the :py:class:`ee.Feature` class.""" 2 | from __future__ import annotations 3 | 4 | import ee 5 | 6 | from .accessors import register_class_accessor 7 | 8 | 9 | @register_class_accessor(ee.Feature, "geetools") 10 | class FeatureAccessor: 11 | """Toolbox for the :py:class:`ee.Feature` class.""" 12 | 13 | def __init__(self, obj: ee.Feature): 14 | """Initialize the class.""" 15 | self._obj = obj 16 | 17 | def toFeatureCollection(self) -> ee.FeatureCollection: 18 | """Convert a :py:class:`ee.Feature` composed of a multiGeometry geometry into a :py:class:`ee.FeatureCollection`. 19 | 20 | Returns: 21 | The :py:class:`ee.FeatureCollection`. 22 | 23 | Example: 24 | .. jupyter-execute:: 25 | 26 | import ee, geetools 27 | from geetools.utils import initialize_documentation 28 | 29 | initialize_documentation() 30 | 31 | geoms = ee.Geometry.MultiPoint([[0,0], [0,1]]) 32 | feature = ee.Feature(geoms).set("foo", "bar") 33 | fc = feature.geetools.toFeatureCollection() 34 | fc.getInfo() 35 | """ 36 | geoms = self._obj.geometry().geometries() 37 | fc = geoms.map(lambda g: self._obj.setGeometry(g)) 38 | return ee.FeatureCollection(fc) 39 | 40 | def removeProperties(self, properties: list[str] | ee.List) -> ee.Feature: 41 | """Remove properties from a feature. 42 | 43 | Args: 44 | properties : List of properties to remove. 45 | 46 | Returns: 47 | The feature without the properties. 48 | 49 | Example: 50 | .. jupyter-execute:: 51 | 52 | import ee, geetools 53 | from geetools.utils import initialize_documentation 54 | 55 | initialize_documentation() 56 | 57 | feature = ee.Feature(None).set("foo", "bar", "baz", "foo") 58 | feature = feature.geetools.removeProperties(["foo"]) 59 | feature.getInfo() 60 | """ 61 | properties = ee.List(properties) 62 | proxy = ee.Feature(self._obj.geometry()) # drop properties 63 | return proxy.copyProperties(self._obj, exclude=properties) 64 | -------------------------------------------------------------------------------- /geetools/ee_filter.py: -------------------------------------------------------------------------------- 1 | """Extra method for the :py:class:`ee.Filter` class.""" 2 | from __future__ import annotations 3 | 4 | import ee 5 | 6 | from .accessors import register_class_accessor 7 | 8 | 9 | @register_class_accessor(ee.Filter, "geetools") 10 | class FilterAccessor: 11 | """Toolbox for the :py:class:`ee.Filter` class.""" 12 | 13 | def __init__(self, obj: ee.Filter): 14 | """Initialize the Filter class.""" 15 | self._obj = obj 16 | 17 | def dateRange(self, range: ee.DateRange) -> ee.Filter: 18 | """Filter by daterange. 19 | 20 | Parameters: 21 | range: The date range to filter by. 22 | 23 | Returns: 24 | The filter to apply to a collection. 25 | 26 | Examples: 27 | .. jupyter-execute:: 28 | 29 | import ee, geetools 30 | from geetools.utils import initialize_documentation 31 | 32 | initialize_documentation() 33 | 34 | # Create a collection and filter it by a date range 35 | collection = ee.ImageCollection("LANDSAT/LC08/C02/T1_L2") 36 | 37 | # filter by date range 38 | range = ee.DateRange("2018-01-01", "2019-01-01") 39 | filteredCollection = collection.filter(ee.Filter.geetools.dateRange(range)) 40 | 41 | # print the total size of the collections 42 | print(f"landsat full collection: {collection.size().getInfo()}") 43 | print(f"landsat filtered collection: {filteredCollection.size().getInfo()}") 44 | """ 45 | return ee.Filter.date(range.start(), range.end()) 46 | -------------------------------------------------------------------------------- /geetools/ee_geometry.py: -------------------------------------------------------------------------------- 1 | """Toolbox for the :py:class:`ee.Geometry` class.""" 2 | from __future__ import annotations 3 | 4 | import ee 5 | 6 | from .accessors import register_class_accessor 7 | 8 | 9 | @register_class_accessor(ee.Geometry, "geetools") 10 | class GeometryAccessor: 11 | """Toolbox for the :py:class:`ee.Geometry` class.""" 12 | 13 | def __init__(self, obj: ee.Geometry): 14 | """Initialize the Geometry class.""" 15 | self._obj = obj 16 | 17 | def keepType(self, type: str) -> ee.Geometry: 18 | """Only keep the geometries of the given type from a GeometryCollection. 19 | 20 | Args: 21 | type: The type of geometries to keep. Can be one of: Point, LineString, LineRing Polygon. 22 | 23 | Returns: 24 | The geometries of the given type. 25 | 26 | Examples: 27 | .. jupyter-execute:: 28 | 29 | import ee, geetools 30 | from geetools.utils import initialize_documentation 31 | 32 | initialize_documentation() 33 | 34 | # generate multiple geometries of different types 35 | point0 = ee.Geometry.Point([0,0], proj="EPSG:4326") 36 | point1 = ee.Geometry.Point([0,1], proj="EPSG:4326") 37 | poly0 = point0.buffer(1, proj="EPSG:4326") 38 | poly1 = point1.buffer(1, proj="EPSG:4326").bounds(proj="EPSG:4326") 39 | line = ee.Geometry.LineString([point1, point0], proj="EPSG:4326") 40 | multiPoly = ee.Geometry.MultiPolygon([poly0, poly1], proj="EPSG:4326") 41 | 42 | # create a geometry collection from them 43 | geometryCollection = ee.Algorithms.GeometryConstructors.MultiGeometry( 44 | [multiPoly, poly0, poly1, point0, line], 45 | crs="EPSG:4326", 46 | geodesic=True, 47 | maxError=1 48 | ) 49 | 50 | # extract only the LineString geometries from the collection 51 | geom = geometryCollection.geetools.keepType('LineString') 52 | geom.getInfo() 53 | """ 54 | # will raise an error if self is not a GeometryCollection 55 | error_msg = "This method can only be used with GeometryCollections" 56 | assert self._obj.type().getInfo() == "GeometryCollection", error_msg 57 | 58 | def filterType(geom): 59 | geom = ee.Geometry(geom) 60 | return ee.Algorithms.If(geom.type().compareTo(type), None, geom) 61 | 62 | geometries = self._obj.geometries().map(filterType, True) 63 | return getattr(ee.Geometry, "Multi" + type)(geometries, self._obj.projection()) 64 | -------------------------------------------------------------------------------- /geetools/ee_join.py: -------------------------------------------------------------------------------- 1 | """Extra methods for the :py:class:`ee.Join` class.""" 2 | from __future__ import annotations 3 | 4 | import ee 5 | 6 | from .accessors import register_class_accessor 7 | 8 | 9 | @register_class_accessor(ee.Join, "geetools") 10 | class JoinAccessor: 11 | """Toolbox for the :py:class:`ee.Join` class.""" 12 | 13 | def __init__(self, obj: ee.Join): 14 | """Initialize the Join class.""" 15 | self._obj = obj 16 | 17 | @staticmethod 18 | def byProperty( 19 | primary: ee.FeatureCollection, 20 | secondary: ee.FeatureCollection, 21 | field: str | ee.String, 22 | outer: bool = False, 23 | ) -> ee.FeatureCollection: 24 | """Join 2 collections by a given property field. 25 | 26 | It assumes ids are unique so uses :py:meth:`ee.Join.saveFirst`. 27 | 28 | Args: 29 | primary: The first collection. 30 | secondary: The second collection. 31 | field: The field to join by. 32 | outer: Whether to keep non-matching features. 33 | 34 | Returns: 35 | The joined collection. 36 | 37 | 38 | Example: 39 | .. jupyter-execute:: 40 | 41 | import ee, geetools 42 | from geetools.utils import initialize_documentation 43 | 44 | initialize_documentation() 45 | 46 | # build fake featureCollections on the same point 47 | point = ee.Geometry.Point([0,0]) 48 | prop1 = {'id': 1, 'prop_from_fc1': 'I am from fc1'} 49 | prop2 = {'id': 1, 'prop_from_fc2': 'I am from fc2'} 50 | fc1 = ee.FeatureCollection([ee.Feature(point, prop1)]) 51 | fc2 = ee.FeatureCollection([ee.Feature(point, prop2)]) 52 | 53 | # join them together in the same featureCollection 54 | joined = ee.Join.geetools.byProperty(fc1, fc2, 'id') 55 | joined.getInfo() 56 | """ 57 | field = ee.String(field) 58 | primary, secondary = ee.FeatureCollection(primary), ee.FeatureCollection(secondary) 59 | Filter = ee.Filter.equals(leftField=field, rightField=field) 60 | join = ee.Join.saveFirst(matchKey="match", outer=outer) 61 | joined = join.apply(primary, secondary, Filter) 62 | 63 | def cleanJoin(feat): 64 | primaryProp = feat.propertyNames().remove("match") 65 | secondaryProp = ee.Feature(feat.get("match")).toDictionary() 66 | return feat.select(primaryProp).setMulti(secondaryProp) 67 | 68 | return ee.FeatureCollection(joined.map(cleanJoin)) 69 | -------------------------------------------------------------------------------- /geetools/ee_number.py: -------------------------------------------------------------------------------- 1 | """Extra methods for the :py:class:`ee.Number` class.""" 2 | from __future__ import annotations 3 | 4 | import ee 5 | 6 | from .accessors import register_class_accessor 7 | 8 | 9 | @register_class_accessor(ee.Number, "geetools") 10 | class NumberAccessor: 11 | """toolbox for the :py:class:`ee.Number` class.""" 12 | 13 | def __init__(self, obj: ee.Number): 14 | """Initialize the Number class.""" 15 | self._obj = obj 16 | 17 | def truncate(self, nbDecimals: int | ee.Number = 2) -> ee.Number: 18 | """Truncate a number to a given number of decimals. 19 | 20 | Parameters: 21 | nbDecimals: The number of decimals to truncate to. 22 | 23 | Returns: 24 | The truncated number. 25 | 26 | Examples: 27 | .. jupyter-execute:: 28 | 29 | import ee, geetools 30 | from geetools.utils import initialize_documentation 31 | 32 | initialize_documentation() 33 | 34 | n = ee.Number(1.23456).geetools.truncate(3) 35 | n.getInfo() 36 | """ 37 | nbDecimals = ee.Number(nbDecimals).toInt() 38 | factor = ee.Number(10).pow(nbDecimals) 39 | return self._obj.multiply(factor).toInt().divide(factor) 40 | 41 | def isClose( 42 | self, other: int | float | ee.Number, tol: int | float | ee.Number = 1e-9 43 | ) -> ee.Number: 44 | """Check if a number is close to another number. 45 | 46 | Args: 47 | other: The number to compare. 48 | tol: The tolerance to consider the numbers close. 49 | 50 | Returns: 51 | A number with value 1 if the numbers are close, 0 otherwise. 52 | 53 | Examples: 54 | .. jupyter-execute:: 55 | 56 | import ee, geetools 57 | from geetools.utils import initialize_documentation 58 | 59 | initialize_documentation() 60 | 61 | n = ee.Number(1.23456).geetools.isClose(1.23456, 1e-5) 62 | n.getInfo() 63 | """ 64 | return self._obj.subtract(other).abs().lte(tol) 65 | -------------------------------------------------------------------------------- /geetools/tools/__init__.py: -------------------------------------------------------------------------------- 1 | """Legacy import package for tools.""" 2 | from . import _deprecated_imagecollection as imagecollection # noqa: F401 3 | -------------------------------------------------------------------------------- /notebooks/algorithms/harmonize.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import ee\n", 10 | "ee.Initialize()" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": null, 16 | "metadata": {}, 17 | "outputs": [], 18 | "source": [ 19 | "import ipygee as ui\n", 20 | "import geedatasets\n", 21 | "import geetools" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": null, 27 | "metadata": {}, 28 | "outputs": [], 29 | "source": [ 30 | "Map = ui.Map()" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": null, 36 | "metadata": {}, 37 | "outputs": [], 38 | "source": [ 39 | "Map.show()" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": null, 45 | "metadata": {}, 46 | "outputs": [], 47 | "source": [ 48 | "l8 = geedatasets.landsat.Landsat8SR()" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": null, 54 | "metadata": {}, 55 | "outputs": [], 56 | "source": [ 57 | "i = l8.collection().filterBounds(ee.Geometry.Point([-72,-42])).first()" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": null, 63 | "metadata": {}, 64 | "outputs": [], 65 | "source": [ 66 | "Map.addLayer(i, l8.visualization('NSR'), 'Original L8 Image')" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": null, 72 | "metadata": {}, 73 | "outputs": [], 74 | "source": [ 75 | "i_harmonized = geetools.algorithms.Landsat.harmonization(i)" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": null, 81 | "metadata": {}, 82 | "outputs": [], 83 | "source": [ 84 | "Map.addLayer(i_harmonized, l8.visualization('NSR'), 'Harmonized L8 Image')" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": null, 90 | "metadata": {}, 91 | "outputs": [], 92 | "source": [] 93 | } 94 | ], 95 | "metadata": { 96 | "kernelspec": { 97 | "display_name": "Python 3", 98 | "language": "python", 99 | "name": "python3" 100 | }, 101 | "language_info": { 102 | "codemirror_mode": { 103 | "name": "ipython", 104 | "version": 3 105 | }, 106 | "file_extension": ".py", 107 | "mimetype": "text/x-python", 108 | "name": "python", 109 | "nbconvert_exporter": "python", 110 | "pygments_lexer": "ipython3", 111 | "version": "3.7.6" 112 | } 113 | }, 114 | "nbformat": 4, 115 | "nbformat_minor": 2 116 | } 117 | -------------------------------------------------------------------------------- /notebooks/collection/joinByProperty.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "Join the data of two collections that share a common property, commonly an id property" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": null, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "import ee\n", 17 | "ee.Initialize()\n", 18 | "import geetools" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": null, 24 | "metadata": {}, 25 | "outputs": [], 26 | "source": [ 27 | "nullGeom = ee.Geometry.Point([0, 0])" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": null, 33 | "metadata": {}, 34 | "outputs": [], 35 | "source": [ 36 | "col1 = ee.FeatureCollection([\n", 37 | " ee.Feature(nullGeom, {'fid': 1, 'a': 10, 'b': 20}),\n", 38 | " ee.Feature(nullGeom, {'fid': 2, 'a': 20, 'b': 10}),\n", 39 | " ee.Feature(nullGeom, {'fid': 3, 'a': 5, 'b': 5}),\n", 40 | " ee.Feature(nullGeom, {'fid': 4, 'a': 30, 'b': 40})\n", 41 | "])" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": null, 47 | "metadata": {}, 48 | "outputs": [], 49 | "source": [ 50 | "col2 = ee.FeatureCollection([\n", 51 | " ee.Feature(nullGeom, {'fid': 2, 'c': 1000, 'd': 2000}),\n", 52 | " ee.Feature(nullGeom, {'fid': 3, 'c': 3000, 'd': 4000}),\n", 53 | " ee.Feature(nullGeom, {'fid': 5, 'c': 5000, 'd': 6000})\n", 54 | "])" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": null, 60 | "metadata": {}, 61 | "outputs": [], 62 | "source": [ 63 | "joined = geetools.tools.collection.joinByProperty(col1, col2, 'fid')" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": null, 69 | "metadata": {}, 70 | "outputs": [], 71 | "source": [ 72 | "joined.toDictionary().getInfo()" 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": null, 78 | "metadata": {}, 79 | "outputs": [], 80 | "source": [] 81 | } 82 | ], 83 | "metadata": { 84 | "kernelspec": { 85 | "display_name": "Python 3", 86 | "language": "python", 87 | "name": "python3" 88 | }, 89 | "language_info": { 90 | "codemirror_mode": { 91 | "name": "ipython", 92 | "version": 3 93 | }, 94 | "file_extension": ".py", 95 | "mimetype": "text/x-python", 96 | "name": "python", 97 | "nbconvert_exporter": "python", 98 | "pygments_lexer": "ipython3", 99 | "version": "3.7.6" 100 | } 101 | }, 102 | "nbformat": 4, 103 | "nbformat_minor": 4 104 | } 105 | -------------------------------------------------------------------------------- /notebooks/date/dayRangeIntervals.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "### Divide a date range into equal day intervals" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": null, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "import ee\n", 17 | "ee.Initialize()\n", 18 | "import geetools" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": null, 24 | "metadata": {}, 25 | "outputs": [], 26 | "source": [ 27 | "import ipygee as ui" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": null, 33 | "metadata": {}, 34 | "outputs": [], 35 | "source": [ 36 | "start = '2020-01-01'\n", 37 | "end = '2020-06-07'\n", 38 | "# make 30 day intervals\n", 39 | "interval = 30" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": null, 45 | "metadata": {}, 46 | "outputs": [], 47 | "source": [ 48 | "intervals = geetools.tools.date.dayRangeIntervals(\n", 49 | " start, end, \n", 50 | " interval=interval,\n", 51 | " reverse=False\n", 52 | ")" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": null, 58 | "metadata": {}, 59 | "outputs": [], 60 | "source": [ 61 | "ui.eprint(intervals)" 62 | ] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "execution_count": null, 67 | "metadata": {}, 68 | "outputs": [], 69 | "source": [ 70 | "intervals_inverse = geetools.tools.date.dayRangeIntervals(\n", 71 | " start, end, \n", 72 | " interval=interval,\n", 73 | " reverse=True\n", 74 | ")" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": null, 80 | "metadata": {}, 81 | "outputs": [], 82 | "source": [ 83 | "ui.eprint(intervals_inverse)" 84 | ] 85 | } 86 | ], 87 | "metadata": { 88 | "kernelspec": { 89 | "display_name": "Python 3", 90 | "language": "python", 91 | "name": "python3" 92 | }, 93 | "language_info": { 94 | "codemirror_mode": { 95 | "name": "ipython", 96 | "version": 3 97 | }, 98 | "file_extension": ".py", 99 | "mimetype": "text/x-python", 100 | "name": "python", 101 | "nbconvert_exporter": "python", 102 | "pygments_lexer": "ipython3", 103 | "version": "3.7.6" 104 | } 105 | }, 106 | "nbformat": 4, 107 | "nbformat_minor": 4 108 | } 109 | -------------------------------------------------------------------------------- /notebooks/image/bufferMask.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import ee\n", 10 | "ee.Initialize()\n", 11 | "import geetools" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "import ipygee as ui" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": null, 26 | "metadata": {}, 27 | "outputs": [], 28 | "source": [ 29 | "Map = ui.Map()\n", 30 | "Map.show()" 31 | ] 32 | }, 33 | { 34 | "cell_type": "markdown", 35 | "metadata": {}, 36 | "source": [ 37 | "Site" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": null, 43 | "metadata": {}, 44 | "outputs": [], 45 | "source": [ 46 | "site = ee.Geometry.Point([-71.5, -41.7]).buffer(2000)\n", 47 | "Map.centerObject(site)" 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "metadata": {}, 53 | "source": [ 54 | "Masked image" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": null, 60 | "metadata": {}, 61 | "outputs": [], 62 | "source": [ 63 | "image = ee.Image('COPERNICUS/S2/20151123T142942_20170221T180430_T18GYU')\n", 64 | "fclouds = geetools.cloud_mask.sentinel2()\n", 65 | "masked = fclouds(image)" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": null, 71 | "metadata": {}, 72 | "outputs": [], 73 | "source": [ 74 | "vis = dict(bands=['B4', 'B3', 'B2'], min=0, max=2500)" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": null, 80 | "metadata": {}, 81 | "outputs": [], 82 | "source": [ 83 | "Map.addLayer(masked, vis, 'Not buffered')" 84 | ] 85 | }, 86 | { 87 | "cell_type": "markdown", 88 | "metadata": {}, 89 | "source": [ 90 | "Buffer Mask" 91 | ] 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": null, 96 | "metadata": {}, 97 | "outputs": [], 98 | "source": [ 99 | "buffer = geetools.tools.image.bufferMask(masked, 500, units='meters')" 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "execution_count": null, 105 | "metadata": {}, 106 | "outputs": [], 107 | "source": [ 108 | "Map.addLayer(buffer, vis, 'buffered 500 m')" 109 | ] 110 | }, 111 | { 112 | "cell_type": "code", 113 | "execution_count": null, 114 | "metadata": {}, 115 | "outputs": [], 116 | "source": [] 117 | } 118 | ], 119 | "metadata": { 120 | "kernelspec": { 121 | "display_name": "Python 3", 122 | "language": "python", 123 | "name": "python3" 124 | }, 125 | "language_info": { 126 | "codemirror_mode": { 127 | "name": "ipython", 128 | "version": 3 129 | }, 130 | "file_extension": ".py", 131 | "mimetype": "text/x-python", 132 | "name": "python", 133 | "nbconvert_exporter": "python", 134 | "pygments_lexer": "ipython3", 135 | "version": "3.7.6" 136 | } 137 | }, 138 | "nbformat": 4, 139 | "nbformat_minor": 4 140 | } 141 | -------------------------------------------------------------------------------- /notebooks/imagecollection/parametrizeProperty.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import ee\n", 10 | "ee.Initialize()" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": null, 16 | "metadata": {}, 17 | "outputs": [], 18 | "source": [ 19 | "from geetools import tools" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": null, 25 | "metadata": {}, 26 | "outputs": [], 27 | "source": [ 28 | "import ipygee as ui\n", 29 | "import geedatasets" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": null, 35 | "metadata": {}, 36 | "outputs": [], 37 | "source": [ 38 | "l8 = geedatasets.landsat.Landsat8SR()" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": null, 44 | "metadata": {}, 45 | "outputs": [], 46 | "source": [ 47 | "col = l8.collection().limit(10)" 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "metadata": {}, 53 | "source": [ 54 | "## Parametrize CLOUD_COVER from 0-100 to 0-1" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": null, 60 | "metadata": {}, 61 | "outputs": [], 62 | "source": [ 63 | "parametrized = tools.imagecollection.parametrizeProperty(col, 'CLOUD_COVER', [0, 100], [0, 1])" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": null, 69 | "metadata": {}, 70 | "outputs": [], 71 | "source": [ 72 | "cloud_cover = parametrized.toList(10).map(lambda img: ee.Image(img).get('CLOUD_COVER_PARAMETRIZED'))" 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": null, 78 | "metadata": {}, 79 | "outputs": [], 80 | "source": [ 81 | "ui.eprint(cloud_cover)" 82 | ] 83 | }, 84 | { 85 | "cell_type": "markdown", 86 | "metadata": {}, 87 | "source": [ 88 | "## Values out of range" 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": null, 94 | "metadata": {}, 95 | "outputs": [], 96 | "source": [ 97 | "parametrized2 = tools.imagecollection.parametrizeProperty(col, 'CLOUD_COVER', [0, 80], [0, 1])" 98 | ] 99 | }, 100 | { 101 | "cell_type": "code", 102 | "execution_count": null, 103 | "metadata": {}, 104 | "outputs": [], 105 | "source": [ 106 | "out_of_range = parametrized2.toList(10).map(lambda img: ee.Image(img).get('CLOUD_COVER_PARAMETRIZED'))" 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": null, 112 | "metadata": {}, 113 | "outputs": [], 114 | "source": [ 115 | "ui.eprint(out_of_range)" 116 | ] 117 | }, 118 | { 119 | "cell_type": "code", 120 | "execution_count": null, 121 | "metadata": {}, 122 | "outputs": [], 123 | "source": [] 124 | } 125 | ], 126 | "metadata": { 127 | "kernelspec": { 128 | "display_name": "Python 3", 129 | "language": "python", 130 | "name": "python3" 131 | }, 132 | "language_info": { 133 | "codemirror_mode": { 134 | "name": "ipython", 135 | "version": 3 136 | }, 137 | "file_extension": ".py", 138 | "mimetype": "text/x-python", 139 | "name": "python", 140 | "nbconvert_exporter": "python", 141 | "pygments_lexer": "ipython3", 142 | "version": "3.7.6" 143 | } 144 | }, 145 | "nbformat": 4, 146 | "nbformat_minor": 2 147 | } 148 | -------------------------------------------------------------------------------- /noxfile.py: -------------------------------------------------------------------------------- 1 | """All the process that can be run using nox. 2 | 3 | The nox run are build in isolated environment that will be stored in .nox. to force the venv update, remove the .nox/xxx folder. 4 | """ 5 | 6 | import nox 7 | 8 | nox.options.sessions = ["lint", "test", "docs", "mypy"] 9 | 10 | 11 | @nox.session(reuse_venv=True) 12 | def lint(session): 13 | """Apply the pre-commits.""" 14 | session.install("pre-commit") 15 | session.run("pre-commit", "run", "--all-files", *session.posargs) 16 | 17 | 18 | @nox.session(reuse_venv=True, name="ci-test") 19 | def ci_test(session): 20 | """Run all the test using the environment variable of the running machine.""" 21 | session.install(".[test]") 22 | test_files = session.posargs or ["tests"] 23 | session.run( 24 | "pytest", 25 | "--color=yes", 26 | "--cov", 27 | "--cov-report=xml", 28 | *test_files, 29 | ) 30 | 31 | 32 | @nox.session(reuse_venv=True) 33 | def test(session): 34 | """Run all the test using the environment variable of the running machine.""" 35 | session.install(".[test]") 36 | test_files = session.posargs or ["tests"] 37 | session.run( 38 | "pytest", 39 | "--color=yes", 40 | "--cov", 41 | "--cov-report=html", 42 | *test_files, 43 | ) 44 | 45 | 46 | @nox.session(reuse_venv=True, name="dead-fixtures") 47 | def dead_fixtures(session): 48 | """Check for dead fixtures within the tests.""" 49 | session.install(".[test]") 50 | session.run("pytest", "--dead-fixtures") 51 | 52 | 53 | @nox.session(reuse_venv=True) 54 | def docs(session): 55 | """Build the documentation.""" 56 | build = session.posargs.pop() if session.posargs else "html" 57 | session.install(".[doc]") 58 | dst, warn = f"docs/_build/{build}", "warnings.txt" 59 | session.run("sphinx-build", "-v", "-b", build, "docs", dst, "-w", warn) 60 | 61 | 62 | @nox.session(name="mypy", reuse_venv=True) 63 | def mypy(session): 64 | """Run a mypy check of the lib.""" 65 | session.install("mypy") 66 | test_files = session.posargs or ["geetools"] 67 | session.run("mypy", *test_files) 68 | 69 | 70 | @nox.session(reuse_venv=True) 71 | def stubgen(session): 72 | """Generate stub files for the lib but requires human attention before merge.""" 73 | session.install("mypy") 74 | package = session.posargs or ["geetools"] 75 | session.run("stubgen", "-p", package[0], "-o", "stubs", "--include-private") 76 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | """make test folder a package for coverage.""" 2 | -------------------------------------------------------------------------------- /tests/test_Array.py: -------------------------------------------------------------------------------- 1 | """Test the Array class methods.""" 2 | import ee 3 | 4 | 5 | class TestFull: 6 | """Test the full method.""" 7 | 8 | def test_full_with_integers(self): 9 | full_array = ee.Array.geetools.full(3, 3, 1) 10 | assert full_array.getInfo() == [[1, 1, 1], [1, 1, 1], [1, 1, 1]] 11 | 12 | def test_full_with_floats(self): 13 | full_array = ee.Array.geetools.full(3.1, 3.1, 1.0) 14 | assert full_array.getInfo() == [ 15 | [1.0, 1.0, 1.0], 16 | [1.0, 1.0, 1.0], 17 | [1.0, 1.0, 1.0], 18 | ] 19 | 20 | def test_full_with_ee_numbers(self): 21 | full_array = ee.Array.geetools.full(ee.Number(3), ee.Number(3), ee.Number(1)) 22 | assert full_array.getInfo() == [[1, 1, 1], [1, 1, 1], [1, 1, 1]] 23 | 24 | 25 | class TestSet: 26 | """Test the set method.""" 27 | 28 | def test_set_with_integers(self): 29 | array = ee.Array.geetools.full(3, 3, 1) 30 | set_array = array.geetools.set(1, 1, 0) 31 | assert set_array.getInfo() == [[1, 1, 1], [1, 0, 1], [1, 1, 1]] 32 | 33 | def test_set_with_floats(self): 34 | array = ee.Array.geetools.full(3.1, 3.1, 1.0) 35 | set_array = array.geetools.set(1, 1, 0.0) 36 | assert set_array.getInfo() == [ 37 | [1.0, 1.0, 1.0], 38 | [1.0, 0.0, 1.0], 39 | [1.0, 1.0, 1.0], 40 | ] 41 | 42 | def test_set_with_ee_numbers(self): 43 | array = ee.Array.geetools.full(3, 3, ee.Number(1)) 44 | set_array = array.geetools.set(1, 1, ee.Number(0)) 45 | assert set_array.getInfo() == [[1, 1, 1], [1, 0, 1], [1, 1, 1]] 46 | -------------------------------------------------------------------------------- /tests/test_Asset/test_glob.yml: -------------------------------------------------------------------------------- 1 | - projects/ee-project/assets/hash/folder/image 2 | -------------------------------------------------------------------------------- /tests/test_Asset/test_iterdir.yml: -------------------------------------------------------------------------------- 1 | - projects/ee-project/assets/hash/folder/image 2 | - projects/ee-project/assets/hash/folder/subfolder 3 | -------------------------------------------------------------------------------- /tests/test_Asset/test_iterdir_recursive.yml: -------------------------------------------------------------------------------- 1 | - projects/ee-project/assets/hash/folder/image 2 | - projects/ee-project/assets/hash/folder/subfolder 3 | - projects/ee-project/assets/hash/folder/subfolder/image 4 | -------------------------------------------------------------------------------- /tests/test_Asset/test_parents.yml: -------------------------------------------------------------------------------- 1 | - projects/test/assets/foo/bar 2 | - projects/test/assets/foo 3 | -------------------------------------------------------------------------------- /tests/test_Asset/test_rglob.yml: -------------------------------------------------------------------------------- 1 | - projects/ee-project/assets/hash/folder/image 2 | - projects/ee-project/assets/hash/folder/subfolder/image 3 | -------------------------------------------------------------------------------- /tests/test_Asset/test_rmdir_recursive_dry_run.yml: -------------------------------------------------------------------------------- 1 | - projects/ee-project/assets/hash/rmdir_folder/subfolder/image 2 | - projects/ee-project/assets/hash/rmdir_folder/image 3 | - projects/ee-project/assets/hash/rmdir_folder/subfolder 4 | - projects/ee-project/assets/hash/rmdir_folder 5 | -------------------------------------------------------------------------------- /tests/test_ComputedObect.py: -------------------------------------------------------------------------------- 1 | """Test the ComputedObject class methods.""" 2 | 3 | import ee 4 | import pytest 5 | 6 | 7 | class TestIsinstance: 8 | """Test the isInstance method.""" 9 | 10 | def test_isinstance_with_string(self): 11 | assert ee.String("").isInstance(ee.String).getInfo() == 1 12 | 13 | def test_isinstance_with_integer(self): 14 | assert ee.Number(1).isInstance(ee.Integer).getInfo() == 1 15 | 16 | def test_isinstance_with_float(self): 17 | assert ee.Number(1.1).isInstance(ee.Float).getInfo() == 1 18 | 19 | def test_isinstance_with_image(self): 20 | assert ee.Image().isInstance(ee.Image).getInfo() == 1 21 | 22 | def test_isinstance_with_imagecollection(self): 23 | ic = ee.ImageCollection([ee.Image()]) 24 | assert ic.isInstance(ee.ImageCollection).getInfo() == 1 25 | 26 | def test_isinstance_with_feature(self): 27 | assert ee.Feature(None).isInstance(ee.Feature).getInfo() == 1 28 | 29 | def test_isinstance_with_geometry(self): 30 | assert ee.Geometry.Point([0, 0]).isInstance(ee.Geometry).getInfo() == 1 31 | 32 | 33 | class TestSave: 34 | """Test the ``save`` method.""" 35 | 36 | def test_save(self, tmp_path): 37 | file = tmp_path / "test.gee" 38 | ee.Number(1.1).save(file) 39 | assert file.exists() 40 | 41 | 42 | class TestOpen: 43 | """Test the ``open`` method.""" 44 | 45 | def test_open(self, tmp_path): 46 | (object := ee.Number(1.1)).save((file := tmp_path / "test.gee")) 47 | opened = ee.Number.open(file) 48 | assert object.eq(opened).getInfo() 49 | 50 | def test_open_not_correct_suffix(self): 51 | with pytest.raises(ValueError): 52 | ee.Number.open("file.toto") 53 | -------------------------------------------------------------------------------- /tests/test_Date.py: -------------------------------------------------------------------------------- 1 | """Test the Date class methods.""" 2 | from datetime import datetime as dt 3 | from zoneinfo import ZoneInfo 4 | 5 | import ee 6 | import pytest 7 | 8 | import geetools # noqa: F401 9 | 10 | 11 | class TestToDatetime: 12 | """Test the toDatetime method.""" 13 | 14 | def test_to_datetime(self, date_instance): 15 | py_dt = date_instance.geetools.to_datetime() 16 | assert py_dt == dt(2020, 1, 1, tzinfo=ZoneInfo("UTC")) 17 | 18 | def test_to_datetime_timezone(self, date_instance): 19 | tz = ZoneInfo("America/Buenos_Aires") 20 | py_dt = date_instance.geetools.to_datetime(tz) 21 | # Buenos Aires time is -3 22 | assert py_dt == dt(2019, 12, 31, 21, tzinfo=tz) 23 | 24 | def test_to_datetime_str_timezone(self, date_instance): 25 | str_tz = "America/Buenos_Aires" 26 | py_dt = date_instance.geetools.to_datetime(str_tz) 27 | # Buenos Aires time is -3 28 | assert py_dt == dt(2019, 12, 31, 21, tzinfo=ZoneInfo(str_tz)) 29 | 30 | 31 | class TestGetUnitSinceEpoch: 32 | """Test the getUnitSinceEpoch method.""" 33 | 34 | def test_unit_since_epoch(self, date_instance): 35 | unit = date_instance.geetools.getUnitSinceEpoch("year") 36 | assert unit.getInfo() >= 49 # 2020 - 1970 37 | 38 | def test_wrong_unit(self, date_instance): 39 | with pytest.raises(ValueError): 40 | date_instance.geetools.getUnitSinceEpoch("foo") 41 | 42 | 43 | class TestFromEpoch: 44 | """Test the fromEpoch method.""" 45 | 46 | def test_from_epoch(self): 47 | date = ee.Date.geetools.fromEpoch(49, "year") 48 | assert date.format("YYYY-MM-DD").getInfo() == "2019-01-01" 49 | 50 | def test_wrong_unit(self): 51 | with pytest.raises(ValueError): 52 | ee.Date.geetools.fromEpoch(49, "foo") 53 | 54 | 55 | class TestFromDOY: 56 | """Test the fromDOY method.""" 57 | 58 | def test_from_doy(self): 59 | date = ee.Date.geetools.fromDOY(1, 2020) 60 | assert date.format("YYYY-MM-DD").getInfo() == "2020-01-01" 61 | 62 | def test_wrong_year(self): 63 | # check GEE can use year < EPOCH 64 | date = ee.Date.geetools.fromDOY(1, 3) 65 | assert date.format("YYYY-MM-DD").getInfo() == "0003-01-01" 66 | 67 | 68 | class TestToDOY: 69 | """Test the toDOY method.""" 70 | 71 | def test_to_doy(self): 72 | doy = ee.Date("2025-04-09").geetools.toDOY() 73 | assert doy.getInfo() == 99 74 | 75 | def test_to_doy_leap(self): 76 | doy = ee.Date("2020-03-01").geetools.toDOY() 77 | assert doy.getInfo() == 60 78 | 79 | def test_to_doy_non_leap(self): 80 | doy = ee.Date("2021-03-01").geetools.toDOY() 81 | assert doy.getInfo() == 60 82 | 83 | 84 | class TestIsLeap: 85 | """Test the isLeap method.""" 86 | 87 | def test_is_leap_1992(self): 88 | leap = ee.Date("1992-01-01").geetools.isLeap() 89 | assert leap.getInfo() == 1 90 | 91 | def test_is_leap_2000(self): 92 | leap = ee.Date("2000-01-01").geetools.isLeap() 93 | assert leap.getInfo() == 1 94 | 95 | def test_is_leap_1900(self): 96 | leap = ee.Date("1900-01-01").geetools.isLeap() 97 | assert leap.getInfo() == 0 98 | 99 | 100 | class TestNow: 101 | """Test the now method.""" 102 | 103 | def test_now(self): 104 | date = ee.Date.geetools.now() 105 | assert date.getInfo() is not None 106 | -------------------------------------------------------------------------------- /tests/test_DateRange.py: -------------------------------------------------------------------------------- 1 | """Test the ``DateRange`` class.""" 2 | import ee 3 | import pytest 4 | 5 | 6 | class TestSplit: 7 | """Test the ``split`` method.""" 8 | 9 | def test_split(self, daterange_instance): 10 | list = daterange_instance.geetools.split(1, "day") 11 | first = ee.DateRange(list.get(0)).start() 12 | last = ee.DateRange(list.get(-1)).end() 13 | assert list.size().getInfo() == 30 14 | assert first.format("YYYY-MM-dd").getInfo() == "2020-01-01" 15 | assert last.format("YYYY-MM-dd").getInfo() == "2020-01-31" 16 | 17 | def split_with_end_outside(self, daterange_instance): 18 | list = daterange_instance.geetools.split(2, "month") 19 | first = ee.DateRange(list.get(0)).start() 20 | last = ee.DateRange(list.get(-1)).end() 21 | assert list.size().getInfo() == 1 22 | assert first.format("YYYY-MM-dd").getInfo() == "2020-01-01" 23 | assert last.format("YYYY-MM-dd").getInfo() == "2020-01-31" 24 | 25 | 26 | class TestCheckUnit: 27 | """Test the ``check_unit`` method exception.""" 28 | 29 | def test_check_unit(self): 30 | with pytest.raises(ValueError): 31 | ee.DateRange.geetools.check_unit("toto") 32 | -------------------------------------------------------------------------------- /tests/test_Dictionary.py: -------------------------------------------------------------------------------- 1 | """Test the Dictionary class methods.""" 2 | import ee 3 | 4 | import geetools # noqa: F401 5 | 6 | 7 | class TestFromPairs: 8 | """Test the fromPairs method.""" 9 | 10 | def test_from_pairs_with_list(self): 11 | d = ee.Dictionary.geetools.fromPairs([["foo", 1], ["bar", 2]]) 12 | assert d.getInfo() == {"foo": 1, "bar": 2} 13 | 14 | def test_from_pairs_with_ee_list(self): 15 | d = ee.Dictionary.geetools.fromPairs(ee.List([["foo", 1], ["bar", 2]])) 16 | assert d.getInfo() == {"foo": 1, "bar": 2} 17 | 18 | 19 | class TestSort: 20 | """Test the sort method.""" 21 | 22 | def test_sort(self): 23 | d = ee.Dictionary({"foo": 1, "bar": 2}).geetools.sort() 24 | assert d.getInfo() == {"bar": 2, "foo": 1} 25 | 26 | 27 | class TestGetMany: 28 | """Test the getMany method.""" 29 | 30 | def test_getMany(self): 31 | d = ee.Dictionary({"foo": 1, "bar": 2}).geetools.getMany(["foo"]) 32 | assert d.getInfo() == [1] 33 | 34 | 35 | class TestToTable: 36 | """Test the `toTable` method.""" 37 | 38 | def test_to_table_any(self, data_regression): 39 | ee_dict = ee.Dictionary({"foo": 1, "bar": 2}) 40 | res = ee_dict.geetools.toTable() 41 | data_regression.check(res.getInfo()) 42 | 43 | def test_to_table_list(self, data_regression): 44 | ee_dict = ee.Dictionary({"Argentina": [12, 278.289196625], "Armenia": [13, 3.13783139285]}) 45 | res = ee_dict.geetools.toTable("list") 46 | data_regression.check(res.getInfo()) 47 | 48 | def test_to_table_dict(self, data_regression): 49 | ee_dict = ee.Dictionary( 50 | { 51 | "Argentina": {"ADM0_CODE": 12, "Shape_Area": 278.289196625}, 52 | "Armenia": {"ADM0_CODE": 13, "Shape_Area": 3.13783139285}, 53 | } 54 | ) 55 | res = ee_dict.geetools.toTable("dict") 56 | data_regression.check(res.getInfo()) 57 | -------------------------------------------------------------------------------- /tests/test_Dictionary/test_to_table_any.yml: -------------------------------------------------------------------------------- 1 | columns: 2 | system:index: String 3 | value: Integer 4 | features: 5 | - geometry: null 6 | id: bar 7 | properties: 8 | value: 2 9 | type: Feature 10 | - geometry: null 11 | id: foo 12 | properties: 13 | value: 1 14 | type: Feature 15 | type: FeatureCollection 16 | -------------------------------------------------------------------------------- /tests/test_Dictionary/test_to_table_dict.yml: -------------------------------------------------------------------------------- 1 | columns: 2 | ADM0_CODE: Integer 3 | Shape_Area: Float 4 | system:index: String 5 | features: 6 | - geometry: null 7 | id: Argentina 8 | properties: 9 | ADM0_CODE: 12 10 | Shape_Area: 278.289196625 11 | type: Feature 12 | - geometry: null 13 | id: Armenia 14 | properties: 15 | ADM0_CODE: 13 16 | Shape_Area: 3.13783139285 17 | type: Feature 18 | type: FeatureCollection 19 | -------------------------------------------------------------------------------- /tests/test_Dictionary/test_to_table_list.yml: -------------------------------------------------------------------------------- 1 | columns: 2 | system:index: String 3 | value_0: Integer 4 | value_1: Float 5 | features: 6 | - geometry: null 7 | id: Argentina 8 | properties: 9 | value_0: 12 10 | value_1: 278.289196625 11 | type: Feature 12 | - geometry: null 13 | id: Armenia 14 | properties: 15 | value_0: 13 16 | value_1: 3.13783139285 17 | type: Feature 18 | type: FeatureCollection 19 | -------------------------------------------------------------------------------- /tests/test_Export.py: -------------------------------------------------------------------------------- 1 | """Test the ``Export`` class.""" 2 | import ee 3 | import pytest 4 | from ee.cli.utils import wait_for_task 5 | 6 | import geetools # noqa F401 7 | 8 | 9 | class TestImageCollection: 10 | """Test the ``imagecollection`` namespace.""" 11 | 12 | @pytest.mark.skip(reason="The export task timeout when to many tests are run at the same time") 13 | def test_toAsset(self, gee_test_folder): 14 | task_list = ee.batch.Export.geetools.imagecollection.toAsset( 15 | imagecollection=self.ic, 16 | description="ic_to_asset", 17 | index_property="index", 18 | assetId=(gee_test_folder / "ic_to_asset").as_posix(), 19 | region=ee.Geometry.Point([0, 0]).buffer(100).bounds(), 20 | scale=50, 21 | ) 22 | [task.start() for task in task_list] 23 | [wait_for_task(task.id, timeout=50) for task in task_list] 24 | 25 | ic = ee.ImageCollection((gee_test_folder / "ic_to_asset").as_posix()) 26 | assert ic.size().getInfo() == 2 27 | 28 | @property 29 | def ic(self): 30 | """Return a test image collection.""" 31 | image_list = [ee.Image(i).set("index", f"image_{i}") for i in range(2)] 32 | return ee.ImageCollection(image_list) 33 | -------------------------------------------------------------------------------- /tests/test_Feature.py: -------------------------------------------------------------------------------- 1 | """Test the ``Feature`` class.""" 2 | import ee 3 | 4 | import geetools # noqa: F401 5 | 6 | 7 | class TestToFeatureCollection: 8 | """Test the ``toFeatureCollection`` method.""" 9 | 10 | def test_to_feature_collection(self, multipoint_feature, ee_feature_collection_regression): 11 | fc = multipoint_feature.geetools.toFeatureCollection() 12 | ee_feature_collection_regression.check(fc) 13 | 14 | 15 | class TestRemoveProperties: 16 | """Test the ``removeProperties`` method.""" 17 | 18 | def test_remove_properties(self, multipoint_feature, ee_feature_collection_regression): 19 | feature = multipoint_feature.geetools.removeProperties(["foo"]) 20 | ee_feature_collection_regression.check(ee.FeatureCollection(feature)) 21 | -------------------------------------------------------------------------------- /tests/test_Feature/serialized_test_remove_properties.yml: -------------------------------------------------------------------------------- 1 | result: '0' 2 | values: 3 | '0': 4 | functionInvocationValue: 5 | arguments: 6 | destination: 7 | functionInvocationValue: 8 | arguments: 9 | geometry: 10 | functionInvocationValue: 11 | arguments: 12 | feature: 13 | valueReference: '1' 14 | functionName: Feature.geometry 15 | functionName: Feature 16 | exclude: 17 | arrayValue: 18 | values: 19 | - valueReference: '3' 20 | source: 21 | valueReference: '1' 22 | functionName: Element.copyProperties 23 | '1': 24 | functionInvocationValue: 25 | arguments: 26 | key: 27 | valueReference: '2' 28 | object: 29 | functionInvocationValue: 30 | arguments: 31 | key: 32 | valueReference: '3' 33 | object: 34 | functionInvocationValue: 35 | arguments: 36 | geometry: 37 | functionInvocationValue: 38 | arguments: 39 | coordinates: 40 | constantValue: 41 | - - 0 42 | - 0 43 | - - 0 44 | - 1 45 | functionName: GeometryConstructors.MultiPoint 46 | functionName: Feature 47 | value: 48 | valueReference: '2' 49 | functionName: Element.set 50 | value: 51 | valueReference: '3' 52 | functionName: Element.set 53 | '2': 54 | constantValue: bar 55 | '3': 56 | constantValue: foo 57 | -------------------------------------------------------------------------------- /tests/test_Feature/serialized_test_to_feature_collection.yml: -------------------------------------------------------------------------------- 1 | result: '0' 2 | values: 3 | '0': 4 | functionInvocationValue: 5 | arguments: 6 | features: 7 | functionInvocationValue: 8 | arguments: 9 | baseAlgorithm: 10 | functionDefinitionValue: 11 | argumentNames: 12 | - _MAPPING_VAR_0_0 13 | body: '1' 14 | dropNulls: 15 | constantValue: false 16 | list: 17 | functionInvocationValue: 18 | arguments: 19 | geometry: 20 | functionInvocationValue: 21 | arguments: 22 | feature: 23 | valueReference: '2' 24 | functionName: Feature.geometry 25 | functionName: Geometry.geometries 26 | functionName: List.map 27 | functionName: Collection 28 | '1': 29 | functionInvocationValue: 30 | arguments: 31 | feature: 32 | valueReference: '2' 33 | geometry: 34 | argumentReference: _MAPPING_VAR_0_0 35 | functionName: Feature.setGeometry 36 | '2': 37 | functionInvocationValue: 38 | arguments: 39 | key: 40 | valueReference: '3' 41 | object: 42 | functionInvocationValue: 43 | arguments: 44 | key: 45 | valueReference: '4' 46 | object: 47 | functionInvocationValue: 48 | arguments: 49 | geometry: 50 | functionInvocationValue: 51 | arguments: 52 | coordinates: 53 | constantValue: 54 | - - 0 55 | - 0 56 | - - 0 57 | - 1 58 | functionName: GeometryConstructors.MultiPoint 59 | functionName: Feature 60 | value: 61 | valueReference: '3' 62 | functionName: Element.set 63 | value: 64 | valueReference: '4' 65 | functionName: Element.set 66 | '3': 67 | constantValue: bar 68 | '4': 69 | constantValue: foo 70 | -------------------------------------------------------------------------------- /tests/test_Feature/test_remove_properties.yml: -------------------------------------------------------------------------------- 1 | geometry: 2 | coordinates: 3 | - - 0 4 | - 0 5 | - - 0 6 | - 1 7 | type: MultiPoint 8 | properties: 9 | bar: foo 10 | type: Feature 11 | -------------------------------------------------------------------------------- /tests/test_Feature/test_to_feature_collection.yml: -------------------------------------------------------------------------------- 1 | columns: 2 | bar: String 3 | foo: String 4 | system:index: String 5 | features: 6 | - geometry: 7 | coordinates: 8 | - 0 9 | - 0 10 | type: Point 11 | id: '0' 12 | properties: 13 | bar: foo 14 | foo: bar 15 | type: Feature 16 | - geometry: 17 | coordinates: 18 | - 0 19 | - 1 20 | type: Point 21 | id: '1' 22 | properties: 23 | bar: foo 24 | foo: bar 25 | type: Feature 26 | type: FeatureCollection 27 | -------------------------------------------------------------------------------- /tests/test_FeatureCollection/serialized_test_from_geo_interface.yml: -------------------------------------------------------------------------------- 1 | result: '0' 2 | values: 3 | '0': 4 | functionInvocationValue: 5 | arguments: 6 | features: 7 | arrayValue: 8 | values: 9 | - functionInvocationValue: 10 | arguments: 11 | geometry: 12 | functionInvocationValue: 13 | arguments: 14 | coordinates: 15 | constantValue: 16 | - -104.99404 17 | - 39.75621 18 | functionName: GeometryConstructors.Point 19 | metadata: 20 | constantValue: 21 | name: Coors Field 22 | system:index: '0' 23 | functionName: Feature 24 | functionName: Collection 25 | -------------------------------------------------------------------------------- /tests/test_FeatureCollection/serialized_test_from_geo_interface_from_dict.yml: -------------------------------------------------------------------------------- 1 | result: '0' 2 | values: 3 | '0': 4 | functionInvocationValue: 5 | arguments: 6 | features: 7 | arrayValue: 8 | values: 9 | - functionInvocationValue: 10 | arguments: 11 | geometry: 12 | functionInvocationValue: 13 | arguments: 14 | coordinates: 15 | constantValue: 16 | - -104.99404 17 | - 39.75621 18 | functionName: GeometryConstructors.Point 19 | metadata: 20 | constantValue: 21 | name: Coors Field 22 | system:index: '0' 23 | functionName: Feature 24 | functionName: Collection 25 | -------------------------------------------------------------------------------- /tests/test_FeatureCollection/serialized_test_to_dictionary.yml: -------------------------------------------------------------------------------- 1 | result: '0' 2 | values: 3 | '0': 4 | functionInvocationValue: 5 | arguments: 6 | keys: 7 | functionInvocationValue: 8 | arguments: 9 | baseAlgorithm: 10 | functionDefinitionValue: 11 | argumentNames: 12 | - _MAPPING_VAR_0_0 13 | body: '1' 14 | dropNulls: 15 | constantValue: false 16 | list: 17 | functionInvocationValue: 18 | arguments: 19 | collection: 20 | valueReference: '2' 21 | property: 22 | valueReference: '3' 23 | functionName: AggregateFeatureCollection.array 24 | functionName: List.map 25 | values: 26 | functionInvocationValue: 27 | arguments: 28 | baseAlgorithm: 29 | functionDefinitionValue: 30 | argumentNames: 31 | - _MAPPING_VAR_0_0 32 | body: '4' 33 | dropNulls: 34 | constantValue: false 35 | list: 36 | functionInvocationValue: 37 | arguments: 38 | collection: 39 | valueReference: '2' 40 | count: 41 | functionInvocationValue: 42 | arguments: 43 | collection: 44 | valueReference: '2' 45 | functionName: Collection.size 46 | functionName: Collection.toList 47 | functionName: List.map 48 | functionName: Dictionary.fromLists 49 | '1': 50 | functionInvocationValue: 51 | arguments: 52 | input: 53 | argumentReference: _MAPPING_VAR_0_0 54 | functionName: String 55 | '2': 56 | functionInvocationValue: 57 | arguments: 58 | collection: 59 | functionInvocationValue: 60 | arguments: 61 | tableId: 62 | constantValue: FAO/GAUL/2015/level0 63 | functionName: Collection.loadTable 64 | filter: 65 | functionInvocationValue: 66 | arguments: 67 | leftField: 68 | valueReference: '3' 69 | rightValue: 70 | constantValue: Ar 71 | functionName: Filter.stringStartsWith 72 | functionName: Collection.filter 73 | '3': 74 | constantValue: ADM0_NAME 75 | '4': 76 | functionInvocationValue: 77 | arguments: 78 | element: 79 | argumentReference: _MAPPING_VAR_0_0 80 | properties: 81 | constantValue: 82 | - ADM0_CODE 83 | - Shape_Area 84 | functionName: Element.toDictionary 85 | -------------------------------------------------------------------------------- /tests/test_FeatureCollection/test_by_features_with_properties.yml: -------------------------------------------------------------------------------- 1 | Desert: 2 | 01_tmean: 5.791 3 | 02_tmean: 7.645 4 | Forest: 5 | 01_tmean: 2.7925 6 | 02_tmean: 3.6091 7 | Grassland: 8 | 01_tmean: -3.7566 9 | 02_tmean: -1.9902 10 | -------------------------------------------------------------------------------- /tests/test_FeatureCollection/test_by_properties_with_properties.yml: -------------------------------------------------------------------------------- 1 | 01_tmean: 2 | Desert: 5.791 3 | Forest: 2.7925 4 | Grassland: -3.7566 5 | 02_tmean: 6 | Desert: 7.645 7 | Forest: 3.6091 8 | Grassland: -1.9902 9 | -------------------------------------------------------------------------------- /tests/test_FeatureCollection/test_from_geo_interface.yml: -------------------------------------------------------------------------------- 1 | features: 2 | - geometry: 3 | coordinates: 4 | - -104.994 5 | - 39.7562 6 | type: Point 7 | id: '0' 8 | properties: 9 | name: Coors Field 10 | type: Feature 11 | type: FeatureCollection 12 | -------------------------------------------------------------------------------- /tests/test_FeatureCollection/test_from_geo_interface_from_dict.yml: -------------------------------------------------------------------------------- 1 | features: 2 | - geometry: 3 | coordinates: 4 | - -104.994 5 | - 39.7562 6 | type: Point 7 | id: '0' 8 | properties: 9 | name: Coors Field 10 | type: Feature 11 | type: FeatureCollection 12 | -------------------------------------------------------------------------------- /tests/test_FeatureCollection/test_plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_FeatureCollection/test_plot.png -------------------------------------------------------------------------------- /tests/test_FeatureCollection/test_plot_by_features_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_FeatureCollection/test_plot_by_features_bar.png -------------------------------------------------------------------------------- /tests/test_FeatureCollection/test_plot_by_features_donut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_FeatureCollection/test_plot_by_features_donut.png -------------------------------------------------------------------------------- /tests/test_FeatureCollection/test_plot_by_features_pie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_FeatureCollection/test_plot_by_features_pie.png -------------------------------------------------------------------------------- /tests/test_FeatureCollection/test_plot_by_features_scatter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_FeatureCollection/test_plot_by_features_scatter.png -------------------------------------------------------------------------------- /tests/test_FeatureCollection/test_plot_by_features_stacked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_FeatureCollection/test_plot_by_features_stacked.png -------------------------------------------------------------------------------- /tests/test_FeatureCollection/test_plot_by_properties_area.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_FeatureCollection/test_plot_by_properties_area.png -------------------------------------------------------------------------------- /tests/test_FeatureCollection/test_plot_by_properties_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_FeatureCollection/test_plot_by_properties_bar.png -------------------------------------------------------------------------------- /tests/test_FeatureCollection/test_plot_by_properties_plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_FeatureCollection/test_plot_by_properties_plot.png -------------------------------------------------------------------------------- /tests/test_FeatureCollection/test_plot_hist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_FeatureCollection/test_plot_hist.png -------------------------------------------------------------------------------- /tests/test_FeatureCollection/test_plot_with_boundaries.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_FeatureCollection/test_plot_with_boundaries.png -------------------------------------------------------------------------------- /tests/test_FeatureCollection/test_plot_with_cmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_FeatureCollection/test_plot_with_cmap.png -------------------------------------------------------------------------------- /tests/test_FeatureCollection/test_plot_with_property.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_FeatureCollection/test_plot_with_property.png -------------------------------------------------------------------------------- /tests/test_FeatureCollection/test_to_dictionary.yml: -------------------------------------------------------------------------------- 1 | Argentina: 2 | ADM0_CODE: 12 3 | Shape_Area: 278.2892 4 | Armenia: 5 | ADM0_CODE: 13 6 | Shape_Area: 3.1378 7 | Aruba: 8 | ADM0_CODE: 14 9 | Shape_Area: 0.0149 10 | Arunachal Pradesh: 11 | ADM0_CODE: 15 12 | Shape_Area: 6.2427 13 | -------------------------------------------------------------------------------- /tests/test_Filter.py: -------------------------------------------------------------------------------- 1 | """Test the Filter class methods.""" 2 | import ee 3 | 4 | 5 | class TestDateRange: 6 | """Test the dateRange method.""" 7 | 8 | def test_dateRange_with_daterange(self, l8_sr_raw): 9 | filter = ee.Filter.geetools.dateRange(ee.DateRange("2018-01-01", "2019-01-01")) 10 | filtered_col = l8_sr_raw.filter(filter) 11 | assert filtered_col.size().getInfo() == 165030 12 | -------------------------------------------------------------------------------- /tests/test_Float.py: -------------------------------------------------------------------------------- 1 | """Test the Float placeholder object.""" 2 | import ee 3 | import pytest 4 | 5 | 6 | class TestFloat: 7 | """Test the Float placeholder class.""" 8 | 9 | def test_init(self): 10 | with pytest.raises(NotImplementedError): 11 | ee.Float() 12 | 13 | def test_name(self): 14 | assert ee.Float.__name__ == "Float" 15 | -------------------------------------------------------------------------------- /tests/test_Geometry.py: -------------------------------------------------------------------------------- 1 | """Test the ``Geometry`` class.""" 2 | 3 | 4 | class TestKeepType: 5 | """Test the ``keepType`` method.""" 6 | 7 | def test_keep_type(self, geom_instance, data_regression): 8 | geom = geom_instance.geetools.keepType("LineString") 9 | geojson = geom.getInfo() 10 | assert geojson["type"] == "MultiLineString" 11 | assert geom.coordinates().getInfo() == [[[0, 1], [0, 0]]] 12 | -------------------------------------------------------------------------------- /tests/test_Geometry/test_deprecated_polygon.npz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_Geometry/test_deprecated_polygon.npz -------------------------------------------------------------------------------- /tests/test_Image/test_add_date.csv: -------------------------------------------------------------------------------- 1 | ,AOT,B1,B11,B12,B2,B3,B4,B5,B6,B7,B8,B8A,B9,MSK_CLASSI_CIRRUS,MSK_CLASSI_OPAQUE,MSK_CLASSI_SNOW_ICE,MSK_CLDPRB,MSK_SNWPRB,QA10,QA20,QA60,SCL,TCI_B,TCI_G,TCI_R,WVP,date 2 | 0,72,214,1175,958,188,366,285,910,1232,1328,1216,1431,2104,,,,2,0,0,0,0,5,21,38,29,588,1577873347042 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_add_date_format.csv: -------------------------------------------------------------------------------- 1 | ,AOT,B1,B11,B12,B2,B3,B4,B5,B6,B7,B8,B8A,B9,MSK_CLDPRB,MSK_SNWPRB,QA10,QA20,QA60,SCL,TCI_B,TCI_G,TCI_R,WVP,date 2 | 0,72,214,1175,958,188,366,285,910,1232,1328,1216,1431,2104,2,0,0,0,0,5,21,38,29,588,20200101 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_add_prefix_to_all.yml: -------------------------------------------------------------------------------- 1 | - prefix_B1 2 | - prefix_B2 3 | - prefix_B3 4 | - prefix_B4 5 | - prefix_B5 6 | - prefix_B6 7 | - prefix_B7 8 | - prefix_B8 9 | - prefix_B8A 10 | - prefix_B9 11 | - prefix_B11 12 | - prefix_B12 13 | - prefix_SCL 14 | -------------------------------------------------------------------------------- /tests/test_Image/test_add_prefix_to_selected.yml: -------------------------------------------------------------------------------- 1 | - prefix_B1 2 | - prefix_B2 3 | - B3 4 | - B4 5 | - B5 6 | - B6 7 | - B7 8 | - B8 9 | - B8A 10 | - B9 11 | - B11 12 | - B12 13 | - SCL 14 | -------------------------------------------------------------------------------- /tests/test_Image/test_add_suffix_to_all.yml: -------------------------------------------------------------------------------- 1 | - B1_suffix 2 | - B2_suffix 3 | - B3_suffix 4 | - B4_suffix 5 | - B5_suffix 6 | - B6_suffix 7 | - B7_suffix 8 | - B8_suffix 9 | - B8A_suffix 10 | - B9_suffix 11 | - B11_suffix 12 | - B12_suffix 13 | - SCL_suffix 14 | -------------------------------------------------------------------------------- /tests/test_Image/test_add_suffix_to_selected.yml: -------------------------------------------------------------------------------- 1 | - B1_suffix 2 | - B2_suffix 3 | - B3 4 | - B4 5 | - B5 6 | - B6 7 | - B7 8 | - B8 9 | - B8A 10 | - B9 11 | - B11 12 | - B12 13 | - SCL 14 | -------------------------------------------------------------------------------- /tests/test_Image/test_class_mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_Image/test_class_mask.png -------------------------------------------------------------------------------- /tests/test_Image/test_class_to_bands.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_Image/test_class_to_bands.png -------------------------------------------------------------------------------- /tests/test_Image/test_clip_on_collection_bands.yml: -------------------------------------------------------------------------------- 1 | - B1 2 | - B2 3 | - B3 4 | - B4 5 | - B5 6 | - B6 7 | - B7 8 | - B8 9 | - B8A 10 | - B9 11 | - B11 12 | - B12 13 | - SCL 14 | -------------------------------------------------------------------------------- /tests/test_Image/test_clip_on_collection_property.yml: -------------------------------------------------------------------------------- 1 | - system:footprint 2 | - system:version 3 | - system:id 4 | - Id 5 | - system:index 6 | - DATATAKE_IDENTIFIER 7 | - AOT_RETRIEVAL_ACCURACY 8 | - SPACECRAFT_NAME 9 | - SATURATED_DEFECTIVE_PIXEL_PERCENTAGE 10 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B8A 11 | - CLOUD_SHADOW_PERCENTAGE 12 | - MEAN_SOLAR_AZIMUTH_ANGLE 13 | - VEGETATION_PERCENTAGE 14 | - SOLAR_IRRADIANCE_B12 15 | - SOLAR_IRRADIANCE_B10 16 | - SENSOR_QUALITY 17 | - SOLAR_IRRADIANCE_B11 18 | - GENERATION_TIME 19 | - SOLAR_IRRADIANCE_B8A 20 | - FORMAT_CORRECTNESS 21 | - CLOUD_COVERAGE_ASSESSMENT 22 | - THIN_CIRRUS_PERCENTAGE 23 | - system:time_end 24 | - WATER_VAPOUR_RETRIEVAL_ACCURACY 25 | - system:time_start 26 | - DATASTRIP_ID 27 | - PROCESSING_BASELINE 28 | - SENSING_ORBIT_NUMBER 29 | - NODATA_PIXEL_PERCENTAGE 30 | - SENSING_ORBIT_DIRECTION 31 | - GENERAL_QUALITY 32 | - GRANULE_ID 33 | - REFLECTANCE_CONVERSION_CORRECTION 34 | - MEDIUM_PROBA_CLOUDS_PERCENTAGE 35 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B8 36 | - DATATAKE_TYPE 37 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B9 38 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B6 39 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B7 40 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B4 41 | - MEAN_INCIDENCE_ZENITH_ANGLE_B1 42 | - NOT_VEGETATED_PERCENTAGE 43 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B5 44 | - RADIOMETRIC_QUALITY 45 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B2 46 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B3 47 | - MEAN_INCIDENCE_ZENITH_ANGLE_B5 48 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B1 49 | - MEAN_INCIDENCE_ZENITH_ANGLE_B4 50 | - MEAN_INCIDENCE_ZENITH_ANGLE_B3 51 | - MEAN_INCIDENCE_ZENITH_ANGLE_B2 52 | - MEAN_INCIDENCE_ZENITH_ANGLE_B9 53 | - MEAN_INCIDENCE_ZENITH_ANGLE_B8 54 | - MEAN_INCIDENCE_ZENITH_ANGLE_B7 55 | - DARK_FEATURES_PERCENTAGE 56 | - HIGH_PROBA_CLOUDS_PERCENTAGE 57 | - MEAN_INCIDENCE_ZENITH_ANGLE_B6 58 | - UNCLASSIFIED_PERCENTAGE 59 | - MEAN_SOLAR_ZENITH_ANGLE 60 | - MEAN_INCIDENCE_ZENITH_ANGLE_B8A 61 | - RADIATIVE_TRANSFER_ACCURACY 62 | - MGRS_TILE 63 | - CLOUDY_PIXEL_PERCENTAGE 64 | - PRODUCT_ID 65 | - MEAN_INCIDENCE_ZENITH_ANGLE_B10 66 | - SOLAR_IRRADIANCE_B9 67 | - SNOW_ICE_PERCENTAGE 68 | - DEGRADED_MSI_DATA_PERCENTAGE 69 | - MEAN_INCIDENCE_ZENITH_ANGLE_B11 70 | - MEAN_INCIDENCE_ZENITH_ANGLE_B12 71 | - SOLAR_IRRADIANCE_B6 72 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B10 73 | - SOLAR_IRRADIANCE_B5 74 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B11 75 | - SOLAR_IRRADIANCE_B8 76 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B12 77 | - SOLAR_IRRADIANCE_B7 78 | - SOLAR_IRRADIANCE_B2 79 | - SOLAR_IRRADIANCE_B1 80 | - SOLAR_IRRADIANCE_B4 81 | - GEOMETRIC_QUALITY 82 | - SOLAR_IRRADIANCE_B3 83 | - system:asset_size 84 | - WATER_PERCENTAGE 85 | - system:bands 86 | - system:band_names 87 | -------------------------------------------------------------------------------- /tests/test_Image/test_clip_on_collection_without_properties_bands.yml: -------------------------------------------------------------------------------- 1 | - B1 2 | - B2 3 | - B3 4 | - B4 5 | - B5 6 | - B6 7 | - B7 8 | - B8 9 | - B8A 10 | - B9 11 | - B11 12 | - B12 13 | - SCL 14 | -------------------------------------------------------------------------------- /tests/test_Image/test_clip_on_collection_without_properties_property.yml: -------------------------------------------------------------------------------- 1 | - system:footprint 2 | - system:version 3 | - system:id 4 | - system:index 5 | - DATATAKE_IDENTIFIER 6 | - AOT_RETRIEVAL_ACCURACY 7 | - SPACECRAFT_NAME 8 | - SATURATED_DEFECTIVE_PIXEL_PERCENTAGE 9 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B8A 10 | - CLOUD_SHADOW_PERCENTAGE 11 | - MEAN_SOLAR_AZIMUTH_ANGLE 12 | - VEGETATION_PERCENTAGE 13 | - SOLAR_IRRADIANCE_B12 14 | - SOLAR_IRRADIANCE_B10 15 | - SENSOR_QUALITY 16 | - SOLAR_IRRADIANCE_B11 17 | - GENERATION_TIME 18 | - SOLAR_IRRADIANCE_B8A 19 | - FORMAT_CORRECTNESS 20 | - CLOUD_COVERAGE_ASSESSMENT 21 | - THIN_CIRRUS_PERCENTAGE 22 | - system:time_end 23 | - WATER_VAPOUR_RETRIEVAL_ACCURACY 24 | - system:time_start 25 | - DATASTRIP_ID 26 | - PROCESSING_BASELINE 27 | - SENSING_ORBIT_NUMBER 28 | - NODATA_PIXEL_PERCENTAGE 29 | - SENSING_ORBIT_DIRECTION 30 | - GENERAL_QUALITY 31 | - GRANULE_ID 32 | - REFLECTANCE_CONVERSION_CORRECTION 33 | - MEDIUM_PROBA_CLOUDS_PERCENTAGE 34 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B8 35 | - DATATAKE_TYPE 36 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B9 37 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B6 38 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B7 39 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B4 40 | - MEAN_INCIDENCE_ZENITH_ANGLE_B1 41 | - NOT_VEGETATED_PERCENTAGE 42 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B5 43 | - RADIOMETRIC_QUALITY 44 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B2 45 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B3 46 | - MEAN_INCIDENCE_ZENITH_ANGLE_B5 47 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B1 48 | - MEAN_INCIDENCE_ZENITH_ANGLE_B4 49 | - MEAN_INCIDENCE_ZENITH_ANGLE_B3 50 | - MEAN_INCIDENCE_ZENITH_ANGLE_B2 51 | - MEAN_INCIDENCE_ZENITH_ANGLE_B9 52 | - MEAN_INCIDENCE_ZENITH_ANGLE_B8 53 | - MEAN_INCIDENCE_ZENITH_ANGLE_B7 54 | - DARK_FEATURES_PERCENTAGE 55 | - HIGH_PROBA_CLOUDS_PERCENTAGE 56 | - MEAN_INCIDENCE_ZENITH_ANGLE_B6 57 | - UNCLASSIFIED_PERCENTAGE 58 | - MEAN_SOLAR_ZENITH_ANGLE 59 | - MEAN_INCIDENCE_ZENITH_ANGLE_B8A 60 | - RADIATIVE_TRANSFER_ACCURACY 61 | - MGRS_TILE 62 | - CLOUDY_PIXEL_PERCENTAGE 63 | - PRODUCT_ID 64 | - MEAN_INCIDENCE_ZENITH_ANGLE_B10 65 | - SOLAR_IRRADIANCE_B9 66 | - SNOW_ICE_PERCENTAGE 67 | - DEGRADED_MSI_DATA_PERCENTAGE 68 | - MEAN_INCIDENCE_ZENITH_ANGLE_B11 69 | - MEAN_INCIDENCE_ZENITH_ANGLE_B12 70 | - SOLAR_IRRADIANCE_B6 71 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B10 72 | - SOLAR_IRRADIANCE_B5 73 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B11 74 | - SOLAR_IRRADIANCE_B8 75 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B12 76 | - SOLAR_IRRADIANCE_B7 77 | - SOLAR_IRRADIANCE_B2 78 | - SOLAR_IRRADIANCE_B1 79 | - SOLAR_IRRADIANCE_B4 80 | - GEOMETRIC_QUALITY 81 | - SOLAR_IRRADIANCE_B3 82 | - system:asset_size 83 | - WATER_PERCENTAGE 84 | - system:bands 85 | - system:band_names 86 | -------------------------------------------------------------------------------- /tests/test_Image/test_deprecated_distance_to_mask.csv: -------------------------------------------------------------------------------- 1 | ,distance_to_mask 2 | 0,1000 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_deprecated_euclidian_distance.csv: -------------------------------------------------------------------------------- 1 | ,sum_distance 2 | 0,157.25661609998866 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_distance.csv: -------------------------------------------------------------------------------- 1 | ,sum_distance 2 | 0,157.25661609998866 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_distance_to_mask.csv: -------------------------------------------------------------------------------- 1 | ,B1,B11,B12,B2,B3,B4,B5,B6,B7,B8,B8A,B9,SCL,distance_to_mask 2 | 0,238.7171666246534,948.66361230148675,750.75646584320634,320.95785228132081,415.14734055961685,426.16661204940726,604.81486009578975,1007.6004411393997,1140.2466599445429,1217.7626543987888,1200.1272498109399,1389.4672800604985,3.3245021426770851,1000 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_doy_to_date.csv: -------------------------------------------------------------------------------- 1 | ,doy1 2 | 0,20230101 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_doy_to_date_with_band.csv: -------------------------------------------------------------------------------- 1 | ,doy2 2 | 0,20230101 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_doy_to_date_with_format.csv: -------------------------------------------------------------------------------- 1 | ,doy1 2 | 0,2023.001 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_full.csv: -------------------------------------------------------------------------------- 1 | ,constant 2 | 0,0 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_full_like.csv: -------------------------------------------------------------------------------- 1 | ,AOT,B1,B11,B12,B2,B3,B4,B5,B6,B7,B8,B8A,B9,MSK_CLASSI_CIRRUS,MSK_CLASSI_OPAQUE,MSK_CLASSI_SNOW_ICE,MSK_CLDPRB,MSK_SNWPRB,QA10,QA20,QA60,SCL,TCI_B,TCI_G,TCI_R,WVP 2 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_full_like_with_mask.csv: -------------------------------------------------------------------------------- 1 | ,AOT,B1,B11,B12,B2,B3,B4,B5,B6,B7,B8,B8A,B9,MSK_CLASSI_CIRRUS,MSK_CLASSI_OPAQUE,MSK_CLASSI_SNOW_ICE,MSK_CLDPRB,MSK_SNWPRB,QA10,QA20,QA60,SCL,TCI_B,TCI_G,TCI_R,WVP 2 | 0,,,,,,,,,,,,,,,,,,,,,,,,,, 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_full_with_lists.csv: -------------------------------------------------------------------------------- 1 | ,tata,titi,toto 2 | 0,3,2,1 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_full_with_name.csv: -------------------------------------------------------------------------------- 1 | ,toto 2 | 0,1 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_full_with_value.csv: -------------------------------------------------------------------------------- 1 | ,constant 2 | 0,1 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_gauss.csv: -------------------------------------------------------------------------------- 1 | ,B1_gauss 2 | 0,0.66461378242572766 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_gauss_with_band.csv: -------------------------------------------------------------------------------- 1 | ,B2_gauss 2 | 0,0.50929481299884138 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_get_scale_params.yml: -------------------------------------------------------------------------------- 1 | AOT: 0.001 2 | B1: 0.0001 3 | B11: 0.0001 4 | B12: 0.0001 5 | B2: 0.0001 6 | B3: 0.0001 7 | B4: 0.0001 8 | B5: 0.0001 9 | B6: 0.0001 10 | B7: 0.0001 11 | B8: 0.0001 12 | B8A: 0.0001 13 | B9: 0.0001 14 | MSK_CLDPRB: 1.0 15 | MSK_SNWPRB: 1.0 16 | QA10: 1.0 17 | QA20: 1.0 18 | QA60: 1.0 19 | SCL: 1.0 20 | TCI_B: 1.0 21 | TCI_G: 1.0 22 | TCI_R: 1.0 23 | WVP: 0.001 24 | -------------------------------------------------------------------------------- /tests/test_Image/test_get_values.csv: -------------------------------------------------------------------------------- 1 | ,AOT,B1,B11,B12,B2,B3,B4,B5,B6,B7,B8,B8A,B9,MSK_CLASSI_CIRRUS,MSK_CLASSI_OPAQUE,MSK_CLASSI_SNOW_ICE,MSK_CLDPRB,MSK_SNWPRB,QA10,QA20,QA60,SCL,TCI_B,TCI_G,TCI_R,WVP 2 | 0,72,159,1341,1105,487,641,714,861,1356,1538,1622,1617,1298,,,,0,0,0,0,0,4,50,66,73,789 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_get_values_with_scale.csv: -------------------------------------------------------------------------------- 1 | ,AOT,B1,B11,B12,B2,B3,B4,B5,B6,B7,B8,B8A,B9,MSK_CLASSI_CIRRUS,MSK_CLASSI_OPAQUE,MSK_CLASSI_SNOW_ICE,MSK_CLDPRB,MSK_SNWPRB,QA10,QA20,QA60,SCL,TCI_B,TCI_G,TCI_R,WVP 2 | 0,72,117,553,332,161,247,175,384,952,1071,1168,1145,1523,,,,0,0,0,0,0,4,18,26,19,693 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_histogram_match.csv: -------------------------------------------------------------------------------- 1 | ,B,G,R 2 | 0,7500.2627678346307,8388.3192336778411,8269.7086967481646 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_interpolate_bands.csv: -------------------------------------------------------------------------------- 1 | ,B2,B4 2 | 0,4.5200000000000005,5.8399999999999999 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_islet_mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_Image/test_islet_mask.png -------------------------------------------------------------------------------- /tests/test_Image/test_mask_S2_clouds.csv: -------------------------------------------------------------------------------- 1 | ,AOT,B1,B11,B12,B2,B3,B4,B5,B6,B7,B8,B8A,B9,CLOUD_MASK,CLOUD_SHADOW_MASK,MSK_CLASSI_CIRRUS,MSK_CLASSI_OPAQUE,MSK_CLASSI_SNOW_ICE,MSK_CLDPRB,MSK_SNWPRB,QA10,QA20,QA60,SCL,SHADOW_MASK,TCI_B,TCI_G,TCI_R,WVP 2 | 0,72,238.7171666246534,948.66361230148675,750.75646584320634,320.95785228132081,415.14734055961685,426.16661204940726,604.81486009578975,1007.6004411393997,1140.2466599445429,1217.7626543987888,1200.1272498109399,1389.4672800604985,0.016070078144693717,0,,,,0.27464078648853035,0,0,0,0,3.3245021426770851,0.11822535921351142,33.158558104360964,42.684144189563895,43.699306780942756,681.94626922107386 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_merge.yml: -------------------------------------------------------------------------------- 1 | - B1 2 | - B2 3 | - B3 4 | - B4 5 | - B5 6 | - B6 7 | - B7 8 | - B8 9 | - B8A 10 | - B9 11 | - B11 12 | - B12 13 | - SCL 14 | - B1_1 15 | - B2_1 16 | - B3_1 17 | - B4_1 18 | - B5_1 19 | - B6_1 20 | - B7_1 21 | - B8_1 22 | - B8A_1 23 | - B9_1 24 | - B11_1 25 | - B12_1 26 | - SCL_1 27 | - B1_2 28 | - B2_2 29 | - B3_2 30 | - B4_2 31 | - B5_2 32 | - B6_2 33 | - B7_2 34 | - B8_2 35 | - B8A_2 36 | - B9_2 37 | - B11_2 38 | - B12_2 39 | - SCL_2 40 | -------------------------------------------------------------------------------- /tests/test_Image/test_negative_clip.csv: -------------------------------------------------------------------------------- 1 | ,AOT,B1,B11,B12,B2,B3,B4,B5,B6,B7,B8,B8A,B9,MSK_CLASSI_CIRRUS,MSK_CLASSI_OPAQUE,MSK_CLASSI_SNOW_ICE,MSK_CLDPRB,MSK_SNWPRB,QA10,QA20,QA60,SCL,TCI_B,TCI_G,TCI_R,WVP 2 | 0,,,,,,,,,,,,,,,,,,,,,,,,,, 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_pan_sharpen.csv: -------------------------------------------------------------------------------- 1 | ,B2,B3,B4,B5,B6,B7 2 | 0,0.074917420895752956,0.062279983815516041,0.035777563662935274,0.27570176610947872,0.085119200009892163,0.030933266714784642 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_Image/test_plot.png -------------------------------------------------------------------------------- /tests/test_Image/test_plot_by_bands_area.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_Image/test_plot_by_bands_area.png -------------------------------------------------------------------------------- /tests/test_Image/test_plot_by_bands_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_Image/test_plot_by_bands_bar.png -------------------------------------------------------------------------------- /tests/test_Image/test_plot_by_bands_donut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_Image/test_plot_by_bands_donut.png -------------------------------------------------------------------------------- /tests/test_Image/test_plot_by_bands_pie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_Image/test_plot_by_bands_pie.png -------------------------------------------------------------------------------- /tests/test_Image/test_plot_by_bands_plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_Image/test_plot_by_bands_plot.png -------------------------------------------------------------------------------- /tests/test_Image/test_plot_by_regions_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_Image/test_plot_by_regions_bar.png -------------------------------------------------------------------------------- /tests/test_Image/test_plot_by_regions_barh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_Image/test_plot_by_regions_barh.png -------------------------------------------------------------------------------- /tests/test_Image/test_plot_by_regions_stacked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_Image/test_plot_by_regions_stacked.png -------------------------------------------------------------------------------- /tests/test_Image/test_plot_hist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_Image/test_plot_hist.png -------------------------------------------------------------------------------- /tests/test_Image/test_plot_one_band.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_Image/test_plot_one_band.png -------------------------------------------------------------------------------- /tests/test_Image/test_plot_one_band_cmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_Image/test_plot_one_band_cmap.png -------------------------------------------------------------------------------- /tests/test_Image/test_plot_with_crs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_Image/test_plot_with_crs.png -------------------------------------------------------------------------------- /tests/test_Image/test_plot_with_fc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_Image/test_plot_with_fc.png -------------------------------------------------------------------------------- /tests/test_Image/test_prefix.yml: -------------------------------------------------------------------------------- 1 | - prefix_B1 2 | - prefix_B2 3 | - prefix_B3 4 | - prefix_B4 5 | - prefix_B5 6 | - prefix_B6 7 | - prefix_B7 8 | - prefix_B8 9 | - prefix_B8A 10 | - prefix_B9 11 | - prefix_B11 12 | - prefix_B12 13 | - prefix_SCL 14 | -------------------------------------------------------------------------------- /tests/test_Image/test_preprocess.csv: -------------------------------------------------------------------------------- 1 | ,AOT,B1,B11,B12,B2,B3,B4,B5,B6,B7,B8,B8A,B9,MSK_CLDPRB,MSK_SNWPRB,QA10,QA20,QA60,SCL,TCI_B,TCI_G,TCI_R,WVP 2 | 0,0.072000000000000008,0.023871716662465316,0.094866361230148563,0.075075646584320546,0.032095785228132098,0.041514734055961663,0.042616661204940731,0.06048148600957913,0.10076004411394013,0.11402466599445431,0.12177626543987899,0.1200127249810941,0.13894672800604949,0.27464078648853035,0,0,0,0,3.3245021426770851,33.158558104360964,42.684144189563895,43.699306780942756,0.68194626922107227 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_reduce_bands.csv: -------------------------------------------------------------------------------- 1 | ,sum 2 | 0,9663.7526972523283 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_reduce_bands_with_bands.csv: -------------------------------------------------------------------------------- 1 | ,sum 2 | 0,559.67501890597396 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_reduce_bands_with_name.csv: -------------------------------------------------------------------------------- 1 | ,toto 2 | 0,9663.7526972523283 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_remove.yml: -------------------------------------------------------------------------------- 1 | - B3 2 | - B4 3 | - B5 4 | - B6 5 | - B7 6 | - B8 7 | - B8A 8 | - B9 9 | - B11 10 | - B12 11 | - SCL 12 | -------------------------------------------------------------------------------- /tests/test_Image/test_remove_properties.yml: -------------------------------------------------------------------------------- 1 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B8A 2 | - CLOUD_SHADOW_PERCENTAGE 3 | - MEAN_SOLAR_AZIMUTH_ANGLE 4 | - VEGETATION_PERCENTAGE 5 | - SOLAR_IRRADIANCE_B12 6 | - SOLAR_IRRADIANCE_B10 7 | - SENSOR_QUALITY 8 | - SOLAR_IRRADIANCE_B11 9 | - GENERATION_TIME 10 | - SOLAR_IRRADIANCE_B8A 11 | - FORMAT_CORRECTNESS 12 | - CLOUD_COVERAGE_ASSESSMENT 13 | - THIN_CIRRUS_PERCENTAGE 14 | - WATER_VAPOUR_RETRIEVAL_ACCURACY 15 | - DATASTRIP_ID 16 | - PROCESSING_BASELINE 17 | - SENSING_ORBIT_NUMBER 18 | - NODATA_PIXEL_PERCENTAGE 19 | - SENSING_ORBIT_DIRECTION 20 | - GENERAL_QUALITY 21 | - GRANULE_ID 22 | - REFLECTANCE_CONVERSION_CORRECTION 23 | - MEDIUM_PROBA_CLOUDS_PERCENTAGE 24 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B8 25 | - DATATAKE_TYPE 26 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B9 27 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B6 28 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B7 29 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B4 30 | - MEAN_INCIDENCE_ZENITH_ANGLE_B1 31 | - NOT_VEGETATED_PERCENTAGE 32 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B5 33 | - RADIOMETRIC_QUALITY 34 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B2 35 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B3 36 | - MEAN_INCIDENCE_ZENITH_ANGLE_B5 37 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B1 38 | - MEAN_INCIDENCE_ZENITH_ANGLE_B4 39 | - MEAN_INCIDENCE_ZENITH_ANGLE_B3 40 | - MEAN_INCIDENCE_ZENITH_ANGLE_B2 41 | - MEAN_INCIDENCE_ZENITH_ANGLE_B9 42 | - MEAN_INCIDENCE_ZENITH_ANGLE_B8 43 | - MEAN_INCIDENCE_ZENITH_ANGLE_B7 44 | - DARK_FEATURES_PERCENTAGE 45 | - HIGH_PROBA_CLOUDS_PERCENTAGE 46 | - MEAN_INCIDENCE_ZENITH_ANGLE_B6 47 | - UNCLASSIFIED_PERCENTAGE 48 | - MEAN_SOLAR_ZENITH_ANGLE 49 | - MEAN_INCIDENCE_ZENITH_ANGLE_B8A 50 | - RADIATIVE_TRANSFER_ACCURACY 51 | - MGRS_TILE 52 | - CLOUDY_PIXEL_PERCENTAGE 53 | - PRODUCT_ID 54 | - MEAN_INCIDENCE_ZENITH_ANGLE_B10 55 | - SOLAR_IRRADIANCE_B9 56 | - SNOW_ICE_PERCENTAGE 57 | - DEGRADED_MSI_DATA_PERCENTAGE 58 | - MEAN_INCIDENCE_ZENITH_ANGLE_B11 59 | - MEAN_INCIDENCE_ZENITH_ANGLE_B12 60 | - SOLAR_IRRADIANCE_B6 61 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B10 62 | - SOLAR_IRRADIANCE_B5 63 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B11 64 | - SOLAR_IRRADIANCE_B8 65 | - MEAN_INCIDENCE_AZIMUTH_ANGLE_B12 66 | - SOLAR_IRRADIANCE_B7 67 | - SOLAR_IRRADIANCE_B2 68 | - SOLAR_IRRADIANCE_B1 69 | - SOLAR_IRRADIANCE_B4 70 | - GEOMETRIC_QUALITY 71 | - SOLAR_IRRADIANCE_B3 72 | - WATER_PERCENTAGE 73 | - DATATAKE_IDENTIFIER 74 | - AOT_RETRIEVAL_ACCURACY 75 | - SPACECRAFT_NAME 76 | - system:footprint 77 | - SATURATED_DEFECTIVE_PIXEL_PERCENTAGE 78 | - system:bands 79 | - system:band_names 80 | -------------------------------------------------------------------------------- /tests/test_Image/test_rename.yml: -------------------------------------------------------------------------------- 1 | - newB1 2 | - newB2 3 | - B3 4 | - B4 5 | - B5 6 | - B6 7 | - B7 8 | - B8 9 | - B8A 10 | - B9 11 | - B11 12 | - B12 13 | - SCL 14 | -------------------------------------------------------------------------------- /tests/test_Image/test_scale_and_offset.csv: -------------------------------------------------------------------------------- 1 | ,AOT,B1,B11,B12,B2,B3,B4,B5,B6,B7,B8,B8A,B9,MSK_CLDPRB,MSK_SNWPRB,QA10,QA20,QA60,SCL,TCI_B,TCI_G,TCI_R,WVP 2 | 0,0.072000000000000008,0.023871716662465316,0.094866361230148563,0.075075646584320546,0.032095785228132098,0.041514734055961663,0.042616661204940731,0.06048148600957913,0.10076004411394013,0.11402466599445431,0.12177626543987899,0.1200127249810941,0.13894672800604949,0.27464078648853035,0,0,0,0,3.3245021426770851,33.158558104360964,42.684144189563895,43.699306780942756,0.68194626922107227 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_suffix.yml: -------------------------------------------------------------------------------- 1 | - B1_suffix 2 | - B2_suffix 3 | - B3_suffix 4 | - B4_suffix 5 | - B5_suffix 6 | - B6_suffix 7 | - B7_suffix 8 | - B8_suffix 9 | - B8A_suffix 10 | - B9_suffix 11 | - B11_suffix 12 | - B12_suffix 13 | - SCL_suffix 14 | -------------------------------------------------------------------------------- /tests/test_Image/test_tasseled_cap.csv: -------------------------------------------------------------------------------- 1 | ,B1,B2,B3,B4,B5,B7,TCB,TCG,TCW 2 | 0,80.646786099516518,36.996091045013017,39.201923038041691,41.476289750435498,60.247799617469894,37.873670520610993,107.81693958004151,-23.51120101153365,-7.983038306874465 3 | -------------------------------------------------------------------------------- /tests/test_Image/test_to_grid.npz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_Image/test_to_grid.npz -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_aggregate_array_with_properties.yml: -------------------------------------------------------------------------------- 1 | system:index: 2 | - 20210102T150719_20210102T150942_T18MYC 3 | - 20210102T150719_20210102T150942_T18MYD 4 | - 20210102T150719_20210102T150942_T18MZC 5 | - 20210102T150719_20210102T150942_T18MZD 6 | - 20210102T150719_20210102T150942_T18MZE 7 | - 20210102T150719_20210102T150942_T18NZF 8 | - 20210102T150719_20210102T150942_T19MBT 9 | - 20210102T150719_20210102T150942_T19MBU 10 | - 20210102T150719_20210102T150942_T19MBV 11 | - 20210102T150719_20210102T150942_T19MCR 12 | system:time_start: 13 | - 1609600422628 14 | - 1609600409366 15 | - 1609600419630 16 | - 1609600405212 17 | - 1609600390766 18 | - 1609600376122 19 | - 1609600417688 20 | - 1609600403048 21 | - 1609600388626 22 | - 1609600443330 23 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_append.yml: -------------------------------------------------------------------------------- 1 | 2450 2 | ... 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_closest_date.csv: -------------------------------------------------------------------------------- 1 | ,B1,B11,B12,B2,B3,B4,B5,B6,B7,B8,B8A,B9,SCL 2 | 0,7013.1499356644645,4707.9961241683077,3919.893125538782,6578.679351288074,6183.2784174693725,5784.3242832570231,6164.3671240171716,6327.8494090005433,6550.4332522288923,6188.5737541288727,6620.4358590515458,11144.482102417895,8.8304504414322942 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_closest_s2_sr.yml: -------------------------------------------------------------------------------- 1 | 8 2 | ... 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_collection_mask.csv: -------------------------------------------------------------------------------- 1 | ,AOT,B1,B11,B12,B2,B3,B4,B5,B6,B7,B8,B8A,B9,MSK_CLDPRB,MSK_SNWPRB,QA10,QA20,QA60,SCL,TCI_B,TCI_G,TCI_R,WVP 2 | 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_deprecated_closest_date.csv: -------------------------------------------------------------------------------- 1 | ,B1,B11,B12,B2,B3,B4,B5,B6,B7,B8,B8A,B9,SCL 2 | 0,7013.1499356644645,4707.9961241683077,3919.893125538782,6578.679351288074,6183.2784174693725,5784.3242832570231,6164.3671240171716,6327.8494090005433,6550.4332522288923,6188.5737541288727,6620.4358590515458,11144.482102417895,8.8304504414322942 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_deprecated_composite_by_month.csv: -------------------------------------------------------------------------------- 1 | ,gaugeQualityInfo,hourlyPrecipRate,hourlyPrecipRateGC,observationTimeFlag,satelliteInfoFlag 2 | 0,0,0.18768584728240967,0.1922166645526886,-0.0021944569889456034,9149832.9472222216 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_deprecated_composite_by_month.yml: -------------------------------------------------------------------------------- 1 | '20200101_0000': 2 | gaugeQualityInfo: 0.005995 3 | hourlyPrecipRate: 0.147741 4 | hourlyPrecipRateGC: 0.152207 5 | observationTimeFlag: -0.005505 6 | satelliteInfoFlag: 9426463.561311 7 | '20200131_0000': 8 | gaugeQualityInfo: 0.004546 9 | hourlyPrecipRate: 0.244081 10 | hourlyPrecipRateGC: 0.262454 11 | observationTimeFlag: 0.051627 12 | satelliteInfoFlag: 9644649.883837 13 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_deprecated_composite_regular_intervals.csv: -------------------------------------------------------------------------------- 1 | ,gaugeQualityInfo,hourlyPrecipRate,hourlyPrecipRateGC,observationTimeFlag,satelliteInfoFlag 2 | 0,0,0,0.16104844212532043,-0.16916666924953461,6294879.5 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_deprecated_composite_regular_intervals.yml: -------------------------------------------------------------------------------- 1 | '20200101_0000': 2 | gaugeQualityInfo: 0.006202 3 | hourlyPrecipRate: 0.199016 4 | hourlyPrecipRateGC: 0.2462 5 | observationTimeFlag: -0.160625 6 | satelliteInfoFlag: 8172316.590439 7 | '20200102_0000': 8 | gaugeQualityInfo: 0.006202 9 | hourlyPrecipRate: 0.139738 10 | hourlyPrecipRateGC: 0.125355 11 | observationTimeFlag: -0.076046 12 | satelliteInfoFlag: 10486747.044832 13 | '20200103_0000': 14 | gaugeQualityInfo: 0.005213 15 | hourlyPrecipRate: 0.034242 16 | hourlyPrecipRateGC: 0.028368 17 | observationTimeFlag: 0.212139 18 | satelliteInfoFlag: 12111611.320593 19 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_deprecated_fill_with_last.csv: -------------------------------------------------------------------------------- 1 | ,B1,B11,B12,B2,B3,B4,B5,B6,B7,B8,B8A,B9,SCL 2 | 0,7013.1499356644645,4707.9961241683077,3919.893125538782,6578.679351288074,6183.2784174693725,5784.3242832570231,6164.3671240171716,6327.8494090005433,6550.4332522288923,6188.5737541288727,6620.4358590515458,11144.482102417895,8.8304504414322942 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_deprecated_medoid.csv: -------------------------------------------------------------------------------- 1 | ,B1,B11,B12,B2,B3,B4,B5,B6,B7,B8,B8A,B9,SCL 2 | 0,0.6177746823789384,0.79167387556605839,0.75502788442188418,0.60222084925854291,0.63257736183390867,0.60337927161154525,0.63801273546323556,0.79096266749901301,0.85579134939633583,0.79265361382284005,0.87208650729675008,1,0 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_deprecated_mosaic_same_day.csv: -------------------------------------------------------------------------------- 1 | ,gaugeQualityInfo,hourlyPrecipRate,hourlyPrecipRateGC,observationTimeFlag,satelliteInfoFlag 2 | 0,0,0,0.17295975983142853,-1.1200000047683716,-1 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_deprecated_reduce_day_intervals.csv: -------------------------------------------------------------------------------- 1 | ,gaugeQualityInfo,hourlyPrecipRate,hourlyPrecipRateGC,observationTimeFlag,satelliteInfoFlag 2 | 0,0,0,0.16104844212532043,-0.16916666924953461,6294879.5 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_deprecated_reduce_day_intervals.yml: -------------------------------------------------------------------------------- 1 | '20200101_0000': 2 | gaugeQualityInfo: 0.006202 3 | hourlyPrecipRate: 0.199016 4 | hourlyPrecipRateGC: 0.2462 5 | observationTimeFlag: -0.160625 6 | satelliteInfoFlag: 8172316.590439 7 | '20200102_0000': 8 | gaugeQualityInfo: 0.006202 9 | hourlyPrecipRate: 0.139738 10 | hourlyPrecipRateGC: 0.125355 11 | observationTimeFlag: -0.076046 12 | satelliteInfoFlag: 10486747.044832 13 | '20200103_0000': 14 | gaugeQualityInfo: 0.005213 15 | hourlyPrecipRate: 0.034242 16 | hourlyPrecipRateGC: 0.028368 17 | observationTimeFlag: 0.212139 18 | satelliteInfoFlag: 12111611.320593 19 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_deprecated_reduce_equal_interval.csv: -------------------------------------------------------------------------------- 1 | ,gaugeQualityInfo,hourlyPrecipRate,hourlyPrecipRateGC,observationTimeFlag,satelliteInfoFlag 2 | 0,0,0.18768584728240967,0.1922166645526886,-0.0021944569889456034,9149832.9472222216 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_deprecated_reduce_equal_interval.yml: -------------------------------------------------------------------------------- 1 | '20200101_0000': 2 | gaugeQualityInfo: 0.005995 3 | hourlyPrecipRate: 0.147741 4 | hourlyPrecipRateGC: 0.152207 5 | observationTimeFlag: -0.005505 6 | satelliteInfoFlag: 9426463.561311 7 | '20200131_0000': 8 | gaugeQualityInfo: 0.004548 9 | hourlyPrecipRate: 0.24375 10 | hourlyPrecipRateGC: 0.26215 11 | observationTimeFlag: 0.050515 12 | satelliteInfoFlag: 9631254.535388 13 | '20200301_0000': 14 | gaugeQualityInfo: 0.004031 15 | hourlyPrecipRate: 0.393217 16 | hourlyPrecipRateGC: 0.431561 17 | observationTimeFlag: 0.022673 18 | satelliteInfoFlag: 9465107.46433 19 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_get_citation.yml: -------------------------------------------------------------------------------- 1 | Citation not available for this collection. Please check the STAC for more information. 2 | ... 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_get_doi.yml: -------------------------------------------------------------------------------- 1 | The DOI is not available for this collection. Please check the STAC for more information. 2 | ... 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_get_offset_params.yml: -------------------------------------------------------------------------------- 1 | AOT: 0.0 2 | B1: 0.0 3 | B11: 0.0 4 | B12: 0.0 5 | B2: 0.0 6 | B3: 0.0 7 | B4: 0.0 8 | B5: 0.0 9 | B6: 0.0 10 | B7: 0.0 11 | B8: 0.0 12 | B8A: 0.0 13 | B9: 0.0 14 | MSK_CLDPRB: 0.0 15 | MSK_SNWPRB: 0.0 16 | QA10: 0.0 17 | QA20: 0.0 18 | QA60: 0.0 19 | SCL: 0.0 20 | TCI_B: 0.0 21 | TCI_G: 0.0 22 | TCI_R: 0.0 23 | WVP: 0.0 24 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_get_scale_params.yml: -------------------------------------------------------------------------------- 1 | AOT: 0.001 2 | B1: 0.0001 3 | B11: 0.0001 4 | B12: 0.0001 5 | B2: 0.0001 6 | B3: 0.0001 7 | B4: 0.0001 8 | B5: 0.0001 9 | B6: 0.0001 10 | B7: 0.0001 11 | B8: 0.0001 12 | B8A: 0.0001 13 | B9: 0.0001 14 | MSK_CLDPRB: 1.0 15 | MSK_SNWPRB: 1.0 16 | QA10: 1.0 17 | QA20: 1.0 18 | QA60: 1.0 19 | SCL: 1.0 20 | TCI_B: 1.0 21 | TCI_G: 1.0 22 | TCI_R: 1.0 23 | WVP: 0.001 24 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_iloc.csv: -------------------------------------------------------------------------------- 1 | ,AOT,B1,B11,B12,B2,B3,B4,B5,B6,B7,B8,B8A,B9,MSK_CLDPRB,MSK_SNWPRB,QA10,QA20,QA60,SCL,TCI_B,TCI_G,TCI_R,WVP 2 | 0,,,,,,,,,,,,,,0,0,0,0,0,,,,, 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_integral.csv: -------------------------------------------------------------------------------- 1 | ,integral 2 | 0, 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_mask_s2.yml: -------------------------------------------------------------------------------- 1 | AOT: 354 2 | B1: 590.1282626148882 3 | B11: 1986.408679038172 4 | B12: 1522.041930986203 5 | B2: 564.3067665633657 6 | B3: 784.1374447316587 7 | B4: 821.3239234989915 8 | B5: 1217.444006928795 9 | B6: 2003.3571632505652 10 | B7: 2236.471328753445 11 | B8: 2390.463396773381 12 | B8A: 2407.3933334274057 13 | B9: 2422.9298342189186 14 | CLOUD_MASK: 0 15 | CLOUD_MASK_CDI: 0 16 | CLOUD_SHADOW_MASK: 0 17 | MSK_CLDPRB: null 18 | MSK_SNWPRB: null 19 | QA10: 0 20 | QA20: 0 21 | QA60: 0 22 | SCL: 4.598658742666373 23 | SHADOW_MASK: 0 24 | TCI_B: 57.67908547074245 25 | TCI_G: 80.82178790722993 26 | TCI_R: 83.79020123070153 27 | WVP: 602.9321499075425 28 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_mask_s2_sr.csv: -------------------------------------------------------------------------------- 1 | ,AOT,B1,B11,B12,B2,B3,B4,B5,B6,B7,B8,B8A,B9,CLOUD_MASK,CLOUD_MASK_CDI,CLOUD_SHADOW_MASK,MSK_CLDPRB,MSK_SNWPRB,QA10,QA20,QA60,SCL,SHADOW_MASK,TCI_B,TCI_G,TCI_R,WVP 2 | 0,199,16640.094805201559,1568.290431797825,1968.3295548610204,15419.765396984198,14101.613293902175,12931.892357709678,14237.406449381348,12795.376786673241,11806.409740942607,12098.870170407052,11006.397712738837,15899,1,0,0,0,0,0,0,1024,8,0,255,255,255,3645 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_medoid.csv: -------------------------------------------------------------------------------- 1 | ,B1,B11,B12,B2,B3,B4,B5,B6,B7,B8,B8A,B9,SCL 2 | 0,0.6177746823789384,0.79167387556605839,0.75502788442188418,0.60222084925854291,0.63257736183390867,0.60337927161154525,0.63801273546323556,0.79096266749901301,0.85579134939633583,0.79265361382284005,0.87208650729675008,1,0 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_outliers.csv: -------------------------------------------------------------------------------- 1 | ,AOT,AOT_outlier,B1,B11,B11_outlier,B12,B12_outlier,B1_outlier,B2,B2_outlier,B3,B3_outlier,B4,B4_outlier,B5,B5_outlier,B6,B6_outlier,B7,B7_outlier,B8,B8A,B8A_outlier,B8_outlier,B9,B9_outlier,MSK_CLDPRB,MSK_CLDPRB_outlier,MSK_SNWPRB,MSK_SNWPRB_outlier,QA10,QA10_outlier,QA20,QA20_outlier,QA60,QA60_outlier,SCL,SCL_outlier,TCI_B,TCI_B_outlier,TCI_G,TCI_G_outlier,TCI_R,TCI_R_outlier,WVP,WVP_outlier 2 | 0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_outliers_with_bands.csv: -------------------------------------------------------------------------------- 1 | ,AOT,B1,B11,B12,B2,B2_outlier,B3,B4,B4_outlier,B5,B6,B7,B8,B8A,B9,MSK_CLDPRB,MSK_SNWPRB,QA10,QA20,QA60,SCL,TCI_B,TCI_G,TCI_R,WVP 2 | 0,,,,,,,,,,,,,,,,,,,,,,,,, 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_outliers_with_drop.csv: -------------------------------------------------------------------------------- 1 | ,AOT,B1,B11,B12,B2,B3,B4,B5,B6,B7,B8,B8A,B9,MSK_CLDPRB,MSK_SNWPRB,QA10,QA20,QA60,SCL,TCI_B,TCI_G,TCI_R,WVP 2 | 0,,,,,,,,,,,,,,,,,,,,,,, 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_outliers_with_sigma.csv: -------------------------------------------------------------------------------- 1 | ,AOT,AOT_outlier,B1,B11,B11_outlier,B12,B12_outlier,B1_outlier,B2,B2_outlier,B3,B3_outlier,B4,B4_outlier,B5,B5_outlier,B6,B6_outlier,B7,B7_outlier,B8,B8A,B8A_outlier,B8_outlier,B9,B9_outlier,MSK_CLDPRB,MSK_CLDPRB_outlier,MSK_SNWPRB,MSK_SNWPRB_outlier,QA10,QA10_outlier,QA20,QA20_outlier,QA60,QA60_outlier,SCL,SCL_outlier,TCI_B,TCI_B_outlier,TCI_G,TCI_G_outlier,TCI_R,TCI_R_outlier,WVP,WVP_outlier 2 | 0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_pan_sharpen.csv: -------------------------------------------------------------------------------- 1 | ,B2,B3,B4,B5,B6,B7 2 | 0,0.42341190228971326,0.39605810178360285,0.39928781304364891,0.56361231196164929,0.42966321799378288,0.36453387368774781 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_plot_dates_by_bands.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_ImageCollection/test_plot_dates_by_bands.png -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_plot_dates_by_regions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_ImageCollection/test_plot_dates_by_regions.png -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_plot_doy_by_bands.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_ImageCollection/test_plot_doy_by_bands.png -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_plot_doy_by_regions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_ImageCollection/test_plot_doy_by_regions.png -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_plot_doy_by_seasons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_ImageCollection/test_plot_doy_by_seasons.png -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_plot_doy_by_years.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geetools/9bb3d8d4265c5f150476dd20f7b652fdb11c93d8/tests/test_ImageCollection/test_plot_doy_by_years.png -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_preprocess.csv: -------------------------------------------------------------------------------- 1 | ,AOT,B1,B11,B12,B2,B3,B4,B5,B6,B7,B8,B8A,B9,MSK_CLDPRB,MSK_SNWPRB,QA10,QA20,QA60,SCL,TCI_B,TCI_G,TCI_R,WVP 2 | 0,,,,,,,,,,,,,,,,,,,,,,, 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_reduce_interval.yml: -------------------------------------------------------------------------------- 1 | '20200101_0000': 2 | gaugeQualityInfo: 0.005995 3 | hourlyPrecipRate: 0.147741 4 | hourlyPrecipRateGC: 0.152207 5 | observationTimeFlag: -0.005505 6 | satelliteInfoFlag: 9426463.561311 7 | '20200131_0000': 8 | gaugeQualityInfo: 0.004548 9 | hourlyPrecipRate: 0.24375 10 | hourlyPrecipRateGC: 0.26215 11 | observationTimeFlag: 0.050515 12 | satelliteInfoFlag: 9631254.535388 13 | '20200301_0000': 14 | gaugeQualityInfo: 0.004031 15 | hourlyPrecipRate: 0.393217 16 | hourlyPrecipRateGC: 0.431561 17 | observationTimeFlag: 0.022673 18 | satelliteInfoFlag: 9465107.46433 19 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_reduce_interval_properties.yml: -------------------------------------------------------------------------------- 1 | '20200101_0000': 2 | gaugeQualityInfo: 0.005995 3 | hourlyPrecipRate: 0.147741 4 | hourlyPrecipRateGC: 0.152207 5 | observationTimeFlag: -0.005505 6 | satelliteInfoFlag: 9426463.561311 7 | '20200131_0000': 8 | gaugeQualityInfo: 0.004548 9 | hourlyPrecipRate: 0.24375 10 | hourlyPrecipRateGC: 0.26215 11 | observationTimeFlag: 0.050515 12 | satelliteInfoFlag: 9631254.535388 13 | '20200301_0000': 14 | gaugeQualityInfo: 0.004031 15 | hourlyPrecipRate: 0.393217 16 | hourlyPrecipRateGC: 0.431561 17 | observationTimeFlag: 0.022673 18 | satelliteInfoFlag: 9465107.46433 19 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_reduce_interval_with_multi_output_reducer.yml: -------------------------------------------------------------------------------- 1 | '20200101_0000': 2 | gaugeQualityInfo_max: 0.006202 3 | gaugeQualityInfo_min: 0.002067 4 | hourlyPrecipRateGC_max: 1.536121 5 | hourlyPrecipRateGC_min: 0 6 | hourlyPrecipRate_max: 7.068796 7 | hourlyPrecipRate_min: 0 8 | observationTimeFlag_max: 5.425659 9 | observationTimeFlag_min: -5.981587 10 | satelliteInfoFlag_max: 134217733 11 | satelliteInfoFlag_min: -1 12 | '20200131_0000': 13 | gaugeQualityInfo_max: 0.006202 14 | gaugeQualityInfo_min: 0.002067 15 | hourlyPrecipRateGC_max: 4.055826 16 | hourlyPrecipRateGC_min: 0 17 | hourlyPrecipRate_max: 7.90424 18 | hourlyPrecipRate_min: 0 19 | observationTimeFlag_max: 4.897762 20 | observationTimeFlag_min: -5.244269 21 | satelliteInfoFlag_max: 134217733 22 | satelliteInfoFlag_min: -1 23 | '20200301_0000': 24 | gaugeQualityInfo_max: 0.006202 25 | gaugeQualityInfo_min: 0.002067 26 | hourlyPrecipRateGC_max: 6.465589 27 | hourlyPrecipRateGC_min: 0 28 | hourlyPrecipRate_max: 10.038375 29 | hourlyPrecipRate_min: 0 30 | observationTimeFlag_max: 5.381519 31 | observationTimeFlag_min: -5.264098 32 | satelliteInfoFlag_max: 134217730.322997 33 | satelliteInfoFlag_min: -1 34 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_reduce_interval_with_reducer.yml: -------------------------------------------------------------------------------- 1 | '20200101_0000': 2 | gaugeQualityInfo: 0.006202 3 | hourlyPrecipRate: 7.068796 4 | hourlyPrecipRateGC: 1.536121 5 | observationTimeFlag: 5.425659 6 | satelliteInfoFlag: 134217733 7 | '20200131_0000': 8 | gaugeQualityInfo: 0.006202 9 | hourlyPrecipRate: 7.90424 10 | hourlyPrecipRateGC: 4.055826 11 | observationTimeFlag: 4.897762 12 | satelliteInfoFlag: 134217733 13 | '20200301_0000': 14 | gaugeQualityInfo: 0.006202 15 | hourlyPrecipRate: 10.038375 16 | hourlyPrecipRateGC: 6.465589 17 | observationTimeFlag: 5.381519 18 | satelliteInfoFlag: 134217730.322997 19 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_reduce_interval_without_original_names.yml: -------------------------------------------------------------------------------- 1 | '20200101_0000': 2 | gaugeQualityInfo_mean: 0.005995 3 | hourlyPrecipRateGC_mean: 0.152207 4 | hourlyPrecipRate_mean: 0.147741 5 | observationTimeFlag_mean: -0.005505 6 | satelliteInfoFlag_mean: 9426463.561311 7 | '20200131_0000': 8 | gaugeQualityInfo_mean: 0.004548 9 | hourlyPrecipRateGC_mean: 0.26215 10 | hourlyPrecipRate_mean: 0.24375 11 | observationTimeFlag_mean: 0.050515 12 | satelliteInfoFlag_mean: 9631254.535388 13 | '20200301_0000': 14 | gaugeQualityInfo_mean: 0.004031 15 | hourlyPrecipRateGC_mean: 0.431561 16 | hourlyPrecipRate_mean: 0.393217 17 | observationTimeFlag_mean: 0.022673 18 | satelliteInfoFlag_mean: 9465107.46433 19 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_reduce_region_by_date_property.yml: -------------------------------------------------------------------------------- 1 | 2010-01-01T00-00-00: 2 | EVI: 1912.5638 3 | NDVI: 3273.6724 4 | 2010-01-17T00-00-00: 5 | EVI: 3276.7642 6 | NDVI: 7331.2238 7 | 2010-02-02T00-00-00: 8 | EVI: 2963.2602 9 | NDVI: 7845.5146 10 | 2010-02-18T00-00-00: 11 | EVI: 3276.4948 12 | NDVI: 7951.8985 13 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_reduce_region_by_dates.yml: -------------------------------------------------------------------------------- 1 | 2010-01-01T00-00-00: 2 | EVI: 1912.5638 3 | NDVI: 3273.6724 4 | 2010-01-17T00-00-00: 5 | EVI: 3276.7642 6 | NDVI: 7331.2238 7 | 2010-02-02T00-00-00: 8 | EVI: 2963.2602 9 | NDVI: 7845.5146 10 | 2010-02-18T00-00-00: 11 | EVI: 3276.4948 12 | NDVI: 7951.8985 13 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_reduce_region_by_doy.yml: -------------------------------------------------------------------------------- 1 | '001': 2 | EVI: 1517.999 3 | NDVI: 2429.6984 4 | '017': 5 | EVI: 3290.0929 6 | NDVI: 7359.3423 7 | '033': 8 | EVI: 2968.6441 9 | NDVI: 7911.3745 10 | 049: 11 | EVI: 3080.7212 12 | NDVI: 7745.9324 13 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_reduce_regions_by_date_property.yml: -------------------------------------------------------------------------------- 1 | '0': 2 | EVI: 1014.455318 3 | NDVI: 1797.930408 4 | feature_id: '00000000000000000000' 5 | image_id: 2010-01-01T00-00-00 6 | label: Desert 7 | system:index: '0' 8 | value: 0 9 | warm: 1 10 | '1': 11 | EVI: 971.166098 12 | NDVI: 1900.816413 13 | feature_id: '00000000000000000000' 14 | image_id: 2010-01-17T00-00-00 15 | label: Desert 16 | system:index: '1' 17 | value: 0 18 | warm: 1 19 | '10': 20 | EVI: 1111.532233 21 | NDVI: 1770.138801 22 | feature_id: '00000000000000000002' 23 | image_id: 2010-02-02T00-00-00 24 | label: Grassland 25 | system:index: '10' 26 | value: 2 27 | warm: 0 28 | '11': 29 | EVI: 1055.246577 30 | NDVI: 1797.979795 31 | feature_id: '00000000000000000002' 32 | image_id: 2010-02-18T00-00-00 33 | label: Grassland 34 | system:index: '11' 35 | value: 2 36 | warm: 0 37 | '2': 38 | EVI: 973.384019 39 | NDVI: 1825.576545 40 | feature_id: '00000000000000000000' 41 | image_id: 2010-02-02T00-00-00 42 | label: Desert 43 | system:index: '2' 44 | value: 0 45 | warm: 1 46 | '3': 47 | EVI: 986.248517 48 | NDVI: 1790.578384 49 | feature_id: '00000000000000000000' 50 | image_id: 2010-02-18T00-00-00 51 | label: Desert 52 | system:index: '3' 53 | value: 0 54 | warm: 1 55 | '4': 56 | EVI: 1912.56377 57 | NDVI: 3273.672378 58 | feature_id: '00000000000000000001' 59 | image_id: 2010-01-01T00-00-00 60 | label: Forest 61 | system:index: '4' 62 | value: 1 63 | warm: 1 64 | '5': 65 | EVI: 3276.76424 66 | NDVI: 7331.223758 67 | feature_id: '00000000000000000001' 68 | image_id: 2010-01-17T00-00-00 69 | label: Forest 70 | system:index: '5' 71 | value: 1 72 | warm: 1 73 | '6': 74 | EVI: 2963.260225 75 | NDVI: 7845.514551 76 | feature_id: '00000000000000000001' 77 | image_id: 2010-02-02T00-00-00 78 | label: Forest 79 | system:index: '6' 80 | value: 1 81 | warm: 1 82 | '7': 83 | EVI: 3276.494828 84 | NDVI: 7951.898545 85 | feature_id: '00000000000000000001' 86 | image_id: 2010-02-18T00-00-00 87 | label: Forest 88 | system:index: '7' 89 | value: 1 90 | warm: 1 91 | '8': 92 | EVI: 704.321312 93 | NDVI: 1057.387456 94 | feature_id: '00000000000000000002' 95 | image_id: 2010-01-01T00-00-00 96 | label: Grassland 97 | system:index: '8' 98 | value: 2 99 | warm: 0 100 | '9': 101 | EVI: 1231.157133 102 | NDVI: 2044.01015 103 | feature_id: '00000000000000000002' 104 | image_id: 2010-01-17T00-00-00 105 | label: Grassland 106 | system:index: '9' 107 | value: 2 108 | warm: 0 109 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_reduce_regions_by_dates.yml: -------------------------------------------------------------------------------- 1 | '0': 2 | EVI: 1014.455318 3 | NDVI: 1797.930408 4 | feature_id: '00000000000000000000' 5 | image_id: 2010-01-01T00-00-00 6 | label: Desert 7 | system:index: '0' 8 | value: 0 9 | warm: 1 10 | '1': 11 | EVI: 971.166098 12 | NDVI: 1900.816413 13 | feature_id: '00000000000000000000' 14 | image_id: 2010-01-17T00-00-00 15 | label: Desert 16 | system:index: '1' 17 | value: 0 18 | warm: 1 19 | '10': 20 | EVI: 1111.532233 21 | NDVI: 1770.138801 22 | feature_id: '00000000000000000002' 23 | image_id: 2010-02-02T00-00-00 24 | label: Grassland 25 | system:index: '10' 26 | value: 2 27 | warm: 0 28 | '11': 29 | EVI: 1055.246577 30 | NDVI: 1797.979795 31 | feature_id: '00000000000000000002' 32 | image_id: 2010-02-18T00-00-00 33 | label: Grassland 34 | system:index: '11' 35 | value: 2 36 | warm: 0 37 | '2': 38 | EVI: 973.384019 39 | NDVI: 1825.576545 40 | feature_id: '00000000000000000000' 41 | image_id: 2010-02-02T00-00-00 42 | label: Desert 43 | system:index: '2' 44 | value: 0 45 | warm: 1 46 | '3': 47 | EVI: 986.248517 48 | NDVI: 1790.578384 49 | feature_id: '00000000000000000000' 50 | image_id: 2010-02-18T00-00-00 51 | label: Desert 52 | system:index: '3' 53 | value: 0 54 | warm: 1 55 | '4': 56 | EVI: 1912.56377 57 | NDVI: 3273.672378 58 | feature_id: '00000000000000000001' 59 | image_id: 2010-01-01T00-00-00 60 | label: Forest 61 | system:index: '4' 62 | value: 1 63 | warm: 1 64 | '5': 65 | EVI: 3276.76424 66 | NDVI: 7331.223758 67 | feature_id: '00000000000000000001' 68 | image_id: 2010-01-17T00-00-00 69 | label: Forest 70 | system:index: '5' 71 | value: 1 72 | warm: 1 73 | '6': 74 | EVI: 2963.260225 75 | NDVI: 7845.514551 76 | feature_id: '00000000000000000001' 77 | image_id: 2010-02-02T00-00-00 78 | label: Forest 79 | system:index: '6' 80 | value: 1 81 | warm: 1 82 | '7': 83 | EVI: 3276.494828 84 | NDVI: 7951.898545 85 | feature_id: '00000000000000000001' 86 | image_id: 2010-02-18T00-00-00 87 | label: Forest 88 | system:index: '7' 89 | value: 1 90 | warm: 1 91 | '8': 92 | EVI: 704.321312 93 | NDVI: 1057.387456 94 | feature_id: '00000000000000000002' 95 | image_id: 2010-01-01T00-00-00 96 | label: Grassland 97 | system:index: '8' 98 | value: 2 99 | warm: 0 100 | '9': 101 | EVI: 1231.157133 102 | NDVI: 2044.01015 103 | feature_id: '00000000000000000002' 104 | image_id: 2010-01-17T00-00-00 105 | label: Grassland 106 | system:index: '9' 107 | value: 2 108 | warm: 0 109 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_reduce_regions_by_doy.yml: -------------------------------------------------------------------------------- 1 | '0': 2 | EVI: 1009.899538 3 | NDVI: 1769.374256 4 | feature_id: '00000000000000000000' 5 | image_id: '001' 6 | label: Desert 7 | system:index: '0' 8 | value: 0 9 | warm: 1 10 | '1': 11 | EVI: 958.478967 12 | NDVI: 1847.064911 13 | feature_id: '00000000000000000000' 14 | image_id: '017' 15 | label: Desert 16 | system:index: '1' 17 | value: 0 18 | warm: 1 19 | '10': 20 | EVI: 1091.781982 21 | NDVI: 1728.73449 22 | feature_id: '00000000000000000002' 23 | image_id: '033' 24 | label: Grassland 25 | system:index: '10' 26 | value: 2 27 | warm: 0 28 | '11': 29 | EVI: 1051.314147 30 | NDVI: 1777.729305 31 | feature_id: '00000000000000000002' 32 | image_id: 049 33 | label: Grassland 34 | system:index: '11' 35 | value: 2 36 | warm: 0 37 | '2': 38 | EVI: 964.530275 39 | NDVI: 1793.732629 40 | feature_id: '00000000000000000000' 41 | image_id: '033' 42 | label: Desert 43 | system:index: '2' 44 | value: 0 45 | warm: 1 46 | '3': 47 | EVI: 976.570587 48 | NDVI: 1739.140715 49 | feature_id: '00000000000000000000' 50 | image_id: 049 51 | label: Desert 52 | system:index: '3' 53 | value: 0 54 | warm: 1 55 | '4': 56 | EVI: 1517.999026 57 | NDVI: 2429.698433 58 | feature_id: '00000000000000000001' 59 | image_id: '001' 60 | label: Forest 61 | system:index: '4' 62 | value: 1 63 | warm: 1 64 | '5': 65 | EVI: 3290.092853 66 | NDVI: 7359.342325 67 | feature_id: '00000000000000000001' 68 | image_id: '017' 69 | label: Forest 70 | system:index: '5' 71 | value: 1 72 | warm: 1 73 | '6': 74 | EVI: 2968.64415 75 | NDVI: 7911.374471 76 | feature_id: '00000000000000000001' 77 | image_id: '033' 78 | label: Forest 79 | system:index: '6' 80 | value: 1 81 | warm: 1 82 | '7': 83 | EVI: 3080.721238 84 | NDVI: 7745.932431 85 | feature_id: '00000000000000000001' 86 | image_id: 049 87 | label: Forest 88 | system:index: '7' 89 | value: 1 90 | warm: 1 91 | '8': 92 | EVI: 762.859934 93 | NDVI: 1059.116386 94 | feature_id: '00000000000000000002' 95 | image_id: '001' 96 | label: Grassland 97 | system:index: '8' 98 | value: 2 99 | warm: 0 100 | '9': 101 | EVI: 1221.112521 102 | NDVI: 1950.57339 103 | feature_id: '00000000000000000002' 104 | image_id: '017' 105 | label: Grassland 106 | system:index: '9' 107 | value: 2 108 | warm: 0 109 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_scale_and_offset.csv: -------------------------------------------------------------------------------- 1 | ,AOT,B1,B11,B12,B2,B3,B4,B5,B6,B7,B8,B8A,B9,MSK_CLDPRB,MSK_SNWPRB,QA10,QA20,QA60,SCL,TCI_B,TCI_G,TCI_R,WVP 2 | 0,0.19900000000000001,1.6640094805201937,0.15682904317977711,0.19683295548610844,1.5419765396983116,1.4101613293903945,1.2931892357711661,1.4237406449383538,1.2795376786673232,1.1806409740941775,1.2098870170405167,1.1006397712739482,1.5899000000000001,0,0,0,0,1024,8,255,255,255,3.645 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_spectral_indices.csv: -------------------------------------------------------------------------------- 1 | ,AOT,B1,B11,B12,B2,B3,B4,B5,B6,B7,B8,B8A,B9,MSK_CLDPRB,MSK_SNWPRB,NDVI,NDWI,QA10,QA20,QA60,SCL,TCI_B,TCI_G,TCI_R,WVP 2 | 0,199,16640.094805201559,1568.290431797825,1968.3295548610204,15419.765396984198,14101.613293902175,12931.892357709678,14237.406449381348,12795.376786673241,11806.409740942607,12098.870170407052,11006.397712738837,15899,0,0,-0.033280621230818465,0.076438807170131434,0,0,1024,8,255,255,255,3645 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_tasseled_cap.csv: -------------------------------------------------------------------------------- 1 | ,SR_B3,SR_B4,SR_B5,SR_B6,SR_B7,TCB,TCG,TCW 2 | 0,24932.169636948358,24528.146256576434,26797.209132925651,13304.004203999191,13985.102528787485,47555.65488519983,-984.25545628912641,3817.1624108101837 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_validPixel.csv: -------------------------------------------------------------------------------- 1 | ,pct_valid,valid 2 | 0,5.4298642533936654,12 3 | -------------------------------------------------------------------------------- /tests/test_ImageCollection/test_valid_pixels.csv: -------------------------------------------------------------------------------- 1 | ,pct_valid,valid 2 | 0,100,12 3 | -------------------------------------------------------------------------------- /tests/test_Integer.py: -------------------------------------------------------------------------------- 1 | """Test the Integer placeholder object.""" 2 | import ee 3 | import pytest 4 | 5 | 6 | class TestInteger: 7 | """Test the Integer placeholder class.""" 8 | 9 | def test_init(self): 10 | with pytest.raises(NotImplementedError): 11 | ee.Integer() 12 | 13 | def test_name(self): 14 | assert ee.Integer.__name__ == "Integer" 15 | -------------------------------------------------------------------------------- /tests/test_Join.py: -------------------------------------------------------------------------------- 1 | """Test the ``Join`` class.""" 2 | import ee 3 | import pytest 4 | 5 | import geetools # noqa: F401 6 | 7 | 8 | class TestByProperty: 9 | """Test the ``byProperty`` method.""" 10 | 11 | def test_by_property(self, fc1, fc2, ee_feature_collection_regression): 12 | joined = ee.Join.geetools.byProperty(fc1, fc2, "id") 13 | ee_feature_collection_regression.check(joined, prescision=4) 14 | 15 | def test_by_property_outer(self, fc1, fc2, ee_feature_collection_regression): 16 | joined = ee.Join.geetools.byProperty(fc1, fc2, "id", outer=True) 17 | ee_feature_collection_regression.check(joined, prescision=4) 18 | 19 | @pytest.fixture 20 | def fc1(self): 21 | point = ee.Geometry.Point([0, 0]) 22 | prop1 = {"id": 1, "prop_from_fc1": "I am from fc1"} 23 | return ee.FeatureCollection([ee.Feature(point, prop1)]) 24 | 25 | @pytest.fixture 26 | def fc2(self): 27 | point = ee.Geometry.Point([0, 0]) 28 | prop2 = {"id": 1, "prop_from_fc2": "I am from fc2"} 29 | return ee.FeatureCollection([ee.Feature(point, prop2)]) 30 | -------------------------------------------------------------------------------- /tests/test_Join/test_by_property.yml: -------------------------------------------------------------------------------- 1 | features: 2 | - geometry: 3 | coordinates: 4 | - 0.0 5 | - 0.0 6 | type: Point 7 | id: '0' 8 | properties: 9 | id: 1 10 | prop_from_fc1: I am from fc1 11 | prop_from_fc2: I am from fc2 12 | type: Feature 13 | type: FeatureCollection 14 | -------------------------------------------------------------------------------- /tests/test_Join/test_by_property_outer.yml: -------------------------------------------------------------------------------- 1 | features: 2 | - geometry: 3 | coordinates: 4 | - 0.0 5 | - 0.0 6 | type: Point 7 | id: '0' 8 | properties: 9 | id: 1 10 | prop_from_fc1: I am from fc1 11 | prop_from_fc2: I am from fc2 12 | type: Feature 13 | type: FeatureCollection 14 | -------------------------------------------------------------------------------- /tests/test_Join/test_deprecated_join.yml: -------------------------------------------------------------------------------- 1 | columns: {} 2 | features: 3 | - geometry: 4 | coordinates: 5 | - 0 6 | - 0 7 | type: Point 8 | id: '0' 9 | properties: 10 | id: 1 11 | prop_from_fc1: I am from fc1 12 | prop_from_fc2: I am from fc2 13 | type: Feature 14 | type: FeatureCollection 15 | -------------------------------------------------------------------------------- /tests/test_List/serialized_test_complement_with_different_type.yml: -------------------------------------------------------------------------------- 1 | result: '0' 2 | values: 3 | '0': 4 | functionInvocationValue: 5 | arguments: 6 | list: 7 | functionInvocationValue: 8 | arguments: 9 | list: 10 | valueReference: '1' 11 | other: 12 | valueReference: '2' 13 | functionName: List.removeAll 14 | other: 15 | functionInvocationValue: 16 | arguments: 17 | list: 18 | valueReference: '2' 19 | other: 20 | valueReference: '1' 21 | functionName: List.removeAll 22 | functionName: List.cat 23 | '1': 24 | constantValue: 25 | - a 26 | - b 27 | - c 28 | '2': 29 | constantValue: 30 | - 1 31 | - 2 32 | -------------------------------------------------------------------------------- /tests/test_List/serialized_test_complement_with_same_type.yml: -------------------------------------------------------------------------------- 1 | result: '0' 2 | values: 3 | '0': 4 | functionInvocationValue: 5 | arguments: 6 | list: 7 | valueReference: '1' 8 | other: 9 | valueReference: '1' 10 | functionName: List.cat 11 | '1': 12 | functionInvocationValue: 13 | arguments: 14 | list: 15 | valueReference: '2' 16 | other: 17 | valueReference: '2' 18 | functionName: List.removeAll 19 | '2': 20 | constantValue: 21 | - a 22 | - b 23 | - c 24 | -------------------------------------------------------------------------------- /tests/test_List/serialized_test_delete.yml: -------------------------------------------------------------------------------- 1 | result: '0' 2 | values: 3 | '0': 4 | functionInvocationValue: 5 | arguments: 6 | list: 7 | functionInvocationValue: 8 | arguments: 9 | end: 10 | valueReference: '1' 11 | list: 12 | valueReference: '2' 13 | start: 14 | constantValue: 0 15 | functionName: List.slice 16 | other: 17 | functionInvocationValue: 18 | arguments: 19 | list: 20 | valueReference: '2' 21 | start: 22 | functionInvocationValue: 23 | arguments: 24 | left: 25 | valueReference: '1' 26 | right: 27 | constantValue: 1 28 | functionName: Number.add 29 | functionName: List.slice 30 | functionName: List.cat 31 | '1': 32 | functionInvocationValue: 33 | arguments: 34 | input: 35 | constantValue: 1 36 | functionName: Number.toInt 37 | '2': 38 | constantValue: 39 | - a 40 | - b 41 | - c 42 | -------------------------------------------------------------------------------- /tests/test_List/serialized_test_intersection_with_different_type.yml: -------------------------------------------------------------------------------- 1 | result: '0' 2 | values: 3 | '0': 4 | functionInvocationValue: 5 | arguments: 6 | list: 7 | valueReference: '1' 8 | other: 9 | functionInvocationValue: 10 | arguments: 11 | list: 12 | valueReference: '1' 13 | other: 14 | constantValue: 15 | - 1 16 | - 2 17 | functionName: List.removeAll 18 | functionName: List.removeAll 19 | '1': 20 | constantValue: 21 | - a 22 | - b 23 | - c 24 | -------------------------------------------------------------------------------- /tests/test_List/serialized_test_intersection_with_same_type.yml: -------------------------------------------------------------------------------- 1 | result: '0' 2 | values: 3 | '0': 4 | functionInvocationValue: 5 | arguments: 6 | list: 7 | valueReference: '1' 8 | other: 9 | functionInvocationValue: 10 | arguments: 11 | list: 12 | valueReference: '1' 13 | other: 14 | valueReference: '1' 15 | functionName: List.removeAll 16 | functionName: List.removeAll 17 | '1': 18 | constantValue: 19 | - a 20 | - b 21 | - c 22 | -------------------------------------------------------------------------------- /tests/test_List/serialized_test_product_with_different_type.yml: -------------------------------------------------------------------------------- 1 | result: '0' 2 | values: 3 | '0': 4 | functionInvocationValue: 5 | arguments: 6 | list: 7 | functionInvocationValue: 8 | arguments: 9 | baseAlgorithm: 10 | functionDefinitionValue: 11 | argumentNames: 12 | - _MAPPING_VAR_2_0 13 | body: '1' 14 | dropNulls: 15 | constantValue: false 16 | list: 17 | functionInvocationValue: 18 | arguments: 19 | baseAlgorithm: 20 | valueReference: '4' 21 | dropNulls: 22 | constantValue: false 23 | list: 24 | constantValue: 25 | - a 26 | - b 27 | - c 28 | functionName: List.map 29 | functionName: List.map 30 | functionName: List.flatten 31 | '1': 32 | functionInvocationValue: 33 | arguments: 34 | baseAlgorithm: 35 | functionDefinitionValue: 36 | argumentNames: 37 | - _MAPPING_VAR_0_0 38 | body: '2' 39 | dropNulls: 40 | constantValue: false 41 | list: 42 | functionInvocationValue: 43 | arguments: 44 | baseAlgorithm: 45 | valueReference: '4' 46 | dropNulls: 47 | constantValue: false 48 | list: 49 | constantValue: 50 | - 1 51 | - 2 52 | functionName: List.map 53 | functionName: List.map 54 | '2': 55 | functionInvocationValue: 56 | arguments: 57 | string1: 58 | functionInvocationValue: 59 | arguments: 60 | input: 61 | argumentReference: _MAPPING_VAR_2_0 62 | functionName: String 63 | string2: 64 | valueReference: '3' 65 | functionName: String.cat 66 | '3': 67 | functionInvocationValue: 68 | arguments: 69 | input: 70 | argumentReference: _MAPPING_VAR_0_0 71 | functionName: String 72 | '4': 73 | functionDefinitionValue: 74 | argumentNames: 75 | - _MAPPING_VAR_0_0 76 | body: '3' 77 | -------------------------------------------------------------------------------- /tests/test_List/serialized_test_product_with_same_type.yml: -------------------------------------------------------------------------------- 1 | result: '0' 2 | values: 3 | '0': 4 | functionInvocationValue: 5 | arguments: 6 | list: 7 | functionInvocationValue: 8 | arguments: 9 | baseAlgorithm: 10 | functionDefinitionValue: 11 | argumentNames: 12 | - _MAPPING_VAR_2_0 13 | body: '1' 14 | dropNulls: 15 | constantValue: false 16 | list: 17 | valueReference: '4' 18 | functionName: List.map 19 | functionName: List.flatten 20 | '1': 21 | functionInvocationValue: 22 | arguments: 23 | baseAlgorithm: 24 | functionDefinitionValue: 25 | argumentNames: 26 | - _MAPPING_VAR_0_0 27 | body: '2' 28 | dropNulls: 29 | constantValue: false 30 | list: 31 | valueReference: '4' 32 | functionName: List.map 33 | '2': 34 | functionInvocationValue: 35 | arguments: 36 | string1: 37 | functionInvocationValue: 38 | arguments: 39 | input: 40 | argumentReference: _MAPPING_VAR_2_0 41 | functionName: String 42 | string2: 43 | valueReference: '3' 44 | functionName: String.cat 45 | '3': 46 | functionInvocationValue: 47 | arguments: 48 | input: 49 | argumentReference: _MAPPING_VAR_0_0 50 | functionName: String 51 | '4': 52 | functionInvocationValue: 53 | arguments: 54 | baseAlgorithm: 55 | functionDefinitionValue: 56 | argumentNames: 57 | - _MAPPING_VAR_0_0 58 | body: '3' 59 | dropNulls: 60 | constantValue: false 61 | list: 62 | constantValue: 63 | - a 64 | - b 65 | - c 66 | functionName: List.map 67 | -------------------------------------------------------------------------------- /tests/test_List/serialized_test_replace_many.yml: -------------------------------------------------------------------------------- 1 | result: '0' 2 | values: 3 | '0': 4 | functionInvocationValue: 5 | arguments: 6 | first: 7 | constantValue: 8 | - a 9 | - b 10 | - c 11 | function: 12 | functionDefinitionValue: 13 | argumentNames: 14 | - _MAPPING_VAR_0_0 15 | - _MAPPING_VAR_0_1 16 | body: '1' 17 | list: 18 | functionInvocationValue: 19 | arguments: 20 | dictionary: 21 | valueReference: '2' 22 | functionName: Dictionary.keys 23 | functionName: List.iterate 24 | '1': 25 | functionInvocationValue: 26 | arguments: 27 | list: 28 | argumentReference: _MAPPING_VAR_0_1 29 | newval: 30 | functionInvocationValue: 31 | arguments: 32 | dictionary: 33 | valueReference: '2' 34 | key: 35 | functionInvocationValue: 36 | arguments: 37 | input: 38 | argumentReference: _MAPPING_VAR_0_0 39 | functionName: String 40 | functionName: Dictionary.get 41 | oldval: 42 | argumentReference: _MAPPING_VAR_0_0 43 | functionName: List.replace 44 | '2': 45 | constantValue: 46 | a: foo 47 | c: bar 48 | -------------------------------------------------------------------------------- /tests/test_List/serialized_test_union_with_duplicate.yml: -------------------------------------------------------------------------------- 1 | result: '0' 2 | values: 3 | '0': 4 | functionInvocationValue: 5 | arguments: 6 | list: 7 | functionInvocationValue: 8 | arguments: 9 | list: 10 | valueReference: '1' 11 | other: 12 | valueReference: '1' 13 | functionName: List.cat 14 | functionName: List.distinct 15 | '1': 16 | constantValue: 17 | - a 18 | - b 19 | - c 20 | -------------------------------------------------------------------------------- /tests/test_List/serialized_test_union_without_dupplicates.yml: -------------------------------------------------------------------------------- 1 | result: '0' 2 | values: 3 | '0': 4 | functionInvocationValue: 5 | arguments: 6 | list: 7 | functionInvocationValue: 8 | arguments: 9 | list: 10 | constantValue: 11 | - a 12 | - b 13 | - c 14 | other: 15 | constantValue: 16 | - 1 17 | - 2 18 | functionName: List.cat 19 | functionName: List.distinct 20 | -------------------------------------------------------------------------------- /tests/test_List/serialized_test_zip.yml: -------------------------------------------------------------------------------- 1 | result: '0' 2 | values: 3 | '0': 4 | functionInvocationValue: 5 | arguments: 6 | baseAlgorithm: 7 | functionDefinitionValue: 8 | argumentNames: 9 | - _MAPPING_VAR_1_0 10 | body: '1' 11 | dropNulls: 12 | constantValue: false 13 | list: 14 | functionInvocationValue: 15 | arguments: 16 | end: 17 | functionInvocationValue: 18 | arguments: 19 | left: 20 | functionInvocationValue: 21 | arguments: 22 | list: 23 | functionInvocationValue: 24 | arguments: 25 | index: 26 | constantValue: 0 27 | list: 28 | valueReference: '3' 29 | functionName: List.get 30 | functionName: List.size 31 | right: 32 | constantValue: 1 33 | functionName: Number.subtract 34 | start: 35 | constantValue: 0 36 | functionName: List.sequence 37 | functionName: List.map 38 | '1': 39 | functionInvocationValue: 40 | arguments: 41 | baseAlgorithm: 42 | functionDefinitionValue: 43 | argumentNames: 44 | - _MAPPING_VAR_0_0 45 | body: '2' 46 | dropNulls: 47 | constantValue: false 48 | list: 49 | valueReference: '3' 50 | functionName: List.map 51 | '2': 52 | functionInvocationValue: 53 | arguments: 54 | index: 55 | argumentReference: _MAPPING_VAR_1_0 56 | list: 57 | argumentReference: _MAPPING_VAR_0_0 58 | functionName: List.get 59 | '3': 60 | arrayValue: 61 | values: 62 | - valueReference: '4' 63 | - valueReference: '4' 64 | '4': 65 | constantValue: 66 | - a 67 | - b 68 | - c 69 | -------------------------------------------------------------------------------- /tests/test_List/test_chunked_even.yml: -------------------------------------------------------------------------------- 1 | - - 1 2 | - 2 3 | - - 3 4 | - 4 5 | - - 5 6 | - 6 7 | - - 7 8 | - 8 9 | -------------------------------------------------------------------------------- /tests/test_List/test_chunked_odd.yml: -------------------------------------------------------------------------------- 1 | - - 1 2 | - 2 3 | - - 3 4 | - 4 5 | - - 5 6 | - 6 7 | - - 7 8 | - 8 9 | - 9 10 | -------------------------------------------------------------------------------- /tests/test_List/test_complement_with_different_type.yml: -------------------------------------------------------------------------------- 1 | - a 2 | - b 3 | - c 4 | - 1 5 | - 2 6 | -------------------------------------------------------------------------------- /tests/test_List/test_complement_with_same_type.yml: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /tests/test_List/test_delete.yml: -------------------------------------------------------------------------------- 1 | - a 2 | - c 3 | -------------------------------------------------------------------------------- /tests/test_List/test_intersection_with_different_type.yml: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /tests/test_List/test_intersection_with_same_type.yml: -------------------------------------------------------------------------------- 1 | - a 2 | - b 3 | - c 4 | -------------------------------------------------------------------------------- /tests/test_List/test_product_with_different_type.yml: -------------------------------------------------------------------------------- 1 | - a1 2 | - a2 3 | - b1 4 | - b2 5 | - c1 6 | - c2 7 | -------------------------------------------------------------------------------- /tests/test_List/test_product_with_same_type.yml: -------------------------------------------------------------------------------- 1 | - aa 2 | - ab 3 | - ac 4 | - ba 5 | - bb 6 | - bc 7 | - ca 8 | - cb 9 | - cc 10 | -------------------------------------------------------------------------------- /tests/test_List/test_replace_many.yml: -------------------------------------------------------------------------------- 1 | - foo 2 | - b 3 | - bar 4 | -------------------------------------------------------------------------------- /tests/test_List/test_to_strings.yml: -------------------------------------------------------------------------------- 1 | - a 2 | - '1' 3 | - Image 4 | -------------------------------------------------------------------------------- /tests/test_List/test_union_with_duplicate.yml: -------------------------------------------------------------------------------- 1 | - a 2 | - b 3 | - c 4 | -------------------------------------------------------------------------------- /tests/test_List/test_union_without_dupplicates.yml: -------------------------------------------------------------------------------- 1 | - a 2 | - b 3 | - c 4 | - 1 5 | - 2 6 | -------------------------------------------------------------------------------- /tests/test_List/test_zip.yml: -------------------------------------------------------------------------------- 1 | - - a 2 | - a 3 | - - b 4 | - b 5 | - - c 6 | - c 7 | -------------------------------------------------------------------------------- /tests/test_Number.py: -------------------------------------------------------------------------------- 1 | """test the Number class methods.""" 2 | import geetools # noqa: F401 3 | 4 | 5 | class TestTruncate: 6 | """Test the truncate method.""" 7 | 8 | def test_truncate_with_default_decimals(self, number_instance): 9 | truncated_number = number_instance.geetools.truncate() 10 | assert truncated_number.getInfo() == 1234.56 11 | 12 | def test_truncate_with_custom_decimals(self, number_instance): 13 | truncated_number = number_instance.geetools.truncate(1) 14 | assert truncated_number.getInfo() == 1234.5 15 | 16 | def test_truncate_with_zero_decimals(self, number_instance): 17 | truncated_number = number_instance.geetools.truncate(0) 18 | assert truncated_number.getInfo() == 1234.0 19 | 20 | def test_truncate_with_large_decimals(self, number_instance): 21 | truncated_number = number_instance.geetools.truncate(5) 22 | assert truncated_number.getInfo() == 1234.56785 23 | 24 | 25 | class TestIsClose: 26 | """Test the ``isClose`` method.""" 27 | 28 | def test_is_close(self, number_instance): 29 | is_close = number_instance.geetools.isClose(1234.56785678) 30 | assert is_close.getInfo() == 1 31 | 32 | def test_is_not_close(self, number_instance): 33 | is_close = number_instance.geetools.isClose(1234.5) 34 | assert is_close.getInfo() == 0 35 | 36 | def test_is_close_with_custom_tolerance(self, number_instance): 37 | is_close = number_instance.geetools.isClose(1234.5678567, 1e-5) 38 | assert is_close.getInfo() == 1 39 | 40 | def test_is_close_with_zero_tolerance(self, number_instance): 41 | is_close = number_instance.geetools.isClose(1234.56785678, 0) 42 | assert is_close.getInfo() == 1 43 | -------------------------------------------------------------------------------- /tests/test_Profiler.py: -------------------------------------------------------------------------------- 1 | """Test the ee_profiler module.""" 2 | import ee 3 | 4 | import geetools # noqa: F401 5 | 6 | 7 | class TestProfiler: 8 | """Test the Profiler class.""" 9 | 10 | def test_profiler(self): 11 | """Test the Profiler class.""" 12 | 13 | with ee.geetools.Profiler() as p: 14 | ee.Number(3.14).add(0.00159).getInfo() 15 | assert [k for k in p.profile] == ["EECU-s", "PeakMem", "Count", "Description"] 16 | -------------------------------------------------------------------------------- /tests/test_String.py: -------------------------------------------------------------------------------- 1 | """Test the String class methods.""" 2 | import ee 3 | 4 | 5 | class TestEq: 6 | """Test the eq method.""" 7 | 8 | def test_eq_with_same_string(self, string_instance): 9 | eq_number = string_instance.geetools.eq("foo") 10 | assert eq_number.getInfo() == 1 11 | 12 | def test_eq_with_different_string(self, string_instance): 13 | eq_number = string_instance.geetools.eq("bar") 14 | assert eq_number.getInfo() == 0 15 | 16 | 17 | class TestFormat: 18 | """test the format method.""" 19 | 20 | def test_format_with_dictionary(self, format_string_instance): 21 | params = {"greeting": "Hello", "name": "bob"} 22 | formatted_string = format_string_instance.geetools.format(params) 23 | assert formatted_string.getInfo() == "Hello bob !" 24 | 25 | def test_with_number(self, format_string_instance): 26 | params = {"greeting": "Hello", "name": ee.Number(1)} 27 | formatted_string = format_string_instance.geetools.format(params) 28 | assert formatted_string.getInfo() == "Hello 1 !" 29 | 30 | def test_format_formatter(self): 31 | string = ee.String( 32 | "{greeting} developer, pi={number%.2f} start={start%tyyyy-MM-dd} end={end%tdd MMM yyyy}" 33 | ) 34 | params = { 35 | "greeting": "Hello", 36 | "number": 3.1415, 37 | "start": 1577836800000, 38 | "end": "2021-01-01", 39 | } 40 | formatted_string = string.geetools.format(params) 41 | assert ( 42 | formatted_string.getInfo() 43 | == "Hello developer, pi=3.14 start=2020-01-01 end=01 Jan 2021" 44 | ) 45 | 46 | def test_format_missing(self): 47 | string = ee.String("{greeting} {missing}") 48 | params = {"greeting": "Hello", "number": 3.1415, "date": 1577836800000} 49 | formatted_string = string.geetools.format(params) 50 | assert formatted_string.getInfo() == "Hello " 51 | -------------------------------------------------------------------------------- /tests/test_batch/test_utils.py: -------------------------------------------------------------------------------- 1 | """Test the utils module.""" 2 | 3 | from geetools import utils 4 | 5 | 6 | class TestFormatDescription: 7 | """Test the utils.format_description function.""" 8 | 9 | def test_valid_description(self): 10 | """Test a valid description.""" 11 | description = "This is a valid description 123.,:;_-" 12 | result = utils.format_description(description) 13 | assert result == "This_is_a_valid_description_123.,:;_-" 14 | 15 | def test_replacements(self): 16 | """Test replacements.""" 17 | description = "Testing / replacements ?!{}()" 18 | result = utils.format_description(description) 19 | assert result == "Testing_-_replacements_..::::" 20 | 21 | def test_long_description(self): 22 | description = "A" * 150 23 | result = utils.format_description(description) 24 | assert len(result) == 100 25 | 26 | def test_unicode_characters(self): 27 | description = "Unicode characters like é, ä, and ñ should be changed" 28 | result = utils.format_description(description) 29 | assert result == "Unicode_characters_like_e,_a,_and_n_should_be_changed" 30 | 31 | 32 | class TestFormatAssetID: 33 | """Test the utils.format_asset_id function.""" 34 | 35 | def test_valid_description(self): 36 | """Test a valid description.""" 37 | description = "This is a valid description 123.,:;_-" 38 | result = utils.format_asset_id(description) 39 | assert result == "This_is_a_valid_description_123_____-" 40 | 41 | def test_replacements(self): 42 | """Test replacements.""" 43 | description = "Testing / replacements ?!{}()" 44 | result = utils.format_asset_id(description) 45 | assert result == "Testing_-_replacements_______" 46 | 47 | def test_long_description(self): 48 | description = "A" * 150 49 | result = utils.format_asset_id(description) 50 | assert len(result) == 150 51 | 52 | def test_unicode_characters(self): 53 | description = "Unicode characters like é, ä, and ñ should be changed" 54 | result = utils.format_asset_id(description) 55 | assert result == "Unicode_characters_like_e__a__and_n_should_be_changed" 56 | -------------------------------------------------------------------------------- /tests/test_deprecated.py: -------------------------------------------------------------------------------- 1 | """Test all the deprecated methods that have not been kept in the new implementation.""" 2 | 3 | 4 | import pytest 5 | 6 | import geetools 7 | 8 | 9 | class TestImageCollection: 10 | """Test the deprecated_imagecollection module.""" 11 | 12 | def test_linear_function_band(self): 13 | with pytest.raises(NotImplementedError): 14 | geetools.imagecollection.linearFunctionBand(None, None, None, None) 15 | 16 | def test_linear_function_property(self): 17 | with pytest.raises(NotImplementedError): 18 | geetools.imagecollection.linearFunctionProperty(None, None, None, None) 19 | 20 | def linear_interpolation_property(self): 21 | with pytest.raises(NotImplementedError): 22 | geetools.imagecollection.linearInterpolationProperty(None, None, None, None) 23 | 24 | def test_gauss_function_band(self): 25 | with pytest.raises(NotImplementedError): 26 | geetools.imagecollection.gaussFunctionBand(None, None, None, None, None) 27 | 28 | def test_gauss_function_property(self): 29 | with pytest.raises(NotImplementedError): 30 | geetools.imagecollection.gaussFunctionProperty(None, None, None, None, None) 31 | 32 | def testnormal_distribution_property(self): 33 | with pytest.raises(NotImplementedError): 34 | geetools.imagecollection.normalDistributionProperty(None, None, None, None, None) 35 | 36 | def test_normal_distribution_band(self): 37 | with pytest.raises(NotImplementedError): 38 | geetools.imagecollection.normalDistributionBand(None, None, None, None, None) 39 | 40 | def test_moving_average(self): 41 | with pytest.raises(NotImplementedError): 42 | geetools.imagecollection.moving_average(None) 43 | 44 | 45 | class TestAlgorithm: 46 | """Test the deprecated_algorithms module.""" 47 | 48 | def test_pansharpenkernel(self): 49 | with pytest.raises(NotImplementedError): 50 | geetools.algorithms.pansharpenKernel(None, None) 51 | 52 | def test_pansharpenihsFusion(self): 53 | with pytest.raises(NotImplementedError): 54 | geetools.algorithms.pansharpenIhsFusion(None) 55 | 56 | 57 | class TestComposite: 58 | """Test the deprecated_composite module.""" 59 | 60 | def test_max(self, s2_sr): 61 | with pytest.deprecated_call(): 62 | geetools.composite.max(s2_sr) 63 | 64 | def test_medoidScore(self, s2_sr): 65 | with pytest.raises(NotImplementedError): 66 | geetools.composite.medoidScore(s2_sr) 67 | -------------------------------------------------------------------------------- /tests/test_deprecated/test_deprecated_cast_image.yml: -------------------------------------------------------------------------------- 1 | constant: 1 2 | -------------------------------------------------------------------------------- /tests/test_deprecated/test_tobands.yml: -------------------------------------------------------------------------------- 1 | - 20210102T150719_20210102T150942_T18MYC_B1 2 | - 20210102T150719_20210102T150942_T18MYC_B2 3 | - 20210102T150719_20210102T150942_T18MYC_B3 4 | - 20210102T150719_20210102T150942_T18MYC_B4 5 | - 20210102T150719_20210102T150942_T18MYC_B5 6 | - 20210102T150719_20210102T150942_T18MYC_B6 7 | - 20210102T150719_20210102T150942_T18MYC_B7 8 | - 20210102T150719_20210102T150942_T18MYC_B8 9 | - 20210102T150719_20210102T150942_T18MYC_B8A 10 | - 20210102T150719_20210102T150942_T18MYC_B9 11 | - 20210102T150719_20210102T150942_T18MYC_B11 12 | - 20210102T150719_20210102T150942_T18MYC_B12 13 | - 20210102T150719_20210102T150942_T18MYC_SCL 14 | - 20210102T150719_20210102T150942_T18MYD_B1 15 | - 20210102T150719_20210102T150942_T18MYD_B2 16 | - 20210102T150719_20210102T150942_T18MYD_B3 17 | - 20210102T150719_20210102T150942_T18MYD_B4 18 | - 20210102T150719_20210102T150942_T18MYD_B5 19 | - 20210102T150719_20210102T150942_T18MYD_B6 20 | - 20210102T150719_20210102T150942_T18MYD_B7 21 | - 20210102T150719_20210102T150942_T18MYD_B8 22 | - 20210102T150719_20210102T150942_T18MYD_B8A 23 | - 20210102T150719_20210102T150942_T18MYD_B9 24 | - 20210102T150719_20210102T150942_T18MYD_B11 25 | - 20210102T150719_20210102T150942_T18MYD_B12 26 | - 20210102T150719_20210102T150942_T18MYD_SCL 27 | - 20210102T150719_20210102T150942_T18MZC_B1 28 | - 20210102T150719_20210102T150942_T18MZC_B2 29 | - 20210102T150719_20210102T150942_T18MZC_B3 30 | - 20210102T150719_20210102T150942_T18MZC_B4 31 | - 20210102T150719_20210102T150942_T18MZC_B5 32 | - 20210102T150719_20210102T150942_T18MZC_B6 33 | - 20210102T150719_20210102T150942_T18MZC_B7 34 | - 20210102T150719_20210102T150942_T18MZC_B8 35 | - 20210102T150719_20210102T150942_T18MZC_B8A 36 | - 20210102T150719_20210102T150942_T18MZC_B9 37 | - 20210102T150719_20210102T150942_T18MZC_B11 38 | - 20210102T150719_20210102T150942_T18MZC_B12 39 | - 20210102T150719_20210102T150942_T18MZC_SCL 40 | --------------------------------------------------------------------------------