← GeoAI SkillsCONTENT HISTORY

Update to GeoAI Skills

Snapshot Sep 30, 2026 · 23:13 UTC · version 0.4.0

Collection source: not recorded for this historical snapshot.

WHAT CHANGED · RULE-BASED ANALYSIS

First saved snapshot

No earlier snapshot is available to establish a change.

Compare saved observations

Download comparison JSON
Full technical diff · 0 changed fields
Full snapshot data
{
  "name": "remote-sensing-analysis",
  "description": "Always invoke for classical analysis, classification, validation, or comparability of satellite, aerial, or drone imagery. This skill owns sensor, product, processing-level and processing-baseline harmonization, including multi-date inputs; add change-detection only after comparable observations exist. Two scenes of the same product level are not automatically comparable: Sentinel-2 L2A crossed a reflectance offset at Processing Baseline 04.00 in January 2022, so any pair spanning that date starts here. Covers spectral indices, masking, compositing, SAR, land cover, and accuracy assessment. Route neural methods to geo-deep-learning and planetary server-side execution to google-earth-engine.",
  "included_files": [
    {
      "relative_path": "agents/openai.yaml",
      "size_in_bytes": 220
    },
    {
      "relative_path": "references/authoritative-sources.md",
      "size_in_bytes": 1382
    }
  ],
  "skill_md_contents": "---\nname: remote-sensing-analysis\ndescription: >-\n  Always invoke for classical analysis, classification, validation, or\n  comparability of satellite, aerial, or drone imagery. This skill owns\n  sensor, product, processing-level and processing-baseline harmonization,\n  including multi-date inputs; add change-detection only after comparable\n  observations exist. Two scenes of the same product level are not\n  automatically comparable: Sentinel-2 L2A crossed a reflectance offset at\n  Processing Baseline 04.00 in January 2022, so any pair spanning that date\n  starts here. Covers spectral indices, masking, compositing, SAR, land cover,\n  and accuracy assessment. Route neural methods to geo-deep-learning and\n  planetary server-side execution to google-earth-engine.\nlicense: MIT\nmetadata:\n  author: Muhammed Enes Duran\n---\n\n# Remote Sensing Analysis\n\nPurpose: turn raw Earth observation imagery into defensible analytical\nproducts. The failure modes here are subtle — uncorrected DNs treated as\nreflectance, clouds counted as land cover change, indices computed on the\nwrong bands — so this skill front-loads the checks.\n\n## Data access (STAC-first)\n\nSearch via STAC APIs rather than per-provider portals; the workflow is\nuniform and scriptable:\n\n```python\nimport pystac_client\nimport odc.stac\n\ncatalog = pystac_client.Client.open(\"https://earth-search.aws.element84.com/v1\")\nitems = catalog.search(\n    collections=[\"sentinel-2-l2a\"],\n    bbox=[27.0, 38.3, 27.4, 38.6],\n    datetime=\"2025-05-01/2025-09-30\",\n    query={\"eo:cloud_cover\": {\"lt\": 20}},\n).item_collection()\nds = odc.stac.load(items, bands=[\"red\", \"nir\", \"scl\"], resolution=10, chunks={})\n```\n\nKey collections: `sentinel-2-l2a` (10 m optical, surface reflectance),\n`landsat-c2-l2` (30 m, 1982→), `sentinel-1-grd` (SAR, weather-independent).\nMicrosoft Planetary Computer mirrors most (needs `planetary_computer`\nsigning). For continental/global extents or decades-long stacks, route to\n`google-earth-engine` instead of downloading. Record collection + item IDs +\nsearch parameters for reproducibility.\n\n## Processing-level discipline\n\n| Level | Meaning | Analysis-ready? |\n|---|---|---|\n| L1C / L1TP | Top-of-atmosphere (TOA) | Indices OK-ish; cross-date comparison risky |\n| **L2A / L2SP** | Surface reflectance (BOA) | Yes — default choice |\n| GRD (SAR) | Detected amplitude | Needs terrain correction + speckle filter |\n\nAlways state which level you used. Never mix TOA and BOA scenes in one\ncomposite or time series. Landsat Collection 2 L2 needs its scale factors\napplied (`reflectance = DN * 0.0000275 - 0.2`).\n\n### The Sentinel-2 baseline discontinuity — passes the level check above\n\nProcessing Baseline 04.00, applied from **25 January 2022**, added a constant\n`BOA_ADD_OFFSET` (currently −1000) to L2A digital numbers so that negative\nsurface reflectance can be encoded. Two scenes on opposite sides of that date\nare **both L2A**: the level check above sees nothing wrong while their DNs sit\n1000 apart. Differencing them yields a systematic reflectance shift that reads\nas real change and survives every mask, threshold and accuracy report you\napply afterwards.\n\n- Read `BOA_ADD_OFFSET` and `QUANTIFICATION_VALUE` from each product's\n  metadata rather than hardcoding −1000 and 10000; both are per-band and the\n  baseline has changed before.\n- Convert with `reflectance = (DN + BOA_ADD_OFFSET) / QUANTIFICATION_VALUE`.\n- Record the **processing baseline of every scene** in the manifest, not just\n  the product level. Two L2A scenes is not a sufficient statement.\n- **Do not correct twice.** Harmonised collections — Earth Engine's\n  `COPERNICUS/S2_SR_HARMONIZED` and several commercial mirrors — have already\n  shifted post-baseline data back to the pre-2022 range. Applying the offset\n  again inverts the error rather than removing it.\n- If the baseline is undocumented for either scene, the comparison is not\n  defensible. Say that instead of assuming pre- or post-2022.\n\n## Cloud and quality masking — before anything else\n\n- Sentinel-2: mask with SCL band (drop classes 3 cloud shadow, 8-9 clouds,\n  10 cirrus, 11 snow — keep 4 vegetation, 5 bare, 6 water, 7 unclassified\n  with care).\n- Landsat C2: decode `QA_PIXEL` bitfields (cloud, shadow, cirrus bits).\n- Report the % of valid pixels after masking per scene; scenes below ~60%\n  valid usually deserve exclusion.\n- For gap-free products, build median composites over a season rather than\n  cherry-picking single scenes.\n\n## Spectral indices\n\nCompute on surface reflectance, guard against division by zero, and name\nbands explicitly — band **numbers differ across sensors** (NIR is B8 on\nSentinel-2, B5 on Landsat 8/9):\n\n```python\nimport numpy as np\nimport xarray as xr\n\ndef normalized_diff(a: xr.DataArray, b: xr.DataArray) -> xr.DataArray:\n    \"\"\"(a - b) / (a + b) with zero-denominator protection.\"\"\"\n    return xr.where(a + b == 0, np.nan, (a - b) / (a + b))\n\nndvi = normalized_diff(ds.nir, ds.red)     # vegetation\nndwi = normalized_diff(ds.green, ds.nir)   # open water (McFeeters)\nndbi = normalized_diff(ds.swir16, ds.nir)  # built-up\n```\n\nInterpretation guardrails: NDVI thresholds are scene- and season-dependent;\nnever hardcode \"NDVI > 0.3 = vegetation\" without checking the histogram.\nWater confuses NDBI; shadows mimic water in NDWI — cross-check indices\nagainst each other and against true-color.\n\n## Classification workflow\n\n1. Define a legend with mutually exclusive, imagery-separable classes.\n2. Collect training samples spatially spread across the scene; record them\n   as a versioned vector file.\n3. Features: bands + indices + texture (GLCM) + temporal statistics if\n   multi-date. For deep learning routes, hand off to `geo-deep-learning`.\n4. Validate with a **spatially independent** test set (see\n   `ml-experiment-standards` → `references/spatial-cv-protocol.md`) and\n   report per-class F1/IoU plus a confusion matrix — overall accuracy alone\n   hides rare-class failure.\n5. Map the errors: a spatial plot of misclassifications reveals systematic\n   problems (terrain shadow, urban/bare confusion) that global metrics hide.\n\n## SAR notes (Sentinel-1)\n\nPreprocess: orbit file → thermal noise removal → calibration (σ⁰) →\nterrain correction (Range-Doppler with a DEM) → speckle filter (Lee/Refined\nLee) → dB conversion. Work in dB for statistics; VV/VH ratio is a strong\nwater/vegetation discriminator. SAR sees through clouds — prefer it for\nflood mapping and continuous monitoring.\n\n## Pitfalls checklist\n\n- Comparing scenes across dates without consistent atmospheric correction.\n- Mixing Sentinel-2 scenes across the 2022-01-25 baseline change without\n  applying `BOA_ADD_OFFSET` — or applying it a second time on a collection\n  that is already harmonised.\n- Ignoring 20 m→10 m band mixing on Sentinel-2 (B11/B12 are natively 20 m).\n- Computing indices on integer DNs without scale factors → nonsense ranges.\n- Median composites of SAR in linear units (do statistics in dB).\n- Training and test pixels from the same field/polygon → leaked accuracy.\n- Forgetting nodata masks after reprojection (edges become zeros → fake\n  land cover).\n\n## Execution contract\n\n- **Workflow:** define phenomenon and scale; select sensor, product level, and dates; harmonize calibration, masks, CRS, and resolution; derive features; analyze; validate spatially; publish provenance.\n- **Decision rules:** use this skill for imagery preparation and classical analysis, change detection for explicit temporal differencing, deep learning for neural training, and Earth Engine for archive-scale execution.\n- **Verification protocol:** inspect masks and valid counts, confirm scale factors, offsets and processing baseline per scene, confirm band resolution, overlay outputs, use spatially independent validation, map errors, and test seasonal or sensor sensitivity.\n- **Failure modes:** reject results for cloud or shadow leakage, incomparable processing levels, undocumented or mismatched processing baselines, resampling artifacts, label leakage, nodata contamination, or claims beyond sensor resolution.\n- **Deliverables:** analysis-ready imagery or features, processing manifest, masks, derived products, validation metrics and error map, reproducible code, and limitations.\n- **Source freshness:** consult [the authoritative source registry](references/authoritative-sources.md) at execution time for product, calibration, and catalog changes.\n"
}

SHA-256: 59a1293f21440653ef65f337d69b09a6d31492719d16673fa91964b384cd44cf