| Line 1187... |
Line 1187... |
| 1187 |
var lbl=fmtDur2(s.seconds);
|
1187 |
var lbl=fmtDur2(s.seconds);
|
| 1188 |
pin({lat:s.lat,lng:s.lng}, bjStopPin(lbl), 80, 'Idle '+lbl,
|
1188 |
pin({lat:s.lat,lng:s.lng}, bjStopPin(lbl), 80, 'Idle '+lbl,
|
| 1189 |
'<div style="font-size:12px"><b>⏱ Idle stop</b><br>Stayed ~'+esc(lbl)+' within 50 m</div>');
|
1189 |
'<div style="font-size:12px"><b>⏱ Idle stop</b><br>Stayed ~'+esc(lbl)+' within 50 m</div>');
|
| 1190 |
});
|
1190 |
});
|
| 1191 |
|
1191 |
|
| - |
|
1192 |
// 3) every visit — visited stops are numbered in array order; pending / deferred
|
| - |
|
1193 |
// stops (plotted at their planned store location) get a neutral dot and sit
|
| 1192 |
// 3) every visit
|
1194 |
// below the visited pins.
|
| 1193 |
var idx=0;
|
1195 |
var idx=0;
|
| 1194 |
(data.visits||[]).forEach(function(v){
|
1196 |
(data.visits||[]).forEach(function(v){
|
| 1195 |
var color=bjMarkColor(v.markType);
|
1197 |
var color=bjMarkColor(v.markType);
|
| - |
|
1198 |
var visited = !!v.checkInTime;
|
| 1196 |
pin({lat:v.lat,lng:v.lng}, bjPin(color, String(++idx)), 100,
|
1199 |
pin({lat:v.lat,lng:v.lng}, bjPin(color, visited?String(++idx):'•'), visited?100:60,
|
| 1197 |
(v.name||'')+' ('+v.markType+')', bjMarkInfo(v,color));
|
1200 |
(v.name||'')+' ('+v.markType+')', bjMarkInfo(v,color));
|
| 1198 |
});
|
1201 |
});
|
| 1199 |
|
1202 |
|
| 1200 |
// 4) punch in / punch out
|
1203 |
// 4) punch in / punch out
|
| 1201 |
if(data.punchIn){
|
1204 |
if(data.punchIn){
|
| Line 1212... |
Line 1215... |
| 1212 |
// 5) routes — actual road taken vs Google-suggested optimal, for comparison.
|
1215 |
// 5) routes — actual road taken vs Google-suggested optimal, for comparison.
|
| 1213 |
// Checkpoints in journey order: punch in → visits (by check-in time) → punch out.
|
1216 |
// Checkpoints in journey order: punch in → visits (by check-in time) → punch out.
|
| 1214 |
var cps=[];
|
1217 |
var cps=[];
|
| 1215 |
if(data.punchIn) cps.push({lat:data.punchIn.lat,lng:data.punchIn.lng});
|
1218 |
if(data.punchIn) cps.push({lat:data.punchIn.lat,lng:data.punchIn.lng});
|
| 1216 |
(data.visits||[]).slice()
|
1219 |
(data.visits||[]).slice()
|
| 1217 |
.filter(function(v){ return v.lat && v.lng; })
|
1220 |
.filter(function(v){ return v.lat && v.lng && v.checkInTime; }) // visited stops only
|
| 1218 |
.sort(function(a,b){ return tlSecs(a.checkInTime)-tlSecs(b.checkInTime); })
|
1221 |
.sort(function(a,b){ return tlSecs(a.checkInTime)-tlSecs(b.checkInTime); })
|
| 1219 |
.forEach(function(v){ cps.push({lat:v.lat,lng:v.lng}); });
|
1222 |
.forEach(function(v){ cps.push({lat:v.lat,lng:v.lng}); });
|
| 1220 |
if(data.punchOut) cps.push({lat:data.punchOut.lat,lng:data.punchOut.lng});
|
1223 |
if(data.punchOut) cps.push({lat:data.punchOut.lat,lng:data.punchOut.lng});
|
| 1221 |
// Actual time window of the GPS trail (first → last breadcrumb timestamp),
|
1224 |
// Actual time window of the GPS trail (first → last breadcrumb timestamp),
|
| 1222 |
// shown on the taken-route click detail alongside the driving estimate.
|
1225 |
// shown on the taken-route click detail alongside the driving estimate.
|