diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..19dc69e --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,37 @@ +name: Deploy Documentation + +on: + push: + branches: + - main + workflow_dispatch: + +permissions: + contents: write + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install uv + uses: astral-sh/setup-uv@v5 + + - name: Set up Python + run: uv python install + + - name: Install dependencies + run: | + uv sync --all-extras + + - name: Build documentation + run: | + uv run sphinx-build -b html docs/source docs/build/html + + - name: Deploy to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./docs/build/html diff --git a/.gitignore b/.gitignore index 1dae2d6..70b1963 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ build/ .coverage .coverage.* dist/ +docs/build/html *.egg-info .eggs examples/sentinel-2*/ @@ -14,3 +15,4 @@ __pycache__ .pytest* .ruff_cache .vscode/ +.venv \ No newline at end of file diff --git a/docs/source/api.rst b/docs/source/api.rst new file mode 100644 index 0000000..2b365fd --- /dev/null +++ b/docs/source/api.rst @@ -0,0 +1,37 @@ +API Reference +============= + +.. autosummary:: + :toctree: generated + :recursive: + + mapchete_eo.base + mapchete_eo.product + mapchete_eo.source + mapchete_eo.search.base + mapchete_eo.search.stac_search + mapchete_eo.search.stac_static + mapchete_eo.search.utm_search + mapchete_eo.platforms.sentinel2.driver + mapchete_eo.platforms.sentinel2.source + mapchete_eo.platforms.sentinel2.product + mapchete_eo.platforms.sentinel2.preprocessing_tasks + mapchete_eo.platforms.sentinel2.masks + mapchete_eo.image_operations.compositing + mapchete_eo.image_operations.blend_functions + mapchete_eo.image_operations.color_correction + mapchete_eo.image_operations.filters + mapchete_eo.image_operations.linear_normalization + mapchete_eo.processes.merge_rasters + mapchete_eo.processes.dtype_scale + mapchete_eo.processes.eo_to_xarray + mapchete_eo.io.products + mapchete_eo.io.levelled_cubes + mapchete_eo.io.assets + mapchete_eo.io.items + mapchete_eo.array.convert + mapchete_eo.array.color + mapchete_eo.array.buffer + mapchete_eo.time + mapchete_eo.types + mapchete_eo.sort diff --git a/docs/source/conf.py b/docs/source/conf.py index 7362f57..9a2db7d 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -41,12 +41,9 @@ def get_metadata(): version, author = get_metadata() project = "mapchete-eo" -author = author release = version -version, author = get_metadata() - rst_prolog = f""" .. |author| replace:: {author} .. |version| replace:: {version} @@ -58,8 +55,18 @@ def get_metadata(): "sphinx.ext.napoleon", "sphinx.ext.viewcode", "sphinx.ext.autosummary", + "sphinx.ext.intersphinx", ] +intersphinx_mapping = { + "python": ("https://docs.python.org/3", None), + "numpy": ("https://numpy.org/doc/stable/", None), + "matplotlib": ("https://matplotlib.org/stable/", None), + "rasterio": ("https://rasterio.readthedocs.io/en/latest/", None), + "xarray": ("https://docs.xarray.dev/en/stable/", None), + "mapchete": ("https://mapchete.readthedocs.io/en/latest/", None), +} + autosummary_generate = True # Optional: include tests folder on path (if you want to import tests modules) @@ -71,3 +78,10 @@ def get_metadata(): html_theme = "sphinx_rtd_theme" html_static_path = ["_static"] +# docs/source/conf.py + +# Tells Sphinx to be strict, but ignore these specific ambiguous targets +nitpicky = True +nitpick_ignore = [ + ("py:class", "MergeMethod"), +] diff --git a/docs/source/examples.rst b/docs/source/examples.rst index 8b2c8eb..d5b5245 100644 --- a/docs/source/examples.rst +++ b/docs/source/examples.rst @@ -3,10 +3,40 @@ Examples Examples can be found in the `examples` directory of this repository. -List of available examples: +List of available Examples +======== -1) `sentinel-2_2025-may-june_first-pixel.mapchete` -2) *placeholder* +Mapchete-EO Drivers +------------------- + +You can execute mapchete-eo drivers as any other mapchete processes. + + +Sentinel-2 First Pixel +----------------------- + +This example uses Sentinel-2 data and picks the first available cloud-free pixel from a time range. + +* `Config `_ +* `Process `_ + + +Sentinel-2 NDVI +--------------- + +Calculate the Normalized Difference Vegetation Index (NDVI) from Sentinel-2 data. + +* `Config `_ +* `Process `_ + + +Sentinel-2 Temporal Mean +------------------------ + +Create a temporal mean composite of cloud-free pixels over a given time range. + +* `Config `_ +* `Process `_ Usage ----- diff --git a/docs/source/generated/mapchete_eo.array.buffer.rst b/docs/source/generated/mapchete_eo.array.buffer.rst new file mode 100644 index 0000000..da104aa --- /dev/null +++ b/docs/source/generated/mapchete_eo.array.buffer.rst @@ -0,0 +1,12 @@ +mapchete\_eo.array.buffer +========================= + +.. automodule:: mapchete_eo.array.buffer + + + .. rubric:: Functions + + .. autosummary:: + + buffer_array + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.array.color.rst b/docs/source/generated/mapchete_eo.array.color.rst new file mode 100644 index 0000000..d6f54a8 --- /dev/null +++ b/docs/source/generated/mapchete_eo.array.color.rst @@ -0,0 +1,14 @@ +mapchete\_eo.array.color +======================== + +.. automodule:: mapchete_eo.array.color + + + .. rubric:: Functions + + .. autosummary:: + + color_array + hex_to_rgb + outlier_pixels + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.array.convert.rst b/docs/source/generated/mapchete_eo.array.convert.rst new file mode 100644 index 0000000..b54efa6 --- /dev/null +++ b/docs/source/generated/mapchete_eo.array.convert.rst @@ -0,0 +1,15 @@ +mapchete\_eo.array.convert +========================== + +.. automodule:: mapchete_eo.array.convert + + + .. rubric:: Functions + + .. autosummary:: + + to_bands_mask + to_dataarray + to_dataset + to_masked_array + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.array.rst b/docs/source/generated/mapchete_eo.array.rst new file mode 100644 index 0000000..712e939 --- /dev/null +++ b/docs/source/generated/mapchete_eo.array.rst @@ -0,0 +1,37 @@ +mapchete\_eo.array package +========================== + +Submodules +---------- + +mapchete\_eo.array.buffer module +-------------------------------- + +.. automodule:: mapchete_eo.array.buffer + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.array.color module +------------------------------- + +.. automodule:: mapchete_eo.array.color + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.array.convert module +--------------------------------- + +.. automodule:: mapchete_eo.array.convert + :members: + :show-inheritance: + :undoc-members: + +Module contents +--------------- + +.. automodule:: mapchete_eo.array + :members: + :show-inheritance: + :undoc-members: diff --git a/docs/source/generated/mapchete_eo.base.rst b/docs/source/generated/mapchete_eo.base.rst new file mode 100644 index 0000000..2083952 --- /dev/null +++ b/docs/source/generated/mapchete_eo.base.rst @@ -0,0 +1,14 @@ +mapchete\_eo.base +================= + +.. automodule:: mapchete_eo.base + + + .. rubric:: Classes + + .. autosummary:: + + BaseDriverConfig + EODataCube + InputData + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.cli.rst b/docs/source/generated/mapchete_eo.cli.rst new file mode 100644 index 0000000..0f11ad8 --- /dev/null +++ b/docs/source/generated/mapchete_eo.cli.rst @@ -0,0 +1,101 @@ +mapchete\_eo.cli package +======================== + +Submodules +---------- + +mapchete\_eo.cli.bounds module +------------------------------ + +.. automodule:: mapchete_eo.cli.bounds + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.cli.options\_arguments module +------------------------------------------ + +.. automodule:: mapchete_eo.cli.options_arguments + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.cli.s2\_brdf module +-------------------------------- + +.. automodule:: mapchete_eo.cli.s2_brdf + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.cli.s2\_cat\_results module +---------------------------------------- + +.. automodule:: mapchete_eo.cli.s2_cat_results + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.cli.s2\_find\_broken\_products module +-------------------------------------------------- + +.. automodule:: mapchete_eo.cli.s2_find_broken_products + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.cli.s2\_jp2\_static\_catalog module +------------------------------------------------ + +.. automodule:: mapchete_eo.cli.s2_jp2_static_catalog + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.cli.s2\_mask module +-------------------------------- + +.. automodule:: mapchete_eo.cli.s2_mask + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.cli.s2\_mgrs module +-------------------------------- + +.. automodule:: mapchete_eo.cli.s2_mgrs + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.cli.s2\_rgb module +------------------------------- + +.. automodule:: mapchete_eo.cli.s2_rgb + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.cli.s2\_verify module +---------------------------------- + +.. automodule:: mapchete_eo.cli.s2_verify + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.cli.static\_catalog module +--------------------------------------- + +.. automodule:: mapchete_eo.cli.static_catalog + :members: + :show-inheritance: + :undoc-members: + +Module contents +--------------- + +.. automodule:: mapchete_eo.cli + :members: + :show-inheritance: + :undoc-members: diff --git a/docs/source/generated/mapchete_eo.image_operations.blend_functions.rst b/docs/source/generated/mapchete_eo.image_operations.blend_functions.rst new file mode 100644 index 0000000..2b1ad91 --- /dev/null +++ b/docs/source/generated/mapchete_eo.image_operations.blend_functions.rst @@ -0,0 +1,26 @@ +mapchete\_eo.image\_operations.blend\_functions +=============================================== + +.. automodule:: mapchete_eo.image_operations.blend_functions + + + .. rubric:: Functions + + .. autosummary:: + + addition + darken_only + difference + divide + dodge + grain_extract + grain_merge + hard_light + lighten_only + multiply + normal + overlay + screen + soft_light + subtract + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.image_operations.color_correction.rst b/docs/source/generated/mapchete_eo.image_operations.color_correction.rst new file mode 100644 index 0000000..2b55c30 --- /dev/null +++ b/docs/source/generated/mapchete_eo.image_operations.color_correction.rst @@ -0,0 +1,12 @@ +mapchete\_eo.image\_operations.color\_correction +================================================ + +.. automodule:: mapchete_eo.image_operations.color_correction + + + .. rubric:: Functions + + .. autosummary:: + + color_correct + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.image_operations.compositing.rst b/docs/source/generated/mapchete_eo.image_operations.compositing.rst new file mode 100644 index 0000000..9711bf1 --- /dev/null +++ b/docs/source/generated/mapchete_eo.image_operations.compositing.rst @@ -0,0 +1,36 @@ +mapchete\_eo.image\_operations.compositing +========================================== + +.. automodule:: mapchete_eo.image_operations.compositing + + + .. rubric:: Functions + + .. autosummary:: + + addition + composite + darken_only + difference + divide + dodge + fuzzy_alpha_mask + fuzzy_mask + grain_extract + grain_merge + hard_light + lighten_only + multiply + normal + overlay + screen + soft_light + subtract + to_rgba + + .. rubric:: Classes + + .. autosummary:: + + GradientPosition + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.image_operations.filters.rst b/docs/source/generated/mapchete_eo.image_operations.filters.rst new file mode 100644 index 0000000..07a14de --- /dev/null +++ b/docs/source/generated/mapchete_eo.image_operations.filters.rst @@ -0,0 +1,25 @@ +mapchete\_eo.image\_operations.filters +====================================== + +.. automodule:: mapchete_eo.image_operations.filters + + + .. rubric:: Functions + + .. autosummary:: + + blur + contour + detail + edge_enhance + edge_enhance_more + emboss + find_edges + gaussian_blur + median + sharpen + sharpen_16bit + smooth + smooth_more + unsharp_mask + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.image_operations.linear_normalization.rst b/docs/source/generated/mapchete_eo.image_operations.linear_normalization.rst new file mode 100644 index 0000000..661982c --- /dev/null +++ b/docs/source/generated/mapchete_eo.image_operations.linear_normalization.rst @@ -0,0 +1,6 @@ +mapchete\_eo.image\_operations.linear\_normalization +==================================================== + +.. currentmodule:: mapchete_eo.image_operations + +.. autofunction:: linear_normalization \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.image_operations.rst b/docs/source/generated/mapchete_eo.image_operations.rst new file mode 100644 index 0000000..b804a5a --- /dev/null +++ b/docs/source/generated/mapchete_eo.image_operations.rst @@ -0,0 +1,77 @@ +mapchete\_eo.image\_operations package +====================================== + +Submodules +---------- + +mapchete\_eo.image\_operations.blend\_functions module +------------------------------------------------------ + +.. automodule:: mapchete_eo.image_operations.blend_functions + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.image\_operations.color\_correction module +------------------------------------------------------- + +.. automodule:: mapchete_eo.image_operations.color_correction + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.image\_operations.compositing module +------------------------------------------------- + +.. automodule:: mapchete_eo.image_operations.compositing + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.image\_operations.dtype\_scale module +-------------------------------------------------- + +.. automodule:: mapchete_eo.image_operations.dtype_scale + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.image\_operations.fillnodata module +------------------------------------------------ + +.. automodule:: mapchete_eo.image_operations.fillnodata + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.image\_operations.filters module +--------------------------------------------- + +.. automodule:: mapchete_eo.image_operations.filters + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.image\_operations.linear\_normalization module +----------------------------------------------------------- + +.. automodule:: mapchete_eo.image_operations.linear_normalization + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.image\_operations.sigmoidal module +----------------------------------------------- + +.. automodule:: mapchete_eo.image_operations.sigmoidal + :members: + :show-inheritance: + :undoc-members: + +Module contents +--------------- + +.. automodule:: mapchete_eo.image_operations + :members: + :show-inheritance: + :undoc-members: diff --git a/docs/source/generated/mapchete_eo.io.assets.rst b/docs/source/generated/mapchete_eo.io.assets.rst new file mode 100644 index 0000000..2484d85 --- /dev/null +++ b/docs/source/generated/mapchete_eo.io.assets.rst @@ -0,0 +1,25 @@ +mapchete\_eo.io.assets +====================== + +.. automodule:: mapchete_eo.io.assets + + + .. rubric:: Functions + + .. autosummary:: + + asset_to_np_array + convert_asset + convert_raster + copy_asset + get_assets + get_metadata_assets + read_mask_as_raster + should_be_converted + + .. rubric:: Classes + + .. autosummary:: + + STACRasterBandProperties + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.io.items.rst b/docs/source/generated/mapchete_eo.io.items.rst new file mode 100644 index 0000000..3d9f64a --- /dev/null +++ b/docs/source/generated/mapchete_eo.io.items.rst @@ -0,0 +1,15 @@ +mapchete\_eo.io.items +===================== + +.. automodule:: mapchete_eo.io.items + + + .. rubric:: Functions + + .. autosummary:: + + expand_params + get_item_property + item_fix_footprint + item_to_np_array + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.io.levelled_cubes.rst b/docs/source/generated/mapchete_eo.io.levelled_cubes.rst new file mode 100644 index 0000000..cd53e2d --- /dev/null +++ b/docs/source/generated/mapchete_eo.io.levelled_cubes.rst @@ -0,0 +1,13 @@ +mapchete\_eo.io.levelled\_cubes +=============================== + +.. automodule:: mapchete_eo.io.levelled_cubes + + + .. rubric:: Functions + + .. autosummary:: + + read_levelled_cube_to_np_array + read_levelled_cube_to_xarray + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.io.products.rst b/docs/source/generated/mapchete_eo.io.products.rst new file mode 100644 index 0000000..54048bf --- /dev/null +++ b/docs/source/generated/mapchete_eo.io.products.rst @@ -0,0 +1,22 @@ +mapchete\_eo.io.products +======================== + +.. automodule:: mapchete_eo.io.products + + + .. rubric:: Functions + + .. autosummary:: + + generate_slice_dataarrays + merge_products + products_to_np_array + products_to_slices + products_to_xarray + + .. rubric:: Classes + + .. autosummary:: + + Slice + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.io.rst b/docs/source/generated/mapchete_eo.io.rst new file mode 100644 index 0000000..feab166 --- /dev/null +++ b/docs/source/generated/mapchete_eo.io.rst @@ -0,0 +1,61 @@ +mapchete\_eo.io package +======================= + +Submodules +---------- + +mapchete\_eo.io.assets module +----------------------------- + +.. automodule:: mapchete_eo.io.assets + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.io.items module +---------------------------- + +.. automodule:: mapchete_eo.io.items + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.io.levelled\_cubes module +-------------------------------------- + +.. automodule:: mapchete_eo.io.levelled_cubes + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.io.path module +--------------------------- + +.. automodule:: mapchete_eo.io.path + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.io.products module +------------------------------- + +.. automodule:: mapchete_eo.io.products + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.io.profiles module +------------------------------- + +.. automodule:: mapchete_eo.io.profiles + :members: + :show-inheritance: + :undoc-members: + +Module contents +--------------- + +.. automodule:: mapchete_eo.io + :members: + :show-inheritance: + :undoc-members: diff --git a/docs/source/generated/mapchete_eo.platforms.sentinel2.driver.rst b/docs/source/generated/mapchete_eo.platforms.sentinel2.driver.rst new file mode 100644 index 0000000..96bb56d --- /dev/null +++ b/docs/source/generated/mapchete_eo.platforms.sentinel2.driver.rst @@ -0,0 +1,13 @@ +mapchete\_eo.platforms.sentinel2.driver +======================================= + +.. automodule:: mapchete_eo.platforms.sentinel2.driver + + + .. rubric:: Classes + + .. autosummary:: + + InputData + Sentinel2Cube + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.platforms.sentinel2.masks.rst b/docs/source/generated/mapchete_eo.platforms.sentinel2.masks.rst new file mode 100644 index 0000000..297e2d6 --- /dev/null +++ b/docs/source/generated/mapchete_eo.platforms.sentinel2.masks.rst @@ -0,0 +1,17 @@ +mapchete\_eo.platforms.sentinel2.masks +====================================== + +.. automodule:: mapchete_eo.platforms.sentinel2.masks + + + .. rubric:: Functions + + .. autosummary:: + + generate_masks + generate_slice_masks_dataarrays + masks_to_xarray + merge_products_masks + product_masks_to_slices + read_masks + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.platforms.sentinel2.preprocessing_tasks.rst b/docs/source/generated/mapchete_eo.platforms.sentinel2.preprocessing_tasks.rst new file mode 100644 index 0000000..89fc677 --- /dev/null +++ b/docs/source/generated/mapchete_eo.platforms.sentinel2.preprocessing_tasks.rst @@ -0,0 +1,12 @@ +mapchete\_eo.platforms.sentinel2.preprocessing\_tasks +===================================================== + +.. automodule:: mapchete_eo.platforms.sentinel2.preprocessing_tasks + + + .. rubric:: Functions + + .. autosummary:: + + parse_s2_product + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.platforms.sentinel2.product.rst b/docs/source/generated/mapchete_eo.platforms.sentinel2.product.rst new file mode 100644 index 0000000..a29d0ee --- /dev/null +++ b/docs/source/generated/mapchete_eo.platforms.sentinel2.product.rst @@ -0,0 +1,19 @@ +mapchete\_eo.platforms.sentinel2.product +======================================== + +.. automodule:: mapchete_eo.platforms.sentinel2.product + + + .. rubric:: Functions + + .. autosummary:: + + asset_name_to_l2a_band + + .. rubric:: Classes + + .. autosummary:: + + Cache + S2Product + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.platforms.sentinel2.source.rst b/docs/source/generated/mapchete_eo.platforms.sentinel2.source.rst new file mode 100644 index 0000000..4bc28ed --- /dev/null +++ b/docs/source/generated/mapchete_eo.platforms.sentinel2.source.rst @@ -0,0 +1,18 @@ +mapchete\_eo.platforms.sentinel2.source +======================================= + +.. automodule:: mapchete_eo.platforms.sentinel2.source + + + .. rubric:: Functions + + .. autosummary:: + + known_collection_to_url + + .. rubric:: Classes + + .. autosummary:: + + Sentinel2Source + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.processes.dtype_scale.rst b/docs/source/generated/mapchete_eo.processes.dtype_scale.rst new file mode 100644 index 0000000..ae8a26a --- /dev/null +++ b/docs/source/generated/mapchete_eo.processes.dtype_scale.rst @@ -0,0 +1,12 @@ +mapchete\_eo.processes.dtype\_scale +=================================== + +.. automodule:: mapchete_eo.processes.dtype_scale + + + .. rubric:: Functions + + .. autosummary:: + + execute + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.processes.eo_to_xarray.rst b/docs/source/generated/mapchete_eo.processes.eo_to_xarray.rst new file mode 100644 index 0000000..bcb1522 --- /dev/null +++ b/docs/source/generated/mapchete_eo.processes.eo_to_xarray.rst @@ -0,0 +1,12 @@ +mapchete\_eo.processes.eo\_to\_xarray +===================================== + +.. automodule:: mapchete_eo.processes.eo_to_xarray + + + .. rubric:: Functions + + .. autosummary:: + + execute + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.processes.merge_rasters.rst b/docs/source/generated/mapchete_eo.processes.merge_rasters.rst new file mode 100644 index 0000000..f06035e --- /dev/null +++ b/docs/source/generated/mapchete_eo.processes.merge_rasters.rst @@ -0,0 +1,21 @@ +mapchete\_eo.processes.merge\_rasters +===================================== + +.. automodule:: mapchete_eo.processes.merge_rasters + + + .. rubric:: Functions + + .. autosummary:: + + execute + fillnodata_merge + gradient_merge + merge_rasters + + .. rubric:: Classes + + .. autosummary:: + + MergeMethod + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.processes.rst b/docs/source/generated/mapchete_eo.processes.rst new file mode 100644 index 0000000..3cb6ecb --- /dev/null +++ b/docs/source/generated/mapchete_eo.processes.rst @@ -0,0 +1,45 @@ +mapchete\_eo.processes package +============================== + +Submodules +---------- + +mapchete\_eo.processes.config module +------------------------------------ + +.. automodule:: mapchete_eo.processes.config + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.processes.dtype\_scale module +------------------------------------------ + +.. automodule:: mapchete_eo.processes.dtype_scale + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.processes.eo\_to\_xarray module +-------------------------------------------- + +.. automodule:: mapchete_eo.processes.eo_to_xarray + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.processes.merge\_rasters module +-------------------------------------------- + +.. automodule:: mapchete_eo.processes.merge_rasters + :members: + :show-inheritance: + :undoc-members: + +Module contents +--------------- + +.. automodule:: mapchete_eo.processes + :members: + :show-inheritance: + :undoc-members: diff --git a/docs/source/generated/mapchete_eo.product.rst b/docs/source/generated/mapchete_eo.product.rst new file mode 100644 index 0000000..2b02e72 --- /dev/null +++ b/docs/source/generated/mapchete_eo.product.rst @@ -0,0 +1,21 @@ +mapchete\_eo.product +==================== + +.. automodule:: mapchete_eo.product + + + .. rubric:: Functions + + .. autosummary:: + + add_to_blacklist + blacklist_products + eo_bands_to_band_locations + find_eo_band + + .. rubric:: Classes + + .. autosummary:: + + EOProduct + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.rst b/docs/source/generated/mapchete_eo.rst new file mode 100644 index 0000000..df6a704 --- /dev/null +++ b/docs/source/generated/mapchete_eo.rst @@ -0,0 +1,106 @@ +mapchete\_eo package +==================== + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + mapchete_eo.array + mapchete_eo.cli + mapchete_eo.image_operations + mapchete_eo.io + mapchete_eo.processes + mapchete_eo.search + +Submodules +---------- + +mapchete\_eo.base module +------------------------ + +.. automodule:: mapchete_eo.base + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.eostac module +-------------------------- + +.. automodule:: mapchete_eo.eostac + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.exceptions module +------------------------------ + +.. automodule:: mapchete_eo.exceptions + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.product module +--------------------------- + +.. automodule:: mapchete_eo.product + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.protocols module +----------------------------- + +.. automodule:: mapchete_eo.protocols + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.settings module +---------------------------- + +.. automodule:: mapchete_eo.settings + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.sort module +------------------------ + +.. automodule:: mapchete_eo.sort + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.source module +-------------------------- + +.. automodule:: mapchete_eo.source + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.time module +------------------------ + +.. automodule:: mapchete_eo.time + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.types module +------------------------- + +.. automodule:: mapchete_eo.types + :members: + :show-inheritance: + :undoc-members: + +Module contents +--------------- + +.. automodule:: mapchete_eo + :members: + :show-inheritance: + :undoc-members: diff --git a/docs/source/generated/mapchete_eo.search.base.rst b/docs/source/generated/mapchete_eo.search.base.rst new file mode 100644 index 0000000..5fe4692 --- /dev/null +++ b/docs/source/generated/mapchete_eo.search.base.rst @@ -0,0 +1,20 @@ +mapchete\_eo.search.base +======================== + +.. automodule:: mapchete_eo.search.base + + + .. rubric:: Functions + + .. autosummary:: + + filter_items + + .. rubric:: Classes + + .. autosummary:: + + CollectionSearcher + FSSpecStacIO + StaticCollectionWriterMixin + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.search.rst b/docs/source/generated/mapchete_eo.search.rst new file mode 100644 index 0000000..b61cea0 --- /dev/null +++ b/docs/source/generated/mapchete_eo.search.rst @@ -0,0 +1,61 @@ +mapchete\_eo.search package +=========================== + +Submodules +---------- + +mapchete\_eo.search.base module +------------------------------- + +.. automodule:: mapchete_eo.search.base + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.search.config module +--------------------------------- + +.. automodule:: mapchete_eo.search.config + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.search.s2\_mgrs module +----------------------------------- + +.. automodule:: mapchete_eo.search.s2_mgrs + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.search.stac\_search module +--------------------------------------- + +.. automodule:: mapchete_eo.search.stac_search + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.search.stac\_static module +--------------------------------------- + +.. automodule:: mapchete_eo.search.stac_static + :members: + :show-inheritance: + :undoc-members: + +mapchete\_eo.search.utm\_search module +-------------------------------------- + +.. automodule:: mapchete_eo.search.utm_search + :members: + :show-inheritance: + :undoc-members: + +Module contents +--------------- + +.. automodule:: mapchete_eo.search + :members: + :show-inheritance: + :undoc-members: diff --git a/docs/source/generated/mapchete_eo.search.stac_search.rst b/docs/source/generated/mapchete_eo.search.stac_search.rst new file mode 100644 index 0000000..f6f6e96 --- /dev/null +++ b/docs/source/generated/mapchete_eo.search.stac_search.rst @@ -0,0 +1,13 @@ +mapchete\_eo.search.stac\_search +================================ + +.. automodule:: mapchete_eo.search.stac_search + + + .. rubric:: Classes + + .. autosummary:: + + STACSearchCollection + SpatialSearchChunks + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.search.stac_static.rst b/docs/source/generated/mapchete_eo.search.stac_static.rst new file mode 100644 index 0000000..f1a8245 --- /dev/null +++ b/docs/source/generated/mapchete_eo.search.stac_static.rst @@ -0,0 +1,12 @@ +mapchete\_eo.search.stac\_static +================================ + +.. automodule:: mapchete_eo.search.stac_static + + + .. rubric:: Classes + + .. autosummary:: + + STACStaticCollection + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.search.utm_search.rst b/docs/source/generated/mapchete_eo.search.utm_search.rst new file mode 100644 index 0000000..10854b3 --- /dev/null +++ b/docs/source/generated/mapchete_eo.search.utm_search.rst @@ -0,0 +1,20 @@ +mapchete\_eo.search.utm\_search +=============================== + +.. automodule:: mapchete_eo.search.utm_search + + + .. rubric:: Functions + + .. autosummary:: + + find_items + items_from_directories + items_from_static_index + + .. rubric:: Classes + + .. autosummary:: + + UTMSearchCatalog + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.sort.rst b/docs/source/generated/mapchete_eo.sort.rst new file mode 100644 index 0000000..dffaa43 --- /dev/null +++ b/docs/source/generated/mapchete_eo.sort.rst @@ -0,0 +1,21 @@ +mapchete\_eo.sort +================= + +.. automodule:: mapchete_eo.sort + + + .. rubric:: Functions + + .. autosummary:: + + sort_objects_by_cloud_cover + sort_objects_by_target_date + + .. rubric:: Classes + + .. autosummary:: + + CloudCoverSort + SortMethodConfig + TargetDateSort + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.source.rst b/docs/source/generated/mapchete_eo.source.rst new file mode 100644 index 0000000..4f7c021 --- /dev/null +++ b/docs/source/generated/mapchete_eo.source.rst @@ -0,0 +1,12 @@ +mapchete\_eo.source +=================== + +.. automodule:: mapchete_eo.source + + + .. rubric:: Classes + + .. autosummary:: + + Source + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.time.rst b/docs/source/generated/mapchete_eo.time.rst new file mode 100644 index 0000000..28886d4 --- /dev/null +++ b/docs/source/generated/mapchete_eo.time.rst @@ -0,0 +1,15 @@ +mapchete\_eo.time +================= + +.. automodule:: mapchete_eo.time + + + .. rubric:: Functions + + .. autosummary:: + + day_range + time_ranges_intersect + timedelta + to_datetime + \ No newline at end of file diff --git a/docs/source/generated/mapchete_eo.types.rst b/docs/source/generated/mapchete_eo.types.rst new file mode 100644 index 0000000..10c7be6 --- /dev/null +++ b/docs/source/generated/mapchete_eo.types.rst @@ -0,0 +1,15 @@ +mapchete\_eo.types +================== + +.. automodule:: mapchete_eo.types + + + .. rubric:: Classes + + .. autosummary:: + + BandLocation + GeodataType + MergeMethod + TimeRange + \ No newline at end of file diff --git a/docs/source/generated/modules.rst b/docs/source/generated/modules.rst new file mode 100644 index 0000000..76b2955 --- /dev/null +++ b/docs/source/generated/modules.rst @@ -0,0 +1,7 @@ +mapchete_eo +=========== + +.. toctree:: + :maxdepth: 4 + + mapchete_eo diff --git a/docs/source/index.rst b/docs/source/index.rst index 3343e9e..2eb3ff3 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -12,20 +12,20 @@ cloud masking, temporal compositing, BRDF, etc. With STAC API and catalogs handling for data sources. -CLI ---- +Generic Info +------------ .. toctree:: :maxdepth: 2 - :caption: Generic Info + usage cli + api Example Usage ------------- .. toctree:: :maxdepth: 2 - :caption: Basic Examples examples diff --git a/docs/source/usage.rst b/docs/source/usage.rst new file mode 100644 index 0000000..28009f7 --- /dev/null +++ b/docs/source/usage.rst @@ -0,0 +1,60 @@ +Usage Guide +=========== + +Introduction +------------ + +**mapchete-eo** extends Mapchete with Earth Observation specific capabilities. This guide covers common patterns for data discovery and processing. + +Data Discovery (Search) +----------------------- + +Search for data using `Source` objects. + +.. code-block:: python + + from mapchete_eo.source import Source + + source = Source( + collection="sentinel-2-l2a", + catalog_type="stac", + # ... other config + ) + + # Search for items + items = list(source.search(area=roi, time="2023-01-01/2023-01-31")) + +Reading Data +------------ + +Products are used to read data into `xarray` or `numpy` cubes. + +.. code-block:: python + + # Inside a mapchete process + def execute(mp, **kwargs): + with mp.open("sentinel-2") as s2: + # Read as xarray + ds = s2.read(eo_bands=["red", "green", "blue"]) + + # Read as MaskedArray + arr = s2.read_np_array(eo_bands=["nir"]) + +Compositing and Blending +------------------------ + +You can use various blending methods to combine overlapping products. + +.. code-block:: python + + from mapchete_eo.image_operations.compositing import composite + + # Composite foreground and background using 'multiply' + blended = composite("multiply", bg_arr, fg_arr) + +Example Workflow +---------------- + +1. Define your tileset and process area in a `.mapchete` file. +2. Use `mapchete-eo` drivers (e.g., `sentinel2`) to declare inputs. +3. Access and process Earth Observation data with high-level API functions. diff --git a/examples/ndvi.mapchete b/examples/ndvi.mapchete new file mode 100644 index 0000000..e914031 --- /dev/null +++ b/examples/ndvi.mapchete @@ -0,0 +1,21 @@ +process: ndvi_process.py +input: + element84_sentinel2: + format: Sentinel-2 + level: L2A + max_cloud_percent: 5 + time: + start: 2025-06-01 + end: 2025-06-30 +output: + format: GTiff + bands: 1 + path: sentinel-2_ndvi + dtype: float32 +pyramid: + grid: geodetic + metatiling: 8 +zoom_levels: + min: 8 + max: 13 +bounds: [16.20, 48.00, 16.75, 48.5] diff --git a/examples/ndvi_process.py b/examples/ndvi_process.py new file mode 100644 index 0000000..1ba8ccb --- /dev/null +++ b/examples/ndvi_process.py @@ -0,0 +1,41 @@ +import logging +import numpy as np +import numpy.ma as ma +from rasterio.enums import Resampling + +from mapchete_eo.platforms.sentinel2.driver import Sentinel2Cube + + +logger = logging.getLogger(__name__) + + +def execute( + element84_sentinel2: Sentinel2Cube, + resampling: str = "bilinear", + nodata: float = 0.0, +) -> ma.MaskedArray: + """ + Calculate NDVI (Normalized Difference Vegetation Index). + """ + logger.debug("Reading Sentinel-2 NIR and Red bands.") + + # Read the first available cloud-free pixel for NIR and Red + # (Simplified for example purposes) + data = element84_sentinel2.read_np_array( + assets=["red", "nir"], + resampling=Resampling[resampling], + nodatavals=nodata, + ) + + red = data[0].astype(float) + nir = data[1].astype(float) + + # Calculate NDVI: (NIR - Red) / (NIR + Red) + with np.errstate(divide="ignore", invalid="ignore"): + ndvi = (nir - red) / (nir + red) + ndvi[np.isnan(ndvi)] = nodata + + # NDVI is typically in range [-1, 1]. + # For visualization, we could scale it to 0-255 or just return the float array. + # Here we return it as a single-band float32 array. + return ma.masked_array(data=ndvi.astype(np.float32), mask=data.mask[0]) diff --git a/examples/temporal_mean.mapchete b/examples/temporal_mean.mapchete new file mode 100644 index 0000000..af44d77 --- /dev/null +++ b/examples/temporal_mean.mapchete @@ -0,0 +1,23 @@ +process: temporal_mean_process.py +input: + element84_sentinel2: + format: Sentinel-2 + level: L2A + max_cloud_percent: 20 + time: + start: 2025-06-01 + end: 2025-08-31 +output: + format: GTiff + bands: 3 + path: sentinel-2_temporal_mean + dtype: uint16 +pyramid: + grid: geodetic + metatiling: 8 +zoom_levels: + min: 8 + max: 13 +bounds: [16.20, 48.00, 16.75, 48.5] +process_parameters: + assets: [red, green, blue] diff --git a/examples/temporal_mean_process.py b/examples/temporal_mean_process.py new file mode 100644 index 0000000..1c1933a --- /dev/null +++ b/examples/temporal_mean_process.py @@ -0,0 +1,46 @@ +import logging +import numpy as np +import numpy.ma as ma +from rasterio.enums import Resampling +from typing import List + +from mapchete_eo.platforms.sentinel2.driver import Sentinel2Cube + + +logger = logging.getLogger(__name__) + + +def execute( + element84_sentinel2: Sentinel2Cube, + assets: List[str], + resampling: str = "bilinear", + nodata: float = 0.0, +) -> ma.MaskedArray: + """ + Create a temporal mean composite of cloud-free pixels. + """ + logger.debug("Reading Sentinel-2 time series.") + + # Read all available products into an xarray dataset + ds = element84_sentinel2.read( + assets=assets, + resampling=Resampling[resampling], + nodatavals=nodata, + ) + + # Calculate mean over the time dimension + # (Assuming xarray handle mask/nodata correctly via _FillValue) + mean_composite = ds.mean(dim="time", skipna=True) + + # Convert back to numpy masked array + # This is a simplified conversion for the example + out_data = [] + out_mask = [] + for asset in assets: + arr = mean_composite[asset].values + out_data.append(arr) + out_mask.append(np.isnan(arr)) + + return ma.masked_array( + data=np.stack(out_data).astype(np.uint16), mask=np.stack(out_mask) + ) diff --git a/mapchete_eo/base.py b/mapchete_eo/base.py index 7f61188..eb9bdec 100644 --- a/mapchete_eo/base.py +++ b/mapchete_eo/base.py @@ -44,6 +44,10 @@ class BaseDriverConfig(BaseModel): + """ + Configuration for mapchete-eo drivers. + """ + format: str source: Sequence[Source] time: Optional[Union[TimeRange, List[TimeRange]]] = None @@ -114,6 +118,9 @@ def __init__( @cached_property def products(self) -> IndexedFeatures[EOProductProtocol]: + """ + Indexed products. + """ # during task graph processing, the products have to be fetched as preprocessing task results if self._products is None: # pragma: no cover return IndexedFeatures( @@ -158,11 +165,7 @@ def read( **kwargs, ) -> xr.Dataset: """ - Read reprojected & resampled input data. - - Returns - ------- - data : xarray.Dataset + Read input data into an xarray.Dataset. """ return products_to_xarray( products=self.filter_products( @@ -201,6 +204,9 @@ def read_np_array( raise_empty: bool = True, **kwargs, ) -> ma.MaskedArray: + """ + Read input data as a MaskedArray. + """ return products_to_np_array( products=self.filter_products( start_time=start_time, @@ -286,6 +292,27 @@ def read_levelled_np_array( raise_empty: bool = True, **kwargs, ) -> ma.MaskedArray: + """ + Read levelled data (cubes with depth) as a MaskedArray. + + Args: + target_height: Target stack height. + assets: List of asset names. + eo_bands: List of EO bands. + start_time: Start time. + end_time: End time. + timestamps: List of timestamps. + time_pattern: Time pattern. + resampling: Resampling method. + nodatavals: Nodata values. + merge_products_by: Property to merge by. + merge_method: Merge method. + sort: Sorting configuration. + raise_empty: Raise error if no data found. + + Returns: + ma.MaskedArray: Output data array. + """ return read_levelled_cube_to_np_array( products=self.filter_products( start_time=start_time, @@ -317,6 +344,19 @@ def read_masks( nodatavals: NodataVals = None, **kwargs, ): + """ + Read product masks. + + Args: + start_time: Start time. + end_time: End time. + timestamps: List of timestamps. + time_pattern: Time pattern. + nodatavals: Nodata values. + + Returns: + ma.MaskedArray: Mask data. + """ from mapchete_eo.platforms.sentinel2.masks import read_masks return read_masks( @@ -423,6 +463,10 @@ def get_read_mask(self) -> np.ndarray: class InputData(base.InputData): + """ + Main driver class used by mapchete to handle input data discovery and indexing. + """ + default_preprocessing_task: Callable = staticmethod(EOProduct.from_stac_item) driver_config_model: Type[BaseDriverConfig] = BaseDriverConfig params: BaseDriverConfig diff --git a/mapchete_eo/image_operations/compositing.py b/mapchete_eo/image_operations/compositing.py index 9cec1a4..e70b713 100644 --- a/mapchete_eo/image_operations/compositing.py +++ b/mapchete_eo/image_operations/compositing.py @@ -153,6 +153,18 @@ def overlay(bg: np.ndarray, fg: np.ndarray, opacity: float = 1) -> ma.MaskedArra def composite( method: str, bg: np.ndarray, fg: np.ndarray, opacity: float = 1 ) -> ma.MaskedArray: + """ + Composite two image arrays using a named blending method. + + Args: + method: Blending method name (e.g., 'multiply', 'screen'). + bg: Background image array (channels-first). + fg: Foreground image array (channels-first). + opacity: Opacity of the foreground layer (0-1). + + Returns: + ma.MaskedArray: Blended RGBA result. + """ return METHODS[method](bg, fg, opacity) diff --git a/mapchete_eo/platforms/sentinel2/driver.py b/mapchete_eo/platforms/sentinel2/driver.py index 8d84c34..6a576dc 100644 --- a/mapchete_eo/platforms/sentinel2/driver.py +++ b/mapchete_eo/platforms/sentinel2/driver.py @@ -17,6 +17,10 @@ class Sentinel2Cube(base.EODataCube): + """ + Sentinel-2 data cube for Mapchete. + """ + # Sentinel-2 driver specific default values: default_read_merge_method: MergeMethod = MergeMethod.average default_read_merge_products_by: Optional[str] = "s2:datastrip_id" @@ -29,7 +33,7 @@ class Sentinel2Cube(base.EODataCube): class InputData(base.InputData): """ - Main driver class used by mapchete. + Sentinel-2 driver for Mapchete. """ # Sentinel-2 driver specific parameters: diff --git a/mapchete_eo/platforms/sentinel2/masks.py b/mapchete_eo/platforms/sentinel2/masks.py index 6aee5d3..0357fb0 100644 --- a/mapchete_eo/platforms/sentinel2/masks.py +++ b/mapchete_eo/platforms/sentinel2/masks.py @@ -61,7 +61,9 @@ def masks_to_xarray( raise_empty: bool = True, product_read_kwargs: dict = {}, ) -> xr.Dataset: - """Read grid window of EOProducts and merge into a 4D xarray.""" + """ + Read masks of products and merge into an xarray.Dataset. + """ data_vars = [ s for s in generate_slice_masks_dataarrays( @@ -307,7 +309,9 @@ def product_masks_to_slices( group_by_property: Optional[str] = None, sort: Optional[SortMethodConfig] = None, ) -> List[Slice]: - """Group products per given property into Slice objects and optionally sort slices.""" + """ + Group products by a property into Slices and optionally sort. + """ if group_by_property: grouped = defaultdict(list) for product in products: diff --git a/mapchete_eo/platforms/sentinel2/preprocessing_tasks.py b/mapchete_eo/platforms/sentinel2/preprocessing_tasks.py index 6ade002..15735f8 100644 --- a/mapchete_eo/platforms/sentinel2/preprocessing_tasks.py +++ b/mapchete_eo/platforms/sentinel2/preprocessing_tasks.py @@ -19,7 +19,10 @@ def parse_s2_product( cache_config: Optional[CacheConfig] = None, cache_all: bool = False, ) -> Union[S2Product, CorruptedProductMetadata]: - # use mapper from source if applickable + """ + Parse a Sentinel-2 STAC Item into an S2Product. + """ + # use mapper from source if applicable source: Union[Sentinel2Source, None] = item.properties.pop( "mapchete_eo:source", None ) diff --git a/mapchete_eo/platforms/sentinel2/product.py b/mapchete_eo/platforms/sentinel2/product.py index d85a422..88ea3a8 100644 --- a/mapchete_eo/platforms/sentinel2/product.py +++ b/mapchete_eo/platforms/sentinel2/product.py @@ -143,6 +143,10 @@ def get_brdf_grid(self, band: L2ABand): class S2Product(EOProduct, EOProductProtocol): + """ + Sentinel-2 specific EOProduct implementation. + """ + _item_dict: Optional[dict] = None cache: Optional[Cache] = None _scl_cache: Dict[GridProtocol, np.ndarray] @@ -245,6 +249,9 @@ def read_np_array( read_mask: Optional[np.ndarray] = None, **kwargs, ) -> ma.MaskedArray: + """ + Read Sentinel-2 assets into a MaskedArray with masks and BRDF. + """ assets = assets or [] eo_bands = eo_bands or [] apply_offset = apply_offset and not self.metadata.boa_offset_applied @@ -451,7 +458,9 @@ def read_scl( grid: Union[GridProtocol, Resolution] = Resolution["20m"], cached_read: bool = False, ) -> ReferencedRaster: - """Return SCL mask.""" + """ + Read Scene Classification Layer mask. + """ grid = ( self.metadata.grid(grid) if isinstance(grid, Resolution) @@ -519,7 +528,9 @@ def get_mask( mask_config: MaskConfig = MaskConfig(), target_mask: Optional[np.ndarray] = None, ) -> ReferencedRaster: - """Merge masks into one 2D array.""" + """ + Merge all configured masks into one. + """ grid = ( self.metadata.grid(grid) if isinstance(grid, Resolution) diff --git a/mapchete_eo/product.py b/mapchete_eo/product.py index 32392c0..9dce923 100644 --- a/mapchete_eo/product.py +++ b/mapchete_eo/product.py @@ -26,7 +26,9 @@ class EOProduct(EOProductProtocol): - """Wrapper class around a Item which provides read functions.""" + """ + Wrapper class around a STAC Item which provides data reading capabilities. + """ id: str default_dtype: DTypeLike = np.uint16 @@ -70,7 +72,22 @@ def read( raise_empty: bool = True, **kwargs, ) -> xr.Dataset: - """Read bands and assets into xarray.""" + """ + Read bands and assets into an xarray.Dataset. + + Args: + assets: List of asset names. + eo_bands: List of EO band names. + grid: Target grid protocol. + resampling: Resampling algorithm. + nodatavals: Custom nodata values. + x_axis_name: Name of X axis in output. + y_axis_name: Name of Y axis in output. + raise_empty: Raise exception if no data is found. + + Returns: + xr.Dataset: Dataset with assets as data variables. + """ # developer info: all fancy stuff for special platforms like Sentinel-2 # should be implemented in the respective read_np_array() methods which get # called by this method. No need to apply masks etc. here too. @@ -121,6 +138,21 @@ def read_np_array( apply_offset: bool = True, **kwargs, ) -> ma.MaskedArray: + """ + Read assets or EO bands into a MaskedArray. + + Args: + assets: List of asset names. + eo_bands: List of EO band names. + grid: Target grid. + resampling: Resampling method. + nodatavals: Nodata values. + raise_empty: Raise if empty. + apply_offset: Apply offset/scale metadata if present. + + Returns: + ma.MaskedArray: Output array. + """ assets = assets or [] eo_bands = eo_bands or [] bands = assets or eo_bands @@ -182,7 +214,15 @@ def eo_bands_to_band_locations( role: Literal["data", "reflectance", "visual"] = "data", ) -> List[BandLocation]: """ - Find out location (asset and band index) of EO band. + Map EO band names to asset locations. + + Args: + item: STAC Item. + eo_bands: List of common band names. + role: Functional role of the assets. + + Returns: + List[BandLocation]: List of location objects. """ return [find_eo_band(item, eo_band, role=role) for eo_band in eo_bands] diff --git a/mapchete_eo/search/base.py b/mapchete_eo/search/base.py index 782ef99..9d8dbf2 100644 --- a/mapchete_eo/search/base.py +++ b/mapchete_eo/search/base.py @@ -50,7 +50,7 @@ def save_json(dest: MPathLike, json_dict: dict, *args, **kwargs) -> None: class CollectionSearcher(ABC): """ - This class serves as a bridge between an Archive and a catalog implementation. + Bridge between a Source and a catalog implementation. """ config_cls: Type[BaseModel] @@ -129,7 +129,29 @@ def write_static_catalog( stac_io: DefaultStacIO = FSSpecStacIO(), progress_callback: Optional[Callable] = None, ) -> MPath: - """Dump static version of current items.""" + """ + Export a static STAC catalog from the search results. + + Args: + output_path: Destination directory for the static catalog. + bounds: Spatial filter bounds. + area: Spatial filter geometry. + time: Temporal filter range. + search_kwargs: Additional search arguments. + name: Catalog name. + description: Catalog description. + assets: List of assets to download. + assets_dst_resolution: Sub-sampling resolution for assets. + assets_convert_profile: Output profile for assets (e.g. for COG conversion). + copy_metadata: Whether to copy sidecar metadata files. + metadata_parser_classes: Custom parser classes for metadata. + overwrite: Overwrite existing files. + stac_io: Custom STAC IO implementation. + progress_callback: Optional function for progress reporting. + + Returns: + MPath: Path to the generated catalog.json. + """ output_path = MPath.from_inp(output_path) assets = assets or [] # initialize catalog diff --git a/mapchete_eo/search/stac_search.py b/mapchete_eo/search/stac_search.py index 8fd144a..4cec37e 100644 --- a/mapchete_eo/search/stac_search.py +++ b/mapchete_eo/search/stac_search.py @@ -21,6 +21,10 @@ class STACSearchCollection(StaticCollectionWriterMixin, CollectionSearcher): + """ + Search implementation for STAC APIs. + """ + collection: str config_cls = StacSearchConfig @@ -206,6 +210,10 @@ def _search( class SpatialSearchChunks: + """ + Split spatial search areas into smaller chunks for large queries. + """ + bounds: Bounds area: BaseGeometry search_kw: str diff --git a/mapchete_eo/search/stac_static.py b/mapchete_eo/search/stac_static.py index 9e020ea..15b45f3 100644 --- a/mapchete_eo/search/stac_static.py +++ b/mapchete_eo/search/stac_static.py @@ -29,6 +29,10 @@ class STACStaticCollection(StaticCollectionWriterMixin, CollectionSearcher): + """ + Search implementation for static STAC collections. + """ + config_cls = StacStaticConfig @cached_property diff --git a/mapchete_eo/search/utm_search.py b/mapchete_eo/search/utm_search.py index 46e1653..ca271a2 100644 --- a/mapchete_eo/search/utm_search.py +++ b/mapchete_eo/search/utm_search.py @@ -28,6 +28,10 @@ class UTMSearchCatalog(StaticCollectionWriterMixin, CollectionSearcher): + """ + Search implementation for UTM-grid based catalogs (e.g. Sentinel-2 on AWS). + """ + config_cls = UTMSearchConfig @cached_property diff --git a/mapchete_eo/sort.py b/mapchete_eo/sort.py index 8b5e30a..cba9c7e 100644 --- a/mapchete_eo/sort.py +++ b/mapchete_eo/sort.py @@ -22,9 +22,7 @@ def sort_objects_by_target_date( **kwargs, ) -> List[DateTimeProtocol]: """ - Return sorted list of objects according to their distance to the target_date. - - Default for target date is the middle between the objects start date and end date. + Sort objects by their distance to a target date. """ if len(objects) == 0: return objects diff --git a/mapchete_eo/source.py b/mapchete_eo/source.py index 9c3c846..1b40d9e 100644 --- a/mapchete_eo/source.py +++ b/mapchete_eo/source.py @@ -17,7 +17,9 @@ class Source(BaseModel): - """All information required to consume EO products.""" + """ + All information required to consume EO products. + """ collection: str catalog_crs: Optional[CRSLike] = mapchete_eo_settings.default_catalog_crs diff --git a/mapchete_eo/time.py b/mapchete_eo/time.py index 8d2b391..152bdb1 100644 --- a/mapchete_eo/time.py +++ b/mapchete_eo/time.py @@ -9,7 +9,9 @@ def to_datetime(t: DateTimeLike, append_time="min") -> datetime.datetime: - """Convert input into datetime object.""" + """ + Convert input into datetime object. + """ if isinstance(t, datetime.datetime): return t elif isinstance(t, datetime.date): @@ -22,7 +24,9 @@ def time_ranges_intersect( t1: Tuple[DateTimeLike, DateTimeLike], t2: Tuple[DateTimeLike, DateTimeLike], ) -> bool: - """Check if two time ranges intersect.""" + """ + Check if two time ranges intersect. + """ t1_start = to_datetime(t1[0], "min").replace(tzinfo=None) t1_end = to_datetime(t1[1], "max").replace(tzinfo=None) t2_start = to_datetime(t2[0], "min").replace(tzinfo=None) @@ -31,7 +35,9 @@ def time_ranges_intersect( def timedelta(date: DateTimeLike, target: DateTimeLike, seconds: bool = True): - """Return difference between two time stamps.""" + """ + Return difference between two time stamps in seconds or days. + """ delta = to_datetime(date) - to_datetime(target) if seconds: return abs(delta.total_seconds()) @@ -43,6 +49,9 @@ def day_range( start_date: Union[datetime.datetime, datetime.date], end_date: Union[datetime.datetime, datetime.date], ) -> List[datetime.date]: + """ + Return a list of dates between start and end. + """ start_date = ( start_date.date() if isinstance(start_date, datetime.datetime) else start_date ) diff --git a/mapchete_eo/types.py b/mapchete_eo/types.py index 3bd7325..4a64026 100644 --- a/mapchete_eo/types.py +++ b/mapchete_eo/types.py @@ -10,8 +10,9 @@ class GeodataType(str, Enum): - vector = "vector" - raster = "raster" + """ + Type of geodata (vector or raster). + """ class MergeMethod(str, Enum): @@ -42,12 +43,14 @@ class BandLocation: roles: List[str] = field(default_factory=list) eo_band_name: Optional[str] = None - @staticmethod def from_asset( asset: Asset, name: str, band_index: PositiveInt, ) -> BandLocation: + """ + Extract band location info from STAC Asset. + """ try: bands_info = asset.extra_fields.get( "eo:bands", asset.extra_fields.get("bands", [])