420 lines
15 KiB
HTML
420 lines
15 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="id">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>WebGIS SPBU, Jalan & Parsil</title>
|
||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
||
<link rel="stylesheet" href="css/style.css">
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&family=Fira+Code:wght@400;500&display=swap">
|
||
</head>
|
||
<body>
|
||
|
||
<div id="loading">
|
||
<div class="ld-inner">
|
||
<div class="spin"></div>
|
||
<p>Memuat WebGIS…</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="app">
|
||
|
||
<!-- ═══════════ SIDEBAR ═══════════ -->
|
||
<aside id="sidebar">
|
||
<div class="sb-header">
|
||
<div class="sb-brand">
|
||
<div class="sb-icon">⛽</div>
|
||
<div>
|
||
<div class="sb-title">WebGIS SPBU</div>
|
||
<div class="sb-sub">Jalan & Parsil Tanah</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="sb-scroll">
|
||
|
||
<!-- Tipe Geometri -->
|
||
<div class="sb-section">
|
||
<div class="sb-label">Tipe Geometri</div>
|
||
<div class="geom-selector">
|
||
<button class="geom-btn" data-geom="point">📍 Point</button>
|
||
<button class="geom-btn" data-geom="polyline">📏 Line</button>
|
||
<button class="geom-btn" data-geom="polygon">🗺️ Polygon</button>
|
||
</div>
|
||
<div class="geom-hint" id="geom-hint">
|
||
<span class="gh-dot"></span>
|
||
<span id="geom-hint-text">Klik tipe untuk mulai menggambar</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Legenda SPBU -->
|
||
<div class="sb-section">
|
||
<div class="sb-label">Legenda SPBU</div>
|
||
<div class="legend-card">
|
||
<div class="leg-row"><span class="leg-dot spbu-24"></span> Buka 24 Jam</div>
|
||
<div class="leg-row"><span class="leg-dot spbu-ltd"></span> Tidak 24 Jam</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Legenda Jalan -->
|
||
<div class="sb-section">
|
||
<div class="sb-label">Legenda Jalan</div>
|
||
<div class="legend-card">
|
||
<div class="leg-row"><span class="leg-line jalan-nas"></span> Jalan Nasional</div>
|
||
<div class="leg-row"><span class="leg-line jalan-prov"></span> Jalan Provinsi</div>
|
||
<div class="leg-row"><span class="leg-line jalan-kab"></span> Jalan Kabupaten</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Legenda Parsil -->
|
||
<div class="sb-section">
|
||
<div class="sb-label">Legenda Parsil Tanah</div>
|
||
<div class="legend-card">
|
||
<div class="leg-row"><span class="leg-poly parsil-shm"></span> SHM — Hak Milik</div>
|
||
<div class="leg-row"><span class="leg-poly parsil-hgb"></span> HGB — Hak Guna Bangunan</div>
|
||
<div class="leg-row"><span class="leg-poly parsil-hgu"></span> HGU — Hak Guna Usaha</div>
|
||
<div class="leg-row"><span class="leg-poly parsil-hp"></span> HP — Hak Pakai</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Statistik -->
|
||
<div class="sb-section">
|
||
<div class="sb-label">Statistik</div>
|
||
<div class="stat-grid">
|
||
<div class="stat-item"><div class="stat-num" id="cnt-total">—</div><div class="stat-lbl">Total SPBU</div></div>
|
||
<div class="stat-item green"><div class="stat-num" id="cnt-24">—</div><div class="stat-lbl">Buka 24 Jam</div></div>
|
||
<div class="stat-item blue"><div class="stat-num" id="cnt-jalan">—</div><div class="stat-lbl">Jalan</div></div>
|
||
<div class="stat-item purple"><div class="stat-num" id="cnt-parsil">—</div><div class="stat-lbl">Parsil</div></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Daftar SPBU -->
|
||
<div class="sb-section">
|
||
<div class="sb-label">Daftar SPBU</div>
|
||
<div id="spbu-list"></div>
|
||
</div>
|
||
|
||
</div>
|
||
</aside>
|
||
|
||
<!-- ═══════════ MAIN ═══════════ -->
|
||
<div id="main">
|
||
<div id="topbar">
|
||
<div class="coord-pill">
|
||
<span>📍</span>
|
||
<span id="cur-lat">—</span><span class="pill-sep">|</span><span id="cur-lng">—</span>
|
||
</div>
|
||
|
||
<div id="search-wrap">
|
||
<div class="search-box">
|
||
<span class="search-icon">🔍</span>
|
||
<input id="search-input" type="text" placeholder="Cari SPBU, Jalan, Parsil…" autocomplete="off">
|
||
</div>
|
||
<div id="search-results"></div>
|
||
</div>
|
||
|
||
<!-- Layer toggle button -->
|
||
<div class="layer-wrap" id="lw">
|
||
<button class="layer-btn" id="ldbtn">
|
||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||
<path d="M8 1L14.5 4.5L8 8L1.5 4.5L8 1Z" stroke="currentColor" stroke-width="1.4" stroke-linejoin="round"/>
|
||
<path d="M1.5 8L8 11.5L14.5 8" stroke="currentColor" stroke-width="1.4" stroke-linejoin="round"/>
|
||
<path d="M1.5 11.5L8 15L14.5 11.5" stroke="currentColor" stroke-width="1.4" stroke-linejoin="round"/>
|
||
</svg>
|
||
Layer <span class="chev">▼</span>
|
||
</button>
|
||
<div class="layer-menu" id="layer-menu">
|
||
<div class="lm-label">Tampilkan Layer</div>
|
||
|
||
<label class="lm-item">
|
||
<input type="checkbox" id="lm-point" checked>
|
||
<span class="lm-check"></span>
|
||
<span class="lm-icon">📍</span>
|
||
<span>SPBU</span>
|
||
</label>
|
||
|
||
<div class="lm-sub" id="lm-sub-spbu">
|
||
<label class="lm-sub-item">
|
||
<input type="checkbox" id="lm-spbu24" checked>
|
||
<span class="lm-check sm"></span>
|
||
<span class="lm-sub-dot dot-green"></span>
|
||
<span>Buka 24 Jam</span>
|
||
</label>
|
||
<label class="lm-sub-item">
|
||
<input type="checkbox" id="lm-spbuLtd" checked>
|
||
<span class="lm-check sm"></span>
|
||
<span class="lm-sub-dot dot-red"></span>
|
||
<span>Tidak 24 Jam</span>
|
||
</label>
|
||
</div>
|
||
|
||
<label class="lm-item">
|
||
<input type="checkbox" id="lm-jalan" checked>
|
||
<span class="lm-check"></span>
|
||
<span class="lm-icon">📏</span>
|
||
<span>Jalan</span>
|
||
</label>
|
||
|
||
<label class="lm-item">
|
||
<input type="checkbox" id="lm-parsil" checked>
|
||
<span class="lm-check"></span>
|
||
<span class="lm-icon">🗺️</span>
|
||
<span>Parsil</span>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="map-wrap">
|
||
<div id="map"></div>
|
||
|
||
<!-- Draw toolbar -->
|
||
<div id="draw-toolbar">
|
||
<div class="dt-hint">ℹ️ <span id="dt-hint-text">Klik peta untuk menggambar</span></div>
|
||
<span class="dt-counter" id="dt-counter">0 titik</span>
|
||
<button class="dt-btn undo" id="btn-undo" disabled>↩️ Undo</button>
|
||
<button class="dt-btn redo" id="btn-redo" disabled>↪️ Redo</button>
|
||
<button class="dt-btn cancel" id="btn-cancel-draw">❌ Batal</button>
|
||
<button class="dt-btn finish" id="btn-finish">✅ Selesai</button>
|
||
</div>
|
||
|
||
<!-- Geom Edit toolbar -->
|
||
<div id="geom-edit-toolbar">
|
||
<div class="dt-hint">📐 <span id="geom-edit-hint">Drag titik untuk edit geometri</span></div>
|
||
<span class="dt-counter geom-edit-counter" id="geom-edit-info"></span>
|
||
<button class="dt-btn cancel" id="btn-geom-cancel">❌ Batal</button>
|
||
<button class="dt-btn finish" id="btn-geom-save">💾 Simpan</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ═══════════ MODALS ═══════════ -->
|
||
|
||
<!-- Tambah SPBU -->
|
||
<div class="overlay" id="m-add-spbu">
|
||
<div class="modal">
|
||
<div class="modal-head">
|
||
<div class="modal-head-icon">⛽</div>
|
||
<h2>Tambah SPBU</h2>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="form-group">
|
||
<label>Nama SPBU</label>
|
||
<input id="spbu-nama" placeholder="Contoh: SPBU MJ 1234">
|
||
</div>
|
||
<div class="form-group">
|
||
<label>No WhatsApp</label>
|
||
<input id="spbu-wa" placeholder="Contoh: 62812345678">
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Status Operasional</label>
|
||
<select id="spbu-status">
|
||
<option value="full">Buka 24 Jam</option>
|
||
<option value="limited">Tidak 24 Jam</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Koordinat</label>
|
||
<div class="form-row">
|
||
<input id="spbu-lat" placeholder="Latitude" readonly>
|
||
<input id="spbu-lng" placeholder="Longitude" readonly>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal-foot">
|
||
<button class="btn-ghost" onclick="closeModal('m-add-spbu')">Batal</button>
|
||
<button class="btn-primary green" onclick="saveSpbu()">💾 Simpan SPBU</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tambah Jalan -->
|
||
<div class="overlay" id="m-add-jalan">
|
||
<div class="modal">
|
||
<div class="modal-head">
|
||
<div class="modal-head-icon">🛣️</div>
|
||
<h2>Tambah Jalan</h2>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="form-group">
|
||
<label>Nama Jalan</label>
|
||
<input id="j-nama" placeholder="Contoh: Jalan Ahmad Yani">
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Status Jalan</label>
|
||
<select id="j-status">
|
||
<option value="nasional">Nasional</option>
|
||
<option value="provinsi">Provinsi</option>
|
||
<option value="kabupaten">Kabupaten</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Panjang (meter)</label>
|
||
<input id="j-panjang" readonly>
|
||
</div>
|
||
</div>
|
||
<div class="modal-foot">
|
||
<button class="btn-ghost" onclick="closeModal('m-add-jalan')">Batal</button>
|
||
<button class="btn-primary green" onclick="saveJalan()">💾 Simpan Jalan</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tambah Parsil -->
|
||
<div class="overlay" id="m-add-parsil">
|
||
<div class="modal">
|
||
<div class="modal-head">
|
||
<div class="modal-head-icon">🗺️</div>
|
||
<h2>Tambah Parsil</h2>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="form-group">
|
||
<label>Nama Parsil</label>
|
||
<input id="p-nama" placeholder="Contoh: Tanah A">
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Status Kepemilikan</label>
|
||
<select id="p-status">
|
||
<option value="SHM">SHM — Hak Milik</option>
|
||
<option value="HGB">HGB — Hak Guna Bangunan</option>
|
||
<option value="HGU">HGU — Hak Guna Usaha</option>
|
||
<option value="HP">HP — Hak Pakai</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Luas (m²)</label>
|
||
<input id="p-luas" readonly>
|
||
</div>
|
||
</div>
|
||
<div class="modal-foot">
|
||
<button class="btn-ghost" onclick="closeModal('m-add-parsil')">Batal</button>
|
||
<button class="btn-primary purple" onclick="saveParsil()">💾 Simpan Parsil</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Edit SPBU -->
|
||
<div class="overlay" id="m-edit-spbu">
|
||
<div class="modal">
|
||
<div class="modal-head">
|
||
<div class="modal-head-icon">✏️</div>
|
||
<h2>Edit SPBU</h2>
|
||
</div>
|
||
<input type="hidden" id="e-spbu-id">
|
||
<div class="modal-body">
|
||
<div class="form-group">
|
||
<label>Nama SPBU</label>
|
||
<input id="e-spbu-nama">
|
||
</div>
|
||
<div class="form-group">
|
||
<label>No WhatsApp</label>
|
||
<input id="e-spbu-wa">
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Status Operasional</label>
|
||
<select id="e-spbu-status">
|
||
<option value="full">Buka 24 Jam</option>
|
||
<option value="limited">Tidak 24 Jam</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div class="modal-foot">
|
||
<button class="btn-ghost" onclick="closeModal('m-edit-spbu')">Batal</button>
|
||
<button class="btn-primary green" onclick="updateSpbu()">✅ Update SPBU</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Edit Jalan -->
|
||
<div class="overlay" id="m-edit-jalan">
|
||
<div class="modal">
|
||
<div class="modal-head">
|
||
<div class="modal-head-icon">✏️</div>
|
||
<h2>Edit Jalan</h2>
|
||
</div>
|
||
<input type="hidden" id="e-jalan-id">
|
||
<div class="modal-body">
|
||
<div class="form-group">
|
||
<label>Nama Jalan</label>
|
||
<input id="e-j-nama">
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Status Jalan</label>
|
||
<select id="e-j-status">
|
||
<option value="nasional">Nasional</option>
|
||
<option value="provinsi">Provinsi</option>
|
||
<option value="kabupaten">Kabupaten</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Panjang (meter)</label>
|
||
<input id="e-j-panjang" readonly>
|
||
</div>
|
||
</div>
|
||
<div class="modal-foot">
|
||
<button class="btn-ghost" onclick="closeModal('m-edit-jalan')">Batal</button>
|
||
<button class="btn-primary blue" onclick="updateJalan()">✅ Update Jalan</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Edit Parsil -->
|
||
<div class="overlay" id="m-edit-parsil">
|
||
<div class="modal">
|
||
<div class="modal-head">
|
||
<div class="modal-head-icon">✏️</div>
|
||
<h2>Edit Parsil</h2>
|
||
</div>
|
||
<input type="hidden" id="e-parsil-id">
|
||
<div class="modal-body">
|
||
<div class="form-group">
|
||
<label>Nama Parsil</label>
|
||
<input id="e-p-nama">
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Status Kepemilikan</label>
|
||
<select id="e-p-status">
|
||
<option value="SHM">SHM — Hak Milik</option>
|
||
<option value="HGB">HGB — Hak Guna Bangunan</option>
|
||
<option value="HGU">HGU — Hak Guna Usaha</option>
|
||
<option value="HP">HP — Hak Pakai</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Luas (m²)</label>
|
||
<input id="e-p-luas" readonly>
|
||
</div>
|
||
</div>
|
||
<div class="modal-foot">
|
||
<button class="btn-ghost" onclick="closeModal('m-edit-parsil')">Batal</button>
|
||
<button class="btn-primary purple" onclick="updateParsil()">✅ Update Parsil</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Confirm Dialog -->
|
||
<div class="overlay" id="confirm-overlay">
|
||
<div class="modal confirm-modal">
|
||
<div class="modal-head">
|
||
<div class="modal-head-icon" style="background:#dc2626;">⚠️</div>
|
||
<h2 id="confirm-title" style="color:var(--red);">Konfirmasi</h2>
|
||
</div>
|
||
<div class="confirm-body">
|
||
<p id="confirm-message" class="confirm-message">Apakah Anda yakin?</p>
|
||
</div>
|
||
<div class="modal-foot">
|
||
<button class="btn-ghost" id="confirm-cancel">Tidak, Batal</button>
|
||
<button class="btn-primary red" id="confirm-ok">🗑️ Ya, Hapus</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="toasts"></div>
|
||
|
||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
||
<script src="https://cdn.jsdelivr.net/npm/@turf/turf@6/turf.min.js"></script>
|
||
<script src="js/main.js"></script>
|
||
</body>
|
||
</html> |