equi7grid-lite


Nameequi7grid-lite JSON
Version 0.6.0 PyPI version JSON
download
home_pagehttps://github.com/csaybar/equi7grid-lite
SummaryA user-friendly Python interface to interact with the Equi7Grid grid system
upload_time2024-06-22 07:34:33
maintainerNone
docs_urlNone
authorCesar Aybar
requires_python<4.0,>=3.9
licenseNone
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # equi7grid-lite

<p align="center">
  <a href="https://ipl-uv.github.io"><img src="docs/logo.jpeg" alt="header" width="50%"></a>
</p>

<p align="center">
    <em>
    No one will drive us from the paradise which Equi7Grid created for us
    </em>
</p>

<p align="center">
<a href='https://pypi.python.org/pypi/equi7grid-lite'>
<img src='https://img.shields.io/pypi/v/equi7grid-lite.svg' alt='PyPI' />
</a>
<a href='https://colab.research.google.com/drive/1SBjl4GVgCFUpVch2Prju5oiXN8WyzZTi?usp=sharing'>
<img src='https://colab.research.google.com/assets/colab-badge.svg' alt='COLAB' />
</a>
<a href="https://opensource.org/licenses/MIT" target="_blank">
<img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License">
</a>
<a href="https://github.com/psf/black" target="_blank">
<img src="https://img.shields.io/badge/code%20style-black-000000.svg" alt="Black">
</a>
<a href="https://pycqa.github.io/isort/" target="_blank">
<img src="https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336" alt="isort">
</a>
</p>

