Skip to content
AFM Studio
  • Pages

    AFM Studio
  • Work
  • Lab
  • About
  • CV
  • Contact
  • Projects

    AksaraA searchable library for Otorita IKN's knowledge, where the server checks every reader's access across three levels
  • Daily TaqwaTamper-resistant prayer attendance system for ~2,000 OIKN government employees at Masjid Negara IKN
  • Lantara v2A permit engine for Otorita IKN where administrators add new permit types from a screen, without a developer
  • eKiosk IKNTwo control rooms for Nusantara: kiosk content management and live bus tracking with arrival times that grade themselves
  • E-Monev IKNA monitoring platform for Nusantara's 23-year build, tracking every unit's quarterly progress against 24 national KPIs
  • JDIH OIKNOIKN's public legal document portal, with a controlled publishing workflow and AI summaries that never leave the server
  • Jejak PenanamanA check-in app for IKN tree-planting events that proves each participant was on site with a geofenced selfie
  • Dashboard SAKTIA nightly pipeline and dashboard that replaces OIKN's manual budget downloads for all six of its budget units
  • DoseRxA bedside dose calculator for 127 drugs that rounds each dose to tablets and syrups Indonesian pharmacies sell
  • CubiqA speedcubing trainer with competition-grade timing and a solver I wrote for each of the 8 major puzzles
  • ScimotionAn interactive science library of 86 articles, each explained next to animations the reader can control
  • WA Daily Scrum BotA WhatsApp bot that chases missing standup reports for a 14-person team and flags tasks stuck for days

↑ ↓ to move · Enter to open · Esc to close

Pola Hujan

An atlas of Indonesia's three rainfall patterns, computed from raw satellite data so anyone can check it

Screenshots
locations classified from satellite rainfall
86
agreement with BMKG across 52 compared cities
71%
verified disagreements reported, not hidden
4
network calls at runtime
0
On this page

The problem

Indonesians learn that the country has two seasons, rainy and dry. That's true for Java and wrong in much of the rest of the country. Ambon's wet season falls in Java's dry months, and parts of the equatorial belt get two wet peaks a year. BMKG, the national weather agency, knows this. It maps 699 season zones in three families: Monsunal, Ekuatorial and Lokal. But that knowledge lives in PDF bulletins and expert judgement, not in something a curious person can open and explore.

I built Pola Hujan for general Indonesian readers who want to know why "rainy season" means different things in different places. It describes long-term climate. It isn't a forecast or a planting calendar, and the site says so on its first screen.

What I built

I computed the map from raw data

The easy route was to digitise BMKG's zone map and colour it in. I computed my own classification from satellite rainfall instead. Each place's twelve-month rainfall cycle is treated as a wave and split into a yearly part and a twice-a-year part, the same maths that describes tides. Which part is stronger, and when it peaks, decides the family. Anyone can check the result.

Disagreements with BMKG stay on the map

The thresholds live in one file, each cited to Aldrian and Susanto (2003), the paper behind the three-family system. I set a rule never to adjust them until the map matches BMKG. Four places where my result differs, Medan, Palu, Tobelo and Labuha, stay on the map as reported findings, not quietly resolved. A separate layer marks every place where the two maps disagree, with sources, and the agreement rate has moved as I've added more cited comparisons, never from touching a threshold.

I tested the classifier on made-up data first

A generator builds rainfall cycles from known wave settings, and the classifier has to recover those exact settings. One permanent test covers a cycle that peaks six months after Java's, which must come out as the inverted family. Only after those tests passed did I run it on satellite data.

A static site with no heavy libraries

The pipeline downloads CHIRPS satellite archives and reads the raster files with decoders I wrote by hand. There is no mapping, charting, statistics or machine-learning library. Everything runs once at build time, so the site is static, makes no network calls and costs nothing to host. Download cost is dominated by the fixed set of monthly rasters, not by how many places get sampled from them. Coverage grew from an initial 15 cities to 34, then to 86, at almost no extra cost each time.

I turned down the obvious build

The easy pitch was an animated wind map: a gridded field, a month dial, particles drifting across it. I would have built a third near-identical animated-field project. I chose a categorical atlas instead, small multiples and time series rather than a continuous vector field, because the map's job here is to show which family a place belongs to, not to look impressive in motion.

Result

Pola Hujan is live, in Indonesian. A story-driven home page introduces the three families, then the atlas, individual city pages, a two-place comparison, and a merged method-and-explainer page carry the detail. It covers 86 locations. I've compared 52 of them against BMKG's published families, and my map agrees on 71%. Of those 52 comparisons, 32 are independently verified against the agency's own bulletin, up from zero; the other 20 are marked as estimates. I built the first version in three days in mid-August 2026, then kept returning over the following weeks to redesign the palette and type system, merge the method pages into one, and more than double the city count.

Under the hoodTechnical detail for engineers
  • The harmonic fit decomposes each location's monthly climatology into annual and semi-annual components. Amplitude ratio and peak phase decide Monsunal, Ekuatorial or Lokal.
  • Thresholds live in a single cited config file. Agreement with BMKG is computed by the pipeline, never written by hand.
  • A synthetic generator produces cycles from known parameters, with a permanent regression case for the phase-inverted family.
  • Hand-written decoders (lib/geo/bil.ts, lib/geo/tar.ts) read CHIRPS BIL rasters and tar archives directly, so there's no GDAL dependency.
  • The build downloads 120 monthly CHIRPS rasters, samples all 86 city coordinates plus a 0.25° mosaic grid of 2,414 land cells over Indonesia, then runs the harmonic fit over every point. A determinism check asserts the same source version and thresholds produce a byte-identical bundle; the original 34 cities' values stayed byte-identical after the sampling method changed for the newer ones.
  • The design system's shared border-radius rule is softened here on purpose: 2px on data marks, 10px and 22px on panels and sheets, recorded as a named per-app deviation rather than an inconsistency.
  • Fetch, fit and classification run at build time. The output is a static export on GitHub Pages, deployed by GitHub Actions on every push to main.
  • 169 tests across 17 files gate CI. About 6,369 lines of TypeScript, 98 commits between 17 August and 29 September 2026: the first three days built the pipeline and the original site, then a further stretch of weeks redesigned the palette and type system, merged /metode and /harmonik into one /cara-kerja page, and expanded coverage from 34 cities to 86.

Screenshots

Beranda
Beranda (2)
Beranda (3)
Peta Pola Hujan
Semua Kota
Perbandingan

Hiring, or building something similar?

I'm open to full-time roles and select freelance work.