# GeoPre: Geospatial Data Processing Toolkit
**GeoPre** is a Python library designed to streamline common geospatial data operations, offering a unified interface for handling raster and vector datasets. It simplifies preprocessing tasks essential for GIS analysis, machine learning workflows, and remote sensing applications.
### Key Features
- **Data Scaling**:
- Normalization (Z-Score) and Min-Max scaling for raster bands.
- Prepares data for ML models while preserving geospatial metadata.
- **CRS Management**:
- Retrieve and compare Coordinate Reference Systems (CRS) across raster (Rasterio/Xarray) and vector (GeoPandas) datasets.
- Ensure consistency between datasets with automated CRS checks.
- **Reprojection**:
- Reproject vector data (GeoDataFrames) and raster data (Rasterio/Xarray) to any target CRS.
- Supports EPSG codes, WKT, and Proj4 strings.
- **No-Data Masking**:
- Handle missing values in raster datasets (NumPy/Xarray) with flexible masking.
- Integrates seamlessly with raster metadata for error-free workflows.
- **Cloud Masking**:
- Identify and mask clouds in Sentinel-2 and Landsat imagery.
- Supports multiple methods: QA bands, scene classification layers (SCL), probability bands, and OmniCloudMask AI-based detection.
- Optionally mask cloud shadows for improved accuracy.
- **Band Stacking**:
- Stack multiple raster bands from a folder into a single multi-band raster for analysis.
- Supports automatic band detection and resampling for different resolutions.
### Supported Data Types
- **Raster**: NumPy arrays, Rasterio `DatasetReader`, Xarray `DataArray` (via rioxarray).
- **Vector**: GeoPandas `GeoDataFrame`.
### Benefits of GeoPre
- **Unified Workflow**: Eliminates boilerplate code by providing consistent functions for raster and vector data.
- **Interoperability**: Bridges gaps between GeoPandas, Rasterio, and Xarray, ensuring smooth data transitions.
- **Robust Error Handling**: Automatically detects CRS mismatches and missing metadata to prevent silent failures.
- **Efficiency**: Optimized reprojection and masking operations reduce preprocessing time for large datasets.
- **ML-Ready Outputs**: Scaling functions preserve data structure, making outputs directly usable in machine learning pipelines.
Ideal for researchers and developers working with geospatial data, **GeoPre** enhances productivity by standardizing preprocessing steps and ensuring compatibility across diverse geospatial tools.
## Installation
Ensure you have the required dependencies installed before using this library:
```bash
pip install numpy geopandas rasterio rioxarray xarray pyproj
```
## Usage
### 1. Data Scaling
#### `Z-Score Scaling`
**Description**:This method centers the data around zero by subtracting the mean and dividing by the standard deviation, which is useful for machine learning models sensitive to outliers
and can standardize a band of pixel values for clustering/classification.
**Parameters**:
- data (numpy.ndarray): Input array to normalize.
**Returns**:
- numpy.ndarray: Standardized data with mean 0 and standard deviation 1.
#### `Min_Max_Scaling`
**Description**: This method scales the pixel values to a fixed range, typically [0, 1] or [-1, 1]. Ideal when you want to preserve the relative range of values.
For GeoTIFF image values (e.g., 0 to 65535), scale them to [0, 1].
**Parameters**:
- data (numpy.ndarray): Input array to normalize.
**Returns**:
- numpy.ndarray: Scaled data with values between 0 and 1, or -1 and 1.
#### Example:
```python
import numpy as np
from scaling_and_reproject import Z_score_scaling, Min_Max_Scaling
data = np.array([[10, 20, 30], [40, 50, 60]])
z_scaled = Z_score_scaling(data)
minmax_scaled = Min_Max_Scaling(data)
```
### 2. CRS Management
#### `get_crs`
**Description**: Retrieve CRS from geospatial data objects.
**Parameters**:
- data: GeoPandas GeoDataFrames (vector), Rasterio DatasetReaders (raster) or Xarray DataArrays with rio accessor (raster)
**Returns**:
- pyproj.CRS: Coordinate reference system or None if undefined
#### `compare_crs`
**Description**: Compare CRS between raster and vector datasets.
**Parameters**:
- raster_obj (DatasetReader/xarray.DataArray): Raster data source.
- vector_gdf (gpd.GeoDataFrame): Vector data source.
**Returns**:
**dict**: Comparison results with keys:
- raster_crs: Formatted CRS string
- vector_crs: Formatted CRS string
- same_crs: Boolean comparison result
- error: Exception message if any
#### Example:
```python
import geopandas as gpd
import rasterio
from scaling_and_reproject import get_crs, compare_crs
vector = gpd.read_file("data.shp")
raster = rasterio.open("image.tif")
print(get_crs(vector)) # EPSG:4326
print(compare_crs(raster, vector)) # CRS comparison results
```
### 3. Reprojection
#### `reproject_data`
**Description**: Reproject geospatial data to target CRS.
**Parameters**:
- data: GeoDataFrames (vector reprojection), or Rasterio datasets (returns array + metadata), or Xarray objects (rioxarray reprojection)
- target_crs: CRS to reproject to (EPSG code/WKT/proj4 string)
**Returns**:
- Reprojected data in format matching input type
#### Example:
```python
import rasterio
import xarray as xr
from scaling_and_reproject import reproject_data
# Vector reprojection
reprojected_vector = reproject_data(vector, "EPSG:3857")
# Raster reprojection (Rasterio)
with rasterio.open("input.tif") as src:
array, metadata = reproject_data(src, "EPSG:32633")
# Xarray reprojection
da = xr.open_rasterio("image.tif")
reprojected_da = reproject_data(da, "EPSG:4326")
```
### 4. No-Data Masking
#### `mask_raster_data`
**Description**: Mask no-data values in raster datasets. Handles both rasterio (numpy) and rioxarray (xarray) workflows.
**Parameters**:
- data: Raster data (numpy.ndarray or xarray.DataArray)
- profile: Rasterio metadata dict (required for numpy arrays)
- no_data_value: Override for metadata's nodata value
- return_mask: Whether to return boolean mask
**Returns**:
- Masked data array. For numpy inputs, returns tuple:(masked_array, profile). For xarray, returns DataArray.
#### Example:
```python
import xarray as xr
import rasterio
from scaling_and_reproject import mask_raster_data
# Rasterio workflow
with rasterio.open("data.tif") as src:
data = src.read(1)
masked, profile = mask_raster_data(data, src.profile)
# rioxarray workflow
da = xr.open_rasterio("data.tif")
masked_da = mask_raster_data(da)
```
### 5. Cloud Masking
#### `mask_clouds_S2`
**Description**: Masks clouds and optionally shadows in a Sentinel-2 raster image using various methods.
**Parameters**:
- `image_path` *(str)*: Path to the input raster image.
- `output_path` *(str, optional)*: Path to save the masked output raster. Defaults to the same directory as the input with '_masked' appended to the filename.
- `method` *(str, optional)*: The method for masking. Options are:
- `'auto'`: Automatically chooses the best available method.
- `'qa'`: Uses the QA60 band to mask clouds. WARNING: QA60 is deprecated after 2022-01-25, results for images after that date could be wrong
- `'probability'`: Uses the cloud probability band MSK_CLDPRB with a threshold for masking.
- `'omnicloudmask'`: Utilizes OmniCloudMask for AI-based cloud detection. Might take a long time for big images
- `'scl'`: Leverages the Scene Classification Layer (SCL) for masking.
- `'standard'`: Similar to 'auto', but avoids the OmniCloudMask method.
- `mask_shadows` *(bool)*: Whether to mask cloud shadows. Defaults to `False`.
- `threshold` *(int, optional)*: Cloud probability threshold (if using a cloud probability band), from 0 to 100. Defaults to `20`.
- `qa60_idx` *(int, optional)*: Index of the QA60 band (1-based). Auto-detected if not provided.
- `qa60_path` *(str, optional)*: Path to the QA60 band (if in a separate file).
- `prob_band_idx` *(int, optional)*: Index of the cloud probability band (1-based). Auto-detected if not provided.
- `prob_band_path` *(str, optional)*: Path to the cloud probability band (if in a separate file).
- `scl_idx` *(int, optional)*: Index of the SCL band (1-based). Auto-detected if not provided.
- `scl_path` *(str, optional)*: Path to the SCL band (if in a separate file).
- `red_idx`, `green_idx`, `nir_idx` *(int, optional)*: Indices of the red, green, and NIR bands, respectively. Auto-detected if not provided.
- `nodata_value` *(float)*: Value for no-data regions. Defaults to `np.nan`.
**Returns**:
- *(str)*: The path to the saved masked output raster.
#### Example:
```python
from cloud_masking import mask_clouds_S2
output_s2 = mask_clouds_S2("sentinel2_image.tif", method='auto', mask_shadows=True)
```
#### `mask_clouds_landsat`
**Description**:
Masks clouds and optionally shadows in a Landsat raster image using various methods.
**Parameters**:
- **`image_path`** *(str)*: Path to the input multi-band raster image.
- **`output_path`** *(str, optional)*: Path to save the masked output raster. Defaults to the same directory as the input with `_masked` suffix.
- **`method`** *(str)*: The method for masking. Options are:
- **`'auto'`**: Automatically chooses the best available method.
- **`'qa'`**: Uses the QA_PIXEL band to mask clouds.
- **`'omnicloudmask'`**: Utilizes OmniCloudMask for AI-based cloud detection.
- **`mask_shadows`** *(bool)*: Whether to mask cloud shadows. Defaults to `False`.
- **`qa_pixel_path`** *(str, optional)*: Path to the separate QA_PIXEL raster file.
- **`qa_pixel_idx`** *(int, optional)*: Index of the QA_PIXEL band (1-based).
- **`confidence_threshold`** *(str, optional)*: Confidence threshold for cloud masking (e.g., `'Low'`, `'Medium'`, `'High'`). Defaults to `'High'`. WARNING: as per the Landsat official documentation, the confidence bands are still under development, always use the default 'High' untill further notice. [Source](https://d9-wret.s3.us-west-2.amazonaws.com/assets/palladium/production/s3fs-public/media/files/LSDS-1619_Landsat8-9-Collection2-Level2-Science-Product-Guide-v6.pdf)
- **`red_idx`**, **`green_idx`**, **`nir_idx`** *(int, optional)*: Indices of the red, green, and NIR bands, respectively. Auto-detected if not provided.
- **`nodata_value`** *(float)*: Value for no-data regions. Defaults to `np.nan`.
### Returns
- *(str)*: The path to the saved masked output raster.
### Example
```python
from cloud_masking import mask_clouds_landsat
output_landsat = mask_clouds_landsat("landsat_image.tif", method='auto', mask_shadows=True)
```
## 6. Band Stacking
### `stack_bands`
**Description**:
Stacks multiple raster bands from a folder into a single multi-band raster. Support also .SAFE folders.
### Parameters
- **`input_path`** *(str or Path)*: Path to the folder containing band files.
- **`required_bands`** *(list of str)*: List of band name identifiers (e.g., `["B4", "B3", "B2"]`).
- **`output_path`** *(str or Path, optional)*: Path to save the stacked raster. Defaults to `"stacked.tif"` in the input folder.
- **`resolution`** *(float, optional)*: Target resolution for resampling. Defaults to the highest available resolution.
### Returns
- *(str)*: The path to the saved stacked output raster.
### Example
```python
from stacking import stack_bands
stacked_image = stack_bands("/path/to/folder/containing/bands", ["B4", "B3", "B2"])
```
## Contributing
1. **Fork the repository**
Click the "Fork" button at the top-right of this repository to create your copy.
2. **Create your feature branch**
```bash
git checkout -b feature/your-feature
3. **Commit changes**
```bash
git commit -am 'Add some feature'
4. **Push to branch**
```bash
git push origin feature/your-feature
5. **Open a Pull Request**
Navigate to the Pull Requests tab in the original repository and click "New Pull Request" to submit your changes.
## License
This project is licensed under the MIT License. See LICENSE for more information.
## Author
Liang Zhongyou – [GitHub Profile](https://github.com/zyl009)
Matteo Gobbi Frattini – [GitHub Profile](https://github.com/MatteoGobbiF)
Raw data
{
"_id": null,
"home_page": "https://github.com/MatteoGF/GeoPre",
"name": "geopre",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "preprocessing satellite imagery",
"author": "Matteo Gobbi Frattini, Liang Zhongyou",
"author_email": "matteo.gf@live.it",
"download_url": "https://files.pythonhosted.org/packages/62/0b/c8038db6b21a8fbbb1279988284c598878e96e50be2317db7843d98b80e1/geopre-0.1.0.tar.gz",
"platform": null,
"description": "# GeoPre: Geospatial Data Processing Toolkit \r\n**GeoPre** is a Python library designed to streamline common geospatial data operations, offering a unified interface for handling raster and vector datasets. It simplifies preprocessing tasks essential for GIS analysis, machine learning workflows, and remote sensing applications.\r\n\r\n\r\n### Key Features \r\n- **Data Scaling**: \r\n - Normalization (Z-Score) and Min-Max scaling for raster bands. \r\n - Prepares data for ML models while preserving geospatial metadata. \r\n\r\n- **CRS Management**: \r\n - Retrieve and compare Coordinate Reference Systems (CRS) across raster (Rasterio/Xarray) and vector (GeoPandas) datasets. \r\n - Ensure consistency between datasets with automated CRS checks. \r\n\r\n- **Reprojection**: \r\n - Reproject vector data (GeoDataFrames) and raster data (Rasterio/Xarray) to any target CRS. \r\n - Supports EPSG codes, WKT, and Proj4 strings. \r\n\r\n- **No-Data Masking**: \r\n - Handle missing values in raster datasets (NumPy/Xarray) with flexible masking. \r\n - Integrates seamlessly with raster metadata for error-free workflows. \r\n\r\n- **Cloud Masking**: \r\n - Identify and mask clouds in Sentinel-2 and Landsat imagery. \r\n - Supports multiple methods: QA bands, scene classification layers (SCL), probability bands, and OmniCloudMask AI-based detection. \r\n - Optionally mask cloud shadows for improved accuracy. \r\n\r\n- **Band Stacking**: \r\n - Stack multiple raster bands from a folder into a single multi-band raster for analysis. \r\n - Supports automatic band detection and resampling for different resolutions. \r\n\r\n\r\n### Supported Data Types \r\n- **Raster**: NumPy arrays, Rasterio `DatasetReader`, Xarray `DataArray` (via rioxarray). \r\n- **Vector**: GeoPandas `GeoDataFrame`. \r\n\r\n\r\n### Benefits of GeoPre \r\n- **Unified Workflow**: Eliminates boilerplate code by providing consistent functions for raster and vector data. \r\n- **Interoperability**: Bridges gaps between GeoPandas, Rasterio, and Xarray, ensuring smooth data transitions. \r\n- **Robust Error Handling**: Automatically detects CRS mismatches and missing metadata to prevent silent failures. \r\n- **Efficiency**: Optimized reprojection and masking operations reduce preprocessing time for large datasets. \r\n- **ML-Ready Outputs**: Scaling functions preserve data structure, making outputs directly usable in machine learning pipelines. \r\n\r\n\r\nIdeal for researchers and developers working with geospatial data, **GeoPre** enhances productivity by standardizing preprocessing steps and ensuring compatibility across diverse geospatial tools.\r\n\r\n\r\n## Installation\r\nEnsure you have the required dependencies installed before using this library:\r\n```bash\r\npip install numpy geopandas rasterio rioxarray xarray pyproj\r\n```\r\n\r\n## Usage\r\n### 1. Data Scaling\r\n#### `Z-Score Scaling`\r\n**Description**:This method centers the data around zero by subtracting the mean and dividing by the standard deviation, which is useful for machine learning models sensitive to outliers \r\nand can standardize a band of pixel values for clustering/classification.\r\n\r\n**Parameters**:\r\n- data (numpy.ndarray): Input array to normalize.\r\n \r\n**Returns**:\r\n- numpy.ndarray: Standardized data with mean 0 and standard deviation 1.\r\n\r\n#### `Min_Max_Scaling`\r\n**Description**: This method scales the pixel values to a fixed range, typically [0, 1] or [-1, 1]. Ideal when you want to preserve the relative range of values. \r\nFor GeoTIFF image values (e.g., 0 to 65535), scale them to [0, 1].\r\n\r\n**Parameters**:\r\n- data (numpy.ndarray): Input array to normalize.\r\n\r\n**Returns**:\r\n- numpy.ndarray: Scaled data with values between 0 and 1, or -1 and 1.\r\n \r\n#### Example:\r\n```python\r\nimport numpy as np\r\nfrom scaling_and_reproject import Z_score_scaling, Min_Max_Scaling\r\n\r\ndata = np.array([[10, 20, 30], [40, 50, 60]])\r\nz_scaled = Z_score_scaling(data)\r\nminmax_scaled = Min_Max_Scaling(data)\r\n```\r\n\r\n### 2. CRS Management\r\n\r\n#### `get_crs`\r\n**Description**: Retrieve CRS from geospatial data objects.\r\n\r\n**Parameters**:\r\n- data: GeoPandas GeoDataFrames (vector), Rasterio DatasetReaders (raster) or Xarray DataArrays with rio accessor (raster)\r\n\r\n**Returns**:\r\n- pyproj.CRS: Coordinate reference system or None if undefined\r\n\r\n#### `compare_crs`\r\n**Description**: Compare CRS between raster and vector datasets.\r\n\r\n**Parameters**:\r\n- raster_obj (DatasetReader/xarray.DataArray): Raster data source.\r\n- vector_gdf (gpd.GeoDataFrame): Vector data source.\r\n \r\n**Returns**:\r\n\r\n**dict**: Comparison results with keys:\r\n- raster_crs: Formatted CRS string\r\n- vector_crs: Formatted CRS string \r\n- same_crs: Boolean comparison result\r\n- error: Exception message if any\r\n\r\n#### Example:\r\n```python\r\nimport geopandas as gpd\r\nimport rasterio\r\nfrom scaling_and_reproject import get_crs, compare_crs\r\n\r\nvector = gpd.read_file(\"data.shp\")\r\nraster = rasterio.open(\"image.tif\")\r\n\r\nprint(get_crs(vector)) # EPSG:4326\r\nprint(compare_crs(raster, vector)) # CRS comparison results\r\n```\r\n\r\n### 3. Reprojection\r\n#### `reproject_data`\r\n**Description**: Reproject geospatial data to target CRS.\r\n\r\n**Parameters**:\r\n- data: GeoDataFrames (vector reprojection), or Rasterio datasets (returns array + metadata), or Xarray objects (rioxarray reprojection) \r\n- target_crs: CRS to reproject to (EPSG code/WKT/proj4 string)\r\n\r\n**Returns**:\r\n- Reprojected data in format matching input type\r\n\r\n#### Example:\r\n```python\r\nimport rasterio\r\nimport xarray as xr\r\nfrom scaling_and_reproject import reproject_data\r\n\r\n# Vector reprojection\r\nreprojected_vector = reproject_data(vector, \"EPSG:3857\")\r\n\r\n# Raster reprojection (Rasterio)\r\nwith rasterio.open(\"input.tif\") as src:\r\n array, metadata = reproject_data(src, \"EPSG:32633\")\r\n\r\n# Xarray reprojection\r\nda = xr.open_rasterio(\"image.tif\")\r\nreprojected_da = reproject_data(da, \"EPSG:4326\")\r\n```\r\n\r\n### 4. No-Data Masking\r\n#### `mask_raster_data`\r\n**Description**: Mask no-data values in raster datasets. Handles both rasterio (numpy) and rioxarray (xarray) workflows.\r\n\r\n**Parameters**:\r\n- data: Raster data (numpy.ndarray or xarray.DataArray)\r\n- profile: Rasterio metadata dict (required for numpy arrays)\r\n- no_data_value: Override for metadata's nodata value\r\n- return_mask: Whether to return boolean mask\r\n\r\n**Returns**:\r\n- Masked data array. For numpy inputs, returns tuple:(masked_array, profile). For xarray, returns DataArray.\r\n\r\n#### Example:\r\n```python\r\nimport xarray as xr\r\nimport rasterio\r\nfrom scaling_and_reproject import mask_raster_data\r\n\r\n# Rasterio workflow\r\nwith rasterio.open(\"data.tif\") as src:\r\n data = src.read(1)\r\n masked, profile = mask_raster_data(data, src.profile)\r\n\r\n# rioxarray workflow\r\nda = xr.open_rasterio(\"data.tif\")\r\nmasked_da = mask_raster_data(da)\r\n```\r\n\r\n### 5. Cloud Masking\r\n#### `mask_clouds_S2`\r\n**Description**: Masks clouds and optionally shadows in a Sentinel-2 raster image using various methods.\r\n\r\n**Parameters**:\r\n- `image_path` *(str)*: Path to the input raster image.\r\n- `output_path` *(str, optional)*: Path to save the masked output raster. Defaults to the same directory as the input with '_masked' appended to the filename.\r\n- `method` *(str, optional)*: The method for masking. Options are:\r\n - `'auto'`: Automatically chooses the best available method.\r\n - `'qa'`: Uses the QA60 band to mask clouds. WARNING: QA60 is deprecated after 2022-01-25, results for images after that date could be wrong\r\n - `'probability'`: Uses the cloud probability band MSK_CLDPRB with a threshold for masking.\r\n - `'omnicloudmask'`: Utilizes OmniCloudMask for AI-based cloud detection. Might take a long time for big images\r\n - `'scl'`: Leverages the Scene Classification Layer (SCL) for masking.\r\n - `'standard'`: Similar to 'auto', but avoids the OmniCloudMask method.\r\n- `mask_shadows` *(bool)*: Whether to mask cloud shadows. Defaults to `False`.\r\n- `threshold` *(int, optional)*: Cloud probability threshold (if using a cloud probability band), from 0 to 100. Defaults to `20`.\r\n- `qa60_idx` *(int, optional)*: Index of the QA60 band (1-based). Auto-detected if not provided.\r\n- `qa60_path` *(str, optional)*: Path to the QA60 band (if in a separate file).\r\n- `prob_band_idx` *(int, optional)*: Index of the cloud probability band (1-based). Auto-detected if not provided.\r\n- `prob_band_path` *(str, optional)*: Path to the cloud probability band (if in a separate file).\r\n- `scl_idx` *(int, optional)*: Index of the SCL band (1-based). Auto-detected if not provided.\r\n- `scl_path` *(str, optional)*: Path to the SCL band (if in a separate file).\r\n- `red_idx`, `green_idx`, `nir_idx` *(int, optional)*: Indices of the red, green, and NIR bands, respectively. Auto-detected if not provided.\r\n- `nodata_value` *(float)*: Value for no-data regions. Defaults to `np.nan`.\r\n\r\n**Returns**:\r\n- *(str)*: The path to the saved masked output raster.\r\n\r\n#### Example:\r\n```python\r\nfrom cloud_masking import mask_clouds_S2\r\n\r\noutput_s2 = mask_clouds_S2(\"sentinel2_image.tif\", method='auto', mask_shadows=True)\r\n```\r\n\r\n#### `mask_clouds_landsat`\r\n\r\n**Description**: \r\nMasks clouds and optionally shadows in a Landsat raster image using various methods.\r\n\r\n**Parameters**:\r\n\r\n- **`image_path`** *(str)*: Path to the input multi-band raster image. \r\n- **`output_path`** *(str, optional)*: Path to save the masked output raster. Defaults to the same directory as the input with `_masked` suffix. \r\n- **`method`** *(str)*: The method for masking. Options are: \r\n - **`'auto'`**: Automatically chooses the best available method. \r\n - **`'qa'`**: Uses the QA_PIXEL band to mask clouds. \r\n - **`'omnicloudmask'`**: Utilizes OmniCloudMask for AI-based cloud detection. \r\n- **`mask_shadows`** *(bool)*: Whether to mask cloud shadows. Defaults to `False`. \r\n- **`qa_pixel_path`** *(str, optional)*: Path to the separate QA_PIXEL raster file. \r\n- **`qa_pixel_idx`** *(int, optional)*: Index of the QA_PIXEL band (1-based). \r\n- **`confidence_threshold`** *(str, optional)*: Confidence threshold for cloud masking (e.g., `'Low'`, `'Medium'`, `'High'`). Defaults to `'High'`. WARNING: as per the Landsat official documentation, the confidence bands are still under development, always use the default 'High' untill further notice. [Source](https://d9-wret.s3.us-west-2.amazonaws.com/assets/palladium/production/s3fs-public/media/files/LSDS-1619_Landsat8-9-Collection2-Level2-Science-Product-Guide-v6.pdf)\r\n- **`red_idx`**, **`green_idx`**, **`nir_idx`** *(int, optional)*: Indices of the red, green, and NIR bands, respectively. Auto-detected if not provided. \r\n- **`nodata_value`** *(float)*: Value for no-data regions. Defaults to `np.nan`. \r\n\r\n### Returns\r\n\r\n- *(str)*: The path to the saved masked output raster. \r\n\r\n### Example\r\n\r\n```python\r\nfrom cloud_masking import mask_clouds_landsat\r\n\r\noutput_landsat = mask_clouds_landsat(\"landsat_image.tif\", method='auto', mask_shadows=True)\r\n```\r\n\r\n## 6. Band Stacking\r\n\r\n### `stack_bands`\r\n\r\n**Description**: \r\nStacks multiple raster bands from a folder into a single multi-band raster. Support also .SAFE folders.\r\n\r\n### Parameters\r\n\r\n- **`input_path`** *(str or Path)*: Path to the folder containing band files. \r\n- **`required_bands`** *(list of str)*: List of band name identifiers (e.g., `[\"B4\", \"B3\", \"B2\"]`). \r\n- **`output_path`** *(str or Path, optional)*: Path to save the stacked raster. Defaults to `\"stacked.tif\"` in the input folder. \r\n- **`resolution`** *(float, optional)*: Target resolution for resampling. Defaults to the highest available resolution. \r\n\r\n### Returns\r\n\r\n- *(str)*: The path to the saved stacked output raster. \r\n\r\n### Example\r\n\r\n```python\r\nfrom stacking import stack_bands\r\n\r\nstacked_image = stack_bands(\"/path/to/folder/containing/bands\", [\"B4\", \"B3\", \"B2\"])\r\n```\r\n\r\n\r\n## Contributing\r\n\r\n1. **Fork the repository** \r\n \r\n Click the \"Fork\" button at the top-right of this repository to create your copy.\r\n \r\n2. **Create your feature branch** \r\n ```bash\r\n git checkout -b feature/your-feature\r\n \r\n3. **Commit changes** \r\n ```bash\r\n git commit -am 'Add some feature'\r\n \r\n4. **Push to branch** \r\n ```bash\r\n git push origin feature/your-feature\r\n\r\n5. **Open a Pull Request**\r\n \r\n Navigate to the Pull Requests tab in the original repository and click \"New Pull Request\" to submit your changes.\r\n\r\n \r\n## License\r\nThis project is licensed under the MIT License. See LICENSE for more information.\r\n\r\n\r\n## Author\r\nLiang Zhongyou \u00e2\u20ac\u201c [GitHub Profile](https://github.com/zyl009)\r\n\r\nMatteo Gobbi Frattini \u00e2\u20ac\u201c [GitHub Profile](https://github.com/MatteoGobbiF)\r\n",
"bugtrack_url": null,
"license": "MIT",
"summary": null,
"version": "0.1.0",
"project_urls": {
"Homepage": "https://github.com/MatteoGF/GeoPre"
},
"split_keywords": [
"preprocessing",
"satellite",
"imagery"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "55bd310b81a2b226f4e51c457eee00969de916ae7c95226e7460861bd14d79b9",
"md5": "0a678ceb34b140d8a7359741bee09280",
"sha256": "013f30dc943236d3440f98a8038a2b9f42ae57476714f4aa6a7aeeea103b1f5d"
},
"downloads": -1,
"filename": "geopre-0.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "0a678ceb34b140d8a7359741bee09280",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 16665,
"upload_time": "2025-02-02T21:23:49",
"upload_time_iso_8601": "2025-02-02T21:23:49.946182Z",
"url": "https://files.pythonhosted.org/packages/55/bd/310b81a2b226f4e51c457eee00969de916ae7c95226e7460861bd14d79b9/geopre-0.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "620bc8038db6b21a8fbbb1279988284c598878e96e50be2317db7843d98b80e1",
"md5": "f13eb7c1c08acf4dea83bde1600c1669",
"sha256": "e4d2d47f6534088d494c678d616f53f1dbab6cecbd86cb9eb4d2dd7b7e195cbd"
},
"downloads": -1,
"filename": "geopre-0.1.0.tar.gz",
"has_sig": false,
"md5_digest": "f13eb7c1c08acf4dea83bde1600c1669",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 21352,
"upload_time": "2025-02-02T21:23:52",
"upload_time_iso_8601": "2025-02-02T21:23:52.064955Z",
"url": "https://files.pythonhosted.org/packages/62/0b/c8038db6b21a8fbbb1279988284c598878e96e50be2317db7843d98b80e1/geopre-0.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-02-02 21:23:52",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "MatteoGF",
"github_project": "GeoPre",
"github_not_found": true,
"lcname": "geopre"
}