The `equi7grid-lite` package implements a user-friendly Python interface to interact with the [**Equi7Grid**](https://github.com/TUW-GEO/Equi7Grid) grid system. 

`equi7grid-lite` is an **unofficial Python implementation of [**Equi7Grid**](https://github.com/TUW-GEO/Equi7Grid)**. With this package, users can convert geographic coordinates to Equi7Grid tiles and vice versa. This implementation differs from the official version in tree key ways:

- *Quad-Tree Grid Splitting*: Users are required to split the grid in a Quad-Tree fashion, meaning each grid level is divided into four tiles. For example, transitioning from level 1 to level 0 involves splitting each tile into four regular smaller tiles.

- *Revised Grid ID Encoding*: The grid ID is always encoded in meters, and the reference to the tile system (e.g., "T1", "T3", "T6") is removed. Instead, tiles are dynamically defined by the `min_grid_size` parameter. Here is a comparison between the original Equi7Grid and equi7grid-lite name conventions:

    - 'EU500M_E036N006T6' -> 'EU2560_E4521N3011'

    Where 'EU' is the Equi7Grid zone, '2560' is the `min_grid_size`, 'E4521' is the position in the *x* tile grid, and 'N3011' is the position in the *y* tile grid.

- *Upper Bound Level*: The maximum grid level is determined as the nearest lower distance to 2_500_000 meters. This threshold serves as a limit to create the Quad-Tree grid structure.


<p align="center">
  <img src="docs/equi7grid_tiling.gif" alt="equi7grid-lite" width="100%"/>
</p>

Please refer to the [Equi7Grid repository](https://github.com/TUW-GEO/Equi7Grid) for **more information of the official implementation**.

## Installation

The `equi7grid-lite` package is available on PyPI and can be installed using `pip`:

```python
pip install equi7grid-lite
```

## Usage

The `equi7grid-lite` package provides a single class, `Equi7Grid`, which can be used to convert between geographic coordinates and Equi7Grid tiles.

```python
from equi7grid_lite import Equi7Grid

grid_system = Equi7Grid(min_grid_size=2560)
# Equi7Grid(min_grid_size=2560)
# ----------------
# levels: 0, 1, ... , 7, 8
# zones: AN, NA, OC, SA, AF, EU, AS
# min_grid_size: 2560 meters
# max_grid_size: 1310720 meters
```

To convert between geographic coordinates and Equi7Grid tiles, use the `lonlat2grid` method.

```python

lon, lat = -79.5, -5.49
grid_system.lonlat2grid(lon=lon, lat=lat)
#                  id        lon       lat          x          y zone level  land             geometry
#0  SA2560_E2009N2525 -79.507568 -5.485739  5144320.0  6465280.0   SA    Z0  True  POLYGON ((514560...
```

Use the `grid2lonlat` method to convert from Equi7Grid tile id to geographic coordinates.


```python
grid_system.grid2lonlat(grid_id="SA2560_E2009N2525")
#                  id        lon       lat          x          y zone level  land             geometry
#0  SA2560_E2009N2525 -79.507568 -5.485739  5144320.0  6465280.0   SA    Z0  True  POLYGON ((514560...
```

The `Equi7Grid` class also provides a method to create a grid of Equi7Grid upper-level tiles that
cover a given bounding box.

```python
import geopandas as gpd

from equi7grid_lite import Equi7Grid

# Define a POLYGON geometry
world_filepath = gpd.datasets.get_path('naturalearth_lowres')
world = gpd.read_file(world_filepath)
country = world[world.name == "Peru"].geometry

# Create a grid of Equi7Grid tiles that cover the bounding box of the POLYGON geometry
grid = grid_system.create_grid(
    level=4,
    zone="SA",
    mask=country # Only include tiles that intersect the polygon
)

# Export the grid to a GeoDataFrame
grid.to_file("grid.shp")
```

By running `create_grid` with different levels, you can obtain its corresponding Equi7Grid Quad-Tree grid structure for any region.

![grid](docs/equi7grid_demo.gif)

Obtain the metadata of each Equi7Grid zone:

```python
from equi7grid_lite import Equi7Grid

# Zones: SA, EU, AF, AS, NA, AU
Equi7Grid.SA
```

Each zone has the following attributes:

- *id*: The zone ID code.
- *crs*: The WKT representation of the CRS.
- *geometry_geo*: The geometry of the zone in EPSG:4326.
- *geometry_equi7grid*: The geometry of the zone in the Equi7Grid CRS.
- *bbox_geo*: The bounding box of the zone in EPSG:4326.
- *bbox_equi7grid*: The bounding box of the zone in the Equi7Grid CRS.
- *landmasses_equi7grid*: The landmasses of the zone in the Equi7Grid CRS.
- *origin*: The central meridian and the latitude of origin.

## Use Equi7Grid with cubo

The `equi7grid-lite` package can be used in conjunction with the [cubo](https://github.com/ESDS-Leipzig/cubo) to retrieve Earth Observation (EO) data.

```python
import cubo
import matplotlib.pyplot as plt
import numpy as np
import rioxarray
from rasterio.enums import Resampling

from equi7grid_lite import Equi7Grid

# Initialize Equi7Grid system
grid_system = Equi7Grid(min_grid_size=2560)

# Specify the center coordinates
lon, lat = -122.4194, 37.7749

# Retrieve parameters for the CUBO request
cubo_parameters = grid_system.cubo_utm_parameters(lon=lon, lat=lat)

# Define the cube request using CUBO
da = cubo.create(
    lat=cubo_parameters["lat"],
    lon=cubo_parameters["lon"],
    collection="sentinel-2-l2a",  # Name of the STAC collection
    bands=["B04", "B03", "B02"],   # Bands to retrieve
    start_date="2021-08-01",       # Start date of the cube
    end_date="2021-10-30",         # End date of the cube
    edge_size=cubo_parameters["distance"] // 10,  # Distance in pixels
    resolution=10,                 # Pixel size of the cube (m)
    query={"eo:cloud_cover": {"lt": 50}}  # Query parameters
)

# Add the CRS to the cube
da = da.rio.write_crs(f"epsg:{da.attrs['epsg']}")
da = da.drop_vars("cubo:distance_from_center")

# Convert the cube to a dataset and compute median over time
image = da.to_dataset("band").median("time", skipna=True)

# Increase the resolution of the cube with Lanczos resampling
image_reprojected = image.rio.reproject(
    cubo_parameters["crs"],
    resolution=2.5,
    resampling=Resampling.lanczos
)

# Downsample the cube with nearest neighbor resampling
image_reprojected = image_reprojected.rio.reproject(
    cubo_parameters["crs"],
    resolution=10,
    resampling=Resampling.nearest
)

# Clip the cube to the specified polygon
composite_e7g = image_reprojected.rio.clip([cubo_parameters["polygon"]]).to_array()

# Save the images in UTM and E7G projections
composite_e7g.rio.to_raster("composite_e7g.tif")
image.to_array().rio.to_raster("composite_utm.tif")
```

## License

This package is released under the MIT License. For more information, see the [LICENSE](LICENSE) file.

## Contributing

Contributions are welcome! For bug reports or feature requests, please open an issue on GitHub. For contributions, please submit a pull request with a detailed description of the changes.

## Citation

This is a simple adaptation of the Equi7Grid paper and code. If you use this package in your research, please consider citing the original Equi7Grid package and paper.

**Package:**

```
@software{bernhard_bm_2023_8252376,
  author       = {Bernhard BM and
                  Sebastian Hahn and
                  actions-user and
                  cnavacch and
                  Manuel Schmitzer and
                  shochsto and
                  Senmao Cao},
  title        = {TUW-GEO/Equi7Grid: v0.2.4},
  month        = aug,
  year         = 2023,
  publisher    = {Zenodo},
  version      = {v0.2.4},
  doi          = {10.5281/zenodo.8252376},
  url          = {https://doi.org/10.5281/zenodo.8252376}
}
```

**Paper:**

```
@article{BAUERMARSCHALLINGER201484,
title = {Optimisation of global grids for high-resolution remote sensing data},
journal = {Computers & Geosciences},
volume = {72},
pages = {84-93},
year = {2014},
issn = {0098-3004},
doi = {https://doi.org/10.1016/j.cageo.2014.07.005},
url = {https://www.sciencedirect.com/science/article/pii/S0098300414001629},
author = {Bernhard Bauer-Marschallinger and Daniel Sabel and Wolfgang Wagner},
keywords = {Remote sensing, High resolution, Big data, Global grid, Projection, Sampling, Equi7 Grid}
}
```


            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/csaybar/equi7grid-lite",
    "name": "equi7grid-lite",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.9",
    "maintainer_email": null,
    "keywords": null,
    "author": "Cesar Aybar",
    "author_email": "cesar.aybar@uv.es",
    "download_url": "https://files.pythonhosted.org/packages/d2/c5/0755b7821489da0bfd81ae81329e048d76ee60c65a1ee09efc4131642acf/equi7grid_lite-0.6.0.tar.gz",
    "platform": null,
    "description": "# equi7grid-lite\n\n<p align=\"center\">\n  <a href=\"https://ipl-uv.github.io\"><img src=\"docs/logo.jpeg\" alt=\"header\" width=\"50%\"></a>\n</p>\n\n<p align=\"center\">\n    <em>\n    No one will drive us from the paradise which Equi7Grid created for us\n    </em>\n</p>\n\n<p align=\"center\">\n<a href='https://pypi.python.org/pypi/equi7grid-lite'>\n<img src='https://img.shields.io/pypi/v/equi7grid-lite.svg' alt='PyPI' />\n</a>\n<a href='https://colab.research.google.com/drive/1SBjl4GVgCFUpVch2Prju5oiXN8WyzZTi?usp=sharing'>\n<img src='https://colab.research.google.com/assets/colab-badge.svg' alt='COLAB' />\n</a>\n<a href=\"https://opensource.org/licenses/MIT\" target=\"_blank\">\n<img src=\"https://img.shields.io/badge/License-MIT-blue.svg\" alt=\"License\">\n</a>\n<a href=\"https://github.com/psf/black\" target=\"_blank\">\n<img src=\"https://img.shields.io/badge/code%20style-black-000000.svg\" alt=\"Black\">\n</a>\n<a href=\"https://pycqa.github.io/isort/\" target=\"_blank\">\n<img src=\"https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336\" alt=\"isort\">\n</a>\n</p>\n\nThe `equi7grid-lite` package implements a user-friendly Python interface to interact with the [**Equi7Grid**](https://github.com/TUW-GEO/Equi7Grid) grid system. \n\n`equi7grid-lite` is an **unofficial Python implementation of [**Equi7Grid**](https://github.com/TUW-GEO/Equi7Grid)**. With this package, users can convert geographic coordinates to Equi7Grid tiles and vice versa. This implementation differs from the official version in tree key ways:\n\n- *Quad-Tree Grid Splitting*: Users are required to split the grid in a Quad-Tree fashion, meaning each grid level is divided into four tiles. For example, transitioning from level 1 to level 0 involves splitting each tile into four regular smaller tiles.\n\n- *Revised Grid ID Encoding*: The grid ID is always encoded in meters, and the reference to the tile system (e.g., \"T1\", \"T3\", \"T6\") is removed. Instead, tiles are dynamically defined by the `min_grid_size` parameter. Here is a comparison between the original Equi7Grid and equi7grid-lite name conventions:\n\n    - 'EU500M_E036N006T6' -> 'EU2560_E4521N3011'\n\n    Where 'EU' is the Equi7Grid zone, '2560' is the `min_grid_size`, 'E4521' is the position in the *x* tile grid, and 'N3011' is the position in the *y* tile grid.\n\n- *Upper Bound Level*: The maximum grid level is determined as the nearest lower distance to 2_500_000 meters. This threshold serves as a limit to create the Quad-Tree grid structure.\n\n\n<p align=\"center\">\n  <img src=\"docs/equi7grid_tiling.gif\" alt=\"equi7grid-lite\" width=\"100%\"/>\n</p>\n\nPlease refer to the [Equi7Grid repository](https://github.com/TUW-GEO/Equi7Grid) for **more information of the official implementation**.\n\n## Installation\n\nThe `equi7grid-lite` package is available on PyPI and can be installed using `pip`:\n\n```python\npip install equi7grid-lite\n```\n\n## Usage\n\nThe `equi7grid-lite` package provides a single class, `Equi7Grid`, which can be used to convert between geographic coordinates and Equi7Grid tiles.\n\n```python\nfrom equi7grid_lite import Equi7Grid\n\ngrid_system = Equi7Grid(min_grid_size=2560)\n# Equi7Grid(min_grid_size=2560)\n# ----------------\n# levels: 0, 1, ... , 7, 8\n# zones: AN, NA, OC, SA, AF, EU, AS\n# min_grid_size: 2560 meters\n# max_grid_size: 1310720 meters\n```\n\nTo convert between geographic coordinates and Equi7Grid tiles, use the `lonlat2grid` method.\n\n```python\n\nlon, lat = -79.5, -5.49\ngrid_system.lonlat2grid(lon=lon, lat=lat)\n#                  id        lon       lat          x          y zone level  land             geometry\n#0  SA2560_E2009N2525 -79.507568 -5.485739  5144320.0  6465280.0   SA    Z0  True  POLYGON ((514560...\n```\n\nUse the `grid2lonlat` method to convert from Equi7Grid tile id to geographic coordinates.\n\n\n```python\ngrid_system.grid2lonlat(grid_id=\"SA2560_E2009N2525\")\n#                  id        lon       lat          x          y zone level  land             geometry\n#0  SA2560_E2009N2525 -79.507568 -5.485739  5144320.0  6465280.0   SA    Z0  True  POLYGON ((514560...\n```\n\nThe `Equi7Grid` class also provides a method to create a grid of Equi7Grid upper-level tiles that\ncover a given bounding box.\n\n```python\nimport geopandas as gpd\n\nfrom equi7grid_lite import Equi7Grid\n\n# Define a POLYGON geometry\nworld_filepath = gpd.datasets.get_path('naturalearth_lowres')\nworld = gpd.read_file(world_filepath)\ncountry = world[world.name == \"Peru\"].geometry\n\n# Create a grid of Equi7Grid tiles that cover the bounding box of the POLYGON geometry\ngrid = grid_system.create_grid(\n    level=4,\n    zone=\"SA\",\n    mask=country # Only include tiles that intersect the polygon\n)\n\n# Export the grid to a GeoDataFrame\ngrid.to_file(\"grid.shp\")\n```\n\nBy running `create_grid` with different levels, you can obtain its corresponding Equi7Grid Quad-Tree grid structure for any region.\n\n![grid](docs/equi7grid_demo.gif)\n\nObtain the metadata of each Equi7Grid zone:\n\n```python\nfrom equi7grid_lite import Equi7Grid\n\n# Zones: SA, EU, AF, AS, NA, AU\nEqui7Grid.SA\n```\n\nEach zone has the following attributes:\n\n- *id*: The zone ID code.\n- *crs*: The WKT representation of the CRS.\n- *geometry_geo*: The geometry of the zone in EPSG:4326.\n- *geometry_equi7grid*: The geometry of the zone in the Equi7Grid CRS.\n- *bbox_geo*: The bounding box of the zone in EPSG:4326.\n- *bbox_equi7grid*: The bounding box of the zone in the Equi7Grid CRS.\n- *landmasses_equi7grid*: The landmasses of the zone in the Equi7Grid CRS.\n- *origin*: The central meridian and the latitude of origin.\n\n## Use Equi7Grid with cubo\n\nThe `equi7grid-lite` package can be used in conjunction with the [cubo](https://github.com/ESDS-Leipzig/cubo) to retrieve Earth Observation (EO) data.\n\n```python\nimport cubo\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport rioxarray\nfrom rasterio.enums import Resampling\n\nfrom equi7grid_lite import Equi7Grid\n\n# Initialize Equi7Grid system\ngrid_system = Equi7Grid(min_grid_size=2560)\n\n# Specify the center coordinates\nlon, lat = -122.4194, 37.7749\n\n# Retrieve parameters for the CUBO request\ncubo_parameters = grid_system.cubo_utm_parameters(lon=lon, lat=lat)\n\n# Define the cube request using CUBO\nda = cubo.create(\n    lat=cubo_parameters[\"lat\"],\n    lon=cubo_parameters[\"lon\"],\n    collection=\"sentinel-2-l2a\",  # Name of the STAC collection\n    bands=[\"B04\", \"B03\", \"B02\"],   # Bands to retrieve\n    start_date=\"2021-08-01\",       # Start date of the cube\n    end_date=\"2021-10-30\",         # End date of the cube\n    edge_size=cubo_parameters[\"distance\"] // 10,  # Distance in pixels\n    resolution=10,                 # Pixel size of the cube (m)\n    query={\"eo:cloud_cover\": {\"lt\": 50}}  # Query parameters\n)\n\n# Add the CRS to the cube\nda = da.rio.write_crs(f\"epsg:{da.attrs['epsg']}\")\nda = da.drop_vars(\"cubo:distance_from_center\")\n\n# Convert the cube to a dataset and compute median over time\nimage = da.to_dataset(\"band\").median(\"time\", skipna=True)\n\n# Increase the resolution of the cube with Lanczos resampling\nimage_reprojected = image.rio.reproject(\n    cubo_parameters[\"crs\"],\n    resolution=2.5,\n    resampling=Resampling.lanczos\n)\n\n# Downsample the cube with nearest neighbor resampling\nimage_reprojected = image_reprojected.rio.reproject(\n    cubo_parameters[\"crs\"],\n    resolution=10,\n    resampling=Resampling.nearest\n)\n\n# Clip the cube to the specified polygon\ncomposite_e7g = image_reprojected.rio.clip([cubo_parameters[\"polygon\"]]).to_array()\n\n# Save the images in UTM and E7G projections\ncomposite_e7g.rio.to_raster(\"composite_e7g.tif\")\nimage.to_array().rio.to_raster(\"composite_utm.tif\")\n```\n\n## License\n\nThis package is released under the MIT License. For more information, see the [LICENSE](LICENSE) file.\n\n## Contributing\n\nContributions are welcome! For bug reports or feature requests, please open an issue on GitHub. For contributions, please submit a pull request with a detailed description of the changes.\n\n## Citation\n\nThis is a simple adaptation of the Equi7Grid paper and code. If you use this package in your research, please consider citing the original Equi7Grid package and paper.\n\n**Package:**\n\n```\n@software{bernhard_bm_2023_8252376,\n  author       = {Bernhard BM and\n                  Sebastian Hahn and\n                  actions-user and\n                  cnavacch and\n                  Manuel Schmitzer and\n                  shochsto and\n                  Senmao Cao},\n  title        = {TUW-GEO/Equi7Grid: v0.2.4},\n  month        = aug,\n  year         = 2023,\n  publisher    = {Zenodo},\n  version      = {v0.2.4},\n  doi          = {10.5281/zenodo.8252376},\n  url          = {https://doi.org/10.5281/zenodo.8252376}\n}\n```\n\n**Paper:**\n\n```\n@article{BAUERMARSCHALLINGER201484,\ntitle = {Optimisation of global grids for high-resolution remote sensing data},\njournal = {Computers & Geosciences},\nvolume = {72},\npages = {84-93},\nyear = {2014},\nissn = {0098-3004},\ndoi = {https://doi.org/10.1016/j.cageo.2014.07.005},\nurl = {https://www.sciencedirect.com/science/article/pii/S0098300414001629},\nauthor = {Bernhard Bauer-Marschallinger and Daniel Sabel and Wolfgang Wagner},\nkeywords = {Remote sensing, High resolution, Big data, Global grid, Projection, Sampling, Equi7 Grid}\n}\n```\n\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "A user-friendly Python interface to interact with the Equi7Grid grid system",
    "version": "0.6.0",
    "project_urls": {
        "Documentation": "https://ipl-uv.github.io/equi7grid-lite/",
        "Homepage": "https://github.com/csaybar/equi7grid-lite",
        "Repository": "https://github.com/csaybar/equi7grid-lite"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "203713fba87d657c7db841b5e5120c7c25b061b2a8a0c318c47fd6bbc39aa7bd",
                "md5": "2a06961f42ffb026a22556bbf36b7053",
                "sha256": "e0a72ba6ce3f38facaf45e7be16c634d6b13e30c6ebef9891902dbcfc5905da7"
            },
            "downloads": -1,
            "filename": "equi7grid_lite-0.6.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "2a06961f42ffb026a22556bbf36b7053",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.9",
            "size": 6856237,
            "upload_time": "2024-06-22T07:34:30",
            "upload_time_iso_8601": "2024-06-22T07:34:30.218188Z",
            "url": "https://files.pythonhosted.org/packages/20/37/13fba87d657c7db841b5e5120c7c25b061b2a8a0c318c47fd6bbc39aa7bd/equi7grid_lite-0.6.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "d2c50755b7821489da0bfd81ae81329e048d76ee60c65a1ee09efc4131642acf",
                "md5": "1e2374413ea535feaa5613953a54fffa",
                "sha256": "6e07c326b509458b216f5d26750867caa791ccfd675abdf0c9b941ba15521c08"
            },
            "downloads": -1,
            "filename": "equi7grid_lite-0.6.0.tar.gz",
            "has_sig": false,
            "md5_digest": "1e2374413ea535feaa5613953a54fffa",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.9",
            "size": 6861774,
            "upload_time": "2024-06-22T07:34:33",
            "upload_time_iso_8601": "2024-06-22T07:34:33.300777Z",
            "url": "https://files.pythonhosted.org/packages/d2/c5/0755b7821489da0bfd81ae81329e048d76ee60c65a1ee09efc4131642acf/equi7grid_lite-0.6.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-06-22 07:34:33",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "csaybar",
    "github_project": "equi7grid-lite",
    "github_not_found": true,
    "lcname": "equi7grid-lite"
}
        
Elapsed time: 0.68815s