`);
});
});
}
function statusSPBU(spbu) {
if (spbu.buka_24_jam == 1) {
return `
BUKA 24 JAM
`;
}
if (!spbu.jam_buka || !spbu.jam_tutup) {
return `
Jam belum diatur
`;
}
let now = new Date().toTimeString().substring(0, 5);
let buka = spbu.jam_buka.substring(0, 5);
let tutup = spbu.jam_tutup.substring(0, 5);
let bukaStatus = false;
if (buka < tutup) {
bukaStatus = now >= buka && now <= tutup;
} else {
bukaStatus = now >= buka || now <= tutup;
}
return bukaStatus
? `BUKA`
: `TUTUP`;
}
map.on("click", function (e) {
if (!modeAdmin) {
return;
}
if (sedangMenggambar) {
return;
}
if (
map._container.classList.contains("leaflet-draw-draw-polygon") ||
map._container.classList.contains("leaflet-draw-draw-polyline")
) {
return;
}
let lat = e.latlng.lat;
let lng = e.latlng.lng;
L.popup()
.setLatLng(e.latlng)
.setContent(
`
Tambah SPBU
`,
)
.openOn(map);
});
document.addEventListener("change", function (e) {
if (e.target.id !== "buka_24_jam") return;
let checked = e.target.checked;
document.getElementById("jam_buka").disabled = checked;
document.getElementById("jam_tutup").disabled = checked;
});
function simpanSPBU() {
let nama = document.getElementById("nama").value;
let alamat = document.getElementById("alamat").value;
let lat = document.getElementById("lat").value;
let lng = document.getElementById("lng").value;
let formData = new FormData();
formData.append("nama", nama);
formData.append("alamat", alamat);
formData.append("lat", lat);
formData.append("lng", lng);
let jamBuka = document.getElementById("jam_buka").value;
let jamTutup = document.getElementById("jam_tutup").value;
let buka24Jam = document.getElementById("buka_24_jam").checked ? 1 : 0;
formData.append("jam_buka", jamBuka);
formData.append("jam_tutup", jamTutup);
formData.append("buka_24_jam", buka24Jam);
let foto = document.getElementById("foto");
if (foto && foto.files.length > 0) {
formData.append("foto", foto.files[0]);
}
fetch("api/tambah_spbu.php", {
method: "POST",
body: formData,
})
.then((res) => res.json())
.then((data) => {
if (data.status == "success") {
alert("Data berhasil disimpan");
map.closePopup();
loadSPBU();
loadObjekPeta();
}
});
}
function openEdit(spbu) {
if (!modeAdmin) {
return;
}
if (currentMarker) {
currentMarker.dragging.disable();
}
document.getElementById("sidebar").classList.remove("hidden");
document.getElementById("edit_id").value = spbu.id;
document.getElementById("edit_nama").value = spbu.nama_spbu;
document.getElementById("edit_alamat").value = spbu.alamat;
document.getElementById("edit_foto").value = "";
let preview = document.getElementById("preview_edit_foto");
if (spbu.foto) {
preview.src = "uploads/spbu/" + spbu.foto + "?t=" + Date.now();
preview.classList.remove("hidden");
} else {
preview.src = "";
preview.classList.add("hidden");
}
document.getElementById("edit_jam_buka").value = spbu.jam_buka || "";
document.getElementById("edit_jam_tutup").value = spbu.jam_tutup || "";
document.getElementById("edit_24jam").checked = spbu.buka_24_jam == 1;
document.getElementById("edit_jam_buka").disabled = spbu.buka_24_jam == 1;
document.getElementById("edit_jam_tutup").disabled = spbu.buka_24_jam == 1;
document.getElementById("edit_lat").value = spbu.latitude;
document.getElementById("edit_lng").value = spbu.longitude;
currentMarker = markerData[spbu.id];
if (currentMarker) {
currentMarker.dragging.enable();
}
}
function openEditById(id) {
if (!modeAdmin) {
return;
}
let marker = markerData[id];
if (!marker) return;
openEdit(marker.spbuData);
}
function tutupSidebar() {
document.getElementById("sidebar").classList.add("hidden");
if (currentMarker) {
currentMarker.dragging.disable();
}
currentMarker = null;
}
function updateSPBU() {
if (!modeAdmin) {
return;
}
let formData = new FormData();
formData.append("id", document.getElementById("edit_id").value);
formData.append("nama", document.getElementById("edit_nama").value);
formData.append("alamat", document.getElementById("edit_alamat").value);
formData.append("lat", document.getElementById("edit_lat").value);
formData.append("lng", document.getElementById("edit_lng").value);
let foto = document.getElementById("edit_foto");
if (foto.files.length > 0) {
formData.append("foto", foto.files[0]);
}
formData.append("jam_buka", document.getElementById("edit_jam_buka").value);
formData.append("jam_tutup", document.getElementById("edit_jam_tutup").value);
formData.append(
"buka_24_jam",
document.getElementById("edit_24jam").checked ? 1 : 0,
);
fetch("api/edit_spbu.php", {
method: "POST",
body: formData,
})
.then((res) => res.json())
.then((data) => {
if (data.status == "success") {
alert("Data berhasil diperbarui");
tutupSidebar();
loadSPBU();
loadObjekPeta();
}
});
}
function hapusSPBU(id) {
if (!modeAdmin) {
return;
}
if (!confirm("Yakin hapus data ini?")) {
return;
}
fetch("api/hapus_spbu.php", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
id: id,
}),
})
.then((res) => res.json())
.then((data) => {
if (data.status == "success") {
alert("Data berhasil dihapus");
loadSPBU();
loadObjekPeta();
}
});
}
document.addEventListener("keyup", function (e) {
if (e.target.id !== "search_spbu") return;
let keyword = e.target.value.toLowerCase();
markerGroup.eachLayer(function (marker) {
let nama = (marker.spbuData.nama_spbu || "").toLowerCase();
if (nama.includes(keyword)) {
map.setView(marker.getLatLng(), 18);
marker.openPopup();
}
});
});
function cariSPBU() {
let keyword = document.getElementById("search_spbu").value.toLowerCase();
let ditemukan = false;
markerGroup.eachLayer(function (marker) {
let nama = (marker.spbuData.nama_spbu || "").toLowerCase();
if (nama.includes(keyword)) {
ditemukan = true;
map.setView(marker.getLatLng(), 18);
marker.openPopup();
}
});
if (!ditemukan) {
alert("SPBU tidak ditemukan");
}
}
function lokasiSaya() {
if (!navigator.geolocation) {
alert("Browser tidak mendukung geolocation");
return;
}
navigator.geolocation.getCurrentPosition(
function (position) {
let lat = position.coords.latitude;
let lng = position.coords.longitude;
userLat = lat;
userLng = lng;
if (userMarker) {
map.removeLayer(userMarker);
}
userMarker = L.circleMarker([lat, lng], {
radius: 10,
color: "#2563eb",
fillColor: "#2563eb",
fillOpacity: 1,
}).addTo(map);
userMarker.bindPopup(`
Lokasi Anda
Lat : ${lat}
Lng : ${lng}
`);
userMarker.openPopup();
map.setView([lat, lng], 16);
},
function () {
alert("Lokasi tidak dapat diakses");
},
);
}
function hitungJarak(lat1, lon1, lat2, lon2) {
const R = 6371;
const dLat = ((lat2 - lat1) * Math.PI) / 180;
const dLon = ((lon2 - lon1) * Math.PI) / 180;
const a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos((lat1 * Math.PI) / 180) *
Math.cos((lat2 * Math.PI) / 180) *
Math.sin(dLon / 2) *
Math.sin(dLon / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return R * c;
}
function cariTerdekat() {
if (userLat === null) {
alert("Klik Lokasi Saya terlebih dahulu");
return;
}
let terdekat = null;
let jarakMin = Infinity;
markerGroup.eachLayer(function (marker) {
let lat = marker.getLatLng().lat;
let lng = marker.getLatLng().lng;
let jarak = hitungJarak(userLat, userLng, lat, lng);
if (jarak < jarakMin) {
jarakMin = jarak;
terdekat = marker;
}
});
if (terdekat) {
map.setView(terdekat.getLatLng(), 18);
terdekat.openPopup();
alert(
"SPBU terdekat: " +
terdekat.spbuData.nama_spbu +
"\nJarak: " +
jarakMin.toFixed(2) +
" km",
);
}
}
function getMarkerTerdekat() {
let terdekat = null;
let jarakMin = Infinity;
markerGroup.eachLayer(function (marker) {
let lat = marker.getLatLng().lat;
let lng = marker.getLatLng().lng;
let jarak = hitungJarak(userLat, userLng, lat, lng);
if (jarak < jarakMin) {
jarakMin = jarak;
terdekat = marker;
}
});
return terdekat;
}
function buatRuteTerdekat() {
if (userLat === null) {
alert("Klik Lokasi Saya terlebih dahulu");
return;
}
let marker = getMarkerTerdekat();
if (!marker) {
alert("Tidak ada SPBU ditemukan");
return;
}
if (routingControl) {
map.removeControl(routingControl);
}
routingControl = L.Routing.control({
show: false,
collapsible: true,
waypoints: [
L.latLng(userLat, userLng),
L.latLng(marker.getLatLng().lat, marker.getLatLng().lng),
],
router: L.Routing.osrmv1({
serviceUrl: "https://router.project-osrm.org/route/v1",
}),
routeWhileDragging: false,
addWaypoints: false,
draggableWaypoints: false,
}).addTo(map);
}
document.addEventListener("change", function (e) {
if (e.target.id !== "foto") return;
let file = e.target.files[0];
if (!file) return;
let preview = document.getElementById("previewFoto");
preview.src = URL.createObjectURL(file);
preview.classList.remove("hidden");
});
document.addEventListener("change", function (e) {
if (e.target.id !== "edit_foto") return;
let file = e.target.files[0];
if (!file) return;
let preview = document.getElementById("preview_edit_foto");
preview.src = URL.createObjectURL(file);
preview.classList.remove("hidden");
});
document.addEventListener("change", function (e) {
if (e.target.id !== "edit_24jam") return;
let checked = e.target.checked;
document.getElementById("edit_jam_buka").disabled = checked;
document.getElementById("edit_jam_tutup").disabled = checked;
});
function isBuka(spbu) {
if (spbu.buka_24_jam == 1) {
return true;
}
if (!spbu.jam_buka || !spbu.jam_tutup) {
return false;
}
let now = new Date().toTimeString().substring(0, 5);
let buka = spbu.jam_buka.substring(0, 5);
let tutup = spbu.jam_tutup.substring(0, 5);
if (buka < tutup) {
return now >= buka && now <= tutup;
}
return now >= buka || now <= tutup;
}
function filterSPBU() {
let filter = document.getElementById("filter_spbu").value;
markerGroup.clearLayers();
Object.values(markerData).forEach(function (marker) {
let spbu = marker.spbuData;
let tampil = false;
if (filter == "all") {
tampil = true;
}
if (filter == "24" && spbu.buka_24_jam == 1) {
tampil = true;
}
if (filter == "non24" && spbu.buka_24_jam == 0) {
tampil = true;
}
if (filter == "buka" && isBuka(spbu)) {
tampil = true;
}
if (filter == "tutup" && !isBuka(spbu)) {
tampil = true;
}
if (tampil) {
marker.addTo(markerGroup);
}
});
}
function toggleMode() {
modeAdmin = !modeAdmin;
let btn = document.getElementById("btnMode");
let banner = document.getElementById("bannerMode");
if (modeAdmin) {
banner.classList.add("hidden");
btn.innerHTML = "Pindah ke Mode Lihat";
btn.classList.remove("bg-green-600");
btn.classList.add("bg-blue-600");
status.className =
"bg-blue-100 text-blue-700 px-3 py-2 rounded font-semibold";
} else {
banner.classList.remove("hidden");
btn.innerHTML = "Masuk Mode Admin";
btn.classList.remove("bg-blue-600");
btn.classList.add("bg-yellow-600");
status.innerHTML = "View";
status.className =
"bg-yellow-100 text-yellow-700 px-3 py-2 rounded font-semibold";
tutupSidebar();
map.closePopup();
}
loadSPBU();
loadObjekPeta();
updateModeUI();
}
function updateModeUI() {
let status = document.getElementById("statusMode");
let banner = document.getElementById("bannerMode");
if (modeAdmin) {
status.innerHTML = "🔓 ADMIN";
banner.classList.add("hidden");
} else {
status.innerHTML = "👁️ VIEW";
banner.classList.remove("hidden");
}
}
function loadObjekPeta() {
fetch("api/get_objek.php")
.then((res) => res.json())
.then((data) => {
drawnItems.clearLayers();
data.forEach((obj) => {
let geo = JSON.parse(obj.geojson);
let layer = L.geoJSON(geo);
layer.eachLayer(function (l) {
l.objekId = obj.id;
l.on("click", function (e) {
L.DomEvent.stopPropagation(e);
l.bindPopup(`
${obj.nama || "-"}
${obj.deskripsi || "-"}
`);
l.openPopup();
});
l.on("dblclick", function (e) {
L.DomEvent.stopPropagation(e);
if (!modeAdmin) {
return;
}
openObjekSidebar(obj, l);
});
drawnItems.addLayer(l);
});
});
});
}
map.on(L.Draw.Event.CREATED, function (e) {
let layer = e.layer;
drawnItems.addLayer(layer);
currentObjekLayer = layer;
document.getElementById("sidebarObjek").classList.remove("hidden");
document.getElementById("objek_id").value = "";
document.getElementById("objek_nama").value = "";
document.getElementById("objek_deskripsi").value = "";
document.getElementById("objek_tipe").value = layer.toGeoJSON().geometry.type;
});
map.on("draw:edited", function (e) {
e.layers.eachLayer(function (layer) {
let geojson = JSON.stringify(layer.toGeoJSON());
fetch("api/update_objek.php", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: "id=" + layer.objekId + "&geojson=" + encodeURIComponent(geojson),
});
});
});
map.on("draw:deleted", function (e) {
e.layers.eachLayer(function (layer) {
fetch("api/hapus_objek.php", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: "id=" + layer.objekId,
});
});
});
function openObjekSidebar(obj, layer) {
currentObjekLayer = layer;
document.getElementById("sidebarObjek").classList.remove("hidden");
document.getElementById("objek_id").value = obj.id;
document.getElementById("objek_nama").value = obj.nama || "";
document.getElementById("objek_deskripsi").value = obj.deskripsi || "";
document.getElementById("objek_tipe").value = obj.tipe;
}
function tutupSidebarObjek() {
document.getElementById("sidebarObjek").classList.add("hidden");
currentObjekLayer = null;
}
function updateObjek() {
let id = document.getElementById("objek_id").value;
let nama = document.getElementById("objek_nama").value;
let deskripsi = document.getElementById("objek_deskripsi").value;
let tipe = document.getElementById("objek_tipe").value;
if (id == "") {
let geojson = JSON.stringify(currentObjekLayer.toGeoJSON());
fetch("api/simpan_objek.php", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body:
"nama=" +
encodeURIComponent(nama) +
"&deskripsi=" +
encodeURIComponent(deskripsi) +
"&tipe=" +
tipe +
"&geojson=" +
encodeURIComponent(geojson),
})
.then((res) => res.json())
.then((data) => {
alert("Objek berhasil disimpan");
tutupSidebarObjek();
loadObjekPeta();
});
} else {
fetch("api/update_objek.php", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body:
"id=" +
id +
"&nama=" +
encodeURIComponent(nama) +
"&deskripsi=" +
encodeURIComponent(deskripsi),
})
.then((res) => res.json())
.then((data) => {
alert("Objek berhasil diperbarui");
tutupSidebarObjek();
loadObjekPeta();
});
}
}