update
This commit is contained in:
@ -314,6 +314,20 @@
|
|||||||
// Timestamp 'start' TIDAK diubah karena itu waktu kejadian sebenarnya —
|
// Timestamp 'start' TIDAK diubah karena itu waktu kejadian sebenarnya —
|
||||||
// yang disamakan hanya titik lokasi & odometer supaya laporan terlihat
|
// yang disamakan hanya titik lokasi & odometer supaya laporan terlihat
|
||||||
// kontinu (finish trip N == start trip N+1).
|
// kontinu (finish trip N == start trip N+1).
|
||||||
|
//
|
||||||
|
// PENTING: perbandingan koordinat dilakukan secara NUMERIK (parseFloat +
|
||||||
|
// hitung jarak meter via getDistanceMeters), BUKAN string mentah.
|
||||||
|
// Ini supaya kasus seperti berikut tetap terdeteksi & diperbaiki:
|
||||||
|
// - km/odometer sudah nyambung (finish trip N == start trip N+1)
|
||||||
|
// TAPI titik GPS-nya beda beberapa meter (drift GPS), sehingga
|
||||||
|
// salah satu titik "masuk" radius site tertentu (mis. "Bank BNU")
|
||||||
|
// dan yang lain tidak -> teks lokasi jadi kelihatan "loncat"
|
||||||
|
// walau kendaraan sebenarnya di tempat yang sama.
|
||||||
|
// Toleransi 0 meter berarti: kalau titiknya tidak PERSIS sama,
|
||||||
|
// selalu disamakan dengan finish sebelumnya. Ini paling aman untuk
|
||||||
|
// laporan (finish trip N akan selalu == start trip N+1).
|
||||||
|
const TRIP_CONTINUITY_TOLERANCE_METERS = 0; // >>> ADDED
|
||||||
|
|
||||||
function normalizeTripContinuity(rows) { // >>> ADDED
|
function normalizeTripContinuity(rows) { // >>> ADDED
|
||||||
if (!Array.isArray(rows) || rows.length === 0) return rows;
|
if (!Array.isArray(rows) || rows.length === 0) return rows;
|
||||||
|
|
||||||
@ -333,14 +347,54 @@
|
|||||||
const prev = groupRows[i - 1];
|
const prev = groupRows[i - 1];
|
||||||
const curr = groupRows[i];
|
const curr = groupRows[i];
|
||||||
|
|
||||||
const locMismatch = (prev.finish_lat_long || '').trim() !== (curr.start_lat_long || '')
|
// 1) Cek mismatch km/odometer
|
||||||
.trim();
|
|
||||||
const kmMismatch = Number(prev.finishMileage) !== Number(curr.startMileage);
|
const kmMismatch = Number(prev.finishMileage) !== Number(curr.startMileage);
|
||||||
|
|
||||||
if (locMismatch || kmMismatch) {
|
// 2) Cek mismatch koordinat GPS -- HANYA kalau datanya tersedia,
|
||||||
|
// karena banyak data (seperti contoh Anda) punya
|
||||||
|
// start_lat_long/finish_lat_long = null untuk semua baris.
|
||||||
|
const prevCoord = parseLatLong(prev.finish_lat_long);
|
||||||
|
const currCoord = parseLatLong(curr.start_lat_long);
|
||||||
|
let coordMismatch = false;
|
||||||
|
if (prevCoord.lat !== null && currCoord.lat !== null) {
|
||||||
|
const distMeters = getDistanceMeters(
|
||||||
|
prevCoord.lat, prevCoord.lng,
|
||||||
|
currCoord.lat, currCoord.lng
|
||||||
|
);
|
||||||
|
coordMismatch = distMeters > TRIP_CONTINUITY_TOLERANCE_METERS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3) Cek mismatch TEKS lokasi (startLoc vs finishLoc). Ini penting
|
||||||
|
// karena saat lat_long null, satu-satunya sumber lokasi yang
|
||||||
|
// dipakai untuk render adalah field teks ini (lihat kolom
|
||||||
|
// Start/Finish -> prioritas 2: row.startLoc / row.finishLoc).
|
||||||
|
// Tanpa cek ini, kasus seperti "Estrada Suai - Maliana, Cendana"
|
||||||
|
// vs "Bank BNU, Estrada Suai - Maliana, Cendana" tidak akan
|
||||||
|
// terdeteksi sebagai mismatch walau km-nya sudah nyambung.
|
||||||
|
const prevFinishText = (prev.finishLoc || '').trim();
|
||||||
|
const currStartText = (curr.startLoc || '').trim();
|
||||||
|
const textMismatch = prevFinishText !== currStartText;
|
||||||
|
|
||||||
|
if (kmMismatch || coordMismatch || textMismatch) {
|
||||||
curr.start_lat_long = prev.finish_lat_long;
|
curr.start_lat_long = prev.finish_lat_long;
|
||||||
curr.startLoc = prev.finishLoc;
|
curr.startLoc = prev.finishLoc;
|
||||||
curr.startMileage = prev.finishMileage;
|
curr.startMileage = prev.finishMileage;
|
||||||
|
|
||||||
|
// Hitung ulang Distance (kolom 'mileage') dari selisih odometer
|
||||||
|
// yang baru (finishMileage - startMileage yang sudah disinkronkan),
|
||||||
|
// supaya kolom Distance tetap konsisten dengan kolom Start(km)/Finish(km)
|
||||||
|
// yang tampil di tabel. Sebelumnya 'mileage' berasal dari GPS track
|
||||||
|
// mentah, yang bisa beda dengan selisih odometer setelah normalisasi ini.
|
||||||
|
//
|
||||||
|
// - Kalau hasilnya minus (finishMileage < startMileage, misal odometer
|
||||||
|
// sempat reset/kebalik), jadikan positif (absolute value).
|
||||||
|
// - Lalu bulatkan ke bilangan bulat terdekat: desimal >= 0.5 dibulatkan
|
||||||
|
// ke atas, desimal < 0.5 dibulatkan ke bawah (standard round-half-up;
|
||||||
|
// Math.round sudah berlaku demikian untuk angka positif).
|
||||||
|
const rawDiff = Number(curr.finishMileage) - Number(curr.startMileage);
|
||||||
|
if (!isNaN(rawDiff)) {
|
||||||
|
curr.mileage = Math.round(Math.abs(rawDiff));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -600,7 +654,8 @@
|
|||||||
locationLabel = formatSiteLabel(nearestSite);
|
locationLabel = formatSiteLabel(nearestSite);
|
||||||
} else if (row.startLoc) {
|
} else if (row.startLoc) {
|
||||||
// Prioritas 2: startLoc sudah ada dari API
|
// Prioritas 2: startLoc sudah ada dari API
|
||||||
locationLabel = Helper.shortenText(decodeURIComponent(row.startLoc), 255);
|
locationLabel = Helper.shortenText(decodeURIComponent(row
|
||||||
|
.startLoc), 255);
|
||||||
} else if (type === 'export') {
|
} else if (type === 'export') {
|
||||||
// Export bersifat sinkron, tidak bisa menunggu hasil geocode background
|
// Export bersifat sinkron, tidak bisa menunggu hasil geocode background
|
||||||
locationLabel = '-';
|
locationLabel = '-';
|
||||||
@ -630,7 +685,8 @@
|
|||||||
if (nearestSite) {
|
if (nearestSite) {
|
||||||
locationLabel = formatSiteLabel(nearestSite);
|
locationLabel = formatSiteLabel(nearestSite);
|
||||||
} else if (row.finishLoc) {
|
} else if (row.finishLoc) {
|
||||||
locationLabel = Helper.shortenText(decodeURIComponent(row.finishLoc), 255);
|
locationLabel = Helper.shortenText(decodeURIComponent(row
|
||||||
|
.finishLoc), 255);
|
||||||
} else if (type === 'export') {
|
} else if (type === 'export') {
|
||||||
locationLabel = '-';
|
locationLabel = '-';
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user