|
1 | | -# pygeofilter-aeronet |
| 1 | + |
| 2 | +# pygeofilter-aeronet |
| 3 | + |
| 4 | +[](https://terradue.github.io/pygeofilter-aeronet/) |
| 5 | +[](LICENSE) |
| 6 | + |
| 7 | +**pygeofilter-aeronet** provides a [pygeofilter](https://github.com/geopython/pygeofilter) extension for querying NASA’s [AERONET](https://aeronet.gsfc.nasa.gov/) aerosol optical depth datasets through the [AERONET Web Service v3 API](https://aeronet.gsfc.nasa.gov/print_web_data_help_v3.html). |
| 8 | + |
| 9 | +It enables filtering AERONET observations using the same spatial and temporal operators as OGC APIs (CQL2 filters), making it easier to integrate AERONET data in geospatial workflows, data lakes, and cloud pipelines. |
| 10 | + |
| 11 | +## Features |
| 12 | + |
| 13 | +- Evaluate **CQL2 expressions** (spatial, temporal, and attribute filters) directly on AERONET datasets |
| 14 | +- Parse and normalize AERONET text responses into **GeoPandas DataFrames** |
| 15 | +- Support for: |
| 16 | + - `AOD10`, `AOD15`, `AOD20` — Aerosol Optical Depth (Levels 1.0–2.0) |
| 17 | + - `SDA10`, `SDA15`, `SDA20` — Size Distribution Analysis |
| 18 | + - `TOT10`, `TOT15`, `TOT20` — Total Optical Depth |
| 19 | +- Simple API for combining AERONET product types and date ranges |
| 20 | +- Compatible with **pygeofilter**, **pandas**, and **geopandas** |
| 21 | + |
| 22 | +## Installation |
| 23 | + |
| 24 | +```bash |
| 25 | +pip install pygeofilter-aeronet |
| 26 | +``` |
| 27 | + |
| 28 | +or directly from GitHub: |
| 29 | + |
| 30 | +``` |
| 31 | +pip install git+https://github.com/Terradue/pygeofilter-aeronet.git |
| 32 | +``` |
| 33 | + |
| 34 | +## Quick example |
| 35 | + |
| 36 | +```python |
| 37 | +import pandas as pd |
| 38 | +from io import StringIO |
| 39 | +from pygeofilter_aeronet.evaluator import ( |
| 40 | + to_aeronet_api_querystring, |
| 41 | + http_invoke |
| 42 | +) |
| 43 | + |
| 44 | +cql2_filter = { |
| 45 | + "op": "and", |
| 46 | + "args": [ |
| 47 | + {"op": "eq", "args": [{"property": "site"}, "Cart_Site"]}, |
| 48 | + {"op": "eq", "args": [{"property": "data_type"}, "AOD10"]}, |
| 49 | + {"op": "eq", "args": [{"property": "format"}, "csv"]}, |
| 50 | + {"op": "eq", "args": [{"property": "data_format"}, "daily-average"]}, |
| 51 | + { |
| 52 | + "op": "t_after", |
| 53 | + "args": [ |
| 54 | + {"property": "time"}, |
| 55 | + {"timestamp": "2023-02-01T00:00:00Z"}, |
| 56 | + ], |
| 57 | + }, |
| 58 | + { |
| 59 | + "op": "t_before", |
| 60 | + "args": [ |
| 61 | + {"property": "time"}, |
| 62 | + {"timestamp": "2023-02-28T23:59:59Z"}, |
| 63 | + ], |
| 64 | + }, |
| 65 | + ], |
| 66 | + } |
| 67 | + |
| 68 | +# print the AERONET API querystring: |
| 69 | +print(to_aeronet_api(cql2_filter=cql2_filter)) |
| 70 | + |
| 71 | +# dry-run the HTTP request: |
| 72 | +http_invoke(cql2_filter=cql2_filter, dry_run=True) |
| 73 | + |
| 74 | +# query the AERONET API |
| 75 | +raw_data = http_invoke(cql2_filter=cql2_filter, dry_run=False) |
| 76 | +df = pd.read_csv(StringIO(raw_data), skiprows=5) |
| 77 | + |
| 78 | +print(df.head(5)) |
| 79 | +``` |
| 80 | + |
| 81 | +## Documentation |
| 82 | + |
| 83 | +User guide and examples available at: [https://terradue.github.io/pygeofilter-aeronet/](https://terradue.github.io/pygeofilter-aeronet/) |
| 84 | + |
| 85 | +## Development |
| 86 | + |
| 87 | +```console |
| 88 | +git clone https://github.com/Terradue/pygeofilter-aeronet.git |
| 89 | +cd pygeofilter-aeronet |
| 90 | +hatch shell |
| 91 | +``` |
| 92 | + |
0 commit comments