diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 71646d5a..9ca8bde5 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -60,4 +60,16 @@ jobs: CDSE_S3_ACCESS_KEY: ${{ secrets.CDSE_S3_ACCESS_KEY }} CDSE_S3_ACCESS_SECRET: ${{ secrets.CDSE_S3_ACCESS_SECRET }} CURL_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt - run: pytest -v --cov mapchete-eo --cov-report xml:coverage.xml --cov-report=term-missing:skip-covered + run: pytest -v --cov mapchete_eo --cov-report xml:coverage.xml --cov-report=term-missing:skip-covered --junitxml=pytest.xml + + # Upload the report to Codecov + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v5 + with: + token: ${{ secrets.CODECOV_TOKEN }} + slug: mapchete/mapchete-eo + + # this will let the workflow fail if coverage is below 100% + - name: Pytest coverage + run: coverage report --skip-covered --show-missing + # --fail-under 100 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 9341c92e..25140ce4 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ dist/ *.gfs .vscode/ __pycache__ +examples/sentinel-2*/ \ No newline at end of file diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 3c5a6054..ec1e473f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -3,6 +3,12 @@ Changelog ######### +2025.8.0 - 2025-08-07 +---------------------- + +* add rudimentary example +* add init docs and readthedocs.yaml for docs build and publish + 2025.7.0 - 2025-07-30 ---------------------- diff --git a/README.md b/README.md deleted file mode 100644 index e4091919..00000000 --- a/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# Mapchete EO driver - diff --git a/README.rst b/README.rst new file mode 100644 index 00000000..d1430466 --- /dev/null +++ b/README.rst @@ -0,0 +1,46 @@ +.. image:: logo/mapchete_eo.svg + +Earth Observation–specific driver extensions for `Mapchete `_. + +.. image:: https://img.shields.io/pypi/v/mapchete-eo.svg + :target: https://pypi.org/project/mapchete-eo/ + +.. image:: https://img.shields.io/pypi/l/mapchete-eo.svg + :target: https://github.com/mapchete/mapchete-eo/blob/main/LICENSE + +.. image:: https://img.shields.io/github/actions/workflow/status/mapchete/mapchete-eo/python-package.yml?label=tests + :target: https://github.com/mapchete/mapchete-eo/actions + +.. image:: https://codecov.io/gh/mapchete/mapchete-eo/graph/badge.svg?token=VD1YOF3QA2 + :target: https://codecov.io/gh/mapchete/mapchete-eo + +.. image:: https://img.shields.io/github/repo-size/mapchete/mapchete-eo + :target: https://github.com/mapchete/mapchete-eo + +This package provides custom input and output drivers tailored for common EO data formats and workflows, enabling seamless integration of satellite data sources into the Mapchete tile-based geoprocessing framework. + +What is this? +------------- + +**mapchete-eo** extends Mapchete by adding support for: + +- Custom **input drivers** to read EO datasets, from STAC search or metadata (catalogs, collections, items) +- Metadata extraction and band management for optical satellite products +- Reading data from sources via **STAC assets** + +This package is intended for advanced users or developers who are working with remote sensing workflows using Mapchete. + +Installation +------------ + +You must have ``mapchete`` with ``s3`` installed, so let's grab the ``complete`` dependencies in this case for convenience: + +.. code-block:: bash + + pip install mapchete[complete] + +Then install mapchete-eo: + +.. code-block:: bash + + pip install mapchete-eo diff --git a/doc/Makefile b/doc/Makefile deleted file mode 100644 index ab80500e..00000000 --- a/doc/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -SPHINXPROJ = mapchete_satellite -SOURCEDIR = source -BUILDDIR = build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/doc/source/conf.py b/doc/source/conf.py deleted file mode 100644 index 0448b346..00000000 --- a/doc/source/conf.py +++ /dev/null @@ -1,186 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Configuration file for the Sphinx documentation builder. -# -# This file does only contain a selection of the most common options. For a -# full list see the documentation: -# http://www.sphinx-doc.org/en/master/config - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -# import os -# import sys -# sys.path.insert(0, os.path.abspath('.')) - - -# -- Project information ----------------------------------------------------- - -project = "mapchete_eo" -copyright = "2022, Petr Sevcik, Joachim Ungar" -author = "Petr Sevcik, Joachim Ungar" - -with open("../../mapchete_eo/__init__.py") as f: - for line in f: - if line.find("__version__") >= 0: - version = line.split("=")[1].strip() - version = version.strip('"') - version = version.strip("'") - continue -release = version - - -# -- General configuration --------------------------------------------------- - -# If your documentation needs a minimal Sphinx version, state it here. -# -# needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = ["sphinx.ext.autodoc", "sphinx.ext.doctest", "numpydoc"] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# -# source_suffix = ['.rst', '.md'] -source_suffix = ".rst" - -# The master toctree document. -master_doc = "index" - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -# language = None - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns: list = [] - -# The name of the Pygments (syntax highlighting) style to use. -# pygments_style = None - - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = "sphinx_rtd_theme" - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -# -# html_theme_options = {} - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ["_static"] - -# Custom sidebar templates, must be a dictionary that maps document names -# to template names. -# -# The default sidebars (for documents that don't match any pattern) are -# defined by theme itself. Builtin themes are using these templates by -# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', -# 'searchbox.html']``. -# -# html_sidebars = {} - - -# -- Options for HTMLHelp output --------------------------------------------- - -# Output file base name for HTML help builder. -htmlhelp_basename = "mapchete_eo_doc" - - -# -- Options for LaTeX output ------------------------------------------------ - -latex_elements: dict = { - # The paper size ('letterpaper' or 'a4paper'). - # - # 'papersize': 'letterpaper', - # The font size ('10pt', '11pt' or '12pt'). - # - # 'pointsize': '10pt', - # Additional stuff for the LaTeX preamble. - # - # 'preamble': '', - # Latex figure (float) alignment - # - # 'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - ( - master_doc, - "orgonite.tex", - "orgonite Documentation", - "Petr Sevcik, Joachim Ungar", - "manual", - ), -] - - -# -- Options for manual page output ------------------------------------------ - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, "mapchete_eo", "Mapchete Satellite Documentation", [author], 1) -] - - -# -- Options for Texinfo output ---------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ( - master_doc, - "mapchete_eo", - "Mapchete Satellite Documentation", - author, - "mapchete_eo", - "Mapchete input plugin for satellite archives on AWS and Mundi.", - "Miscellaneous", - ), -] - - -# -- Options for Epub output ------------------------------------------------- - -# Bibliographic Dublin Core info. -epub_title = project - -# The unique identifier of the text. This can be a ISBN number -# or the project homepage. -# -# epub_identifier = '' - -# A unique identification for the text. -# -# epub_uid = '' - -# A list of files that should not be packed into the epub file. -epub_exclude_files = ["search.html"] - - -# -- Extension configuration ------------------------------------------------- diff --git a/doc/source/configuration_parameters.rst b/doc/source/configuration_parameters.rst deleted file mode 100644 index 4b175496..00000000 --- a/doc/source/configuration_parameters.rst +++ /dev/null @@ -1,240 +0,0 @@ -Configuration Parameters -======================== - -All configuration parameters can be either set in the mapchete file or via environment -variables as long as the variables are provided in uppercase letters and have the -:code:`MP_SATELLITE_` prefix. - -Some parameters also come with default values. Please note that the values coming from -environment variables overrule mapchete file values which themselves overrule default -values. - - ------------------ -Common Parameters ------------------ - -:code:`start_time` / :code:`end_time` ---------------------------------------- -*(required)* - -Start and end time filter settings for input products. - -:code:`remote_timeout` ----------------------- -*(default: 5)* - -Timeout in seconds used for all packages which make calls to external services. These -packages are :code:`urllib`, :code:`requests`, :code:`rasterio`, :code:`fiona` and -:code:`boto`. - -:code:`metadata_concurrency` ----------------------------- -*(default: True)* - -Parse and prepare metadata in parallel. - -:code:`metadata_concurrency_parallelization` --------------------------------------------- -*(one of "threads" or "processes"; default: "threads")* - -Parallelization strategy. - -:code:`metadata_concurrency_threads` ------------------------------------- -*(default: number of CPU cores but 8 at maximum)* - -Number of parallel threads used. - -:code:`metadata_concurrency_processes` --------------------------------------- -*(default: number of CPU cores but 8 at maximum)* - -Number of parallel processes used. - -:code:`footprint_buffer` ------------------------- -*(default: -500)* - -Buffer used to make footprints a bit smaller. The reason is that product bands do not -exactly overlap at the edges and therefore can cause artefacts ("unicorn trails"). - -:code:`max_products` --------------------- -*(default: 4500)* - -Maximum number of products allowed to be parsed before plugin raises an error. - -:code:`max_cloud_percent` -------------------------- -*(default: 100)* - -Filter setting for maximum cloud coverage. - -:code:`first_granule_only` --------------------------- -*(default: False)* - -Only use the first product of the day, e.g. in higher latitudes where multiple products -overlap in one day, the plugin only uses the first product and omits the rest. This avoids -reading unnecessary amounts of data in regions which are covered multiple times by day. - - -Common Caching Parameters -------------------------- - -:code:`path` ------------- -*(required)* - -Local path to cache products. - - -:code:`intersection_percent` ----------------------------- -*(default: 100)* - -Only cache products which intersect to x percent with process bounds. - -:code:`keep` ------------- -*(default: False)* - -Don't clean cache after process is finished. This setting makes debugging easier. - -:code:`max_disk_usage` ------------------------------------- -*(default: 90)* - -Stop caching products if disk is more thatn x % full. - - -------------------- -Sentinel-1 Specific -------------------- - -:code:`level` -------------- -*(currently only "L1" supported; default: "L1")* - -Filter setting for processing level. - -:code:`sensormode` ------------------- -*(currently only "IW" supported; default: "IW")* - -Filter setting for sensor mode. - -:code:`producttype` -------------------- -*(one of "GRD", "IW_SLC" or "EW_SLC"; default: "GRD")* - -Filter setting for product type. - - -Specific Caching Parameters ---------------------------- - -Note: caching is required for Sentinel-1! - -:code:`resampling` ------------------- -*(default: nearest)* - -Resampling method used when projecting raw data. - -:code:`sar_calibration` ------------------------ -*(one of "Beta", "Gamma" or "Sigma"; default: "Gamma")* - -SNAP calibration method used when preprocessing data. - -:code:`tnr` ------------ -*(default: True)* - -SNAP TNR magic. - -:code:`zoom` ------------- -*(default: 13)* - -Process pyramid zoom level to determine projection target grid. - - -------------------- -Sentinel-2 Specific -------------------- - -:code:`level` -------------- -*(one of "L1C" or "L2A"; default: "L1")* - -Filter setting for processing level. Note: "L2A" is currently only available on Mundi. - - -Specific Caching Parameters ---------------------------- - -:code:`scl` ------------ -*(default: False)* - -Also cache SCL data. (Only relevant when using Level-2.) - - ------------- -AWS Specific ------------- - -:code:`cat_baseurl` -------------------- -*(default: "http://opensearch.sentinel-hub.com/resto/api/collections/Sentinel2/search.json?q=&")* - -URL to opensearch catalog. - -:code:`bucket_baseurl` ----------------------- -*(default: "s3://sentinel-s2-l1c/")* - -Base URL to bucket containing the data. - -:code:`metadata_baseurl` ------------------------- -*(default: "s3://sentinel-s2-l1c/")* - -Base URL to bucket containing metadata. - - -------------------------- -Sentinel-1 Mundi Specific -------------------------- - -:code:`cat_baseurl` -------------------- -*(default: "https://mundiwebservices.com/acdc/catalog/proxy/search/Sentinel1/opensearch?&")* - -URL to opensearch catalog. - -:code:`bucket_baseurl` ----------------------- -*(default: "https://obs.eu-de.otc.t-systems.com/")* - -Base URL to bucket containing the data. - - -------------------------- -Sentinel-2 Mundi Specific -------------------------- - -:code:`cat_baseurl` -------------------- -*(default: "https://mundiwebservices.com/acdc/catalog/proxy/search/Sentinel2/opensearch?&")* - -URL to opensearch catalog. - -:code:`bucket_baseurl` ----------------------- -*(default: "https://obs.eu-de.otc.t-systems.com/")* - -Base URL to bucket containing the data. diff --git a/doc/source/examples.rst b/doc/source/examples.rst deleted file mode 100644 index f06c031a..00000000 --- a/doc/source/examples.rst +++ /dev/null @@ -1,80 +0,0 @@ -Examples -======== - - -S2AWS ------ - -.. code-block:: yaml - - input: - s2: - format: S2AWS - start_time: 2018-04-02 # required - end_time: 2018-04-03 # required - with_cloudmasks: True # also get cloud masks - metadata_concurrency: True # parse source metadata concurrently - metadata_concurrency_threads: 4 # use n threads - footprint_buffer: -500 # negative buffer applied to footprints (default: -500) - max_products: 4500 # maximum number of products to be fetched - first_granule_only: False # only use first granule of each day (for Sentinel-2) - cache: # optional - path: cache # path to cache - bands: [1] # specify which bands to cache - keep: true # don't delete cached data after process is finished - intersection_percent: 0 # only cache products with minimum intersection - max_cloud_percent: 10 # only cache products with maximum cloud cover - max_disk_usage: 90 # stop further caching if disk is n% full - - -S2Mundi -------- - -.. code-block:: yaml - - input: - s2: - format: S2Mundi - start_time: 2018-04-02 # required - end_time: 2018-04-03 # required - level: L1C # or 'L2A' for Level 2A data - with_cloudmasks: True # also get cloud masks - metadata_concurrency: True # parse source metadata concurrently - metadata_concurrency_threads: 4 # use n threads - footprint_buffer: -500 # negative buffer applied to footprints (default: -500) - max_products: 4500 # maximum number of products to be fetched - first_granule_only: False # only use first granule of each day (for Sentinel-2) - cache: # optional - path: cache # path to cache - bands: [1] # specify which bands to cache - keep: true # don't delete cached data after process is finished - intersection_percent: 0 # only cache products with minimum intersection - max_cloud_percent: 10 # only cache products with maximum cloud cover - max_disk_usage: 90 # stop further caching if disk is n% full - -S1Mundi -------- - -.. code-block:: yaml - - input: - s2: - format: S1Mundi - start_time: 2018-04-02 # required - end_time: 2018-04-03 # required - level: L1_ - sensormode: IW - producttype: GRD - metadata_concurrency: True # parse source metadata concurrently - metadata_concurrency_threads: 4 # use n threads - footprint_buffer: -500 # negative buffer applied to footprints (default: -500) - max_products: 4500 # maximum number of products to be fetched - first_granule_only: False # only use first granule of each day (for Sentinel-2) - cache: # optional - path: cache # path to cache - resampling: bilinear_interpolation # interpolation used when regridding data - sar_calibration: gamma0 - tnr: true - keep: true # don't delete cached data after process is finished - max_disk_usage: 90 # stop further caching if disk is n% full - zoom: 13 \ No newline at end of file diff --git a/doc/source/index.rst b/doc/source/index.rst deleted file mode 100644 index 0d9da235..00000000 --- a/doc/source/index.rst +++ /dev/null @@ -1,2 +0,0 @@ -mapchete_eo -=========== diff --git a/docs/source/cli.rst b/docs/source/cli.rst new file mode 100644 index 00000000..30a1e06d --- /dev/null +++ b/docs/source/cli.rst @@ -0,0 +1,16 @@ +Mapchete-EO Command Line Interface (CLI) +======================================== + +The `mapchete-eo` package extends Mapchete with Earth Observation (EO) data processing +commands accessible via the `mapchete` CLI. + +Usage +----- + +The CLI commands are registered under `mapchete` as subcommands. + +The test/help for mapchete EO command is: + +.. code-block:: bash + + mapchete eo --help diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 00000000..7362f570 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,73 @@ +import os +import sys +import re +import tomllib # Python 3.11+; use 'tomli' for earlier versions + +sys.path.insert(0, os.path.abspath("..")) + +# -- Project metadata from pyproject.toml ------------------------------------ + + +def get_metadata(): + pyproject_path = os.path.join( + os.path.dirname(__file__), "..", "..", "pyproject.toml" + ) + pyproject_path = os.path.abspath(pyproject_path) + with open(pyproject_path, "rb") as f: + pyproject_data = tomllib.load(f) + project = pyproject_data.get("project", {}) + authors = project.get("authors", []) + author_names = ", ".join(a.get("name", "") for a in authors if "name" in a) + + init_path = os.path.join( + os.path.dirname(__file__), "..", "..", "mapchete_eo", "__init__.py" + ) + init_path = os.path.abspath(init_path) + with open(init_path, "r", encoding="utf-8") as f: + content = f.read() + version_match = re.search( + r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]', content, re.MULTILINE + ) + version = version_match.group(1) if version_match else "0.0.0" + + return version, author_names + + +release, author = get_metadata() + +# -- General configuration --------------------------------------------------- + + +version, author = get_metadata() + +project = "mapchete-eo" +author = author + +release = version + +version, author = get_metadata() + +rst_prolog = f""" +.. |author| replace:: {author} +.. |version| replace:: {version} +""" + + +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.napoleon", + "sphinx.ext.viewcode", + "sphinx.ext.autosummary", +] + +autosummary_generate = True + +# Optional: include tests folder on path (if you want to import tests modules) +sys.path.insert(0, os.path.abspath("../..")) + + +templates_path = ["_templates"] +# exclude_patterns = [] + +html_theme = "sphinx_rtd_theme" +html_static_path = ["_static"] diff --git a/docs/source/examples.rst b/docs/source/examples.rst new file mode 100644 index 00000000..8b2c8eba --- /dev/null +++ b/docs/source/examples.rst @@ -0,0 +1,24 @@ +Examples +========================================== + +Examples can be found in the `examples` directory of this repository. + +List of available examples: + +1) `sentinel-2_2025-may-june_first-pixel.mapchete` +2) *placeholder* + +Usage +----- + +Here is how to execute the `mapchete-eo` drivers via `mapchete execute` on one of the examples. + +.. code-block:: bash + + $ mapchete execute sentinel-2_2025-may-june_first-pixel.mapchete + +This will run `mapchete executor` (default: processes) and output the processing into the `path` under `output` specified in the mapchete file config. + +The `sentinel-2_2025-may-june_first-pixel.mapchete` example shows capabilities by reading the Element84 curated Sentinel-2 Cloud-Optimized GeoTiff (COG) data, which can be read publicly without incurring costs. + +For data discovery we are using the STAC API EarthSearch (https://earth-search.aws.element84.com/v1). \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 00000000..3343e9e6 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,31 @@ +Welcome to mapchete‑eo Documentation +==================================== + +Version: |release| +Authors: |author| + +Overview +-------- + +**mapchete-eo** builds upon Mapchete, adding Earth Observation processing capabilities: +cloud masking, temporal compositing, BRDF, etc. + +With STAC API and catalogs handling for data sources. + +CLI +--- + +.. toctree:: + :maxdepth: 2 + :caption: Generic Info + + cli + +Example Usage +------------- + +.. toctree:: + :maxdepth: 2 + :caption: Basic Examples + + examples diff --git a/examples/first_pixel_process.py b/examples/first_pixel_process.py new file mode 100644 index 00000000..402e9af4 --- /dev/null +++ b/examples/first_pixel_process.py @@ -0,0 +1,55 @@ +import logging +import numpy.ma as ma +from rasterio.enums import Resampling +from typing import List, Optional, Union + +from mapchete import Timer + +from mapchete_eo.platforms.sentinel2.config import MaskConfig +from mapchete_eo.platforms.sentinel2.driver import Sentinel2Cube +from mapchete_eo.sort import TargetDateSort +from mapchete_eo.types import DateTimeLike, MergeMethod + + +logger = logging.getLogger(__name__) + + +def execute( + element84_sentinel2: Sentinel2Cube, + assets: List[str], + target_height: int = 1, + resampling: str = "bilinear", + nodata: float = 0.0, + merge_products_by: str = "s2:datastrip_id", + mask_config: Union[MaskConfig, dict] = MaskConfig( + scl_classes=[ + "nodata", + "saturated_or_defected", + "cloud_shadows", + "thin_cirrus", + "cloud_medium_probability", + "cloud_high_probability", + ] + ), + target_date: Optional[DateTimeLike] = None, +) -> ma.MaskedArray: + """ + This mapchete execute process reads the time-series and tries to fill an array with singular data value from the time-series. + + """ + logger.debug("Reading Sentinel-2 data stack.") + with Timer() as t: + data_stack = element84_sentinel2.read_levelled_np_array( + target_height=target_height, + assets=assets, + resampling=Resampling[resampling], + nodatavals=nodata, + merge_products_by=merge_products_by, + merge_method=MergeMethod.average, + raise_empty=True, + mask_config=MaskConfig.parse(mask_config), + sort=TargetDateSort(target_date=target_date), + ) + logger.debug("Sentinel-2 stack of shape %s read took %s", data_stack.shape, t) + + return data_stack[0] diff --git a/examples/sentinel-2_2025-may-june_first_pixel.mapchete b/examples/sentinel-2_2025-may-june_first_pixel.mapchete new file mode 100644 index 00000000..8ac2b779 --- /dev/null +++ b/examples/sentinel-2_2025-may-june_first_pixel.mapchete @@ -0,0 +1,37 @@ +process: first_pixel_process.py +input: + element84_sentinel2: + format: Sentinel-2 + level: L2A + # The process only masks by SCL masks and is not evaluating values from the timeseries, thus we are taking perfect scenes only (up to 2% cloudcover) + # Note: This could lead to granule and/or tile stripes in the output + max_cloud_percent: 2 + time: + start: 2025-05-01 + end: 2025-06-30 +output: + format: GTiff + # In this example we will be getting Sentinel 2 bands: B04, B03, B02, B08, B11, B12 (RGB, NIR, SWIR) + bands: 6 + path: sentinel-2_2025-may-june_first_pixel + dtype: uint16 +pyramid: + grid: geodetic + metatiling: 8 +zoom_levels: + min: 8 + max: 13 +baselevels: + lower: cubic + min: 13 + +# Some bounds around Vienna +bounds: [16.20, 48.00, 16.75,48.5] + +process_parameters: + target_height: 1 + target_date: 2025-05-01 + assets: [red, green, blue, nir, swir16, swir22] + mask_config: + footprint: true + scl_classes: ["nodata", "saturated_or_defected", "cloud_shadows", "thin_cirrus", "cloud_medium_probability", "cloud_high_probability"] diff --git a/mapchete_eo/__init__.py b/mapchete_eo/__init__.py index f3474be7..117f7b0d 100644 --- a/mapchete_eo/__init__.py +++ b/mapchete_eo/__init__.py @@ -1 +1 @@ -__version__ = "2025.7.0" +__version__ = "2025.8.0" diff --git a/pyproject.toml b/pyproject.toml index 375de8b3..a24eefb6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "hatchling.build" name = "mapchete-eo" dynamic = ["version"] description = "mapchete EO data reader" -readme = "README.md" +readme = "README.rst" license = "MIT" authors = [ { name = "Joachim Ungar", email = "joachim.ungar@eox.at" }, @@ -41,6 +41,10 @@ dependencies = [ ] [project.optional-dependencies] +docs = [ + "sphinx", + "sphinx-rtd-theme" +] test = [ "pytest<8", "pytest-coverage", diff --git a/readthedocs.yaml b/readthedocs.yaml new file mode 100644 index 00000000..336b7221 --- /dev/null +++ b/readthedocs.yaml @@ -0,0 +1,17 @@ +# .readthedocs.yaml +version: 2 + +build: + os: ubuntu-24.04 + tools: + python: "3.12" + +sphinx: + configuration: docs/source/conf.py + +python: + install: + - method: pip + path: . + extra_requirements: + - docs