save dulu
This commit is contained in:
parent
a1d2dd1990
commit
9f467b7dab
|
|
@ -32,7 +32,10 @@ public function store(Request $request)
|
|||
'tanggal_lahir' => 'required|date',
|
||||
'jenis_kelamin' => 'required|in:L,P',
|
||||
'wali_murid_id' => 'required|exists:wali_murids,id',
|
||||
// Alamat dihapus, karena ikut Wali Murid
|
||||
|
||||
// --- TAMBAHAN BARU: Validasi Titik Koordinat Peta ---
|
||||
'latitude' => 'nullable|string',
|
||||
'longitude' => 'nullable|string',
|
||||
]);
|
||||
|
||||
Siswa::create([
|
||||
|
|
@ -43,6 +46,10 @@ public function store(Request $request)
|
|||
'tanggal_lahir' => $request->tanggal_lahir,
|
||||
'jenis_kelamin' => $request->jenis_kelamin,
|
||||
'wali_murid_id' => $request->wali_murid_id,
|
||||
|
||||
// --- TAMBAHAN BARU: Simpan ke Database ---
|
||||
'latitude' => $request->latitude,
|
||||
'longitude' => $request->longitude,
|
||||
]);
|
||||
|
||||
return redirect()->route('siswa.index')->with('success', 'Data Siswa berhasil ditambahkan.');
|
||||
|
|
@ -67,6 +74,10 @@ public function update(Request $request, $id)
|
|||
'tanggal_lahir' => 'required|date',
|
||||
'jenis_kelamin' => 'required|in:L,P',
|
||||
'wali_murid_id' => 'required|exists:wali_murids,id',
|
||||
|
||||
// --- TAMBAHAN BARU: Validasi Titik Koordinat Peta ---
|
||||
'latitude' => 'nullable|string',
|
||||
'longitude' => 'nullable|string',
|
||||
]);
|
||||
|
||||
$siswa->update([
|
||||
|
|
@ -77,6 +88,10 @@ public function update(Request $request, $id)
|
|||
'tanggal_lahir' => $request->tanggal_lahir,
|
||||
'jenis_kelamin' => $request->jenis_kelamin,
|
||||
'wali_murid_id' => $request->wali_murid_id,
|
||||
|
||||
// --- TAMBAHAN BARU: Update ke Database ---
|
||||
'latitude' => $request->latitude,
|
||||
'longitude' => $request->longitude,
|
||||
]);
|
||||
|
||||
return redirect()->route('siswa.index')->with('success', 'Data Siswa berhasil diperbarui!');
|
||||
|
|
|
|||
|
|
@ -0,0 +1,142 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class AStarController extends Controller
|
||||
{
|
||||
public function cariRute(Request $request)
|
||||
{
|
||||
$id_awal = 1; // ID PAUD Aisyiyah Kartoharjo (Start)
|
||||
$awal = DB::table('titik_jalans')->where('id', $id_awal)->first();
|
||||
|
||||
// 1. Ambil kordinat dari HP Flutter
|
||||
$latTujuan = $request->query('lat');
|
||||
$lngTujuan = $request->query('lng');
|
||||
|
||||
if (!$latTujuan || !$lngTujuan) {
|
||||
return response()->json(['success' => false, 'message' => 'Koordinat tidak valid'], 400);
|
||||
}
|
||||
|
||||
$semua_titik = DB::table('titik_jalans')->get()->keyBy('id');
|
||||
|
||||
// 2. CARI TITIK TUJUAN YANG PALING COCOK BERDASARKAN KOORDINAT
|
||||
$tujuan = null;
|
||||
$jarakTerdekat = INF;
|
||||
|
||||
foreach ($semua_titik as $titik) {
|
||||
$jarak = $this->hitungJarak($latTujuan, $lngTujuan, $titik->latitude, $titik->longitude);
|
||||
if ($jarak < $jarakTerdekat) {
|
||||
$jarakTerdekat = $jarak;
|
||||
$tujuan = $titik;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$tujuan) {
|
||||
return response()->json(['success' => false, 'message' => 'Titik tidak ditemukan'], 404);
|
||||
}
|
||||
|
||||
$id_tujuan = $tujuan->id; // Dapatkan ID aslinya di tabel titik_jalans
|
||||
|
||||
// 3. Ambil jalur jembatannya
|
||||
$edges = DB::table('jalur_jalans')->get();
|
||||
$graph = [];
|
||||
foreach ($edges as $edge) {
|
||||
$graph[$edge->titik_awal_id][] = [
|
||||
'tujuan' => $edge->titik_tujuan_id,
|
||||
'jarak' => $edge->jarak
|
||||
];
|
||||
}
|
||||
|
||||
// ==========================================
|
||||
// PROSES A-STAR (A*)
|
||||
// ==========================================
|
||||
$openList = [$id_awal];
|
||||
$closedList = [];
|
||||
$cameFrom = [];
|
||||
|
||||
$gCost = [];
|
||||
$fCost = [];
|
||||
foreach ($semua_titik as $id => $titik) {
|
||||
$gCost[$id] = INF;
|
||||
$fCost[$id] = INF;
|
||||
}
|
||||
$gCost[$id_awal] = 0;
|
||||
$fCost[$id_awal] = $this->hitungHeuristic($awal, $tujuan);
|
||||
|
||||
while (!empty($openList)) {
|
||||
$current = null;
|
||||
$lowestF = INF;
|
||||
foreach ($openList as $nodeId) {
|
||||
if ($fCost[$nodeId] < $lowestF) {
|
||||
$lowestF = $fCost[$nodeId];
|
||||
$current = $nodeId;
|
||||
}
|
||||
}
|
||||
|
||||
if ($current == $id_tujuan) {
|
||||
return $this->rekonstruksiRute($cameFrom, $current, $semua_titik, $gCost[$current]);
|
||||
}
|
||||
|
||||
$openList = array_diff($openList, [$current]);
|
||||
$closedList[] = $current;
|
||||
|
||||
if (isset($graph[$current])) {
|
||||
foreach ($graph[$current] as $neighbor) {
|
||||
$neighborId = $neighbor['tujuan'];
|
||||
|
||||
if (in_array($neighborId, $closedList)) continue;
|
||||
|
||||
$tentativeGCost = $gCost[$current] + $neighbor['jarak'];
|
||||
|
||||
if ($tentativeGCost < $gCost[$neighborId]) {
|
||||
$cameFrom[$neighborId] = $current;
|
||||
$gCost[$neighborId] = $tentativeGCost;
|
||||
|
||||
$hCost = $this->hitungHeuristic($semua_titik[$neighborId], $tujuan);
|
||||
$fCost[$neighborId] = $tentativeGCost + $hCost;
|
||||
|
||||
if (!in_array($neighborId, $openList)) {
|
||||
$openList[] = $neighborId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json(['success' => false, 'message' => 'Rute tidak ditemukan (Buntu)'], 404);
|
||||
}
|
||||
|
||||
// --- RUMUS BANTUAN ---
|
||||
private function hitungJarak($lat1, $lon1, $lat2, $lon2) {
|
||||
$earthRadius = 6371000;
|
||||
$latFrom = deg2rad((float)$lat1);
|
||||
$lonFrom = deg2rad((float)$lon1);
|
||||
$latTo = deg2rad((float)$lat2);
|
||||
$lonTo = deg2rad((float)$lon2);
|
||||
|
||||
$latDelta = $latTo - $latFrom;
|
||||
$lonDelta = $lonTo - $lonFrom;
|
||||
|
||||
$angle = 2 * asin(sqrt(pow(sin($latDelta / 2), 2) + cos($latFrom) * cos($latTo) * pow(sin($lonDelta / 2), 2)));
|
||||
return round($angle * $earthRadius);
|
||||
}
|
||||
|
||||
private function hitungHeuristic($titikA, $titikB) {
|
||||
return $this->hitungJarak($titikA->latitude, $titikA->longitude, $titikB->latitude, $titikB->longitude);
|
||||
}
|
||||
|
||||
private function rekonstruksiRute($cameFrom, $current, $semua_titik, $jarakTotal) {
|
||||
$rute = [];
|
||||
while (isset($cameFrom[$current])) {
|
||||
array_unshift($rute, $semua_titik[$current]);
|
||||
$current = $cameFrom[$current];
|
||||
}
|
||||
array_unshift($rute, $semua_titik[$current]);
|
||||
|
||||
return response()->json(['success' => true, 'jarak_total_meter' => $jarakTotal, 'titik_rute' => $rute]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class JalurJalan extends Model
|
||||
{
|
||||
//
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Kunjungan extends Model
|
||||
{
|
||||
//
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class TitikJalan extends Model
|
||||
{
|
||||
//
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::table('siswas', function (Blueprint $table) {
|
||||
// Menambahkan kolom untuk titik koordinat GPS
|
||||
$table->string('latitude')->nullable()->after('alamat');
|
||||
$table->string('longitude')->nullable()->after('latitude');
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::table('siswas', function (Blueprint $table) {
|
||||
$table->dropColumn(['latitude', 'longitude']);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::create('kunjungans', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('guru_id')->constrained('users')->onDelete('cascade'); // Relasi ke Guru (User)
|
||||
$table->foreignId('siswa_id')->constrained('siswas')->onDelete('cascade'); // Relasi ke Siswa
|
||||
$table->date('tanggal_visit');
|
||||
$table->string('status')->default('menunggu'); // Status: menunggu, jalan, selesai
|
||||
|
||||
// --- Kolom untuk Penilaian (Dibuat fleksibel) ---
|
||||
$table->string('materi_belajar')->nullable();
|
||||
$table->string('nilai')->nullable(); // String, biar bisa diisi "BB", "BSB", atau angka 80
|
||||
$table->text('catatan')->nullable();
|
||||
$table->string('foto_kegiatan')->nullable();
|
||||
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('kunjungans');
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('titik_jalans', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('nama_titik'); // Contoh: "Simpang 3 Diponegoro", "PAUD", "Rumah Achazia"
|
||||
$table->string('latitude');
|
||||
$table->string('longitude');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('titik_jalans');
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('jalur_jalans', function (Blueprint $table) {
|
||||
$table->id();
|
||||
// Titik awal persimpangan
|
||||
$table->foreignId('titik_awal_id')->constrained('titik_jalans')->onDelete('cascade');
|
||||
// Titik tujuan persimpangan
|
||||
$table->foreignId('titik_tujuan_id')->constrained('titik_jalans')->onDelete('cascade');
|
||||
// Jarak asli jalan raya (dalam meter / kilometer) -> Ini jadi G-Cost di A*
|
||||
$table->double('jarak');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('jalur_jalans');
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class JalurJalanSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
// 1. Bersihkan tabel jalur_jalans sebelum diisi
|
||||
DB::statement('SET FOREIGN_KEY_CHECKS=0;');
|
||||
DB::table('jalur_jalans')->truncate();
|
||||
DB::statement('SET FOREIGN_KEY_CHECKS=1;');
|
||||
|
||||
// 2. Ambil semua data titik yang sudah Ghoza input
|
||||
$titik = DB::table('titik_jalans')->get()->keyBy('id');
|
||||
$jalur = [];
|
||||
|
||||
// 3. Hubungkan PAUD (ID 1) dengan Simpang A (2) dan Simpang B (3)
|
||||
$jalur = array_merge($jalur, $this->buatJalurBolakBalik($titik[1], $titik[2]));
|
||||
$jalur = array_merge($jalur, $this->buatJalurBolakBalik($titik[1], $titik[3]));
|
||||
|
||||
// 4. Hubungkan SETIAP RUMAH SISWA (ID 4 sampai 59) ke titik terdekatnya
|
||||
for ($i = 4; $i <= 59; $i++) {
|
||||
if(!isset($titik[$i])) continue; // Lewati kalau ID tidak ada
|
||||
|
||||
$rumah = $titik[$i];
|
||||
|
||||
// Hitung jarak dari rumah ke PAUD & Persimpangan
|
||||
$jarakKePaud = $this->hitungJarak($rumah->latitude, $rumah->longitude, $titik[1]->latitude, $titik[1]->longitude);
|
||||
$jarakKeSimpangA = $this->hitungJarak($rumah->latitude, $rumah->longitude, $titik[2]->latitude, $titik[2]->longitude);
|
||||
$jarakKeSimpangB = $this->hitungJarak($rumah->latitude, $rumah->longitude, $titik[3]->latitude, $titik[3]->longitude);
|
||||
|
||||
// Cari mana yang paling dekat
|
||||
$terdekat = 1;
|
||||
$jarakMin = $jarakKePaud;
|
||||
|
||||
if ($jarakKeSimpangA < $jarakMin) {
|
||||
$terdekat = 2;
|
||||
$jarakMin = $jarakKeSimpangA;
|
||||
}
|
||||
if ($jarakKeSimpangB < $jarakMin) {
|
||||
$terdekat = 3;
|
||||
$jarakMin = $jarakKeSimpangB;
|
||||
}
|
||||
|
||||
// Buat jembatan bolak-balik dari rumah ke titik terdekat tersebut
|
||||
$jalur = array_merge($jalur, $this->buatJalurBolakBalik($rumah, $titik[$terdekat]));
|
||||
}
|
||||
|
||||
// 5. Simpan semua data jembatannya ke Database!
|
||||
DB::table('jalur_jalans')->insert($jalur);
|
||||
|
||||
$totalJalur = count($jalur);
|
||||
$this->command->info("WOW! Berhasil membuat {$totalJalur} jembatan rute secara otomatis pakai Haversine Formula!");
|
||||
}
|
||||
|
||||
// --- RUMUS BANTUAN ---
|
||||
|
||||
// Fungsi bikin jalur 2 arah (Pergi - Pulang)
|
||||
private function buatJalurBolakBalik($titikA, $titikB) {
|
||||
$jarak = $this->hitungJarak($titikA->latitude, $titikA->longitude, $titikB->latitude, $titikB->longitude);
|
||||
return [
|
||||
['titik_awal_id' => $titikA->id, 'titik_tujuan_id' => $titikB->id, 'jarak' => $jarak],
|
||||
['titik_awal_id' => $titikB->id, 'titik_tujuan_id' => $titikA->id, 'jarak' => $jarak],
|
||||
];
|
||||
}
|
||||
|
||||
// Rumus Haversine: Mengubah Latitude & Longitude menjadi jarak Meter aslinya
|
||||
private function hitungJarak($lat1, $lon1, $lat2, $lon2) {
|
||||
$earthRadius = 6371000; // Radius bumi dalam meter
|
||||
$latFrom = deg2rad((float)$lat1);
|
||||
$lonFrom = deg2rad((float)$lon1);
|
||||
$latTo = deg2rad((float)$lat2);
|
||||
$lonTo = deg2rad((float)$lon2);
|
||||
|
||||
$latDelta = $latTo - $latFrom;
|
||||
$lonDelta = $lonTo - $lonFrom;
|
||||
|
||||
$angle = 2 * asin(sqrt(pow(sin($latDelta / 2), 2) +
|
||||
cos($latFrom) * cos($latTo) * pow(sin($lonDelta / 2), 2)));
|
||||
|
||||
return round($angle * $earthRadius); // Dibulatkan
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="bg-white shadow-md rounded-lg p-6 max-w-xl mx-auto mt-10">
|
||||
<div class="bg-white shadow-md rounded-lg p-6 max-w-xl mx-auto mt-10 mb-10">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h1 class="text-xl font-bold text-gray-700">➕ Tambah Siswa Baru</h1>
|
||||
<a href="{{ route('siswa.index') }}" class="text-gray-500 hover:text-gray-700">← Kembali</a>
|
||||
|
|
@ -74,6 +74,24 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4 p-4 border border-blue-200 bg-blue-50 rounded-lg">
|
||||
<label class="block text-gray-800 font-bold mb-2">📍 Titik Lokasi Rumah (Untuk Rute Kunjungan)</label>
|
||||
<p class="text-xs text-gray-600 mb-2">Geser dan klik pada peta di bawah untuk menandai rumah siswa.</p>
|
||||
|
||||
<div id="map" style="height: 300px; width: 100%; border-radius: 8px; z-index: 1;"></div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-4 mt-3">
|
||||
<div>
|
||||
<label class="block text-xs text-gray-500 mb-1">Latitude</label>
|
||||
<input type="text" name="latitude" id="latitude" value="{{ old('latitude') }}" class="w-full border border-gray-300 rounded p-2 bg-gray-100 text-sm" readonly placeholder="Otomatis terisi">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs text-gray-500 mb-1">Longitude</label>
|
||||
<input type="text" name="longitude" id="longitude" value="{{ old('longitude') }}" class="w-full border border-gray-300 rounded p-2 bg-gray-100 text-sm" readonly placeholder="Otomatis terisi">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end mt-6 gap-3">
|
||||
<button type="submit" class="bg-green-600 text-white font-semibold px-6 py-2 rounded-lg hover:bg-green-700 transition shadow-md">
|
||||
💾 Simpan Data
|
||||
|
|
@ -81,4 +99,41 @@
|
|||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
// Titik tengah default: Alun-alun Jember
|
||||
var map = L.map('map').setView([-7.628337, 111.525506], 13);
|
||||
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© OpenStreetMap contributors'
|
||||
}).addTo(map);
|
||||
|
||||
var marker;
|
||||
|
||||
// Kalau ada error validasi dan ada data lama, tampilkan markernya
|
||||
@if(old('latitude') && old('longitude'))
|
||||
var oldLat = {{ old('latitude') }};
|
||||
var oldLng = {{ old('longitude') }};
|
||||
marker = L.marker([oldLat, oldLng]).addTo(map);
|
||||
map.setView([oldLat, oldLng], 15);
|
||||
@endif
|
||||
|
||||
// Event saat peta diklik
|
||||
map.on('click', function(e) {
|
||||
var lat = e.latlng.lat;
|
||||
var lng = e.latlng.lng;
|
||||
|
||||
document.getElementById('latitude').value = lat;
|
||||
document.getElementById('longitude').value = lng;
|
||||
|
||||
if (marker) {
|
||||
map.removeLayer(marker);
|
||||
}
|
||||
marker = L.marker([lat, lng]).addTo(map);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endsection
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="bg-white shadow-md rounded-lg p-6 max-w-xl mx-auto mt-10">
|
||||
<div class="bg-white shadow-md rounded-lg p-6 max-w-xl mx-auto mt-10 mb-10">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h1 class="text-xl font-bold text-gray-700">✏️ Edit Data Siswa</h1>
|
||||
<a href="{{ route('siswa.index') }}" class="text-gray-500 hover:text-gray-700">← Kembali</a>
|
||||
|
|
@ -78,6 +78,24 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4 p-4 border border-blue-200 bg-blue-50 rounded-lg">
|
||||
<label class="block text-gray-800 font-bold mb-2">📍 Titik Lokasi Rumah (Untuk Rute Kunjungan)</label>
|
||||
<p class="text-xs text-gray-600 mb-2">Geser dan klik pada peta untuk mengubah lokasi rumah siswa.</p>
|
||||
|
||||
<div id="map" style="height: 300px; width: 100%; border-radius: 8px; z-index: 1;"></div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-4 mt-3">
|
||||
<div>
|
||||
<label class="block text-xs text-gray-500 mb-1">Latitude</label>
|
||||
<input type="text" name="latitude" id="latitude" value="{{ old('latitude', $siswa->latitude) }}" class="w-full border border-gray-300 rounded p-2 bg-gray-100 text-sm" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs text-gray-500 mb-1">Longitude</label>
|
||||
<input type="text" name="longitude" id="longitude" value="{{ old('longitude', $siswa->longitude) }}" class="w-full border border-gray-300 rounded p-2 bg-gray-100 text-sm" readonly>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end mt-6 gap-3">
|
||||
<button type="submit" class="bg-green-600 text-white font-semibold px-6 py-2 rounded-lg hover:bg-green-700 transition shadow-md">
|
||||
💾 Simpan Perubahan
|
||||
|
|
@ -85,4 +103,42 @@
|
|||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
// Cek apakah siswa sudah punya koordinat
|
||||
var currentLat = {{ $siswa->latitude ?? '-7.628337' }};
|
||||
var currentLng = {{ $siswa->longitude ?? '111.525506' }};
|
||||
var hasLocation = {{ $siswa->latitude ? 'true' : 'false' }};
|
||||
|
||||
var map = L.map('map').setView([currentLat, currentLng], hasLocation ? 16 : 13);
|
||||
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© OpenStreetMap contributors'
|
||||
}).addTo(map);
|
||||
|
||||
var marker;
|
||||
|
||||
// Jika sudah ada koordinat, pasang marker
|
||||
if (hasLocation) {
|
||||
marker = L.marker([currentLat, currentLng]).addTo(map);
|
||||
}
|
||||
|
||||
// Event saat peta diklik
|
||||
map.on('click', function(e) {
|
||||
var lat = e.latlng.lat;
|
||||
var lng = e.latlng.lng;
|
||||
|
||||
document.getElementById('latitude').value = lat;
|
||||
document.getElementById('longitude').value = lng;
|
||||
|
||||
if (marker) {
|
||||
map.removeLayer(marker);
|
||||
}
|
||||
marker = L.marker([lat, lng]).addTo(map);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endsection
|
||||
|
|
@ -10,6 +10,7 @@
|
|||
use App\Http\Controllers\Api\LaporanController;
|
||||
use App\Http\Controllers\Api\GuruController;
|
||||
use App\Http\Controllers\Api\PenjemputanController;
|
||||
use App\Http\Controllers\Api\AStarController;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
@ -26,7 +27,6 @@
|
|||
|
||||
// --- KHUSUS WALI MURID (Lihat Data) ---
|
||||
// Wali melihat daftar anaknya
|
||||
|
||||
// ==========================================
|
||||
// 2. AREA TERKUNCI (BUTUH TOKEN)
|
||||
// ==========================================
|
||||
|
|
@ -55,5 +55,8 @@
|
|||
|
||||
// RUTE PENJEMPUTAN BARU
|
||||
Route::post('/penjemputan', [PenjemputanController::class, 'store']);
|
||||
|
||||
Route::get('/rute-astar', [AStarController::class, 'cariRute']);
|
||||
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -82,4 +82,30 @@
|
|||
Route::get('/rapot/{id}/print', [App\Http\Controllers\Admin\RapotController::class, 'print'])->name('rapot.print');
|
||||
});
|
||||
|
||||
Route::get('/sinkron-kordinat', function () {
|
||||
// Ambil data dari ID 4 sampai akhir (karena ID 1-3 itu PAUD dan Simpang)
|
||||
$titikRumah = DB::table('titik_jalans')->where('id', '>=', 4)->get();
|
||||
$berhasil = 0;
|
||||
|
||||
foreach ($titikRumah as $titik) {
|
||||
// Hilangkan kata "Rumah " biar sisa nama siswanya aja
|
||||
$namaSiswa = str_replace('Rumah ', '', $titik->nama_titik);
|
||||
$namaSiswa = trim($namaSiswa);
|
||||
|
||||
// Update latitude & longitude di tabel siswas yang namanya mirip
|
||||
$update = DB::table('siswas')
|
||||
->where('nama_siswa', 'LIKE', '%' . $namaSiswa . '%')
|
||||
->update([
|
||||
'latitude' => $titik->latitude,
|
||||
'longitude' => $titik->longitude
|
||||
]);
|
||||
|
||||
if($update) {
|
||||
$berhasil++;
|
||||
}
|
||||
}
|
||||
|
||||
return "Selesai Bosku! Berhasil menyinkronkan $berhasil data koordinat siswa!";
|
||||
});
|
||||
|
||||
});
|
||||
Loading…
Reference in New Issue