Nexa Intelligence Docs
Dashboard

CCTV Daerah

Spesifikasi teknis modul CCTV Daerah (/dashboard/cctv), pemetaan database PostgreSQL tabel cctv_cameras, pemantauan streaming kamera ATCS publik & jalan tol, serta status HLS.

CCTV Daerah (/dashboard/cctv)

Modul CCTV Daerah mengagregasikan ribuan tautan streaming video kamera pengawas lalu lintas (ATCS), fasilitas publik, dan kamera jalan tol nasional dari berbagai instansi daerah dan kementerian ke dalam direktori terpadu berbasis peta wilayah.

Seluruh data CCTV disimpan dan dikelola langsung pada tabel PostgreSQL cctv_cameras.


Tabel Pemetaan Komponen ke PostgreSQL & Elasticsearch

Komponen / Bagian UIPostgreSQL (Tabel & Kolom Kunci)Elasticsearch (Indeks & Field Kunci)Kafka (Topik & Alur Event)
Katalog & Pemutar Stream CCTV DKI Jakarta
GET /api/v1/cctv/jakarta
• cctv_cameras
  ↳ Filter: kind = 'jakarta' AND active = true
  ↳ id, name, url, wilayah_kota, kecamatan, instansi, lat, lng, location_approx, status
• cctv_directory (opsional)
  ↳ camera_id, location_name, stream_status, coordinates (geo_point)
queue-cctv-healthcheck
(HLS / RTSP Health Poller)
Dropdown Filter Wilayah Jakarta
GET /api/v1/cctv/jakarta/wilayah
• cctv_cameras
  ↳ Filter: kind = 'jakarta'
  ↳ wilayah_kota, kecamatan (terkelompok hierarkis)
——
Statistik Sebaran & Titik Peta Jakarta
GET /api/v1/cctv/jakarta/peta
• cctv_cameras
  ↳ Filter: kind = 'jakarta'
  ↳ Agregasi per wilayah_kota, kecamatan, centroid lat, lng, location_approx
• cctv_directory
  ↳ Geo-aggregation / cluster
—
Direktori Portal CCTV Nasional
GET /api/v1/cctv
• cctv_cameras
  ↳ Filter: kind = 'national_portal' AND active = true
  ↳ id, portal_id, name, province, instansi, category, url, camera_count
——
Daftar Ruas Jalan Tol
GET /api/v1/cctv/{id}/ruas
• cctv_cameras
  ↳ Filter: kind = 'national_ruas' AND city = <portal_id>
  ↳ id, portal_id, name, city, camera_count
——
Daftar Kamera Portal / Ruas Nasional
GET /api/v1/cctv/{id}/kamera
• cctv_cameras
  ↳ Filter: kind = 'national_camera' AND portal_id = <portal_or_ruas_id>
  ↳ id, name, url, category, portal_id, status
—queue-cctv-healthcheck
Dropdown Filter Wilayah Nasional
GET /api/v1/cctv/wilayah
• cctv_cameras
  ↳ Filter: kind = 'national_portal'
  ↳ DISTINCT province
——

Skema Relasional PostgreSQL (cctv_cameras)

Tabel cctv_cameras memegang peran tunggal (single source of truth) untuk seluruh hierarki CCTV, mulai dari portal agregator nasional, segmen ruas tol, hingga kamera individual Jakarta dan daerah.

DO $$ BEGIN
  CREATE TYPE cctv_camera_kind AS ENUM (
    'jakarta',           -- Kamera individual DKI Jakarta (Balitower, JSC, Dishub)
    'national_camera',  -- Kamera individual dari portal luar Jakarta / ruas tol
    'national_portal',  -- Portal agregator CCTV luar Jakarta
    'national_ruas'     -- Ruas jalan tol (misal ruas tol Bina Marga)
  );
EXCEPTION
  WHEN duplicate_object THEN NULL;
END $$;

CREATE TABLE IF NOT EXISTS cctv_cameras (
  id               UUID            PRIMARY KEY,         -- Deterministic UUID v5
  kind             cctv_camera_kind NOT NULL,
  name             TEXT            NOT NULL,            -- Nama kamera / portal / ruas
  url              TEXT,                                -- Stream URL (HLS .m3u8 / RTSP) atau URL portal
  wilayah_kota     TEXT,                                -- Khusus Jakarta (misal: "Jakarta Pusat")
  kecamatan        TEXT,                                -- Khusus Jakarta (nama kecamatan ternormalisasi)
  instansi         TEXT,                                -- Penyedia/operator (Balitower, Dishub, BPJT, dsb)
  province         TEXT,                                -- Provinsi (portal nasional)
  city             TEXT,                                -- Kota / parent portal id untuk ruas
  category         TEXT,                                -- Kategori: ATCS, Dishub, Polri, Jalan Tol, Pemda, Lainnya
  portal_id        TEXT,                                -- ID portal induk atau ID ruas jalan tol
  mechanism        TEXT,                                -- Mekanisme ingest / stream
  camera_count     INTEGER,                             -- Total kamera yang dikelola portal / ruas
  lat              DOUBLE PRECISION,                    -- Latitude koordinat / centroid
  lng              DOUBLE PRECISION,                    -- Longitude koordinat / centroid
  location_approx  BOOLEAN         NOT NULL DEFAULT false, -- True jika koordinat merupakan centroid kecamatan
  status           TEXT            NOT NULL DEFAULT 'verified', -- Status stream / snapshot
  active           BOOLEAN         NOT NULL DEFAULT true,
  sort_order       INTEGER         NOT NULL DEFAULT 0,
  created_at       TIMESTAMPTZ     NOT NULL DEFAULT now(),
  updated_at       TIMESTAMPTZ     NOT NULL DEFAULT now()
);

-- Indeks performa query
CREATE INDEX IF NOT EXISTS idx_cctv_cameras_kind ON cctv_cameras (kind);
CREATE INDEX IF NOT EXISTS idx_cctv_cameras_portal_id ON cctv_cameras (portal_id);
CREATE INDEX IF NOT EXISTS idx_cctv_cameras_wilayah_kota ON cctv_cameras (wilayah_kota);
CREATE INDEX IF NOT EXISTS idx_cctv_cameras_kecamatan ON cctv_cameras (kecamatan);
CREATE INDEX IF NOT EXISTS idx_cctv_cameras_province ON cctv_cameras (province);
CREATE INDEX IF NOT EXISTS idx_cctv_cameras_category ON cctv_cameras (category);

Aproksimasi Koordinat Geospasial

Untuk kamera DKI Jakarta (kind = 'jakarta'), koordinat lat dan lng menggunakan titik centroid batas administratif kecamatan publik (location_approx = true), bukan titik GPS presisi fisik tiang kamera. Hal ini mencegah tumpang tindih titik acak serta selaras dengan metadata publik dari penyedia stream.


Pemutaran Stream HLS/RTSP & Health Poller

Setiap entri kamera menyimpan metadata URL stream HLS (.m3u8) atau RTSP yang dapat diputar langsung di pemutar web front-end.

  1. Status Snapshot: Kolom status menyimpan verifikasi keaktifan stream (secara default 'verified').
  2. Health Check Worker: Worker background secara periodik memvalidasi ketersediaan manifest .m3u8 melalui antrian event Kafka queue-cctv-healthcheck.
  3. Filter Otomatis: Jika stream mati atau URL kedaluwarsa, status dapat ditandai offline atau active = false sehingga tidak ditampilkan di kartu streaming dashboard.

On this page