Refugee Settlement Detection and Population Displacement Tracking

Quantify population displacement and track informal settlement growth across conflict zones. Klarety processes Sentinel-2 optical and night-time lights composites to detect new shelter clusters, estimate settlement population scale, and map migration corridor changes month-over-month. NGOs and UN agencies use reports to direct aid allocation and camp planning.

Displacement intelligence for humanitarian response teams

Klarety AI
Klarety AI chat composer interface

Settlement detection reports from satellite composites

Klarety agents process Sentinel-2 and night-lights data and return monthly settlement growth estimates with population scale proxies.

VIIRS Night-lights
Klarety satellite analysis output

Night-lights and optical shelter cluster detection

Agents detect new built-up signatures in Sentinel-2 and corroborate with VIIRS night-lights to estimate settlement population scale.

GIS Output
Klarety AI map annotation overlay

Settlement layers for UN and NGO response GIS

Export new settlement polygons with population scale estimates for UNHCR camp planning and humanitarian GIS coordination tools.

Sentinel-2 and VIIRS night-lights settlement detection

Klarety agents detect new built-up structures using NDVI-loss and SWIR-increase signatures from Sentinel-2, then cross-validate with VIIRS night-time lights to confirm human habitation. Shelter cluster area is converted to population estimate using a density proxy (mean 4.5 people per shelter, 25m2 per shelter). Output is a monthly settlement polygon GeoJSON with population estimate and growth rate per cluster.

Klarety AIMap displacement and settlements in your region
analysis/refugee_settlement_detector.pyAgent code
python
import eeimport numpy as npimport pandas as pd
ee.Initialize()
# Kakuma refugee camp surroundings, Kenyaaoi = ee.Geometry.Rectangle([34.6, 3.5, 35.2, 4.1])
def detect_new_settlements(before_start, before_end, after_start, after_end):    """Detect new built-up areas from NDVI-loss + SWIR-increase."""    def s2_composite(start, end):        return (ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED')                .filterBounds(aoi)                .filterDate(start, end)                .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20))                .median())
    before = s2_composite(before_start, before_end)    after  = s2_composite(after_start, after_end)
    ndvi_before = before.normalizedDifference(['B8','B4'])    ndvi_after  = after.normalizedDifference(['B8','B4'])    ndvi_loss   = ndvi_before.subtract(ndvi_after)
    swir_before = before.select('B11')    swir_after  = after.select('B11')    swir_increase = swir_after.subtract(swir_before)
    # New structures: NDVI loss + SWIR increase (bare soil / sheltering material)    new_built = ndvi_loss.gt(0.1).And(swir_increase.gt(400)).rename('new_built')
    # VIIRS night-lights increase (confirms habitation)    viirs = (ee.ImageCollection('NOAA/VIIRS/DNB/MONTHLY_V1/VCMCFG')             .filterBounds(aoi)             .filterDate(after_start, after_end)             .mean()             .select('avg_rad'))
    lights_increase = viirs.gt(0.5)  # radiance > 0.5 nW/cm2/sr = inhabited
    # Confirmed settlement: structural change + lights    confirmed = new_built.And(lights_increase).rename('new_settlement')    area = confirmed.multiply(ee.Image.pixelArea()).reduceRegion(        ee.Reducer.sum(), aoi, 10, maxPixels=1e9    ).get('new_settlement').getInfo()
    area_m2 = area or 0    shelter_count = area_m2 / 25  # 25 m2 per shelter    pop_estimate  = shelter_count * 4.5  # 4.5 people per shelter    return round(area_m2/10000, 1), int(shelter_count), int(pop_estimate)
quarters = [    ('2025-01-01','2025-03-31','2025-04-01','2025-06-30','Q2 2025'),    ('2025-04-01','2025-06-30','2025-07-01','2025-09-30','Q3 2025'),    ('2025-07-01','2025-09-30','2025-10-01','2025-12-31','Q4 2025'),    ('2025-10-01','2025-12-31','2026-01-01','2026-03-31','Q1 2026'),]
print(f"{'Period':<10} {'New Area (ha)':<16} {'Shelters':<12} {'Pop Estimate'}")for *args, label in quarters:    a, s, p = detect_new_settlements(*args)    print(f"{label:<10} {a:<16.1f} {s:<12,} {p:,}")
output/refugee_settlement_report.mdOutput report
python
# Refugee Settlement Detection Report**AOI:** Kakuma surroundings, Kenya (34.6-35.2°E, 3.5-4.1°N)**Method:** Sentinel-2 NDVI-loss + SWIR-increase + VIIRS night-lights**Period:** Q2 2025 to Q1 2026
## Quarterly Settlement Growth| Period  | New Area (ha) | New Shelters | Pop Estimate | Cumulative Pop ||---------|--------------|-------------|-------------|----------------|| Q2 2025 | 18.4         | 7,360       | 33,120      | 33,120         || Q3 2025 | 22.1         | 8,840       | 39,780      | 72,900         || Q4 2025 | 31.4         | 12,560      | 56,520      | 129,420        || Q1 2026 | 28.7         | 11,480      | 51,660      | 181,080        |
## Growth Trend- Q4 2025 surge: **+42% vs Q3** — peak displacement influx- Q4 2025 correlates with conflict escalation in South Sudan border region- Q1 2026: sustained high inflow (+51,660 est.)
## Settlement Cluster Locations- **Cluster 1:** 34.82°E, 3.72°N — 41.2 ha, largest growth zone- **Cluster 2:** 35.01°E, 3.91°N — 28.6 ha, new expansion in NE- **Cluster 3:** 34.71°E, 3.64°N — 16.3 ha, infill of existing camp
## Aid Allocation Implications- Cluster 1 estimated pop: 74,160 — water point capacity gap- Camp total estimated: **181,080** — 36% above UNHCR registered 133,000- Unregistered arrival estimate: ~48,000 — urgent registration sweep needed
## MethodsSentinel-2 SR 10m NDVI-loss >0.1 + SWIR-increase >400 DN.VIIRS DNB night-lights >0.5 nW/cm2/sr for habitation confirmation.Pop proxy: 25 m2/shelter, 4.5 persons/shelter. Confidence: Low-Medium.

Try Klarety now.