Initial commit

This commit is contained in:
ocabacaa
2026-06-11 03:02:00 +07:00
commit 8c74b19cc6
16 changed files with 1912 additions and 0 deletions
+77
View File
@@ -0,0 +1,77 @@
# WebGIS SPBU
## Deskripsi
WebGIS SPBU merupakan Sistem Informasi Geografis berbasis web yang digunakan untuk memetakan, mengelola, dan mencari lokasi SPBU dengan rute terdekat dari titik lokasi user saat ini.
**Nama:** Clara Oxana Azalia
**NIM:** D1041231051
## Fitur
- CRUD Data SPBU
- Upload Foto SPBU
- Pencarian SPBU
- Lokasi Saya
- SPBU Terdekat
- Routing ke SPBU Terdekat
- Status Buka/Tutup Otomatis
- Filter SPBU
- Mode Admin dan View
- Digitasi Polygon
- Digitasi Polyline
- Edit dan Hapus Objek Spasial
- Penyimpanan GeoJSON ke Database
## Teknologi
- PHP Native
- MySQL
- JavaScript
- Leaflet.js
- Leaflet Draw
- Leaflet Routing Machine
- OpenStreetMap
- Tailwind CSS
## Instalasi
1. Clone repository
```bash
git clone https://github.com/USERNAME/webgis-spbu.git
```
2. Import database
```text
database.sql
```
3. Sesuaikan konfigurasi database pada:
```php
koneksi.php
```
4. Jalankan pada server lokal:
```text
http://localhost/webgis-spbu
```
## Struktur Project
```text
api/
assets/
uploads/
database.sql
koneksi.php
index.php
```
## Pengembang
Clara Oxana Azalia
D1041231051
+133
View File
@@ -0,0 +1,133 @@
<?php
include '../koneksi.php';
header('Content-Type: application/json');
$id = $_POST['id'];
$nama = $_POST['nama'];
$alamat = $_POST['alamat'];
$lat = $_POST['lat'];
$lng = $_POST['lng'];
$fotoLama = '';
$jam_buka = $_POST['jam_buka'];
$jam_tutup = $_POST['jam_tutup'];
$buka_24_jam = $_POST['buka_24_jam'];
$getData = mysqli_query(
$conn,
"SELECT foto
FROM spbu
WHERE id='$id'"
);
if($row = mysqli_fetch_assoc($getData)){
$fotoLama = $row['foto'];
}
$updateFoto = "";
$hapusFotoLama = false;
if(
isset($_FILES['foto']) &&
$_FILES['foto']['error'] == 0
){
$namaFile =
time().'_'.
$_FILES['foto']['name'];
$allowed = [
'jpg',
'jpeg',
'png',
'webp'
];
$fileType = strtolower(
pathinfo(
$_FILES['foto']['name'],
PATHINFO_EXTENSION
)
);
if(!in_array($fileType, $allowed)){
echo json_encode([
'status'=>'error',
'message'=>'File type not allowed'
]);
exit;
}
move_uploaded_file(
$_FILES['foto']['tmp_name'],
'../uploads/spbu/' .
$namaFile
);
$updateFoto =
", foto='$namaFile'";
$hapusFotoLama = true;
}
$query = mysqli_query(
$conn,
"UPDATE spbu SET
nama_spbu='$nama',
alamat='$alamat',
latitude='$lat',
longitude='$lng',
jam_buka='$jam_buka',
jam_tutup='$jam_tutup',
buka_24_jam='$buka_24_jam'
$updateFoto
WHERE id='$id'
"
);
if($query){
if(
$hapusFotoLama &&
!empty($fotoLama) &&
file_exists(
'../uploads/spbu/' .
$fotoLama
)
){
unlink(
'../uploads/spbu/' .
$fotoLama
);
}
echo json_encode([
'status'=>'success'
]);
} else{
echo json_encode([
'status'=>'error',
'message'=>mysqli_error($conn)
]);
}
+22
View File
@@ -0,0 +1,22 @@
<?php
include '../koneksi.php';
$query =
mysqli_query(
$conn,
"SELECT * FROM objek_peta"
);
$data = [];
while(
$row =
mysqli_fetch_assoc($query)
){
$data[] = $row;
}
echo json_encode($data);
+16
View File
@@ -0,0 +1,16 @@
<?php
include '../koneksi.php';
$query = mysqli_query(
$conn,
"SELECT * FROM spbu"
);
$data = [];
while($row = mysqli_fetch_assoc($query)){
$data[] = $row;
}
echo json_encode($data);
+15
View File
@@ -0,0 +1,15 @@
<?php
include '../koneksi.php';
$id = $_POST['id'];
mysqli_query(
$conn,
"DELETE FROM objek_peta
WHERE id='$id'"
);
+51
View File
@@ -0,0 +1,51 @@
<?php
include '../koneksi.php';
$data = json_decode(
file_get_contents("php://input"),
true
);
$id = $data['id'];
$foto = '';
$getData = mysqli_query(
$conn,
"SELECT foto
FROM spbu
WHERE id='$id'"
);
if($row = mysqli_fetch_assoc($getData)){
$foto = $row['foto'];
}
if(!empty($foto) && file_exists('../uploads/spbu/' . $foto)){
unlink('../uploads/spbu/' . $foto);
}
$query = mysqli_query(
$conn,
"DELETE FROM spbu WHERE id='$id'"
);
if($query){
echo json_encode([
'status'=>'success'
]);
}else{
echo json_encode([
'status'=>'error'
]);
}
+35
View File
@@ -0,0 +1,35 @@
<?php
include '../koneksi.php';
$nama = $_POST['nama'];
$deskripsi = $_POST['deskripsi'];
$tipe = $_POST['tipe'];
$geojson = $_POST['geojson'];
mysqli_query(
$conn,
"INSERT INTO objek_peta
(
nama,
deskripsi,
tipe,
geojson
)
VALUES
(
'$nama',
'$deskripsi',
'$tipe',
'$geojson'
)"
);
$id = mysqli_insert_id($conn);
echo json_encode([
'id'=>$id
]);
+104
View File
@@ -0,0 +1,104 @@
<?php
include '../koneksi.php';
$nama = $_POST['nama'];
$alamat = $_POST['alamat'];
$lat = $_POST['lat'];
$lng = $_POST['lng'];
$jam_buka = $_POST['jam_buka'] ?? null;
$jam_tutup = $_POST['jam_tutup'] ?? null;
$buka_24_jam = $_POST['buka_24_jam'] ?? 0;
$foto = '';
if(isset($_FILES['foto'])){
$namaFile =
time().'_'.
$_FILES['foto']['name'];
$allowed = [
'jpg',
'jpeg',
'png',
'webp'
];
$ext =
strtolower(
pathinfo(
$_FILES['foto']['name'],
PATHINFO_EXTENSION
)
);
if(
!in_array(
$ext,
$allowed
)
){
echo json_encode([
'status'=>'error',
'message'=>'Format file tidak valid'
]);
exit;
}
move_uploaded_file(
$_FILES['foto']['tmp_name'],
'../uploads/spbu/'.
$namaFile
);
$foto = $namaFile;
}
$query = mysqli_query(
$conn,
"INSERT INTO spbu
(
nama_spbu,
alamat,
latitude,
longitude,
foto,
jam_buka,
jam_tutup,
buka_24_jam
)
VALUES
(
'$nama',
'$alamat',
'$lat',
'$lng',
'$foto',
'$jam_buka',
'$jam_tutup',
'$buka_24_jam'
)"
);
if($query){
echo json_encode([
'status'=>'success'
]);
}else{
echo json_encode([
'status'=>'error',
'message'=>mysqli_error($conn)
]);
}
+43
View File
@@ -0,0 +1,43 @@
<?php
include '../koneksi.php';
$id = $_POST['id'];
$nama = $_POST['nama'] ?? '';
$deskripsi = $_POST['deskripsi'] ?? '';
if(isset($_POST['geojson'])){
$geojson = $_POST['geojson'];
mysqli_query(
$conn,
"UPDATE objek_peta
SET geojson='$geojson'
WHERE id='$id'"
);
}else{
mysqli_query(
$conn,
"UPDATE objek_peta
SET
nama='$nama',
deskripsi='$deskripsi'
WHERE id='$id'"
);
}
echo json_encode([
'status'=>'success'
]);
+3
View File
@@ -0,0 +1,3 @@
.leaflet-interactive{
cursor:pointer;
}
+1072
View File
File diff suppressed because it is too large Load Diff
+23
View File
@@ -0,0 +1,23 @@
CREATE TABLE spbu (
id INT AUTO_INCREMENT PRIMARY KEY,
nama_spbu VARCHAR(100),
alamat TEXT,
latitude DOUBLE,
longitude DOUBLE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
ALTER TABLE spbu
ADD foto VARCHAR(255);
ALTER TABLE spbu
ADD buka_24_jam TINYINT(1) DEFAULT 0,
ADD jam_buka TIME,
ADD jam_tutup TIME;
CREATE TABLE objek_peta (
id INT AUTO_INCREMENT PRIMARY KEY,
nama VARCHAR(100),
tipe VARCHAR(20),
geojson LONGTEXT
);
+306
View File
@@ -0,0 +1,306 @@
<!DOCTYPE html>
<html>
<head>
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
<link rel="stylesheet" href="https://unpkg.com/leaflet-routing-machine@latest/dist/leaflet-routing-machine.css" />
<link rel="stylesheet" href="https://unpkg.com/leaflet-draw/dist/leaflet.draw.css" />
<style>
#map {
height: 100vh;
}
</style>
</head>
<body>
<div class="flex h-screen">
<div class="flex-1 relative">
<div style="
position:absolute;
top:15px;
left:60px;
z-index:9999;
background:white;
padding:10px;
border-radius:8px;
box-shadow:0 2px 8px rgba(0,0,0,.2);
">
<div style="margin-bottom:10px;">
<h1 style="
font-size:24px;
font-weight:bold;
color:#2563eb;
margin:0;
">
Dashboard WebGIS SPBU
</h1>
<p style="
margin:0;
color:#666;
font-size:14px;
">
Sistem Informasi Geografis Pemetaan dan Pencarian Lokasi SPBU
</p>
<p style="
margin:3px 0 0 0;
color:#999;
font-size:12px;
">
Clara Oxana Azalia | D1041231051
</p>
</div>
<!-- toolbar -->
<div class="flex gap-2">
<input type="text" id="search_spbu" placeholder="Cari SPBU..." class="border p-2 rounded">
<button onclick="cariSPBU()" class="bg-blue-500 text-white px-3 rounded">
Cari
</button>
<button onclick="lokasiSaya()" class="bg-green-500 text-white px-3 rounded">
Lokasi Saya
</button>
<button onclick="cariTerdekat()" class="bg-red-500 text-white px-3 rounded">
SPBU Terdekat
</button>
<button onclick="buatRuteTerdekat()" class="bg-purple-500 text-white px-3 rounded">
Rute
</button>
<select id="filter_spbu" onchange="filterSPBU()" class="border p-2 rounded">
<option value="all">
Semua SPBU
</option>
<option value="24">
SPBU 24 Jam
</option>
<option value="non24">
Non 24 Jam
</option>
<option value="buka">
Sedang Buka
</option>
<option value="tutup">
Sedang Tutup
</option>
</select>
<button onclick="toggleMode()" id="btnMode" class="bg-blue-600 text-white px-3 rounded">
Ganti Mode
</button>
<span id="statusMode" class="bg-blue-100 text-blue-700 px-3 py-2 rounded font-semibold">
🔓 ADMIN
</span>
</div>
</div>
<div style="
position:absolute;
bottom:20px;
left:20px;
z-index:9999;
background:white;
padding:12px;
border-radius:8px;
box-shadow:0 2px 8px rgba(0,0,0,.2);
">
<h3 class="font-bold mb-2">
Keterangan
</h3>
<div class="flex items-center gap-2 mb-1">
<span class="w-4 h-4 bg-green-500 rounded-full"></span>
SPBU 24 Jam
</div>
<div class="flex items-center gap-2">
<span class="w-4 h-4 bg-red-500 rounded-full"></span>
SPBU Non 24 Jam
</div>
</div>
<div id="bannerMode" class="hidden" style="
position:absolute;
top:120px;
left:50%;
transform:translateX(-50%);
z-index:99999;
">
</div>
<div id="map" class="h-full"></div>
</div>
<!-- edit -->
<div id="sidebar" class="w-96 bg-white shadow-lg p-5 hidden overflow-y-auto">
<h2 class="text-xl font-bold mb-4">
Edit SPBU
</h2>
<input type="hidden" id="edit_id">
<label class="block mb-1">
Nama SPBU
</label>
<input id="edit_nama" class="w-full border p-2 rounded mb-3">
<label class="block mb-1">
Alamat
</label>
<textarea id="edit_alamat" class="w-full border p-2 rounded mb-3"></textarea>
<label class="block mb-1">
Foto SPBU
</label>
<img id="preview_edit_foto" src="" class="w-full h-40 object-cover rounded mb-2 hidden">
<input type="file" id="edit_foto" class="w-full border p-2 rounded mb-3">
<label class="block mb-1">
Jam Buka
</label>
<input type="time" id="edit_jam_buka" class="w-full border p-2 rounded mb-3">
<label class="block mb-1">
Jam Tutup
</label>
<input type="time" id="edit_jam_tutup" class="w-full border p-2 rounded mb-3">
<label class="flex items-center gap-2 mb-3">
<input type="checkbox" id="edit_24jam">
Buka 24 Jam
</label>
<label class="block mb-1">
Latitude
</label>
<input id="edit_lat" class="w-full border p-2 rounded mb-3">
<label class="block mb-1">
Longitude
</label>
<input id="edit_lng" class="w-full border p-2 rounded mb-3">
<div class="flex gap-2">
<button onclick="updateSPBU()" class="bg-blue-500 text-white px-4 py-2 rounded">
Simpan
</button>
<button onclick="tutupSidebar()" class="bg-gray-500 text-white px-4 py-2 rounded">
Tutup
</button>
</div>
</div>
<div id="sidebarObjek" class="w-96 bg-white shadow-lg p-5 hidden overflow-y-auto">
<h2 class="text-xl font-bold mb-4">
Edit Objek Peta
</h2>
<input type="hidden" id="objek_id">
<label class="block mb-1">
Nama Objek
</label>
<input id="objek_nama" class="w-full border p-2 rounded mb-3">
<label class="block mb-1">
Deskripsi
</label>
<textarea id="objek_deskripsi" class="w-full border p-2 rounded mb-3"></textarea>
<label class="block mb-1">
Tipe
</label>
<input id="objek_tipe" readonly class="w-full border p-2 rounded mb-3 bg-gray-100">
<div class="flex gap-2">
<button onclick="updateObjek()" class="bg-blue-500 text-white px-4 py-2 rounded">
Simpan
</button>
<button onclick="tutupSidebarObjek()" class="bg-gray-500 text-white px-4 py-2 rounded">
Tutup
</button>
</div>
</div>
</div>
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<script src="https://unpkg.com/leaflet-routing-machine@latest/dist/leaflet-routing-machine.js"></script>
<script src="https://unpkg.com/leaflet-draw/dist/leaflet.draw.js"></script>
<script src="assets/js/map.js"></script>
</body>
</html>
+12
View File
@@ -0,0 +1,12 @@
<?php
$conn = mysqli_connect(
"localhost",
"root",
"",
"gis_spbu"
);
if(!$conn){
die(mysqli_connect_error());
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB