Compare commits

...

10 Commits

Author SHA1 Message Date
Freya_Martines 64e1823baa Upload files to "Tugas4" 2026-06-12 17:52:19 +00:00
Freya_Martines c12e7c95a5 Upload files to "Tugas3" 2026-06-12 17:52:03 +00:00
Freya_Martines 55d37deaf6 Upload files to "Tugas2" 2026-06-12 17:51:46 +00:00
Freya_Martines 3c901923a6 Upload files to "Tugas1" 2026-06-12 17:51:22 +00:00
Freya_Martines 73327505be Upload files to "/" 2026-06-12 17:50:53 +00:00
Freya_Martines 11508f5213 Upload files to "/" 2026-06-12 17:50:39 +00:00
Freya_Martines 77051fb0c5 Upload files to "/" 2026-06-12 17:50:24 +00:00
Freya_Martines baa1bca6cc Upload files to "/" 2026-06-12 17:50:05 +00:00
Freya_Martines 9d424b76a0 merge remote repository 2026-06-13 00:04:37 +07:00
Freya_Martines 57505fe2b0 initial commit sistem pemetaan kemiskinan 2026-06-13 00:01:53 +07:00
23 changed files with 730 additions and 0 deletions
File diff suppressed because one or more lines are too long
+9
View File
@@ -0,0 +1,9 @@
FROM php:8.2-apache
RUN docker-php-ext-install mysqli pdo pdo_mysql
COPY . /var/www/html/
RUN chown -R www-data:www-data /var/www/html
EXPOSE 80
+87
View File
@@ -0,0 +1,87 @@
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="utf-8">
<title>Tugas 1 - WebGIS SPBU</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"/>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<style>
html, body {height:100%; margin:0; font-family: Arial, Helvetica, sans-serif;}
#map {height:100%;}
input, select {width:100%; margin-bottom:5px; padding:4px;}
button {margin-top:5px; cursor:pointer;}
.back-link {
position: fixed; z-index: 9999; left: 12px; top: 12px;
background: white; color: #111827; padding: 9px 12px;
border-radius: 10px; text-decoration: none; font-weight: 700;
box-shadow: 0 3px 14px rgba(0,0,0,.18); font-size: 13px;
}
.legend { background:white; padding:10px; line-height:18px; color:#333; border-radius:5px; box-shadow:0 0 5px rgba(0,0,0,.3); }
.legend i { width:18px; height:18px; float:left; margin-right:8px; opacity:.8; }
</style>
</head>
<body>
<a class="back-link" href="../">← Landing Page</a>
<div id="map"></div>
<script>
const map = L.map('map').setView([-0.02, 109.34], 13);
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
const iconSPBU = new L.Icon({ iconUrl:'https://maps.google.com/mapfiles/ms/icons/blue-dot.png', iconSize:[32,32] });
function formPopup(lat,lng){
return `
<b>Input SPBU</b><br>
Nama:<input id="nama"><br>
WA:<input id="wa"><br>
Buka 24 Jam:
<select id="buka"><option>Iya</option><option>Tidak</option></select><br>
<button onclick="simpan(${lat},${lng})">Simpan</button>
<button onclick="map.closePopup()">Batal</button>`;
}
map.on('click',function(e){
L.popup().setLatLng(e.latlng).setContent(formPopup(e.latlng.lat,e.latlng.lng)).openOn(map);
});
function simpan(lat,lng){
const nama=document.getElementById('nama').value;
const wa=document.getElementById('wa').value;
const buka=document.getElementById('buka').value;
fetch('../simpan.php',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:`nama=${encodeURIComponent(nama)}&wa=${encodeURIComponent(wa)}&buka=${encodeURIComponent(buka)}&lat=${lat}&lng=${lng}`}).then(()=>location.reload());
}
fetch('../ambil.php').then(res=>res.json()).then(data=>{
data.forEach(d=>{
L.marker([d.lat,d.lng],{icon:iconSPBU}).addTo(map).bindPopup(`
<b>${d.nama}</b><br>WA: ${d.wa}<br>Buka 24 Jam: ${d.buka}<br><br>
<button onclick="editSPBU(${d.id},'${String(d.nama).replace(/'/g,'')}','${d.wa}','${d.buka}',${d.lat},${d.lng})">Edit</button>
<button onclick="hapusSPBU(${d.id})">Hapus</button>`);
});
});
function editSPBU(id,nama,wa,buka,lat,lng){
const form=`<b>Edit SPBU</b><br>
Nama:<input id="nama" value="${nama}"><br>
WA:<input id="wa" value="${wa}"><br>
<select id="buka"><option ${buka=='Iya'?'selected':''}>Iya</option><option ${buka=='Tidak'?'selected':''}>Tidak</option></select><br>
<button onclick="updateSPBU(${id})">Update</button>`;
L.popup().setLatLng([lat,lng]).setContent(form).openOn(map);
}
function updateSPBU(id){
const nama=document.getElementById('nama').value;
const wa=document.getElementById('wa').value;
const buka=document.getElementById('buka').value;
fetch('../update.php',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:`id=${id}&nama=${encodeURIComponent(nama)}&wa=${encodeURIComponent(wa)}&buka=${encodeURIComponent(buka)}`}).then(()=>location.reload());
}
function hapusSPBU(id){
if(confirm('Hapus SPBU?')){
fetch('../hapus.php',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:`id=${id}`}).then(()=>location.reload());
}
}
</script>
</body>
</html>
+116
View File
@@ -0,0 +1,116 @@
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="utf-8">
<title>Tugas 2 - Jalan dan Kavling</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"/>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-geometryutil/0.10.2/leaflet.geometryutil.min.js"></script>
<style>
html, body {height:100%; margin:0; font-family: Arial, Helvetica, sans-serif;}
#map {height:100%;}
input, select {width:100%; margin-bottom:5px; padding:4px;}
button {margin-top:5px; cursor:pointer;}
.back-link {
position: fixed; z-index: 9999; left: 12px; top: 12px;
background: white; color: #111827; padding: 9px 12px;
border-radius: 10px; text-decoration: none; font-weight: 700;
box-shadow: 0 3px 14px rgba(0,0,0,.18); font-size: 13px;
}
.legend { background:white; padding:10px; line-height:18px; color:#333; border-radius:5px; box-shadow:0 0 5px rgba(0,0,0,.3); }
.legend i { width:18px; height:18px; float:left; margin-right:8px; opacity:.8; }
</style>
</head>
<body>
<a class="back-link" href="../">← Landing Page</a>
<div id="map"></div>
<script>
const map = L.map('map').setView([-0.02, 109.34], 13);
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
const drawnItems=new L.FeatureGroup();
map.addLayer(drawnItems);
const drawControl=new L.Control.Draw({ edit:{featureGroup:drawnItems}, draw:{marker:false,polyline:true,polygon:true,circle:false,circlemarker:false,rectangle:false} });
map.addControl(drawControl);
function formJalan(latlngs){
return `<b>Input Jalan</b><br>Nama:<input id="nama_jalan"><br>Status:<select id="status_jalan"><option>Nasional</option><option>Provinsi</option><option>Kabupaten</option></select><br><button onclick='simpanJalan(${JSON.stringify(latlngs)})'>Simpan</button>`;
}
function formKavling(latlngs){
return `<b>Input Kavling</b><br>Pemilik:<input id="pemilik"><br>Status:<select id="status_kavling"><option>SHM</option><option>HGB</option><option>HGU</option><option>HP</option></select><br><button onclick='simpanKavling(${JSON.stringify(latlngs)})'>Simpan</button>`;
}
map.on(L.Draw.Event.CREATED,function(e){
const layer=e.layer; drawnItems.addLayer(layer);
if(e.layerType==='polyline'){
const latlngs=layer.getLatLngs();
L.popup().setLatLng(layer.getBounds().getCenter()).setContent(formJalan(latlngs)).openOn(map);
}
if(e.layerType==='polygon'){
const latlngs=layer.getLatLngs()[0];
L.popup().setLatLng(layer.getBounds().getCenter()).setContent(formKavling(latlngs)).openOn(map);
}
});
function simpanJalan(latlngs){
const nama=document.getElementById('nama_jalan').value;
const status=document.getElementById('status_jalan').value;
let panjang=0;
for(let i=0;i<latlngs.length-1;i++) panjang+=map.distance(latlngs[i],latlngs[i+1]);
fetch('../simpan_jalan.php',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:`nama=${encodeURIComponent(nama)}&status=${encodeURIComponent(status)}&panjang=${panjang}&geom=${encodeURIComponent(JSON.stringify(latlngs))}`}).then(()=>location.reload());
}
function simpanKavling(latlngs){
const pemilik=document.getElementById('pemilik').value;
const status=document.getElementById('status_kavling').value;
let luas=L.GeometryUtil.geodesicArea(latlngs);
fetch('../simpan_kavling.php',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:`pemilik=${encodeURIComponent(pemilik)}&status=${encodeURIComponent(status)}&luas=${luas}&geom=${encodeURIComponent(JSON.stringify(latlngs))}`}).then(()=>location.reload());
}
fetch('../ambil_jalan.php').then(res=>res.json()).then(data=>{
data.forEach(d=>{
const coords=JSON.parse(d.geom);
let warna='blue'; if(d.status=='Nasional') warna='red'; if(d.status=='Provinsi') warna='green'; if(d.status=='Kabupaten') warna='orange';
L.polyline(coords,{color:warna}).addTo(map).bindPopup(`<b>${d.nama}</b><br>Status: Jalan ${d.status}<br>Panjang: ${parseFloat(d.panjang).toFixed(2)} meter<br><br><button onclick="editJalan(${d.id},'${String(d.nama).replace(/'/g,'')}','${d.status}',${coords[0].lat},${coords[0].lng})">Edit</button><button onclick="hapusJalan(${d.id})">Hapus</button>`);
});
});
fetch('../ambil_kavling.php').then(res=>res.json()).then(data=>{
data.forEach(d=>{
const coords=JSON.parse(d.geom);
let warna='purple'; if(d.status=='SHM') warna='green'; if(d.status=='HGB') warna='blue'; if(d.status=='HGU') warna='orange'; if(d.status=='HP') warna='red';
L.polygon(coords,{color:warna}).addTo(map).bindPopup(`<b>${d.pemilik}</b><br>Status: ${d.status}<br>Luas: ${parseFloat(d.luas).toFixed(2)} m²<br><br><button onclick="editKavling(${d.id},'${String(d.pemilik).replace(/'/g,'')}','${d.status}',${coords[0].lat},${coords[0].lng})">Edit</button><button onclick="hapusKavling(${d.id})">Hapus</button>`);
});
});
function editJalan(id,nama,status,lat,lng){
const form=`<b>Edit Jalan</b><br>Nama:<input id="nama_jalan" value="${nama}"><br><select id="status_jalan"><option ${status=='Nasional'?'selected':''}>Nasional</option><option ${status=='Provinsi'?'selected':''}>Provinsi</option><option ${status=='Kabupaten'?'selected':''}>Kabupaten</option></select><br><button onclick="updateJalan(${id})">Update</button>`;
L.popup().setLatLng([lat,lng]).setContent(form).openOn(map);
}
function updateJalan(id){
const nama=document.getElementById('nama_jalan').value;
const status=document.getElementById('status_jalan').value;
fetch('../update_jalan.php',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:`id=${id}&nama=${encodeURIComponent(nama)}&status=${encodeURIComponent(status)}`}).then(()=>location.reload());
}
function hapusJalan(id){ if(confirm('Hapus jalan?')) fetch('../hapus_jalan.php',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:`id=${id}`}).then(()=>location.reload()); }
function editKavling(id,pemilik,status,lat,lng){
const form=`<b>Edit Kavling</b><br>Pemilik:<input id="pemilik" value="${pemilik}"><br><select id="status_kavling"><option ${status=='SHM'?'selected':''}>SHM</option><option ${status=='HGB'?'selected':''}>HGB</option><option ${status=='HGU'?'selected':''}>HGU</option><option ${status=='HP'?'selected':''}>HP</option></select><br><button onclick="updateKavling(${id})">Update</button>`;
L.popup().setLatLng([lat,lng]).setContent(form).openOn(map);
}
function updateKavling(id){
const pemilik=document.getElementById('pemilik').value;
const status=document.getElementById('status_kavling').value;
fetch('../update_kavling.php',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:`id=${id}&pemilik=${encodeURIComponent(pemilik)}&status=${encodeURIComponent(status)}`}).then(()=>location.reload());
}
function hapusKavling(id){ if(confirm('Hapus kavling?')) fetch('../hapus_kavling.php',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:`id=${id}`}).then(()=>location.reload()); }
const legend = L.control({position:'bottomright'});
legend.onAdd=function(){ const div=L.DomUtil.create('div','legend'); div.innerHTML='<b>Legenda</b><br><b>Jalan</b><br><i style="background:red"></i> Nasional<br><i style="background:green"></i> Provinsi<br><i style="background:orange"></i> Kabupaten<br><br><b>Kavling</b><br><i style="background:green"></i> SHM<br><i style="background:blue"></i> HGB<br><i style="background:orange"></i> HGU<br><i style="background:red"></i> HP'; return div; };
legend.addTo(map);
</script>
</body>
</html>
+54
View File
@@ -0,0 +1,54 @@
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="utf-8">
<title>Tugas 3 - Layer Control SPBU</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"/>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<style>
html, body {height:100%; margin:0; font-family: Arial, Helvetica, sans-serif;}
#map {height:100%;}
input, select {width:100%; margin-bottom:5px; padding:4px;}
button {margin-top:5px; cursor:pointer;}
.back-link {
position: fixed; z-index: 9999; left: 12px; top: 12px;
background: white; color: #111827; padding: 9px 12px;
border-radius: 10px; text-decoration: none; font-weight: 700;
box-shadow: 0 3px 14px rgba(0,0,0,.18); font-size: 13px;
}
.legend { background:white; padding:10px; line-height:18px; color:#333; border-radius:5px; box-shadow:0 0 5px rgba(0,0,0,.3); }
.legend i { width:18px; height:18px; float:left; margin-right:8px; opacity:.8; }
</style>
</head>
<body>
<a class="back-link" href="../">← Landing Page</a>
<div id="map"></div>
<script>
const map = L.map('map').setView([-0.02, 109.34], 13);
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
const iconHijau = new L.Icon({iconUrl:'https://maps.google.com/mapfiles/ms/icons/green-dot.png',iconSize:[32,32]});
const iconMerah = new L.Icon({iconUrl:'https://maps.google.com/mapfiles/ms/icons/red-dot.png',iconSize:[32,32]});
const spbuBuka = L.layerGroup();
const spbuTutup = L.layerGroup();
fetch('../ambil.php').then(res=>res.json()).then(data=>{
data.forEach(d=>{
const icon = d.buka=='Iya' ? iconHijau : iconMerah;
const marker = L.marker([d.lat,d.lng],{icon}).bindPopup(`<b>${d.nama}</b><br>WA: ${d.wa}<br>${d.buka=='Iya'?'Buka 24 Jam':'Tidak Buka 24 Jam'}`);
if(d.buka=='Iya') marker.addTo(spbuBuka); else marker.addTo(spbuTutup);
});
spbuBuka.addTo(map); spbuTutup.addTo(map);
});
const overlayMaps = {
'<img src="https://maps.google.com/mapfiles/ms/icons/green-dot.png" width="18"> SPBU Buka 24 Jam': spbuBuka,
'<img src="https://maps.google.com/mapfiles/ms/icons/red-dot.png" width="18"> SPBU Tidak Buka': spbuTutup
};
L.control.layers(null, overlayMaps).addTo(map);
const legend = L.control({position:'bottomright'});
legend.onAdd=function(){ const div=L.DomUtil.create('div','legend'); div.innerHTML='<b>Legenda SPBU</b><br><img src="https://maps.google.com/mapfiles/ms/icons/green-dot.png" width="18"> Buka 24 Jam<br><img src="https://maps.google.com/mapfiles/ms/icons/red-dot.png" width="18"> Tidak Buka 24 Jam'; return div; };
legend.addTo(map);
</script>
</body>
</html>
+60
View File
@@ -0,0 +1,60 @@
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="utf-8">
<title>Tugas 4 - GeoJSON Kecamatan Pontianak</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"/>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<style>
html, body {height:100%; margin:0; font-family: Arial, Helvetica, sans-serif;}
#map {height:100%;}
input, select {width:100%; margin-bottom:5px; padding:4px;}
button {margin-top:5px; cursor:pointer;}
.back-link {
position: fixed; z-index: 9999; left: 12px; top: 12px;
background: white; color: #111827; padding: 9px 12px;
border-radius: 10px; text-decoration: none; font-weight: 700;
box-shadow: 0 3px 14px rgba(0,0,0,.18); font-size: 13px;
}
.legend { background:white; padding:10px; line-height:18px; color:#333; border-radius:5px; box-shadow:0 0 5px rgba(0,0,0,.3); }
.legend i { width:18px; height:18px; float:left; margin-right:8px; opacity:.8; }
</style>
</head>
<body>
<a class="back-link" href="../">← Landing Page</a>
<div id="map"></div>
<script>
const map = L.map('map').setView([-0.02, 109.34], 12);
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
fetch('../Admin_Kecamatan.json')
.then(res => res.json())
.then(data => {
const geojsonLayer = L.geoJSON(data, {
style: function(feature) {
const nama = feature.properties.Ket;
let warna = 'gray';
if(nama == 'Pontianak Timur') warna = 'pink';
else if(nama == 'Pontianak Barat') warna = 'skyblue';
else if(nama == 'Pontianak Kota') warna = 'gold';
else if(nama == 'Pontianak Selatan') warna = 'violet';
else if(nama == 'Pontianak Tenggara') warna = 'sienna';
else if(nama == 'Pontianak Utara') warna = 'slategray';
return { color:'black', weight:2, fillColor:warna, fillOpacity:0.55 };
},
onEachFeature: function(feature, layer) {
const nama = feature.properties.Ket || 'Tidak ada nama';
const populasi = feature.properties.Populasi || 'Tidak ada data';
layer.bindPopup(`<b>Kecamatan:</b> ${nama}<br><b>Populasi:</b> ${populasi}`);
}
}).addTo(map);
try { map.fitBounds(geojsonLayer.getBounds()); } catch(e) {}
})
.catch(err => alert('Gagal memuat Admin_Kecamatan.json. Pastikan file tersebut tetap ada di root repo.'));
const legend = L.control({position:'bottomright'});
legend.onAdd=function(){ const div=L.DomUtil.create('div','legend'); div.innerHTML='<b>Kecamatan Pontianak</b><br><i style="background:pink"></i> Pontianak Timur<br><i style="background:skyblue"></i> Pontianak Barat<br><i style="background:gold"></i> Pontianak Kota<br><i style="background:violet"></i> Pontianak Selatan<br><i style="background:sienna"></i> Pontianak Tenggara<br><i style="background:slategray"></i> Pontianak Utara'; return div; };
legend.addTo(map);
</script>
</body>
</html>
+8
View File
@@ -0,0 +1,8 @@
<?php
require_once 'koneksi.php';
header('Content-Type: application/json');
$result = $conn->query("SELECT * FROM spbu ORDER BY id DESC");
$data = [];
while ($row = $result->fetch_assoc()) { $data[] = $row; }
echo json_encode($data);
?>
+8
View File
@@ -0,0 +1,8 @@
<?php
require_once 'koneksi.php';
header('Content-Type: application/json');
$result = $conn->query("SELECT * FROM jalan ORDER BY id DESC");
$data = [];
while ($row = $result->fetch_assoc()) { $data[] = $row; }
echo json_encode($data);
?>
+8
View File
@@ -0,0 +1,8 @@
<?php
require_once 'koneksi.php';
header('Content-Type: application/json');
$result = $conn->query("SELECT * FROM kavling ORDER BY id DESC");
$data = [];
while ($row = $result->fetch_assoc()) { $data[] = $row; }
echo json_encode($data);
?>
+9
View File
@@ -0,0 +1,9 @@
<?php
// cek_env.php - hapus setelah deploy selesai
header('Content-Type: text/plain');
echo "DB_HOST=" . (getenv('DB_HOST') ?: '(kosong)') . "\n";
echo "DB_PORT=" . (getenv('DB_PORT') ?: '(kosong)') . "\n";
echo "DB_NAME=" . (getenv('DB_NAME') ?: '(kosong)') . "\n";
echo "DB_USER=" . (getenv('DB_USER') ?: '(kosong)') . "\n";
echo "DB_PASS=" . (getenv('DB_PASS') ? 'TERISI' : '(kosong)') . "\n";
?>
+50
View File
@@ -0,0 +1,50 @@
-- database.sql - Tugas SIG Kelas Freya
-- Cocok untuk import via Coolify. Tidak memakai CREATE DATABASE/USE.
-- Akan memakai database aktif dari Coolify, misalnya: gis_spbu.
SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS kavling;
DROP TABLE IF EXISTS jalan;
DROP TABLE IF EXISTS spbu;
SET FOREIGN_KEY_CHECKS = 1;
CREATE TABLE spbu (
id INT AUTO_INCREMENT PRIMARY KEY,
nama VARCHAR(150) NOT NULL,
wa VARCHAR(30) DEFAULT NULL,
buka ENUM('Iya','Tidak') NOT NULL DEFAULT 'Tidak',
lat DOUBLE NOT NULL,
lng DOUBLE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE jalan (
id INT AUTO_INCREMENT PRIMARY KEY,
nama VARCHAR(150) NOT NULL,
status ENUM('Nasional','Provinsi','Kabupaten') NOT NULL DEFAULT 'Kabupaten',
panjang DOUBLE DEFAULT 0,
geom LONGTEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE kavling (
id INT AUTO_INCREMENT PRIMARY KEY,
pemilik VARCHAR(150) NOT NULL,
status ENUM('SHM','HGB','HGU','HP') NOT NULL DEFAULT 'SHM',
luas DOUBLE DEFAULT 0,
geom LONGTEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO spbu (nama, wa, buka, lat, lng) VALUES
('SPBU Ahmad Yani', '081234567890', 'Iya', -0.0556, 109.3468),
('SPBU Tanjungpura', '081234567891', 'Tidak', -0.0319, 109.3422),
('SPBU Siantan', '081234567892', 'Iya', -0.0055, 109.3320);
INSERT INTO jalan (nama, status, panjang, geom) VALUES
('Jalan Ahmad Yani', 'Nasional', 1200, '[{"lat":-0.062,"lng":109.343},{"lat":-0.055,"lng":109.347},{"lat":-0.050,"lng":109.350}]'),
('Jalan Gajah Mada', 'Provinsi', 900, '[{"lat":-0.035,"lng":109.337},{"lat":-0.031,"lng":109.341},{"lat":-0.027,"lng":109.345}]');
INSERT INTO kavling (pemilik, status, luas, geom) VALUES
('Kavling Contoh A', 'SHM', 1500, '[{"lat":-0.045,"lng":109.335},{"lat":-0.044,"lng":109.338},{"lat":-0.047,"lng":109.339},{"lat":-0.048,"lng":109.336}]'),
('Kavling Contoh B', 'HGB', 1000, '[{"lat":-0.025,"lng":109.350},{"lat":-0.023,"lng":109.352},{"lat":-0.026,"lng":109.354},{"lat":-0.028,"lng":109.351}]');
+8
View File
@@ -0,0 +1,8 @@
<?php
require_once 'koneksi.php';
$id = (int)($_POST['id'] ?? 0);
$stmt = $conn->prepare("DELETE FROM spbu WHERE id=?");
$stmt->bind_param('i', $id);
$stmt->execute();
echo json_encode(['status' => 'success']);
?>
+8
View File
@@ -0,0 +1,8 @@
<?php
require_once 'koneksi.php';
$id = (int)($_POST['id'] ?? 0);
$stmt = $conn->prepare("DELETE FROM jalan WHERE id=?");
$stmt->bind_param('i', $id);
$stmt->execute();
echo json_encode(['status' => 'success']);
?>
+8
View File
@@ -0,0 +1,8 @@
<?php
require_once 'koneksi.php';
$id = (int)($_POST['id'] ?? 0);
$stmt = $conn->prepare("DELETE FROM kavling WHERE id=?");
$stmt->bind_param('i', $id);
$stmt->execute();
echo json_encode(['status' => 'success']);
?>
+153
View File
@@ -0,0 +1,153 @@
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Landing Page Tugas SIG - Freya</title>
<style>
:root {
--bg: #f6f7fb;
--card: #ffffff;
--text: #1f2937;
--muted: #6b7280;
--line: #e5e7eb;
--primary: #111827;
--soft: #f3f4f6;
}
* { box-sizing: border-box; }
body {
margin: 0;
font-family: Arial, Helvetica, sans-serif;
background: var(--bg);
color: var(--text);
}
header {
background: var(--primary);
color: white;
padding: 42px 24px;
text-align: center;
}
header h1 {
margin: 0 0 10px;
font-size: clamp(26px, 4vw, 42px);
}
header p {
margin: 0;
color: #d1d5db;
}
main {
max-width: 1120px;
margin: -28px auto 48px;
padding: 0 18px;
}
.grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 18px;
}
.card {
background: var(--card);
border: 1px solid var(--line);
border-radius: 18px;
padding: 22px;
box-shadow: 0 8px 24px rgba(17,24,39,.08);
min-height: 260px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.badge {
display: inline-block;
padding: 7px 10px;
border-radius: 999px;
background: var(--soft);
color: #374151;
font-size: 12px;
font-weight: 700;
margin-bottom: 16px;
}
.card h2 {
margin: 0 0 10px;
font-size: 20px;
}
.card p {
margin: 0 0 18px;
color: var(--muted);
line-height: 1.55;
font-size: 14px;
}
a.btn {
display: inline-block;
text-decoration: none;
background: var(--primary);
color: white;
padding: 11px 14px;
border-radius: 12px;
font-weight: 700;
text-align: center;
}
.info {
background: white;
border: 1px solid var(--line);
border-radius: 16px;
padding: 18px 20px;
margin-top: 18px;
color: var(--muted);
line-height: 1.55;
}
code { background: #f3f4f6; padding: 2px 6px; border-radius: 6px; color: #111827; }
@media (max-width: 900px) { .grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .grid { grid-template-columns: 1fr; } main { margin-top: -18px; } }
</style>
</head>
<body>
<header>
<h1>Landing Page Tugas SIG</h1>
<p>Kumpulan tugas WebGIS kelas milik Freya Martines</p>
</header>
<main>
<section class="grid">
<article class="card">
<div>
<span class="badge">Tugas 1</span>
<h2>WebGIS Pemetaan SPBU</h2>
<p>Menampilkan, menambah, mengedit, dan menghapus titik SPBU menggunakan marker Leaflet.</p>
</div>
<a class="btn" href="Tugas1/">Buka Tugas 1</a>
</article>
<article class="card">
<div>
<span class="badge">Tugas 2</span>
<h2>Jalan & Kavling</h2>
<p>Manajemen data spasial jalan dalam bentuk polyline dan data kavling/tanah dalam bentuk polygon.</p>
</div>
<a class="btn" href="Tugas2/">Buka Tugas 2</a>
</article>
<article class="card">
<div>
<span class="badge">Tugas 3</span>
<h2>Layer Control SPBU</h2>
<p>Menampilkan layer group SPBU berdasarkan status buka 24 jam dan tidak buka 24 jam.</p>
</div>
<a class="btn" href="Tugas3/">Buka Tugas 3</a>
</article>
<article class="card">
<div>
<span class="badge">Tugas 4</span>
<h2>GeoJSON Kecamatan</h2>
<p>Menampilkan batas kecamatan Kota Pontianak dari file GeoJSON beserta nama kecamatan dan populasi.</p>
</div>
<a class="btn" href="Tugas4/">Buka Tugas 4</a>
</article>
</section>
<section class="info">
Setelah deploy, URL tugas akan berbentuk <code>/Tugas1/</code>, <code>/Tugas2/</code>, <code>/Tugas3/</code>, dan <code>/Tugas4/</code> dari domain utama Coolify.
</section>
</main>
</body>
</html>
+47
View File
@@ -0,0 +1,47 @@
<?php
// install_database.php - installer sementara untuk import database.sql
// Hapus file ini setelah database berhasil diimport.
set_time_limit(300);
$host = getenv('DB_HOST') ?: 'localhost';
$user = getenv('DB_USER') ?: 'root';
$pass = getenv('DB_PASS') ?: (getenv('DB_PASSWORD') ?: '');
$db = getenv('DB_NAME') ?: 'gis_spbu';
$port = (int)(getenv('DB_PORT') ?: 3306);
echo "<h2>Install Database Tugas SIG Kelas Freya</h2>";
echo "<p>Target koneksi: <b>" . htmlspecialchars($host) . ":" . htmlspecialchars((string)$port) . "</b>, database: <b>" . htmlspecialchars($db) . "</b>, user: <b>" . htmlspecialchars($user) . "</b></p>";
$conn = new mysqli($host, $user, $pass, $db, $port);
if ($conn->connect_error) {
die("<p style='color:red'>Koneksi gagal: " . htmlspecialchars($conn->connect_error) . "</p>");
}
$conn->set_charset('utf8mb4');
$sqlFile = __DIR__ . '/database.sql';
if (!file_exists($sqlFile)) {
die("<p style='color:red'>File database.sql tidak ditemukan.</p>");
}
$sql = file_get_contents($sqlFile);
$sql = preg_replace('/CREATE\s+DATABASE\s+IF\s+NOT\s+EXISTS\s+`?[^`\s;]+`?.*?;/is', '', $sql);
$sql = preg_replace('/CREATE\s+DATABASE\s+`?[^`\s;]+`?.*?;/is', '', $sql);
$sql = preg_replace('/USE\s+`?[^`\s;]+`?\s*;/is', '', $sql);
if ($conn->multi_query($sql)) {
do {
if ($result = $conn->store_result()) { $result->free(); }
} while ($conn->more_results() && $conn->next_result());
if ($conn->errno) {
echo "<p style='color:red'>Ada error saat import: " . htmlspecialchars($conn->error) . "</p>";
} else {
echo "<p style='color:green;font-weight:bold'>Database berhasil diimport/reset.</p>";
echo "<p>Setelah ini, hapus file <code>install_database.php</code> dari repo lalu redeploy.</p>";
}
} else {
echo "<p style='color:red'>Import gagal: " . htmlspecialchars($conn->error) . "</p>";
}
$conn->close();
?>
+23
View File
@@ -0,0 +1,23 @@
<?php
// koneksi.php - koneksi database untuk Coolify dan XAMPP
// Coolify: pakai environment variable
// XAMPP: fallback ke localhost/root/password kosong/database gis_spbu
$host = getenv('DB_HOST') ?: 'localhost';
$user = getenv('DB_USER') ?: 'root';
$pass = getenv('DB_PASS') ?: (getenv('DB_PASSWORD') ?: '');
$db = getenv('DB_NAME') ?: 'gis_spbu';
$port = (int)(getenv('DB_PORT') ?: 3306);
$conn = new mysqli($host, $user, $pass, $db, $port);
if ($conn->connect_error) {
http_response_code(500);
die(json_encode([
'status' => 'error',
'message' => 'Koneksi database gagal: ' . $conn->connect_error
]));
}
$conn->set_charset('utf8mb4');
?>
+12
View File
@@ -0,0 +1,12 @@
<?php
require_once 'koneksi.php';
$nama = $_POST['nama'] ?? '';
$wa = $_POST['wa'] ?? '';
$buka = $_POST['buka'] ?? 'Tidak';
$lat = $_POST['lat'] ?? 0;
$lng = $_POST['lng'] ?? 0;
$stmt = $conn->prepare("INSERT INTO spbu (nama, wa, buka, lat, lng) VALUES (?, ?, ?, ?, ?)");
$stmt->bind_param('sssdd', $nama, $wa, $buka, $lat, $lng);
$stmt->execute();
echo json_encode(['status' => 'success']);
?>
+11
View File
@@ -0,0 +1,11 @@
<?php
require_once 'koneksi.php';
$nama = $_POST['nama'] ?? '';
$status = $_POST['status'] ?? 'Kabupaten';
$panjang = $_POST['panjang'] ?? 0;
$geom = $_POST['geom'] ?? '[]';
$stmt = $conn->prepare("INSERT INTO jalan (nama, status, panjang, geom) VALUES (?, ?, ?, ?)");
$stmt->bind_param('ssds', $nama, $status, $panjang, $geom);
$stmt->execute();
echo json_encode(['status' => 'success']);
?>
+11
View File
@@ -0,0 +1,11 @@
<?php
require_once 'koneksi.php';
$pemilik = $_POST['pemilik'] ?? '';
$status = $_POST['status'] ?? 'SHM';
$luas = $_POST['luas'] ?? 0;
$geom = $_POST['geom'] ?? '[]';
$stmt = $conn->prepare("INSERT INTO kavling (pemilik, status, luas, geom) VALUES (?, ?, ?, ?)");
$stmt->bind_param('ssds', $pemilik, $status, $luas, $geom);
$stmt->execute();
echo json_encode(['status' => 'success']);
?>
+11
View File
@@ -0,0 +1,11 @@
<?php
require_once 'koneksi.php';
$id = (int)($_POST['id'] ?? 0);
$nama = $_POST['nama'] ?? '';
$wa = $_POST['wa'] ?? '';
$buka = $_POST['buka'] ?? 'Tidak';
$stmt = $conn->prepare("UPDATE spbu SET nama=?, wa=?, buka=? WHERE id=?");
$stmt->bind_param('sssi', $nama, $wa, $buka, $id);
$stmt->execute();
echo json_encode(['status' => 'success']);
?>
+10
View File
@@ -0,0 +1,10 @@
<?php
require_once 'koneksi.php';
$id = (int)($_POST['id'] ?? 0);
$nama = $_POST['nama'] ?? '';
$status = $_POST['status'] ?? 'Kabupaten';
$stmt = $conn->prepare("UPDATE jalan SET nama=?, status=? WHERE id=?");
$stmt->bind_param('ssi', $nama, $status, $id);
$stmt->execute();
echo json_encode(['status' => 'success']);
?>
+10
View File
@@ -0,0 +1,10 @@
<?php
require_once 'koneksi.php';
$id = (int)($_POST['id'] ?? 0);
$pemilik = $_POST['pemilik'] ?? '';
$status = $_POST['status'] ?? 'SHM';
$stmt = $conn->prepare("UPDATE kavling SET pemilik=?, status=? WHERE id=?");
$stmt->bind_param('ssi', $pemilik, $status, $id);
$stmt->execute();
echo json_encode(['status' => 'success']);
?>