The technology stack is selected around five constraints:
- Complete offline operation after staging.
- Ability to train and run custom AI models.
- Support for GeoTIFF/COG and geospatial metadata.
- Incremental vector indexing.
- Reproducible deployment on a local workstation or server.
The recommended stack prioritizes open-source software and local execution.
Frontend
├── React
├── TypeScript
├── Vite
├── Leaflet or OpenLayers
└── Local UI assets
Backend
├── Python
├── FastAPI
├── Pydantic
└── Uvicorn
AI / ML
├── PyTorch
├── torchvision
├── Custom CNN / Vision Transformer
├── Custom Siamese Change Detection Model
└── Optional local text model
Geospatial
├── GDAL
├── Rasterio
├── GeoPandas
├── Shapely
├── pyproj
└── NumPy
Vector Search
├── FAISS
└── Optional HNSW/other local index
Database
├── PostgreSQL
├── PostGIS
└── SQLite fallback for prototype
Deployment
├── Docker
├── Docker Compose
└── Offline package/model bundles
Recommended for:
- Component-based dashboard.
- Search workflows.
- Review queues.
- Interactive state management.
- Typed API integration.
Suggested libraries:
- React.
- TypeScript.
- Vite.
- TanStack Query for API state.
- Zustand or Redux Toolkit for application state.
- Tailwind CSS or another locally bundled styling approach.
Best for a fast prototype.
Advantages:
- Easy integration.
- Lightweight.
- Good marker/layer support.
Better for more advanced geospatial workflows.
Advantages:
- Strong raster/vector support.
- Advanced projections.
- More GIS-oriented capabilities.
Important offline requirement:
Do not depend on a public online tile provider for core functionality. Use:
- Local raster layers.
- Local MBTiles/PMTiles where supported.
- A simple offline basemap packaged with the system.
- Coordinate/grid fallback.
Python is recommended because the ecosystem supports:
- Deep learning.
- Raster processing.
- Geospatial analysis.
- Vector indexing.
Recommended API modules:
/api/search
/api/similarity
/api/change
/api/ingestion
/api/scenes
/api/review
/api/clusters
/api/export
/api/system
Example service structure:
backend/
├── app/
│ ├── main.py
│ ├── api/
│ ├── services/
│ ├── repositories/
│ ├── schemas/
│ └── core/
Use GDAL for:
- Raster inspection.
- Format support.
- Metadata extraction.
- Reprojection.
- Conversion where required.
Use Rasterio for Python-native raster processing:
- Reading GeoTIFF.
- Window/tile extraction.
- Band access.
- Transform preservation.
- Bounding-box calculations.
Use for:
- AOI polygons.
- Spatial filtering.
- Footprints.
- Intersections.
- Exporting GeoJSON-like results.
Use for:
- Coordinate transformation.
- CRS handling.
Primary framework for:
- Custom model development.
- Training.
- GPU inference.
- Checkpointing.
- Offline execution.
The final model should be stored locally, for example:
models/
├── semantic_encoder/
│ ├── model.pt
│ ├── config.json
│ └── metadata.json
└── change_detector/
├── model.pt
├── config.json
└── metadata.json
Recommended prototype options:
Input Tile
↓
Conv Block 1
↓
Conv Block 2
↓
Conv Block 3
↓
Global Average Pooling
↓
Dense Projection
↓
Embedding Vector
Advantages:
- Easier to train from scratch.
- Lower GPU requirements.
- Faster inference.
Image
↓
Patch Embedding
↓
Transformer Encoder Blocks
↓
Pooling
↓
Projection Head
↓
Embedding
Advantages:
- More expressive global context.
- Natural embedding output.
Disadvantage:
- More training data and compute may be required.
Start with:
- 256 dimensions for lightweight indexing, or
- 512 dimensions for richer representations.
Example:
Tile → Custom Encoder → 512 float values
Normalize vectors before cosine/inner-product search.
Before Image ──┐
├── Shared CNN Encoder
After Image ──┘
↓
Feature Comparison
↓
Fusion Layers
↓
Decoder / Classifier
↓
Change Mask + Change Class
The model can produce:
- Pixel-level change mask.
- Tile-level change probability.
- Change class.
Suggested classes:
0 = No Change
1 = Construction
2 = Clearance
3 = Water Increase
4 = Water Decrease
5 = Road Development
6 = Other Supported Change
- Absolute feature difference.
- Concatenation.
- Element-wise multiplication.
- Attention-based fusion.
A simple prototype can use:
abs(features_before - features_after)
followed by convolutional classification.
The project should separate:
from
A local LLM should not be treated as the core vision model.
Architecture:
Text Query ─────> Text Encoder ───> Text Embedding
│
│ similarity
│
Satellite Tile ─> Image Encoder ──> Image Embedding
Training requires image-text pairs.
Example labels/captions:
"new building near river"
"dense road network"
"large water body"
"cleared vegetation"
"industrial structures"
A contrastive objective can train matching text/image pairs closer together in embedding space.
A local language component can transform:
"Find new construction near a river between 2023 and 2025"
into:
{
"concepts": ["construction", "river"],
"date_start": "2023-01-01",
"date_end": "2025-12-31",
"change_required": true
}The structured output is then executed by the retrieval and geospatial systems.
Ollama can be installed locally and used offline after model staging.
Recommended role:
- Query interpretation.
- Filter extraction.
- Result explanation.
- Natural-language report generation.
Not recommended as the main model for:
- Satellite tile embeddings.
- Change masks.
- Geospatial image analysis.
Suggested structure:
training/
├── datasets/
│ ├── semantic_dataset.py
│ ├── change_dataset.py
│ └── augmentations.py
├── models/
│ ├── semantic_encoder.py
│ ├── text_encoder.py
│ └── siamese_change_model.py
├── losses/
│ ├── contrastive_loss.py
│ └── classification_loss.py
├── train_semantic.py
├── train_change.py
├── evaluate.py
└── export_model.py
Useful components:
- PyTorch Dataset/DataLoader.
- Mixed precision when supported.
- TensorBoard or local logs.
- Checkpoint saving.
- Deterministic seeds for reproducibility.
Primary sources specified for the challenge may include:
- Copernicus Sentinel-2 optical imagery.
- Copernicus Sentinel-1 SAR imagery.
- USGS Landsat Collection 2.
- NRSC/ISRO Bhuvan open Earth-observation products.
All datasets and licenses should be documented separately.
datasets/
├── raw/
│ ├── sentinel2/
│ ├── sentinel1/
│ ├── landsat/
│ └── bhuvan/
├── processed/
│ ├── tiles/
│ └── temporal_pairs/
├── labels/
│ ├── semantic/
│ └── changes/
└── manifests/
Each record should include:
{
"scene_id": "example",
"tile_id": "example_tile_001",
"sensor": "Sentinel-2",
"acquisition_time": "2025-01-15T00:00:00Z",
"bbox": [0, 0, 0, 0],
"crs": "EPSG:XXXX",
"labels": ["construction", "river"],
"quality_score": 0.92
}Possible processing:
- Band alignment.
- Reflectance scaling.
- Normalization.
- Cloud detection.
- Shadow detection.
- Haze estimation.
- Seasonal/context-aware comparison.
Possible processing:
- Speckle reduction.
- Calibration.
- Normalization.
- Geometric alignment.
SAR should not simply be mixed with optical data without sensor-aware processing.
Before/after images should be aligned.
Possible methods:
- Metadata/geotransform alignment.
- Feature-based alignment.
- Translation/affine refinement.
- Rejecting pairs with excessive registration error.
FAISS is recommended because it:
- Runs locally.
- Does not require a cloud service.
- Supports efficient nearest-neighbour search.
- Supports adding vectors incrementally.
For small-to-medium datasets:
IndexFlatIP
Advantages:
- Exact search.
- Simple.
- Easy to debug.
For larger datasets, evaluate approximate indexes such as IVF or HNSW implementations available in the selected environment.
Store separately:
FAISS Index
+
Metadata Database
FAISS contains:
vector_id → embedding
Database contains:
vector_id → tile metadata + provenance
Recommended for the full prototype.
Core tables:
scene_id
source
sensor
acquisition_time
crs
footprint
file_path
metadata_json
tile_id
scene_id
vector_id
geometry
tile_path
quality_score
processing_version
change_id
before_tile_id
after_tile_id
change_type
confidence
earliest_supported_observation
status
review_id
candidate_id
decision
timestamp
notes
run_id
input_id
step_name
parameters
model_version
output_id
timestamp
SQLite can be used for a small demonstration if PostGIS setup becomes too heavy, but PostgreSQL/PostGIS is preferred for strong geospatial filtering.
POST /api/search/text
Input:
{
"query": "newly built structures near a river",
"date_start": "2023-01-01",
"date_end": "2025-12-31",
"sensor": ["Sentinel-2"],
"top_k": 20
}POST /api/search/similar
Input:
{
"tile_id": "tile_123",
"top_k": 20
}POST /api/change/analyse
Input:
{
"aoi": {},
"date_start": "2023-01-01",
"date_end": "2025-12-31",
"change_types": ["construction", "clearance"]
}POST /api/ingestion/scene
Workflow:
- Validate.
- Register.
- Tile.
- Preprocess.
- Embed.
- Index.
- Commit.
Services:
docker-compose.yml
├── frontend
├── backend
└── database
AI models may be mounted or copied into the image/container.
Before evaluation, stage:
offline_bundle/
├── docker_images/
├── python_wheels/
├── model_weights/
├── local_llm_models/
├── datasets/
└── configs/
Download packages beforehand:
pip download -r requirements.txt -d offline_packagesInstall offline:
pip install --no-index --find-links=offline_packages -r requirements.txtCustom PyTorch checkpoint:
model.load_state_dict(torch.load("models/model.pt", map_location=device))All model paths should be local and configurable.
- Modern 4-core CPU.
- 16 GB RAM.
- 50+ GB available storage.
- Optional NVIDIA GPU.
- NVIDIA GPU with at least 8 GB VRAM.
- 32 GB RAM preferred.
- SSD storage.
- CUDA-compatible PyTorch environment.
CPU execution may be possible for lightweight models, but GPU acceleration will improve:
- Embedding generation.
- Change detection.
- Query response under load.
Hardware used must be documented in the evaluation report.
Core Python dependencies should include the versions tested by the team.
Example categories:
fastapi
uvicorn
torch
torchvision
numpy
pandas
rasterio
geopandas
shapely
pyproj
gdal
faiss-cpu or GPU-compatible alternative
scikit-learn
opencv-python
pydantic
sqlalchemy
psycopg
Exact versions must be frozen before final packaging.
- Collect public imagery.
- Validate licenses.
- Build scene manifest.
- Implement GeoTIFF reading.
- Implement tiling.
- Define classes/concepts.
- Label training tiles.
- Train custom image encoder.
- Generate embeddings.
- Build FAISS index.
- Implement metadata filtering.
- Implement nearest-neighbour search.
- Add result ranking.
- Build temporal pairs.
- Label change/no-change data.
- Train Siamese model.
- Add quality filtering.
- Build search.
- Build map.
- Build before/after comparison.
- Build review queue.
- Freeze dependencies.
- Package weights.
- Build containers.
- Disconnect network.
- Test from clean start.
Requirement Recommended Technology
Frontend React + TypeScript
Backend FastAPI
Custom model training PyTorch
Semantic embeddings Custom CNN / Small ViT
Change detection Custom Siamese CNN
Natural-language parsing Custom text encoder or optional local Ollama
GeoTIFF Rasterio + GDAL
Vector search FAISS
Geospatial DB PostgreSQL + PostGIS
Clustering scikit-learn / HDBSCAN if staged locally
Containerization Docker + Docker Compose
For the SIH prototype, the balanced stack is:
React + TypeScript
│
▼
FastAPI Backend
│
├── Rasterio / GDAL
├── PostgreSQL + PostGIS
├── FAISS
│
├── Custom Semantic CNN/ViT
│
└── Custom Siamese Change Model
│
▼
Local Model Weights
Optional:
Local Ollama
for query parsing and explanations
This design allows the team to demonstrate custom AI development while keeping the entire application reproducible and offline.