PyGeoFetch 0.1.0__tar.gz → 1.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pygeofetch-0.1.0 → pygeofetch-1.0.1}/LICENSE +1 -1
- pygeofetch-1.0.1/PKG-INFO +588 -0
- pygeofetch-1.0.1/PyGeoFetch.egg-info/PKG-INFO +588 -0
- pygeofetch-1.0.1/PyGeoFetch.egg-info/SOURCES.txt +77 -0
- pygeofetch-1.0.1/PyGeoFetch.egg-info/entry_points.txt +2 -0
- {pygeofetch-0.1.0 → pygeofetch-1.0.1}/PyGeoFetch.egg-info/requires.txt +13 -9
- pygeofetch-1.0.1/PyGeoFetch.egg-info/top_level.txt +1 -0
- pygeofetch-1.0.1/README.md +503 -0
- pygeofetch-1.0.1/pygeofetch/__init__.py +39 -0
- pygeofetch-1.0.1/pygeofetch/cli/__init__.py +1 -0
- pygeofetch-1.0.1/pygeofetch/cli/auth_commands.py +256 -0
- pygeofetch-1.0.1/pygeofetch/cli/config_commands.py +143 -0
- pygeofetch-1.0.1/pygeofetch/cli/download_commands.py +279 -0
- pygeofetch-1.0.1/pygeofetch/cli/index_commands.py +219 -0
- pygeofetch-1.0.1/pygeofetch/cli/main.py +780 -0
- pygeofetch-1.0.1/pygeofetch/cli/pipeline_process_commands.py +150 -0
- pygeofetch-1.0.1/pygeofetch/cli/postprocess_commands.py +132 -0
- pygeofetch-1.0.1/pygeofetch/cli/preprocess_commands.py +185 -0
- pygeofetch-1.0.1/pygeofetch/cli/sar_commands.py +80 -0
- pygeofetch-1.0.1/pygeofetch/cli/search_commands.py +249 -0
- pygeofetch-1.0.1/pygeofetch/config/__init__.py +11 -0
- pygeofetch-1.0.1/pygeofetch/config/defaults.yaml +86 -0
- pygeofetch-1.0.1/pygeofetch/config/settings.py +235 -0
- pygeofetch-1.0.1/pygeofetch/core/__init__.py +18 -0
- pygeofetch-1.0.1/pygeofetch/core/authenticator.py +432 -0
- pygeofetch-1.0.1/pygeofetch/core/cache_manager.py +288 -0
- pygeofetch-1.0.1/pygeofetch/core/downloader.py +354 -0
- pygeofetch-1.0.1/pygeofetch/core/engine.py +336 -0
- pygeofetch-1.0.1/pygeofetch/core/scheduler.py +473 -0
- pygeofetch-1.0.1/pygeofetch/core/searcher.py +341 -0
- pygeofetch-1.0.1/pygeofetch/models/__init__.py +44 -0
- pygeofetch-1.0.1/pygeofetch/models/download_task.py +283 -0
- pygeofetch-1.0.1/pygeofetch/models/satellite_data.py +402 -0
- pygeofetch-1.0.1/pygeofetch/models/search_query.py +329 -0
- pygeofetch-1.0.1/pygeofetch/models/user_auth.py +123 -0
- pygeofetch-1.0.1/pygeofetch/processing/__init__.py +15 -0
- pygeofetch-1.0.1/pygeofetch/processing/base.py +102 -0
- pygeofetch-1.0.1/pygeofetch/processing/batch.py +164 -0
- pygeofetch-1.0.1/pygeofetch/processing/indices.py +777 -0
- pygeofetch-1.0.1/pygeofetch/processing/pipeline.py +328 -0
- pygeofetch-1.0.1/pygeofetch/processing/postprocessor.py +567 -0
- pygeofetch-1.0.1/pygeofetch/processing/preprocessor.py +989 -0
- pygeofetch-1.0.1/pygeofetch/processing/sar.py +315 -0
- pygeofetch-1.0.1/pygeofetch/providers/__init__.py +192 -0
- pygeofetch-1.0.1/pygeofetch/providers/airbus_oneatlas.py +150 -0
- pygeofetch-1.0.1/pygeofetch/providers/alaska_satellite_facility.py +150 -0
- pygeofetch-1.0.1/pygeofetch/providers/aws_earth.py +267 -0
- pygeofetch-1.0.1/pygeofetch/providers/base.py +306 -0
- pygeofetch-1.0.1/pygeofetch/providers/copernicus.py +487 -0
- pygeofetch-1.0.1/pygeofetch/providers/digitalglobe.py +150 -0
- pygeofetch-1.0.1/pygeofetch/providers/earth_explorer_additional.py +150 -0
- pygeofetch-1.0.1/pygeofetch/providers/element84.py +230 -0
- pygeofetch-1.0.1/pygeofetch/providers/esa_scihub.py +150 -0
- pygeofetch-1.0.1/pygeofetch/providers/geoserver_generic.py +150 -0
- pygeofetch-1.0.1/pygeofetch/providers/google_earth_engine.py +150 -0
- pygeofetch-1.0.1/pygeofetch/providers/inpe_cbers.py +150 -0
- pygeofetch-1.0.1/pygeofetch/providers/isro_bhuvan.py +150 -0
- pygeofetch-1.0.1/pygeofetch/providers/jaxa_earth.py +150 -0
- pygeofetch-1.0.1/pygeofetch/providers/maxar_gbdx.py +150 -0
- pygeofetch-1.0.1/pygeofetch/providers/nasa_earthdata.py +160 -0
- pygeofetch-1.0.1/pygeofetch/providers/nasa_earthdata_cloud.py +345 -0
- pygeofetch-1.0.1/pygeofetch/providers/noaa_big_data.py +150 -0
- pygeofetch-1.0.1/pygeofetch/providers/opentopography.py +108 -0
- pygeofetch-1.0.1/pygeofetch/providers/planet.py +369 -0
- pygeofetch-1.0.1/pygeofetch/providers/planetary_computer.py +295 -0
- pygeofetch-1.0.1/pygeofetch/providers/sentinel_hub.py +173 -0
- pygeofetch-1.0.1/pygeofetch/providers/terrabotics.py +278 -0
- pygeofetch-1.0.1/pygeofetch/providers/usgs.py +454 -0
- pygeofetch-1.0.1/pygeofetch/utils/__init__.py +50 -0
- pygeofetch-1.0.1/pygeofetch/utils/file_utils.py +275 -0
- pygeofetch-1.0.1/pygeofetch/utils/geo_utils.py +241 -0
- pygeofetch-1.0.1/pygeofetch/utils/logging_setup.py +107 -0
- pygeofetch-1.0.1/pygeofetch/utils/retry_handler.py +225 -0
- pygeofetch-1.0.1/pygeofetch/utils/validators.py +155 -0
- {pygeofetch-0.1.0 → pygeofetch-1.0.1}/pyproject.toml +24 -28
- pygeofetch-0.1.0/PKG-INFO +0 -720
- pygeofetch-0.1.0/PyGeoFetch.egg-info/PKG-INFO +0 -720
- pygeofetch-0.1.0/PyGeoFetch.egg-info/SOURCES.txt +0 -11
- pygeofetch-0.1.0/PyGeoFetch.egg-info/entry_points.txt +0 -2
- pygeofetch-0.1.0/PyGeoFetch.egg-info/top_level.txt +0 -1
- pygeofetch-0.1.0/README.md +0 -637
- {pygeofetch-0.1.0 → pygeofetch-1.0.1}/PyGeoFetch.egg-info/dependency_links.txt +0 -0
- {pygeofetch-0.1.0 → pygeofetch-1.0.1}/PyGeoFetch.egg-info/not-zip-safe +0 -0
- {pygeofetch-0.1.0 → pygeofetch-1.0.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2024
|
|
3
|
+
Copyright (c) 2024 SatelliteBridge Contributors
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -0,0 +1,588 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: PyGeoFetch
|
|
3
|
+
Version: 1.0.1
|
|
4
|
+
Summary: Universal satellite data pipeline — unified access to 22+ providers
|
|
5
|
+
Author: PyGeoFetch Contributors
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2024 SatelliteBridge Contributors
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Project-URL: Homepage, https://github.com/pygeofetch/PyGeoFetch
|
|
29
|
+
Project-URL: Documentation, https://pygeofetch.readthedocs.io
|
|
30
|
+
Project-URL: Repository, https://github.com/pygeofetch/PyGeoFetch
|
|
31
|
+
Project-URL: Bug Tracker, https://github.com/pygeofetch/PyGeoFetch/issues
|
|
32
|
+
Keywords: satellite,remote-sensing,GIS,earth-observation,geospatial
|
|
33
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
34
|
+
Classifier: Intended Audience :: Science/Research
|
|
35
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
36
|
+
Classifier: Programming Language :: Python :: 3
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
41
|
+
Classifier: Topic :: Scientific/Engineering :: GIS
|
|
42
|
+
Requires-Python: >=3.9
|
|
43
|
+
Description-Content-Type: text/markdown
|
|
44
|
+
License-File: LICENSE
|
|
45
|
+
Requires-Dist: httpx>=0.27
|
|
46
|
+
Requires-Dist: click>=8.1
|
|
47
|
+
Requires-Dist: pydantic>=2.5
|
|
48
|
+
Requires-Dist: pydantic-settings>=2.1
|
|
49
|
+
Requires-Dist: rich>=13.7
|
|
50
|
+
Requires-Dist: PyYAML>=6.0
|
|
51
|
+
Requires-Dist: cryptography>=42.0
|
|
52
|
+
Requires-Dist: keyring>=24.3
|
|
53
|
+
Requires-Dist: aiofiles>=23.2
|
|
54
|
+
Requires-Dist: tenacity>=8.2
|
|
55
|
+
Requires-Dist: python-dateutil>=2.9
|
|
56
|
+
Requires-Dist: tqdm>=4.66
|
|
57
|
+
Requires-Dist: requests>=2.31
|
|
58
|
+
Requires-Dist: anyio>=4.2
|
|
59
|
+
Requires-Dist: boto3>=1.34
|
|
60
|
+
Requires-Dist: click-completion>=0.5
|
|
61
|
+
Provides-Extra: geo
|
|
62
|
+
Requires-Dist: rasterio>=1.3; extra == "geo"
|
|
63
|
+
Requires-Dist: geopandas>=0.14; extra == "geo"
|
|
64
|
+
Requires-Dist: pyarrow>=15.0; extra == "geo"
|
|
65
|
+
Requires-Dist: shapely>=2.0; extra == "geo"
|
|
66
|
+
Requires-Dist: pyproj>=3.6; extra == "geo"
|
|
67
|
+
Provides-Extra: cloud
|
|
68
|
+
Requires-Dist: boto3>=1.34; extra == "cloud"
|
|
69
|
+
Requires-Dist: pystac>=1.9; extra == "cloud"
|
|
70
|
+
Provides-Extra: schedule
|
|
71
|
+
Requires-Dist: croniter>=2.0; extra == "schedule"
|
|
72
|
+
Provides-Extra: dev
|
|
73
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
74
|
+
Requires-Dist: pytest-cov>=4.1; extra == "dev"
|
|
75
|
+
Requires-Dist: pytest-mock>=3.12; extra == "dev"
|
|
76
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
|
|
77
|
+
Requires-Dist: vcrpy>=6.0; extra == "dev"
|
|
78
|
+
Requires-Dist: black>=24.0; extra == "dev"
|
|
79
|
+
Requires-Dist: ruff>=0.3; extra == "dev"
|
|
80
|
+
Requires-Dist: mypy>=1.8; extra == "dev"
|
|
81
|
+
Requires-Dist: bump2version>=1.0; extra == "dev"
|
|
82
|
+
Provides-Extra: all
|
|
83
|
+
Requires-Dist: PyGeoFetch[cloud,dev,geo,schedule]; extra == "all"
|
|
84
|
+
Dynamic: license-file
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
<div align="center">
|
|
88
|
+
|
|
89
|
+
<!-- <img src="https://appiahkubis14.github.io/portfolio/logo/samuel_logo_dark.svg" alt="PyGeoFetch Logo" width="200"/> -->
|
|
90
|
+
|
|
91
|
+
# PyGeoFetch 🛰️
|
|
92
|
+
|
|
93
|
+
[](https://pypi.org/project/pygeofetch/)
|
|
94
|
+
[](https://pypi.org/project/pygeofetch/)
|
|
95
|
+
[](https://opensource.org/licenses/MIT)
|
|
96
|
+
[](https://github.com/appiahkubis14/pygeofetch/actions)
|
|
97
|
+
[](https://codecov.io/gh/appiahkubis14/pygeofetch)
|
|
98
|
+
|
|
99
|
+
**Universal satellite data pipeline + geospatial processing platform — unified access to 22+ satellite repositories, 17 spectral indices, full SAR processing, and chainable YAML pipelines. One CLI, one Python API.**
|
|
100
|
+
|
|
101
|
+
</div>
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## 📖 Introduction
|
|
106
|
+
|
|
107
|
+
PyGeoFetch is a **production-ready satellite data acquisition and processing framework** that provides unified, authenticated access to 22+ Earth observation repositories — including Sentinel, Landsat, Planet, Maxar, Airbus, Copernicus, USGS, NASA, JAXA, and more — through a single consistent CLI and Python API.
|
|
108
|
+
|
|
109
|
+
The package abstracts away the authentication complexity, API fragmentation, and format inconsistencies of individual satellite providers, and adds a complete geospatial processing engine on top. PyGeoFetch provides six core capabilities:
|
|
110
|
+
|
|
111
|
+
1. **Authenticated access** to 22+ providers, with secure credential storage via system keyring (macOS Keychain, Windows Credential Manager, Linux Secret Service).
|
|
112
|
+
2. **Unified federated search** across all providers, returning standardized STAC 1.0 GeoJSON, GeoParquet, or CSV results sortable by cloud cover, date, or relevance score.
|
|
113
|
+
3. **Resilient parallel downloads** with band selection, checksum verification, resume support, exponential backoff, and atomic writes.
|
|
114
|
+
4. **Preprocessing engine** — atmospheric correction, cloud masking, reprojection, resampling, pan-sharpening, mosaicking, and compositing.
|
|
115
|
+
5. **17 spectral indices** — NDVI, EVI, SAVI, NDWI, MNDWI, NDBI, TCT, PCA, LST, Albedo, dNBR, GLCM texture, and more.
|
|
116
|
+
6. **YAML pipeline orchestration** with cron scheduling, batch processing, and full execution history — enabling repeatable, automated geospatial workflows.
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## 📝 Statement of Need
|
|
121
|
+
|
|
122
|
+
Accessing satellite data at scale is surprisingly fragmented. Each provider — USGS, Copernicus, Planet, Maxar, NASA — exposes a different authentication scheme, a different query API, a different download protocol, and a different file format. Researchers and engineers working across multiple providers must maintain a patchwork of custom scripts, scattered credentials, and ad hoc download logic, making workflows difficult to reproduce and brittle to maintain.
|
|
123
|
+
|
|
124
|
+
Existing tools address parts of this problem: EODAG supports several providers but lacks pipeline orchestration and commercial coverage; `pystac-client` handles STAC-compliant endpoints only; `sentinelsat` is Sentinel-specific. No single tool covers the full breadth of providers, processing, and automation needed for operational geospatial workflows.
|
|
125
|
+
|
|
126
|
+
| Feature | PyGeoFetch | EODAG | pystac-client | satpy | sentinelsat |
|
|
127
|
+
|---|---|---|---|---|---|
|
|
128
|
+
| **Providers** | **22+** | 10+ | STAC only | Limited | Sentinel only |
|
|
129
|
+
| **Processing Engine** | ✅ Full | ❌ | ❌ | Partial | ❌ |
|
|
130
|
+
| **Spectral Indices** | ✅ 17+ | ❌ | ❌ | ❌ | ❌ |
|
|
131
|
+
| **SAR Processing** | ✅ | ❌ | ❌ | ✅ | ❌ |
|
|
132
|
+
| **YAML Pipelines** | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
133
|
+
| **Auth Management** | ✅ Keyring | Partial | ❌ | ❌ | ✅ |
|
|
134
|
+
| **STAC 1.0 Output** | ✅ Native | ❌ | ✅ | ❌ | ❌ |
|
|
135
|
+
| **Cron Scheduling** | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
136
|
+
| **Commercial Providers** | ✅ Planet/Maxar | ❌ | ❌ | ❌ | ❌ |
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## 🚀 Key Features
|
|
141
|
+
|
|
142
|
+
### 🛰️ 22+ Satellite Providers
|
|
143
|
+
|
|
144
|
+
**Open access — no login required (10):**
|
|
145
|
+
|
|
146
|
+
| Provider ID | Satellites | Capabilities |
|
|
147
|
+
|---|---|---|
|
|
148
|
+
| `planetary_computer` | Sentinel-1/2, Landsat 8/9, MODIS, NAIP, ALOS DEM | STAC, SAR |
|
|
149
|
+
| `aws_earth` | Sentinel-2 COG, Landsat C2, NAIP | STAC |
|
|
150
|
+
| `element84` | Sentinel-2 L2A, Landsat C2, Sentinel-1 RTC, COP-DEM | STAC, SAR |
|
|
151
|
+
| `noaa_big_data` | GOES-16/17/18, NEXRAD radar | Weather |
|
|
152
|
+
| `esa_scihub` | Sentinel-1/2/3/5P (public mirrors) | SAR |
|
|
153
|
+
| `jaxa_earth` | ALOS 30m DSM, PALSAR-2 | SAR |
|
|
154
|
+
| `isro_bhuvan` | ResourceSat-2/2A (5.8m), Cartosat-1 (2.5m) | — |
|
|
155
|
+
| `inpe_cbers` | CBERS-4, CBERS-4A | — |
|
|
156
|
+
| `digitalglobe` | WorldView open disaster response | <1m VHR |
|
|
157
|
+
| `geoserver_generic` | Any OGC WMS/WFS/WCS endpoint | Generic |
|
|
158
|
+
|
|
159
|
+
**Authenticated providers (12):** USGS · Copernicus CDSE · NASA Earthdata · NASA Earthdata Cloud · Alaska SAR Facility · OpenTopography · Planet Labs · Sentinel Hub · Maxar GBDX · Airbus OneAtlas · Google Earth Engine · TerraBotics
|
|
160
|
+
|
|
161
|
+
### 🔍 Unified Search
|
|
162
|
+
- Federated query across multiple providers simultaneously with deduplicated results
|
|
163
|
+
- Filter by bbox, geometry file, date range, cloud cover, resolution, processing level, and CQL2 expressions
|
|
164
|
+
- 7 output formats: `table` · `json` · `stac` · `geojson` · `geoparquet` · `csv` · `ids`
|
|
165
|
+
|
|
166
|
+
### 📥 Resilient Downloads
|
|
167
|
+
- Adaptive parallel downloads with configurable concurrency and real-time progress
|
|
168
|
+
- Band selection (e.g. `B02,B03,B04` → download 150 MB instead of 600 MB full scene)
|
|
169
|
+
- SHA256 checksum verification, resume support, exponential-backoff retries
|
|
170
|
+
- Atomic writes — no partial files ever written to disk
|
|
171
|
+
|
|
172
|
+
### ⚙️ Preprocessing Engine (`client.preprocess`)
|
|
173
|
+
|
|
174
|
+
| Method | Description |
|
|
175
|
+
|---|---|
|
|
176
|
+
| `atmos()` | Atmospheric correction: DOS1, DOS2, Sen2Cor, FLAASH, 6S, iCOR |
|
|
177
|
+
| `cloud_mask()` | Cloud masking: SCL, FMask, threshold, NDSI |
|
|
178
|
+
| `cloud_fill()` | Fill cloud gaps from time-series |
|
|
179
|
+
| `topo_correct()` | Topographic correction: cosine, Minnaert, C-correction |
|
|
180
|
+
| `clip()` | Clip to bounding box or GeoJSON polygon |
|
|
181
|
+
| `reproject()` | Reproject to any CRS (EPSG:4326, UTM, etc.) |
|
|
182
|
+
| `resample()` | Change resolution: nearest, bilinear, cubic, lanczos |
|
|
183
|
+
| `pansharpen()` | Pan-sharpening: Brovey, IHS, Gram-Schmidt |
|
|
184
|
+
| `tile()` | Split into overlapping tiles for AI inference |
|
|
185
|
+
| `mosaic()` | Merge scenes: first, last, min, max |
|
|
186
|
+
| `composite()` | Multi-temporal: median, mean, max, best-pixel |
|
|
187
|
+
|
|
188
|
+
### 📊 Spectral Indices (`client.indices`)
|
|
189
|
+
|
|
190
|
+
| Index | Formula | Use Case |
|
|
191
|
+
|---|---|---|
|
|
192
|
+
| `ndvi` | (NIR−Red)/(NIR+Red) | Vegetation health |
|
|
193
|
+
| `evi` | G·(NIR−Red)/(NIR+C1·Red−C2·Blue+L) | Dense canopy |
|
|
194
|
+
| `savi` | (NIR−Red)/(NIR+Red+L)·(1+L) | Sparse vegetation |
|
|
195
|
+
| `ndwi` | (Green−NIR)/(Green+NIR) | Water bodies |
|
|
196
|
+
| `mndwi` | (Green−SWIR1)/(Green+SWIR1) | Urban water |
|
|
197
|
+
| `ndbi` | (SWIR1−NIR)/(SWIR1+NIR) | Built-up areas |
|
|
198
|
+
| `ndsi` | (Green−SWIR1)/(Green+SWIR1) | Snow / ice |
|
|
199
|
+
| `ndmi` | (NIR−SWIR1)/(NIR+SWIR1) | Canopy moisture |
|
|
200
|
+
| `nbr` / `dnbr` | (NIR−SWIR2)/(NIR+SWIR2) | Burn severity |
|
|
201
|
+
| `tct` | Matrix coefficients | Brightness, Greenness, Wetness |
|
|
202
|
+
| `pca` | Eigen decomposition | Dimensionality reduction |
|
|
203
|
+
| `texture` | GLCM | Contrast, homogeneity, energy |
|
|
204
|
+
| `lst` | Thermal → Kelvin / Celsius | Land surface temperature |
|
|
205
|
+
| `albedo` | Narrowband→broadband (Liang 2001) | Surface reflectance |
|
|
206
|
+
| `band_math` | Arbitrary expression on B[i] | Custom indices |
|
|
207
|
+
|
|
208
|
+
### 🔧 Post-Processing (`client.post`)
|
|
209
|
+
|
|
210
|
+
`vectorize` → `smooth` → `regularize` → `zonal_stats` → `buffer` → `centroids` → `compress` → `cog`
|
|
211
|
+
|
|
212
|
+
### 📡 SAR Processing (`client.sar`)
|
|
213
|
+
|
|
214
|
+
| Method | Description |
|
|
215
|
+
|---|---|
|
|
216
|
+
| `despeckle()` | Lee, Enhanced Lee, Frost, Gamma MAP, Boxcar |
|
|
217
|
+
| `calibrate()` | DN → sigma0 / gamma0 / beta0 (dB or linear) |
|
|
218
|
+
| `flood_map()` | Threshold or change-based flood detection |
|
|
219
|
+
| `coherence()` | Interferometric coherence (stable surface / change) |
|
|
220
|
+
|
|
221
|
+
### 📋 YAML Pipeline Orchestration
|
|
222
|
+
- Define search → filter → download → process → export workflows in YAML
|
|
223
|
+
- Chain any preprocessing, index, or post-processing step
|
|
224
|
+
- Schedule with cron expressions, run history, and retry
|
|
225
|
+
- 6 built-in templates: `ndvi` · `change_detection` · `flood_map` · `urban_mapping` · `sar_analysis` · `land_cover`
|
|
226
|
+
|
|
227
|
+
### 🔐 Security by Default
|
|
228
|
+
- Credentials stored in system keyring — never logged or written to disk in plaintext
|
|
229
|
+
- TLS 1.2+ enforced, SSL verification always on, no telemetry, no analytics
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## 📦 Installation
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
# Core — free providers work immediately, no extras needed
|
|
237
|
+
pip install PyGeoFetch
|
|
238
|
+
|
|
239
|
+
# + Raster/vector processing (rasterio, geopandas, shapely)
|
|
240
|
+
pip install "PyGeoFetch[geo]"
|
|
241
|
+
|
|
242
|
+
# + Cloud provider S3 access
|
|
243
|
+
pip install "PyGeoFetch[cloud]"
|
|
244
|
+
|
|
245
|
+
# + Cron scheduling
|
|
246
|
+
pip install "PyGeoFetch[schedule]"
|
|
247
|
+
|
|
248
|
+
# Everything
|
|
249
|
+
pip install "PyGeoFetch[all]"
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
**Requirements:** Python 3.9+
|
|
253
|
+
|
|
254
|
+
Verify your installation:
|
|
255
|
+
```bash
|
|
256
|
+
PyGeoFetch doctor
|
|
257
|
+
# ✓ Python 3.11 ✓ httpx ✓ pydantic ✓ rich
|
|
258
|
+
# ✓ AWS Earth Search: HTTP 200
|
|
259
|
+
# ✓ Planetary Computer: HTTP 200
|
|
260
|
+
# ✓ Element 84: HTTP 200
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## ⚡ Quick Start
|
|
266
|
+
|
|
267
|
+
### CLI
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
# Add credentials (free providers need no credentials at all)
|
|
271
|
+
PyGeoFetch auth add usgs --username USER --password PASS
|
|
272
|
+
PyGeoFetch auth add copernicus --username email@example.com --password PASS
|
|
273
|
+
PyGeoFetch auth add planet --api-key YOUR_KEY
|
|
274
|
+
|
|
275
|
+
# Search (free — no login)
|
|
276
|
+
PyGeoFetch search run \
|
|
277
|
+
--bbox "-74.1,40.6,-73.7,40.9" \
|
|
278
|
+
--start-date 2024-01-01 \
|
|
279
|
+
--cloud-cover 0-15 \
|
|
280
|
+
--providers planetary_computer,aws_earth \
|
|
281
|
+
--format table \
|
|
282
|
+
--output results.geojson
|
|
283
|
+
|
|
284
|
+
# Download with band selection
|
|
285
|
+
PyGeoFetch download run \
|
|
286
|
+
--from-search results.geojson \
|
|
287
|
+
--output ./data/ \
|
|
288
|
+
--parallel 4 \
|
|
289
|
+
--bands "B02,B03,B04" \
|
|
290
|
+
--max-items 3
|
|
291
|
+
|
|
292
|
+
# Download with full post-processing chain
|
|
293
|
+
PyGeoFetch download run \
|
|
294
|
+
--from-search results.geojson \
|
|
295
|
+
--output ./data/ \
|
|
296
|
+
--parallel 4 \
|
|
297
|
+
--verify-checksum \
|
|
298
|
+
--post-process "unzip,reproject:EPSG:4326,compress:lzw,cog"
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Python API
|
|
302
|
+
|
|
303
|
+
```python
|
|
304
|
+
from pathlib import Path
|
|
305
|
+
from pygeofetch import PyGeoFetch
|
|
306
|
+
from pygeofetch.models.search_query import SearchQuery, BoundingBox
|
|
307
|
+
from pygeofetch.models.download_task import DownloadOptions
|
|
308
|
+
|
|
309
|
+
client = PyGeoFetch()
|
|
310
|
+
|
|
311
|
+
# Credentials
|
|
312
|
+
client.add_credentials("usgs", username="user", password="pass")
|
|
313
|
+
client.add_credentials("copernicus", username="email@example.com", password="pass")
|
|
314
|
+
client.add_credentials("planet", api_key="PL_KEY")
|
|
315
|
+
|
|
316
|
+
# Search
|
|
317
|
+
results = client.search(
|
|
318
|
+
SearchQuery(
|
|
319
|
+
bbox=BoundingBox.from_string("-74.1,40.6,-73.7,40.9"),
|
|
320
|
+
start_date="2024-01-01",
|
|
321
|
+
end_date="2024-06-01",
|
|
322
|
+
cloud_cover_max=20,
|
|
323
|
+
sort_by="cloud_cover",
|
|
324
|
+
sort_ascending=True,
|
|
325
|
+
),
|
|
326
|
+
providers=["usgs", "copernicus", "planetary_computer", "aws_earth"],
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
# Download
|
|
330
|
+
downloads = client.download(
|
|
331
|
+
results[:5],
|
|
332
|
+
destination=Path("./data/"),
|
|
333
|
+
options=DownloadOptions(
|
|
334
|
+
parallel=4,
|
|
335
|
+
verify_checksum=True,
|
|
336
|
+
resume=True,
|
|
337
|
+
bands=["B02", "B03", "B04"],
|
|
338
|
+
),
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
for dr in downloads:
|
|
342
|
+
if dr.success:
|
|
343
|
+
print(f"✓ {dr.data_id} ({dr.bytes_downloaded // 1024 // 1024:.1f} MB)")
|
|
344
|
+
else:
|
|
345
|
+
print(f"✗ {dr.data_id}: {dr.error}")
|
|
346
|
+
|
|
347
|
+
# Process
|
|
348
|
+
ndvi = client.indices.ndvi(red="B04.tif", nir="B08.tif")
|
|
349
|
+
clipped = client.preprocess.clip("scene.tif", bbox=(-74.1, 40.6, -73.7, 40.9))
|
|
350
|
+
cog = client.post.cog("ndvi.tif", compress="deflate")
|
|
351
|
+
|
|
352
|
+
# End-to-end pipeline
|
|
353
|
+
result = (
|
|
354
|
+
client.pipeline("sentinel2-ndvi")
|
|
355
|
+
.atmos(method="dos1")
|
|
356
|
+
.cloud_mask(method="scl", scl_band="SCL.tif")
|
|
357
|
+
.clip(bbox=(-74.1, 40.6, -73.7, 40.9))
|
|
358
|
+
.ndvi(red="B04.tif", nir="B08.tif")
|
|
359
|
+
.vectorize(threshold=0.3)
|
|
360
|
+
.cog(compress="deflate")
|
|
361
|
+
.run(input="scene.tif", output_dir="./processed/")
|
|
362
|
+
)
|
|
363
|
+
print(f"Pipeline: {result.success} in {result.duration_seconds:.1f}s")
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### YAML Pipeline
|
|
367
|
+
|
|
368
|
+
```yaml
|
|
369
|
+
name: weekly-sentinel2-ndvi
|
|
370
|
+
schedule: "0 6 * * 1" # Every Monday 06:00 UTC
|
|
371
|
+
description: Weekly NDVI monitoring — search, download, process, export
|
|
372
|
+
|
|
373
|
+
steps:
|
|
374
|
+
- search:
|
|
375
|
+
providers: [copernicus, aws_earth, planetary_computer]
|
|
376
|
+
bbox: "-74.1,40.6,-73.7,40.9"
|
|
377
|
+
date_range: last_7_days
|
|
378
|
+
cloud_cover: "0-10"
|
|
379
|
+
max_results: 20
|
|
380
|
+
|
|
381
|
+
- filter:
|
|
382
|
+
expression: "data.cloud_cover < 5"
|
|
383
|
+
|
|
384
|
+
- download:
|
|
385
|
+
parallel: 4
|
|
386
|
+
output: ./raw/
|
|
387
|
+
verify_checksum: true
|
|
388
|
+
bands: [B04, B08]
|
|
389
|
+
|
|
390
|
+
- ndvi:
|
|
391
|
+
red: B04.tif
|
|
392
|
+
nir: B08.tif
|
|
393
|
+
|
|
394
|
+
- vectorize:
|
|
395
|
+
threshold: 0.3
|
|
396
|
+
format: geojson
|
|
397
|
+
|
|
398
|
+
- cog:
|
|
399
|
+
compress: deflate
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
```bash
|
|
403
|
+
# Validate without running
|
|
404
|
+
PyGeoFetch proc-pipeline validate weekly-sentinel2.yaml
|
|
405
|
+
|
|
406
|
+
# Run once
|
|
407
|
+
PyGeoFetch proc-pipeline run weekly-sentinel2.yaml --input scene.tif
|
|
408
|
+
|
|
409
|
+
# Schedule (recurring)
|
|
410
|
+
PyGeoFetch pipeline schedule weekly-sentinel2.yaml --name "ndvi-weekly"
|
|
411
|
+
|
|
412
|
+
# Generate a starter template
|
|
413
|
+
PyGeoFetch proc-pipeline template ndvi
|
|
414
|
+
PyGeoFetch proc-pipeline template flood_map
|
|
415
|
+
PyGeoFetch proc-pipeline template change_detection
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
---
|
|
419
|
+
|
|
420
|
+
## 🖥️ Complete CLI Reference
|
|
421
|
+
|
|
422
|
+
```
|
|
423
|
+
SYSTEM
|
|
424
|
+
PyGeoFetch doctor diagnose installation + connectivity
|
|
425
|
+
PyGeoFetch status [--json] provider and cache overview
|
|
426
|
+
PyGeoFetch version
|
|
427
|
+
|
|
428
|
+
AUTH
|
|
429
|
+
PyGeoFetch auth add PROVIDER [--username U] [--password P] [--api-key K]
|
|
430
|
+
PyGeoFetch auth login PROVIDER interactive prompt
|
|
431
|
+
PyGeoFetch auth list [--json]
|
|
432
|
+
PyGeoFetch auth test PROVIDER
|
|
433
|
+
PyGeoFetch auth remove PROVIDER [--yes]
|
|
434
|
+
PyGeoFetch auth export [--output FILE]
|
|
435
|
+
|
|
436
|
+
PROVIDERS
|
|
437
|
+
PyGeoFetch providers list [--auth|--no-auth] [--capabilities sar] [--json]
|
|
438
|
+
PyGeoFetch providers info PROVIDER
|
|
439
|
+
PyGeoFetch providers search "TERM"
|
|
440
|
+
|
|
441
|
+
SEARCH
|
|
442
|
+
PyGeoFetch search run \
|
|
443
|
+
--bbox "minlon,minlat,maxlon,maxlat" or --geometry-file area.geojson
|
|
444
|
+
--start-date YYYY-MM-DD --end-date YYYY-MM-DD
|
|
445
|
+
--cloud-cover 0-20
|
|
446
|
+
--providers aws_earth,copernicus
|
|
447
|
+
--satellites Sentinel-2
|
|
448
|
+
--sort-by cloud_cover --sort-order asc
|
|
449
|
+
--max-results 50
|
|
450
|
+
--cql2 "eo:cloud_cover < 5"
|
|
451
|
+
--format table|json|stac|geojson|geoparquet|csv|ids
|
|
452
|
+
--output results.geojson
|
|
453
|
+
--no-cache --timeout 60
|
|
454
|
+
|
|
455
|
+
DOWNLOAD
|
|
456
|
+
PyGeoFetch download run \
|
|
457
|
+
--from-search results.geojson
|
|
458
|
+
--output ./data/
|
|
459
|
+
--parallel 4 --retry 5
|
|
460
|
+
--bands "B02,B03,B04"
|
|
461
|
+
--verify-checksum --resume
|
|
462
|
+
--bandwidth-limit 10MB
|
|
463
|
+
--post-process "reproject:EPSG:4326,compress:lzw,cog"
|
|
464
|
+
--on-failure skip
|
|
465
|
+
--max-items 10
|
|
466
|
+
--notify webhook:https://hooks.slack.com/YOUR/WEBHOOK
|
|
467
|
+
--json
|
|
468
|
+
|
|
469
|
+
PREPROCESSING
|
|
470
|
+
PyGeoFetch preprocess atmos scene.tif --method dos1|sen2cor|flaash|6s
|
|
471
|
+
PyGeoFetch preprocess cloud-mask scene.tif --method scl|fmask|threshold
|
|
472
|
+
PyGeoFetch preprocess cloud-fill cloudy.tif t1.tif t2.tif
|
|
473
|
+
PyGeoFetch preprocess topo-correct scene.tif dem.tif --method cosine
|
|
474
|
+
PyGeoFetch preprocess clip scene.tif --bbox "..." | --geometry file.geojson
|
|
475
|
+
PyGeoFetch preprocess reproject scene.tif --crs EPSG:4326
|
|
476
|
+
PyGeoFetch preprocess resample scene.tif --resolution 30
|
|
477
|
+
PyGeoFetch preprocess pansharpen pan.tif ms.tif --method brovey
|
|
478
|
+
PyGeoFetch preprocess mosaic s1.tif s2.tif --method first|last|min|max
|
|
479
|
+
PyGeoFetch preprocess composite *.tif --method median|mean|max|best_pixel
|
|
480
|
+
PyGeoFetch preprocess tile scene.tif --tile-size 512 --overlap 64
|
|
481
|
+
|
|
482
|
+
SPECTRAL INDICES
|
|
483
|
+
PyGeoFetch index ndvi --red B04.tif --nir B08.tif
|
|
484
|
+
PyGeoFetch index evi --blue B02.tif --red B04.tif --nir B08.tif
|
|
485
|
+
PyGeoFetch index savi --red B04.tif --nir B08.tif --soil-l 0.5
|
|
486
|
+
PyGeoFetch index ndwi --green B03.tif --nir B08.tif
|
|
487
|
+
PyGeoFetch index mndwi --green B03.tif --swir1 B11.tif
|
|
488
|
+
PyGeoFetch index ndbi --nir B08.tif --swir1 B11.tif
|
|
489
|
+
PyGeoFetch index ndsi --green B03.tif --swir1 B11.tif
|
|
490
|
+
PyGeoFetch index ndmi --nir B08.tif --swir1 B11.tif
|
|
491
|
+
PyGeoFetch index nbr --nir B08.tif --swir2 B12.tif
|
|
492
|
+
PyGeoFetch index dnbr --pre-nir B08.tif --pre-swir2 B12.tif \
|
|
493
|
+
--post-nir B08_post.tif --post-swir2 B12_post.tif
|
|
494
|
+
PyGeoFetch index tct --blue B02.tif --green B03.tif --red B04.tif \
|
|
495
|
+
--nir B08.tif --swir1 B11.tif --swir2 B12.tif
|
|
496
|
+
PyGeoFetch index pca B02.tif B03.tif B04.tif B08.tif --components 3
|
|
497
|
+
PyGeoFetch index texture B08.tif --window 7 --features contrast,homogeneity
|
|
498
|
+
PyGeoFetch index lst B10.tif --emissivity 0.97 --sensor landsat8
|
|
499
|
+
PyGeoFetch index albedo B02.tif B03.tif B04.tif B08.tif B11.tif B12.tif
|
|
500
|
+
PyGeoFetch index band-math B04.tif B08.tif --expr "(B[1]-B[0])/(B[1]+B[0]+1e-6)"
|
|
501
|
+
PyGeoFetch index stack B02.tif B03.tif B04.tif
|
|
502
|
+
|
|
503
|
+
POST-PROCESSING
|
|
504
|
+
PyGeoFetch post vectorize ndvi.tif --threshold 0.3 --format geojson
|
|
505
|
+
PyGeoFetch post smooth polygons.geojson --tolerance 0.5
|
|
506
|
+
PyGeoFetch post regularize buildings.geojson
|
|
507
|
+
PyGeoFetch post zonal-stats ndvi.tif parcels.geojson --output stats.csv
|
|
508
|
+
PyGeoFetch post buffer roads.geojson --distance 15
|
|
509
|
+
PyGeoFetch post centroids polygons.geojson
|
|
510
|
+
PyGeoFetch post geometry-metrics polygons.geojson
|
|
511
|
+
PyGeoFetch post compress scene.tif --method lzw|deflate|zstd
|
|
512
|
+
PyGeoFetch post cog scene.tif --compress deflate --blocksize 512
|
|
513
|
+
|
|
514
|
+
SAR PROCESSING
|
|
515
|
+
PyGeoFetch sar despeckle sar.tif --filter lee|enhanced_lee|frost|gamma --window 7
|
|
516
|
+
PyGeoFetch sar calibrate sar.tif --output-type sigma0|gamma0|beta0 --db
|
|
517
|
+
PyGeoFetch sar flood-map post.tif --threshold -15 [--reference pre.tif]
|
|
518
|
+
PyGeoFetch sar coherence slc1.tif slc2.tif --window 7
|
|
519
|
+
|
|
520
|
+
PROCESSING PIPELINES
|
|
521
|
+
PyGeoFetch proc-pipeline template ndvi|change_detection|flood_map|urban_mapping|...
|
|
522
|
+
PyGeoFetch proc-pipeline validate FILE
|
|
523
|
+
PyGeoFetch proc-pipeline run FILE [--input scene.tif] [--output-dir ./out/]
|
|
524
|
+
|
|
525
|
+
DATA PIPELINES (search + download)
|
|
526
|
+
PyGeoFetch pipeline run|validate|schedule|list-scheduled|unschedule|history
|
|
527
|
+
|
|
528
|
+
CACHE
|
|
529
|
+
PyGeoFetch cache stats|clear|ttl [show|set N]|location|prune --max-size 1GB
|
|
530
|
+
|
|
531
|
+
CONFIG
|
|
532
|
+
PyGeoFetch config show|get KEY|set KEY VALUE|path|reset
|
|
533
|
+
|
|
534
|
+
COMPLETION
|
|
535
|
+
PyGeoFetch --install-completion bash|zsh|fish
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
---
|
|
539
|
+
|
|
540
|
+
## 📚 Notebooks
|
|
541
|
+
|
|
542
|
+
| Notebook | Topics |
|
|
543
|
+
|---|---|
|
|
544
|
+
| `01_getting_started.ipynb` | Install, doctor, first search, first download |
|
|
545
|
+
| `02_authentication_and_providers.ipynb` | All 22 providers, credentials, capability filters |
|
|
546
|
+
| `03_advanced_search.ipynb` | Federated search, CQL2 filters, 7 output formats, caching |
|
|
547
|
+
| `04_download_and_postprocessing.ipynb` | Band selection, parallel downloads, post-processing |
|
|
548
|
+
| `05_pipelines_and_scheduling.ipynb` | YAML pipelines, scheduling, Python builder API |
|
|
549
|
+
| `06_real_world_workflows.ipynb` | NDVI time series, change detection, multi-sensor fusion |
|
|
550
|
+
| `07_copernicus_and_authenticated_providers.ipynb` | Copernicus, USGS, NASA, Planet, ASF, OpenTopography |
|
|
551
|
+
| `08_cli_complete_reference.ipynb` | Every CLI command with runnable examples |
|
|
552
|
+
| `09_processing_complete.ipynb` | Full processing engine: preprocessing, indices, SAR, pipelines |
|
|
553
|
+
|
|
554
|
+
```bash
|
|
555
|
+
cd notebooks/
|
|
556
|
+
jupyter lab
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
---
|
|
560
|
+
|
|
561
|
+
## 📋 Documentation
|
|
562
|
+
|
|
563
|
+
Full documentation: **https://appiahkubis14.github.io/pygeofetch-docs/**
|
|
564
|
+
|
|
565
|
+
Covers: CLI reference · provider auth guides · pipeline configuration · post-processing catalogue · contributing guide.
|
|
566
|
+
|
|
567
|
+
---
|
|
568
|
+
|
|
569
|
+
## 🤝 Contributing
|
|
570
|
+
|
|
571
|
+
Contributions of all kinds are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for full guidelines.
|
|
572
|
+
|
|
573
|
+
Good first issues include implementing stub providers to full API integrations, improving test coverage, and adding new post-processing actions.
|
|
574
|
+
|
|
575
|
+
```bash
|
|
576
|
+
git clone https://github.com/appiahkubis14/PyGeoFetch
|
|
577
|
+
cd PyGeoFetch
|
|
578
|
+
pip install -e ".[dev,all]"
|
|
579
|
+
pytest tests/unit/ -v
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
---
|
|
583
|
+
|
|
584
|
+
## 📄 License
|
|
585
|
+
|
|
586
|
+
PyGeoFetch is free and open source software, licensed under the [MIT License](LICENSE).
|
|
587
|
+
|
|
588
|
+
© 2026 PyGeoFetch Contributors. Part of the **PyGeoVision** platform — [PyGeoFetch](https://github.com/appiahkubis14/PyGeoFetch) (data + processing) + [GeoAI](https://opengeoai.org) (AI) = complete Earth observation pipeline.
|