Taryana
PostGIS R-Tree EngineGeospatial & Fiber Topology
TESTER READY • LIVE ENGINE

PostGIS Spatial R-Tree & ODP Fiber Allocation

Real-Time EPSG:4326 Point-in-Polygon & Optical Loss Attenuation

Validasi geospasial real-time titik koordinat pelanggan, kalkulasi jarak kabel drop optik, estimasi degradasi redaman (dBm), dan auto-lock port splitter ODP tanpa full-table scan.

Diagram Alur Data & Arsitektur Sistem

Visual Interaktif

Alur Verifikasi Spasial PostGIS & Reservasi Port ODP

Pencarian ODP terdekat dalam radius 150m dengan estimasi redaman optik

client
Field Sales

Sales App

Input Lat/Lng GPS

POST /coverage/check
gateway
Reverse Proxy

API Gateway

Rate Limit & Auth

ST_DWithin Query
db
Spatial R-Tree

PostGIS GiST

ST_DWithin (<4.8ms)

Distance 85m
service
dBm Headroom

Optical Engine

Kalkulasi -dBm Loss

SETNX lock:odp:port
cache
Distributed Mutex

Redis Port Lock

Lock 24h (Anti Double-Book)

Problem & Latar Belakang Kebutuhan

Pada operasional ISP FTTH skala enterprise, verifikasi ketersediaan jaringan secara manual memakan waktu berjam-jam. Pengecekan via query biasa pada jutaan titik kabel dan polygon boundary ODP menyebabkan CPU PostgreSQL 100% dan rawan insiden double-booking port splitter ODP yang sama saat sales mengajukan order bersamaan.

Implementasi Backend NestJS & PostGIS Spasial

Engine memanfaatkan PostgreSQL dengan ekstensi PostGIS dan indeks spasial GiST R-Tree (Spatial Indexing EPSG:4326). Saat sales menginput titik koordinat, query ST_DWithin dan ST_Distance mengeksekusi pencarian ODP terdekat dalam radius 150 meter dalam waktu <4.8ms. Algoritma redaman optik menghitung estimasi dBm berdasarkan panjang drop wire dan jumlah splice. Port ODP yang valid langsung di-lock dengan transaksi SERIALIZABLE dan TTL 24 jam di Redis.

Aspek Skema Geometri PostgreSQL & PostGIS

Tabel PostgreSQL odp_nodes menggunakan kolom geometri geom GEOMETRY(Point, 4326) dengan indeks USING GIST(geom). Status alokasi port disimpan dalam bitmask ports_bitmask dengan verifikasi atomic WHERE (ports_bitmask & (1 << port_index)) = 0.

Keamanan, Idempotensi & Kepatuhan SLA

Mencegah race condition double-booking splitter melalui Redis distributed lock pada ODP key dan database constraint UNIQUE(odp_id, port_number, active_reservation).

NestJS & PostGIS: ST_DWithin Fiber Nearest LookupNestJS (TypeScript) / PostGIS
// PostGIS Spatial Service di NestJS: Cari ODP terdekat & hitung estimasi redaman dBm
@Injectable()
export class CoverageGisService {
  constructor(
    @InjectDataSource() private readonly dataSource: DataSource,
    private readonly redisService: RedisService,
  ) {}

  async checkProspectCoverage(lat: number, lng: number): Promise<CoverageResult> {
    const rawQuery = `
      SELECT
        id, name, code, total_ports, used_ports,
        ST_Distance(geom::geography, ST_SetSRID(ST_MakePoint($1, $2), 4326)::geography) AS distance_meters
      FROM odp_nodes
      WHERE ST_DWithin(geom::geography, ST_SetSRID(ST_MakePoint($1, $2), 4326)::geography, 150.0)
        AND (total_ports - used_ports) > 0
      ORDER BY distance_meters ASC
      LIMIT 1;
    `;

    const [nearestOdp] = await this.dataSource.query(rawQuery, [lng, lat]);

    if (!nearestOdp) {
      return { covered: false, reason: "Titik di luar radius 150m ODP aktif" };
    }

    const dist = parseFloat(nearestOdp.distance_meters);
    // Formula Redaman: Base OLT (-15.0 dBm) - (Jarak km * 0.35 dB/km) - (2 Splice * 0.1 dB)
    const lossDbm = Number((-15.0 - (dist / 1000.0) * 0.35 - 0.2).toFixed(2));

    // Lock port ODP di Redis selama 24 jam untuk cegah double-booking
    await this.redisService.set(`lock:odp:${nearestOdp.id}:port`, "reserved", "EX", 86400);

    return {
      covered: true,
      odpCode: nearestOdp.code,
      distanceMeters: Math.round(dist * 10) / 10,
      estimatedLossDbm: lossDbm,
      availablePorts: nearestOdp.total_ports - nearestOdp.used_ports,
    };
  }
}

Live Simulator & Execution Sandbox

Interactive State Tester
Radius Pencarian ST_DWithin:120 Meter
(ODP terdekat berada pada jarak 84.2m. Atur di bawah 80m untuk menguji respons out-of-range).

Tekan tombol Jalankan Simulasi & Uji Eksekusi di atas untuk mengeksekusi kueri PostGIS ST_DWithin dan memuat visualisasi peta Google Maps interaktif dengan pin penanda serta kartu melayang identitas ODP.

Execution Telemetry Console
HTTP 200 OK
POST/api/v1/network/coverage/check
> Guard Evaluation Trace:

PostGIS GiST R-Tree ST_DWithin query executed in 3.8ms. Matched ODP-FATMAWATI-42 (84.2m).

> Database & State Result:

Estimated optical attenuation: -17.4 dBm. Port 4 of 8 available. Redis lock acquired with 24h TTL.

Audit Trail PostgreSQL & Redis (2 events)Auto-Appended
[10:14:02]SETTLEMENT(Double-Entry Worker)•WEBHOOK_INVOICE_SETTLED

HMAC-SHA256 verified. Redis Redlock acquired. Invoice INV-2026-0982 settled with zero ledger variance.

SUCCESS
[10:22:15]POSTGIS(Coverage Engine (NestJS))•ODP_PORT_RESERVED

ST_DWithin R-Tree matched ODP in 4.1ms (dist: 84.2m). Optical loss -17.4 dBm. Splitter port locked with 24h Redis TTL.

SUCCESS