first commit
This commit is contained in:
+93
@@ -0,0 +1,93 @@
|
||||
window.getRoadColor = function (status) {
|
||||
if (status === "Jalan Nasional") {
|
||||
return "#dc3545";
|
||||
}
|
||||
|
||||
if (status === "Jalan Provinsi") {
|
||||
return "#007bff";
|
||||
}
|
||||
|
||||
return "#28a745";
|
||||
};
|
||||
|
||||
window.normalizeRoadStatus = function (value) {
|
||||
var normalized = String(value || "").trim().toLowerCase();
|
||||
|
||||
if (normalized === "jalan nasional" || normalized === "nasional") {
|
||||
return "Jalan Nasional";
|
||||
}
|
||||
|
||||
if (normalized === "jalan provinsi" || normalized === "provinsi") {
|
||||
return "Jalan Provinsi";
|
||||
}
|
||||
|
||||
if (normalized === "jalan kabupaten" || normalized === "kabupaten") {
|
||||
return "Jalan Kabupaten";
|
||||
}
|
||||
|
||||
return "";
|
||||
};
|
||||
|
||||
window.serializeGeometry = function (latlngs) {
|
||||
return JSON.stringify(latlngs.map(function (point) {
|
||||
return [
|
||||
Number(point.lat.toFixed(6)),
|
||||
Number(point.lng.toFixed(6))
|
||||
];
|
||||
}));
|
||||
};
|
||||
|
||||
window.parseGeometry = function (geom) {
|
||||
try {
|
||||
var parsed = JSON.parse(geom);
|
||||
return Array.isArray(parsed) ? parsed : [];
|
||||
} catch (error) {
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
window.collectRoadData = async function () {
|
||||
return window.openEditModal({
|
||||
title: "Tambah Jalan",
|
||||
subtitle: "Lengkapi atribut jalan untuk garis yang sudah digambar.",
|
||||
fields: [
|
||||
{ name: "nama", label: "Nama Jalan", value: "", required: true },
|
||||
{
|
||||
name: "status",
|
||||
label: "Status Jalan",
|
||||
type: "select",
|
||||
value: "Jalan Nasional",
|
||||
options: [
|
||||
{ value: "Jalan Nasional", label: "Jalan Nasional" },
|
||||
{ value: "Jalan Provinsi", label: "Jalan Provinsi" },
|
||||
{ value: "Jalan Kabupaten", label: "Jalan Kabupaten" }
|
||||
]
|
||||
}
|
||||
],
|
||||
validate: function (data) {
|
||||
if (!data.nama || !window.normalizeRoadStatus(data.status)) {
|
||||
return "Nama dan status jalan wajib valid.";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
window.buildRoadLayer = function (jalan) {
|
||||
var coordinates = window.parseGeometry(jalan.geom).map(function (point) {
|
||||
return L.latLng(point[0], point[1]);
|
||||
});
|
||||
|
||||
if (coordinates.length < 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return L.polyline(coordinates, {
|
||||
color: window.getRoadColor(jalan.status),
|
||||
weight: 4
|
||||
}).bindPopup(
|
||||
"<b>" + window.escapeHtml(jalan.nama) + "</b><br>" +
|
||||
"Status: " + window.escapeHtml(jalan.status) + "<br>" +
|
||||
"Panjang: " + window.formatMeters(jalan.panjang)
|
||||
);
|
||||
};
|
||||
+1007
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,567 @@
|
||||
window.appState = {
|
||||
mode: "view",
|
||||
activeType: "spbu",
|
||||
drawControl: null,
|
||||
layers: {},
|
||||
layerControl: null,
|
||||
layerVisibility: {
|
||||
spbu24: true,
|
||||
spbuTidak: true,
|
||||
kemiskinan: true,
|
||||
masjid: true,
|
||||
jalan: true,
|
||||
kavling: true
|
||||
}
|
||||
};
|
||||
|
||||
window.escapeHtml = function (value) {
|
||||
return String(value ?? "")
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
};
|
||||
|
||||
window.createPointIcon = function (color) {
|
||||
return L.divIcon({
|
||||
className: "custom-point-icon",
|
||||
html: '<span class="point-dot" style="background:' + color + ';"></span>',
|
||||
iconSize: [18, 18],
|
||||
iconAnchor: [9, 9],
|
||||
popupAnchor: [0, -12]
|
||||
});
|
||||
};
|
||||
|
||||
window.greenIcon = window.createPointIcon("#28a745");
|
||||
window.redIcon = window.createPointIcon("#dc3545");
|
||||
window.orangeIcon = window.createPointIcon("#ff8c00");
|
||||
window.blueIcon = window.createPointIcon("#007bff");
|
||||
|
||||
window.calculateLineLength = function (latlngs) {
|
||||
var total = 0;
|
||||
|
||||
for (var i = 1; i < latlngs.length; i += 1) {
|
||||
total += map.distance(latlngs[i - 1], latlngs[i]);
|
||||
}
|
||||
|
||||
return total;
|
||||
};
|
||||
|
||||
window.calculatePolygonArea = function (latlngs) {
|
||||
if (L.GeometryUtil && typeof L.GeometryUtil.geodesicArea === "function") {
|
||||
return L.GeometryUtil.geodesicArea(latlngs);
|
||||
}
|
||||
|
||||
if (!latlngs.length) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var earthRadius = 6378137;
|
||||
var avgLat = latlngs.reduce(function (sum, point) {
|
||||
return sum + point.lat;
|
||||
}, 0) / latlngs.length;
|
||||
var avgLatRad = avgLat * Math.PI / 180;
|
||||
var projected = latlngs.map(function (point) {
|
||||
return {
|
||||
x: earthRadius * point.lng * Math.PI / 180 * Math.cos(avgLatRad),
|
||||
y: earthRadius * point.lat * Math.PI / 180
|
||||
};
|
||||
});
|
||||
var area = 0;
|
||||
|
||||
for (var i = 0; i < projected.length; i += 1) {
|
||||
var next = projected[(i + 1) % projected.length];
|
||||
area += (projected[i].x * next.y) - (next.x * projected[i].y);
|
||||
}
|
||||
|
||||
return Math.abs(area / 2);
|
||||
};
|
||||
|
||||
window.formatMeters = function (value) {
|
||||
return Number(value).toLocaleString("id-ID", {
|
||||
maximumFractionDigits: 2
|
||||
}) + " m";
|
||||
};
|
||||
|
||||
window.formatSquareMeters = function (value) {
|
||||
return Number(value).toLocaleString("id-ID", {
|
||||
maximumFractionDigits: 2
|
||||
}) + " m²";
|
||||
};
|
||||
|
||||
window.postForm = async function (url, payload) {
|
||||
var response = await fetch(url, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded"
|
||||
},
|
||||
body: new URLSearchParams(payload)
|
||||
});
|
||||
var text = (await response.text()).trim();
|
||||
|
||||
if (!response.ok || text !== "success") {
|
||||
throw new Error(text || "Permintaan gagal.");
|
||||
}
|
||||
};
|
||||
|
||||
window.collectSpbuData = async function () {
|
||||
return window.openEditModal({
|
||||
title: "Tambah SPBU",
|
||||
subtitle: "Lengkapi atribut SPBU untuk titik yang dipilih di peta.",
|
||||
fields: [
|
||||
{ name: "nama", label: "Nama SPBU", value: "", required: true },
|
||||
{ name: "no", label: "Nomor SPBU", value: "", required: true },
|
||||
{
|
||||
name: "status",
|
||||
label: "Status Operasional",
|
||||
type: "select",
|
||||
value: "24jam",
|
||||
options: [
|
||||
{ value: "24jam", label: "24 Jam" },
|
||||
{ value: "tidak", label: "Tidak 24 Jam" }
|
||||
]
|
||||
}
|
||||
],
|
||||
validate: function (data) {
|
||||
if (!data.nama || !data.no) {
|
||||
return "Nama dan nomor SPBU wajib diisi.";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
window.collectKemiskinanData = async function () {
|
||||
return window.openEditModal({
|
||||
title: "Tambah Data Kemiskinan",
|
||||
subtitle: "Lengkapi data keluarga untuk titik yang dipilih di peta.",
|
||||
fields: [
|
||||
{ name: "nama_kepala_keluarga", label: "Nama Kepala Keluarga", value: "", required: true },
|
||||
{ name: "jumlah_kk", label: "Jumlah KK", type: "number", min: 1, step: 1, value: 1, required: true },
|
||||
{ name: "alamat", label: "Alamat", type: "textarea", value: "", required: true }
|
||||
],
|
||||
validate: function (data) {
|
||||
if (!data.nama_kepala_keluarga || !data.alamat) {
|
||||
return "Nama kepala keluarga dan alamat wajib diisi.";
|
||||
}
|
||||
if (!Number.isInteger(data.jumlah_kk) || data.jumlah_kk < 1) {
|
||||
return "Jumlah KK harus angka minimal 1.";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
window.collectMasjidData = async function () {
|
||||
return window.openEditModal({
|
||||
title: "Tambah Masjid",
|
||||
subtitle: "Lengkapi identitas masjid untuk titik yang dipilih di peta.",
|
||||
fields: [
|
||||
{ name: "nama_masjid", label: "Nama Masjid", value: "", required: true },
|
||||
{ name: "pic_masjid", label: "PIC Masjid", value: "", required: true },
|
||||
{ name: "alamat", label: "Alamat Masjid", type: "textarea", value: "", required: true },
|
||||
{ name: "radius", label: "Radius Jangkauan (meter)", type: "number", min: 100, max: 5000, step: 1, value: 500, required: true }
|
||||
],
|
||||
validate: function (data) {
|
||||
if (!data.nama_masjid || !data.pic_masjid || !data.alamat) {
|
||||
return "Nama, PIC, dan alamat masjid wajib diisi.";
|
||||
}
|
||||
if (!Number.isInteger(data.radius) || data.radius < 100 || data.radius > 5000) {
|
||||
return "Radius harus angka antara 100 sampai 5000 meter.";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
window.updateMapHint = function () {
|
||||
var hint = document.getElementById("mapHint");
|
||||
if (!hint) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (appState.mode === "view") {
|
||||
hint.textContent = "Mode lihat aktif. Data hanya ditampilkan di peta dan sidebar.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (appState.activeType === "spbu") {
|
||||
hint.textContent = "Mode edit SPBU aktif. Klik peta untuk menambahkan titik SPBU.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (appState.activeType === "kemiskinan") {
|
||||
hint.textContent = "Mode edit Kemiskinan aktif. Klik peta untuk menambahkan titik data kemiskinan.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (appState.activeType === "masjid") {
|
||||
hint.textContent = "Mode edit Masjid aktif. Klik peta untuk menambahkan titik masjid dengan radius awal 500 meter.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (appState.activeType === "jalan") {
|
||||
hint.textContent = "Mode edit Jalan aktif. Gunakan tool draw polyline pada peta.";
|
||||
return;
|
||||
}
|
||||
|
||||
hint.textContent = "Mode edit Kavling aktif. Gunakan tool draw polygon pada peta.";
|
||||
};
|
||||
|
||||
window.updateToolbarState = function () {
|
||||
var buttonStates = {
|
||||
modeViewBtn: appState.mode === "view",
|
||||
modeEditBtn: appState.mode === "edit",
|
||||
typeSpbuBtn: appState.activeType === "spbu",
|
||||
typeKemiskinanBtn: appState.activeType === "kemiskinan",
|
||||
typeMasjidBtn: appState.activeType === "masjid",
|
||||
typeJalanBtn: appState.activeType === "jalan",
|
||||
typeKavlingBtn: appState.activeType === "kavling"
|
||||
};
|
||||
|
||||
Object.keys(buttonStates).forEach(function (id) {
|
||||
var button = document.getElementById(id);
|
||||
if (button) {
|
||||
button.classList.toggle("active", buttonStates[id]);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
window.configureDrawControl = function () {
|
||||
if (!window.map) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (appState.drawControl) {
|
||||
map.removeControl(appState.drawControl);
|
||||
appState.drawControl = null;
|
||||
}
|
||||
|
||||
if (appState.mode !== "edit" || appState.activeType === "spbu" || appState.activeType === "kemiskinan" || appState.activeType === "masjid") {
|
||||
return;
|
||||
}
|
||||
|
||||
var drawOptions = {
|
||||
polyline: false,
|
||||
polygon: false,
|
||||
rectangle: false,
|
||||
circle: false,
|
||||
marker: false,
|
||||
circlemarker: false
|
||||
};
|
||||
|
||||
if (appState.activeType === "jalan") {
|
||||
drawOptions.polyline = {
|
||||
shapeOptions: {
|
||||
color: "#dc3545",
|
||||
weight: 4
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (appState.activeType === "kavling") {
|
||||
drawOptions.polygon = {
|
||||
allowIntersection: false,
|
||||
shapeOptions: {
|
||||
color: "#ff8c00",
|
||||
weight: 3,
|
||||
fillOpacity: 0.35
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
appState.drawControl = new L.Control.Draw({
|
||||
edit: false,
|
||||
draw: drawOptions
|
||||
});
|
||||
|
||||
map.addControl(appState.drawControl);
|
||||
};
|
||||
|
||||
window.setMode = function (mode) {
|
||||
appState.mode = mode;
|
||||
window.updateToolbarState();
|
||||
window.updateMapHint();
|
||||
window.configureDrawControl();
|
||||
|
||||
if (typeof window.loadAllData === "function") {
|
||||
window.loadAllData();
|
||||
}
|
||||
};
|
||||
|
||||
window.setDataType = function (type) {
|
||||
appState.activeType = type;
|
||||
window.updateToolbarState();
|
||||
window.updateMapHint();
|
||||
window.configureDrawControl();
|
||||
};
|
||||
|
||||
window.getLayerGroupByKey = function (key) {
|
||||
if (key === "spbu24") {
|
||||
return appState.layers.spbu24;
|
||||
}
|
||||
|
||||
if (key === "spbuTidak") {
|
||||
return appState.layers.spbuTidak;
|
||||
}
|
||||
|
||||
if (key === "kemiskinan") {
|
||||
return appState.layers.kemiskinan;
|
||||
}
|
||||
|
||||
if (key === "masjid") {
|
||||
return appState.layers.masjid;
|
||||
}
|
||||
|
||||
if (key === "jalan") {
|
||||
return appState.layers.jalan;
|
||||
}
|
||||
|
||||
if (key === "kavling") {
|
||||
return appState.layers.kavling;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
window.setLayerVisibility = function (key, isVisible) {
|
||||
appState.layerVisibility[key] = !!isVisible;
|
||||
|
||||
var layer = window.getLayerGroupByKey(key);
|
||||
if (!layer || !window.map) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isVisible) {
|
||||
if (!map.hasLayer(layer)) {
|
||||
map.addLayer(layer);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (map.hasLayer(layer)) {
|
||||
map.removeLayer(layer);
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
window.map = L.map("map").setView([-0.0263, 109.3425], 13);
|
||||
|
||||
appState.layers.spbu24 = L.layerGroup().addTo(map);
|
||||
appState.layers.spbuTidak = L.layerGroup().addTo(map);
|
||||
appState.layers.kemiskinan = L.layerGroup().addTo(map);
|
||||
appState.layers.masjid = L.layerGroup().addTo(map);
|
||||
appState.layers.jalan = L.layerGroup().addTo(map);
|
||||
appState.layers.kavling = L.layerGroup().addTo(map);
|
||||
|
||||
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
|
||||
attribution: "© OpenStreetMap"
|
||||
}).addTo(map);
|
||||
|
||||
appState.layerControl = L.control.layers(null, {
|
||||
"SPBU 24 Jam": appState.layers.spbu24,
|
||||
"SPBU Tidak 24 Jam": appState.layers.spbuTidak,
|
||||
"Kemiskinan": appState.layers.kemiskinan,
|
||||
"Masjid": appState.layers.masjid,
|
||||
"Jalan": appState.layers.jalan,
|
||||
"Kavling": appState.layers.kavling
|
||||
}).addTo(map);
|
||||
|
||||
map.on("overlayadd", function (event) {
|
||||
if (event.layer === appState.layers.spbu24) {
|
||||
appState.layerVisibility.spbu24 = true;
|
||||
} else if (event.layer === appState.layers.spbuTidak) {
|
||||
appState.layerVisibility.spbuTidak = true;
|
||||
} else if (event.layer === appState.layers.kemiskinan) {
|
||||
appState.layerVisibility.kemiskinan = true;
|
||||
} else if (event.layer === appState.layers.masjid) {
|
||||
appState.layerVisibility.masjid = true;
|
||||
} else if (event.layer === appState.layers.jalan) {
|
||||
appState.layerVisibility.jalan = true;
|
||||
} else if (event.layer === appState.layers.kavling) {
|
||||
appState.layerVisibility.kavling = true;
|
||||
}
|
||||
|
||||
if (typeof window.refreshLayerFilterUI === "function") {
|
||||
window.refreshLayerFilterUI();
|
||||
}
|
||||
});
|
||||
|
||||
map.on("overlayremove", function (event) {
|
||||
if (event.layer === appState.layers.spbu24) {
|
||||
appState.layerVisibility.spbu24 = false;
|
||||
} else if (event.layer === appState.layers.spbuTidak) {
|
||||
appState.layerVisibility.spbuTidak = false;
|
||||
} else if (event.layer === appState.layers.kemiskinan) {
|
||||
appState.layerVisibility.kemiskinan = false;
|
||||
} else if (event.layer === appState.layers.masjid) {
|
||||
appState.layerVisibility.masjid = false;
|
||||
} else if (event.layer === appState.layers.jalan) {
|
||||
appState.layerVisibility.jalan = false;
|
||||
} else if (event.layer === appState.layers.kavling) {
|
||||
appState.layerVisibility.kavling = false;
|
||||
}
|
||||
|
||||
if (typeof window.refreshLayerFilterUI === "function") {
|
||||
window.refreshLayerFilterUI();
|
||||
}
|
||||
});
|
||||
|
||||
map.on("click", async function (event) {
|
||||
if (appState.mode !== "edit") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (appState.activeType === "spbu") {
|
||||
var spbuData = await window.collectSpbuData();
|
||||
if (!spbuData) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await window.postForm("php/create.php", {
|
||||
nama: spbuData.nama,
|
||||
no: spbuData.no,
|
||||
status: spbuData.status,
|
||||
lat: event.latlng.lat.toFixed(6),
|
||||
lng: event.latlng.lng.toFixed(6)
|
||||
});
|
||||
|
||||
await window.loadAllData();
|
||||
alert("Data SPBU berhasil disimpan.");
|
||||
} catch (error) {
|
||||
alert("Gagal menyimpan SPBU: " + error.message);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (appState.activeType === "kemiskinan") {
|
||||
var kemiskinanData = await window.collectKemiskinanData();
|
||||
if (!kemiskinanData) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await window.postForm("php/create_kemiskinan.php", {
|
||||
nama_kepala_keluarga: kemiskinanData.nama_kepala_keluarga,
|
||||
jumlah_kk: kemiskinanData.jumlah_kk,
|
||||
alamat: kemiskinanData.alamat,
|
||||
lat: event.latlng.lat.toFixed(6),
|
||||
lng: event.latlng.lng.toFixed(6)
|
||||
});
|
||||
|
||||
await window.loadAllData();
|
||||
alert("Data kemiskinan berhasil disimpan.");
|
||||
} catch (error) {
|
||||
alert("Gagal menyimpan data kemiskinan: " + error.message);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (appState.activeType === "masjid") {
|
||||
var masjidData = await window.collectMasjidData();
|
||||
if (!masjidData) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await window.postForm("php/create_masjid.php", {
|
||||
nama_masjid: masjidData.nama_masjid,
|
||||
pic_masjid: masjidData.pic_masjid,
|
||||
alamat: masjidData.alamat,
|
||||
radius: masjidData.radius,
|
||||
lat: event.latlng.lat.toFixed(6),
|
||||
lng: event.latlng.lng.toFixed(6)
|
||||
});
|
||||
|
||||
await window.loadAllData();
|
||||
alert("Data masjid berhasil disimpan.");
|
||||
} catch (error) {
|
||||
alert("Gagal menyimpan data masjid: " + error.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
map.on(L.Draw.Event.CREATED, async function (event) {
|
||||
var layer = event.layer;
|
||||
|
||||
if (appState.mode !== "edit") {
|
||||
alert("Pindah ke mode edit sebelum menggambar data.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.layerType === "polyline") {
|
||||
if (appState.activeType !== "jalan") {
|
||||
alert("Tipe aktif saat ini bukan Jalan.");
|
||||
return;
|
||||
}
|
||||
|
||||
var lineLatLngs = layer.getLatLngs();
|
||||
var panjang = window.calculateLineLength(lineLatLngs);
|
||||
var roadData = await window.collectRoadData();
|
||||
|
||||
if (!roadData) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await window.postForm("php/create_line.php", {
|
||||
nama: roadData.nama,
|
||||
status: roadData.status,
|
||||
panjang: panjang.toFixed(2),
|
||||
geom: window.serializeGeometry(lineLatLngs)
|
||||
});
|
||||
|
||||
await window.loadAllData();
|
||||
alert("Data jalan berhasil disimpan.");
|
||||
} catch (error) {
|
||||
alert("Gagal menyimpan jalan: " + error.message);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.layerType === "polygon") {
|
||||
if (appState.activeType !== "kavling") {
|
||||
alert("Tipe aktif saat ini bukan Kavling.");
|
||||
return;
|
||||
}
|
||||
|
||||
var polygonLatLngs = layer.getLatLngs()[0] || [];
|
||||
var luas = window.calculatePolygonArea(polygonLatLngs);
|
||||
var landData = await window.collectPolygonData();
|
||||
|
||||
if (!landData) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await window.postForm("php/create_polygon.php", {
|
||||
nama: landData.nama,
|
||||
status: landData.status,
|
||||
luas: luas.toFixed(2),
|
||||
geom: window.serializeGeometry(polygonLatLngs)
|
||||
});
|
||||
|
||||
await window.loadAllData();
|
||||
alert("Data kavling berhasil disimpan.");
|
||||
} catch (error) {
|
||||
alert("Gagal menyimpan kavling: " + error.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
window.setMode("view");
|
||||
window.setDataType("spbu");
|
||||
|
||||
setTimeout(function () {
|
||||
map.invalidateSize();
|
||||
}, 300);
|
||||
|
||||
if (typeof window.loadAllData === "function") {
|
||||
window.loadAllData();
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,77 @@
|
||||
window.getPolygonColor = function (status) {
|
||||
if (status === "SHM") {
|
||||
return "#ff8c00";
|
||||
}
|
||||
|
||||
if (status === "HGB") {
|
||||
return "#6f42c1";
|
||||
}
|
||||
|
||||
if (status === "HGU") {
|
||||
return "#20c997";
|
||||
}
|
||||
|
||||
return "#6c757d";
|
||||
};
|
||||
|
||||
window.normalizePolygonStatus = function (value) {
|
||||
var normalized = String(value || "").trim().toUpperCase();
|
||||
var allowed = ["SHM", "HGB", "HGU", "HP"];
|
||||
|
||||
if (allowed.indexOf(normalized) === -1) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return normalized;
|
||||
};
|
||||
|
||||
window.collectPolygonData = async function () {
|
||||
return window.openEditModal({
|
||||
title: "Tambah Kavling",
|
||||
subtitle: "Lengkapi atribut kavling untuk polygon yang sudah digambar.",
|
||||
fields: [
|
||||
{ name: "nama", label: "Nama Kavling", value: "", required: true },
|
||||
{
|
||||
name: "status",
|
||||
label: "Status Kavling",
|
||||
type: "select",
|
||||
value: "SHM",
|
||||
options: [
|
||||
{ value: "SHM", label: "SHM" },
|
||||
{ value: "HGB", label: "HGB" },
|
||||
{ value: "HGU", label: "HGU" },
|
||||
{ value: "HP", label: "HP" }
|
||||
]
|
||||
}
|
||||
],
|
||||
validate: function (data) {
|
||||
if (!data.nama || !window.normalizePolygonStatus(data.status)) {
|
||||
return "Nama dan status kavling wajib valid.";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
window.buildPolygonLayer = function (kavling) {
|
||||
var coordinates = window.parseGeometry(kavling.geom).map(function (point) {
|
||||
return L.latLng(point[0], point[1]);
|
||||
});
|
||||
|
||||
if (coordinates.length < 3) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var color = window.getPolygonColor(kavling.status);
|
||||
|
||||
return L.polygon(coordinates, {
|
||||
color: color,
|
||||
fillColor: color,
|
||||
fillOpacity: 0.35,
|
||||
weight: 3
|
||||
}).bindPopup(
|
||||
"<b>" + window.escapeHtml(kavling.nama) + "</b><br>" +
|
||||
"Status: " + window.escapeHtml(kavling.status) + "<br>" +
|
||||
"Luas: " + window.formatSquareMeters(kavling.luas)
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user