Files
WebGIS_Project/02/index.html
T
2026-06-10 18:07:01 +07:00

341 lines
7.9 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<title>WEB GIS FINAL</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css"/>
<link rel="stylesheet" href="https://unpkg.com/leaflet-draw/dist/leaflet.draw.css"/>
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<script src="https://unpkg.com/leaflet-draw/dist/leaflet.draw.js"></script>
<script src="https://unpkg.com/leaflet-geometryutil"></script>
<style>
#map { height: 100vh; }
#searchBox{
position:absolute;
top:10px;
left:260px;
z-index:999;
padding:8px;
width:250px;
}
.modal {
display:none;
position:fixed;
z-index:999;
left:0;top:0;
width:100%;height:100%;
background:rgba(0,0,0,0.5);
}
.modal-content{
background:white;
padding:20px;
width:300px;
margin:120px auto;
border-radius:10px;
text-align:center;
}
</style>
</head>
<body>
<input type="text" id="searchBox" placeholder="Cari semua data...">
<div id="map"></div>
<div id="formModal" class="modal">
<div class="modal-content">
<h3 id="formTitle"></h3>
<input type="text" id="input1"><br>
<select id="input2"></select><br>
<button onclick="submitForm()">Simpan</button>
<button onclick="closeForm()">Batal</button>
</div>
</div>
<script>
// ================= MAP =================
var map = L.map('map').setView([-0.05,109.34],13);
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
var drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);
let semuaLayer = [];
let currentLayer = null;
let currentType = null;
// ================= WARNA =================
function warnaJalan(s){
return s=="Nasional"?"red":s=="Provinsi"?"blue":"green";
}
function warnaParsil(s){
return s=="SHM"?"yellow":
s=="HGB"?"orange":
s=="HGU"?"brown":
"purple";
}
// ================= FORMAT =================
function formatMeter(m){ return m.toFixed(2)+" m"; }
function formatMeter2(m){ return m.toFixed(2)+" m²"; }
// ================= FORM =================
function openForm(type, layer){
currentLayer = layer;
currentType = type;
document.getElementById("formModal").style.display="block";
let select = document.getElementById("input2");
select.innerHTML="";
if(type=="jalan"){
formTitle.innerText="Input Jalan";
input1.placeholder="Nama Jalan";
["Nasional","Provinsi","Kabupaten"].forEach(v=>{
let o=document.createElement("option");
o.value=v;o.text=v;
select.appendChild(o);
});
}
else if(type=="parsil"){
formTitle.innerText="Input Parsil";
input1.placeholder="Nama Pemilik";
["SHM","HGB","HGU","HP"].forEach(v=>{
let o=document.createElement("option");
o.value=v;o.text=v;
select.appendChild(o);
});
}
else if(type=="rusak"){
formTitle.innerText="Jalan Rusak";
input1.placeholder="Keterangan";
["Ringan","Sedang","Berat"].forEach(v=>{
let o=document.createElement("option");
o.value=v;o.text=v;
select.appendChild(o);
});
}
}
function closeForm(){
document.getElementById("formModal").style.display="none";
input1.value = "";
currentLayer = null;
currentType = null;
// Re-enable draw control
map.addControl(drawControl);
}
function submitForm(){
let v1 = input1.value.trim();
let v2 = input2.value;
if(!v1){
alert("Mohon isi nama/keterangan terlebih dahulu!");
return;
}
if(!currentLayer || !currentType){
alert("Tidak ada layer yang dipilih!");
closeForm();
return;
}
// Simpan referensi layer sebelum closeForm me-reset currentLayer
let layer = currentLayer;
let type = currentType;
closeForm();
if(type=="jalan") prosesJalan(layer, v1, v2);
else if(type=="parsil") prosesParsil(layer, v1, v2);
else if(type=="rusak") prosesRusak(layer, v1, v2);
}
// ================= DRAW =================
var drawControl = new L.Control.Draw({
edit:{ featureGroup: drawnItems },
draw:{
polyline:true,
polygon:true,
rectangle:false,
circle:false,
marker:true
}
});
map.addControl(drawControl);
map.on('draw:created', function(e){
var layer = e.layer;
drawnItems.addLayer(layer);
// Disable draw sementara sampai form disubmit
map.removeControl(drawControl);
if(e.layerType=="polyline") openForm("jalan",layer);
if(e.layerType=="polygon") openForm("parsil",layer);
if(e.layerType=="marker") openForm("rusak",layer);
});
// ================= JALAN =================
function prosesJalan(layer,nama,status){
let latlngs = layer.getLatLngs();
let panjang=0;
for(let i=0;i<latlngs.length-1;i++){
panjang += latlngs[i].distanceTo(latlngs[i+1]);
}
layer.setStyle({color:warnaJalan(status)});
fetch('save_jalan.php',{
method:'POST',
headers:{'Content-Type':'application/json'},
body:JSON.stringify({nama,status,panjang,geometry:layer.toGeoJSON().geometry})
})
.then(r=>r.json())
.then(res=> { if(res.success) layer.id=res.id; else console.error('save_jalan error:',res.error); });
layer.bindPopup(`<b>Jalan</b><br>${nama}<br>Panjang: ${formatMeter(panjang)}`);
semuaLayer.push({layer:layer,nama:nama});
}
// ================= PARSIL =================
function prosesParsil(layer,pemilik,status){
let luas = L.GeometryUtil.geodesicArea(layer.getLatLngs()[0]);
layer.setStyle({color:warnaParsil(status)});
fetch('save_parsil.php',{
method:'POST',
headers:{'Content-Type':'application/json'},
body:JSON.stringify({pemilik,status,luas,geometry:layer.toGeoJSON().geometry})
})
.then(r=>r.json())
.then(res=> { if(res.success) layer.id=res.id; else console.error('save_parsil error:',res.error); });
layer.bindPopup(`<b>Parsil</b><br>${pemilik}<br>Luas: ${formatMeter2(luas)}`);
semuaLayer.push({layer:layer,nama:pemilik});
}
// ================= RUSAK =================
function prosesRusak(layer,keterangan,tingkat){
let icon = L.icon({
iconUrl: tingkat=="Ringan"?
"https://maps.google.com/mapfiles/ms/icons/green-dot.png":
tingkat=="Sedang"?
"https://maps.google.com/mapfiles/ms/icons/yellow-dot.png":
"https://maps.google.com/mapfiles/ms/icons/red-dot.png",
iconSize:[25,41],
iconAnchor:[12,41]
});
layer.setIcon(icon);
fetch('save_rusak.php',{
method:'POST',
headers:{'Content-Type':'application/json'},
body:JSON.stringify({keterangan,tingkat,geometry:layer.toGeoJSON().geometry})
})
.then(r=>r.json())
.then(res=> { if(res.success) layer.id=res.id; else console.error('save_rusak error:',res.error); });
layer.bindPopup(`<b>Rusak</b><br>${keterangan}<br><b>Tingkat:</b> ${tingkat}`);
semuaLayer.push({layer:layer,nama:keterangan});
}
// ================= LOAD =================
fetch('get_jalan.php').then(r=>r.json()).then(data=>{
data.forEach(j=>{
let geo=j.geometry;
let layer=L.geoJSON(geo,{style:{color:warnaJalan(j.status)}}).addTo(map);
layer.eachLayer(l=>{
l.bindPopup(`<b>Jalan</b><br>${j.nama}<br>Panjang: ${formatMeter(j.panjang)}`);
semuaLayer.push({layer:l,nama:j.nama});
});
});
});
fetch('get_parsil.php').then(r=>r.json()).then(data=>{
data.forEach(p=>{
let geo=p.geometry;
let layer=L.geoJSON(geo,{style:{color:warnaParsil(p.status)}}).addTo(map);
layer.eachLayer(l=>{
l.bindPopup(`<b>Parsil</b><br>${p.pemilik}<br>Luas: ${formatMeter2(p.luas)}`);
semuaLayer.push({layer:l,nama:p.pemilik});
});
});
});
fetch('get_rusak.php').then(r=>r.json()).then(data=>{
data.forEach(r=>{
let geo=r.geometry;
let icon = L.icon({
iconUrl: r.tingkat=="Ringan"?
"https://maps.google.com/mapfiles/ms/icons/green-dot.png":
r.tingkat=="Sedang"?
"https://maps.google.com/mapfiles/ms/icons/yellow-dot.png":
"https://maps.google.com/mapfiles/ms/icons/red-dot.png",
iconSize:[25,41],
iconAnchor:[12,41]
});
let layer=L.geoJSON(geo,{
pointToLayer:(f,latlng)=>L.marker(latlng,{icon:icon})
}).addTo(map);
layer.eachLayer(l=>{
l.bindPopup(`<b>Rusak</b><br>${r.keterangan}<br><b>Tingkat:</b> ${r.tingkat}`);
semuaLayer.push({layer:l,nama:r.keterangan});
});
});
});
// ================= SEARCH =================
document.getElementById("searchBox").addEventListener("keyup",function(){
let key=this.value.toLowerCase();
semuaLayer.forEach(o=>{
let cocok=o.nama.toLowerCase().includes(key);
if(o.layer.setStyle){
o.layer.setStyle({
opacity:cocok?1:0.1,
fillOpacity:cocok?0.7:0.1
});
}
if(o.layer.setOpacity){
o.layer.setOpacity(cocok?1:0.2);
}
if(cocok){
try{ map.fitBounds(o.layer.getBounds()); }catch(e){}
}
});
});
</script>
</body>
</html>