SatChange is a Python CLI that compares how a place changed between two dates using Sentinel-2 imagery from Google Earth Engine. It turns raw satellite bands into practical outputs you can share: a static change map, a GeoTIFF, summary statistics, and a local web viewer URL with map layers.
If you track urban growth, vegetation loss, or water change, SatChange gives you a reproducible workflow with AOI-local cloud checks, fallback date recovery, and cached downloads to reduce repeated work.
- Why SatChange
- What you get
- Quick start
- Demo artifacts (verified)
- Outputs
- Web viewer flow
- Quality checks
- Packaging notes
- Security notes
- FAQ
- Documentation map
- Contributing
- License
Satellite images are useful, but comparing dates manually is slow and hard to reproduce. SatChange automates that process for a target area of interest (AOI), then packages the result in both analyst-friendly and stakeholder-friendly forms.
- Picking usable scenes is difficult when cloud cover varies by location.
- Raw imagery alone does not explain what changed.
- Sharing results across technical and non-technical teams is often manual.
- Uses AOI-local cloud quality checks (not scene metadata alone).
- Applies fallback strategies when requested dates are too cloudy.
- Produces versionable artifacts (
.npz,.npy,.json,.png,.tif) plus a JobID manifest for the web viewer.
- Spectral change detection with NDVI (vegetation), NDWI (water), and NDBI (urban)
- Stable change classes (
0..7) across processing and visualization - Disk LRU cache to avoid redundant downloads
- Dry-run mode for safe validation without network calls
- Web-first output (
job_id,manifest,/jobs/<job_id>URL hint) - Optional legacy interactive HTML export for compatibility
git clone https://github.com/Rogit-28/GEE-Temporal-Analysis.git
cd GEE-Temporal-Analysis
python -m venv venv
# Windows PowerShell:
.\venv\Scripts\Activate.ps1
# macOS/Linux:
# source venv/bin/activate
pip install -r requirements.txt
pip install -e .
# Maintainer/QA tooling (lint, type-check, tests):
pip install -r requirements-dev.txtpython -m satchange --help
satchange --help
satchange --versionsatchange config init --service-account-key /path/to/key.json --project-id your-project-id
satchange config showconfig init copies your key to ~/.satchange/keys/ and stores that managed path in ~/.satchange/config.yaml.
satchange analyze --center "13.0827,80.2707" --size 100 --date-a "2022-02-04" --date-b "2024-10-26" --change-type all --output ./results --dry-runsatchange analyze --center "13.0827,80.2707" --size 100 --date-a "2022-02-04" --date-b "2024-10-26" --change-type all --output ./results --name chennai --non-interactive
satchange export --result ./results --format allThe following demo evidence was generated from this repository and stored in docs/assets/.
Command:
satchange analyze --center "13.0827,80.2707" --size 100 --date-a "2022-02-04" --date-b "2024-10-26" --change-type all --output ./results --dry-runOutput excerpt (docs/assets/demo-dry-run-output.txt):
[DRY RUN] Local validation complete.
Cloud checks skipped (no network calls in dry-run mode).
Planned output prefix: 13.0827_80.2707_2022-02-04_2024-10-26
[DRY RUN] Would execute the following:
Download images for dates: 2022-02-04, 2024-10-26
Area: 100x100 pixels at (13.0827, 80.2707)
Command (explicit empty config):
satchange --config-file <empty-config.yaml> inspect --center "13.0827,80.2707" --size 100 --date-range "2022-01-01:2022-12-31"Output (docs/assets/demo-missing-auth-output.txt):
[ERROR] Not authenticated with Google Earth Engine
Run 'satchange config init' first
Command:
satchange export --result ./results --format all --include-legacy-htmlOutput excerpt (docs/assets/demo-export-output.txt):
[OK] Visualization generation completed!
Generated files:
static: ..._visualization.png
geotiff: ..._classification.tif
web_manifest: ..._web_bundle\manifest.json
job_id: chennai_2022-02-04_2024-10-26-bc28dac04a0d
web_url_hint: http://localhost:3000/jobs/chennai_2022-02-04_2024-10-26-bc28dac04a0d
SatChange writes artifacts with prefix {name_or_lat_lon}_{date_a}_{date_b}.
| Artifact | Purpose |
|---|---|
{prefix}_bands_a.npz, {prefix}_bands_b.npz |
Band arrays (pickle-free) |
{prefix}_classification.npy |
Change classification map |
{prefix}_change_stats.json |
Statistics for classes and totals |
{prefix}_metadata.json |
Run metadata and processing summary |
{prefix}_visualization.png |
Static comparison map |
{prefix}_classification.tif |
GeoTIFF for GIS workflows |
{prefix}_job.json |
Job index (job_id, manifest path) |
{prefix}_web_bundle/manifest.json |
Web manifest for Next.js job viewer |
{prefix}_interactive.html |
Legacy interactive output (opt-in) |
analyze and export emit a job_id and attempt a best-effort local viewer start.
cd web
npm install
# PowerShell:
$env:SATCHANGE_RESULTS_DIR = "C:\path\to\results"
npm run build
npm run dev:resetOpen:
http://localhost:3000/jobs/<job_id>
http://localhost:3000/api/jobs/<job_id>
If the CLI prints web_viewer: not started (...), run the manual command it prints.
Validated locally from repository root:
black --check satchange examples
flake8 satchange examples
mypy satchange
pytest -q
cd web && npm run buildLatest local baseline in this repo:
black --check: passflake8: passmypy: passpytest: pass (10 passed)web build: pass
- Package metadata is defined in
setup.py(name=satchange,version=1.0.0a1). - CLI entrypoint is
satchange=satchange.cli:main. - Install path verified locally with editable install (
pip install -e .).
- Never commit service-account keys.
satchange config initstores a managed local key copy under~/.satchange/keys/.- Output names are sanitized (
sanitize_output_name) and file paths are confined (safe_join). - Legacy pickled band dictionaries (
*_bands_*.npy) are intentionally unsupported byexport.
No. --dry-run validates local inputs and exits before imagery download or change detection.
SatChange attempts threshold relaxation, temporal window expansion, then median compositing.
inspect is a quick catalog preview. analyze makes AOI-specific quality decisions using local cloud coverage.
Yes, but opt-in only via --include-legacy-html.
Use API_REFERENCE.md.
- RUN_INSTRUCTIONS.md — setup, commands, troubleshooting, release checklist
- API_REFERENCE.md — CLI command and option reference
examples/— programmatic examples (mock/demo-oriented)
See CONTRIBUTING.md.
MIT — see LICENSE.

