fix(gps): инфо-панель точки трека вместо balloon провайдера (время/скорость/направление + плейхед)
This commit is contained in:
@@ -259,22 +259,20 @@ export function GpsRoutesTab() {
|
|||||||
const displayedPoints = activePoints.filter((_, idx) => idx % trackPointsStep === 0);
|
const displayedPoints = activePoints.filter((_, idx) => idx % trackPointsStep === 0);
|
||||||
const pointsThinned = displayedPoints.length < activePoints.length;
|
const pointsThinned = displayedPoints.length < activePoints.length;
|
||||||
|
|
||||||
// Попап точки трека: время, скорость (км/ч), направление, координаты
|
// Формат даты/времени точки для инфо-панели
|
||||||
const pointPopupHtml = (p: GpsTrackPoint): string => {
|
const pointTime = (p: GpsTrackPoint): string => new Date(p.recordedAt).toLocaleString('ru-RU');
|
||||||
const time = new Date(p.recordedAt).toLocaleString('ru-RU');
|
|
||||||
const speed = p.speed != null ? `${Math.round(p.speed)} км/ч` : '—';
|
|
||||||
const course = p.course != null ? `<br/>Направление: ${Math.round(p.course)}°` : '';
|
|
||||||
return `<b>${time}</b><br/>Скорость: ${speed}${course}<br/>${p.lat.toFixed(6)}, ${p.lng.toFixed(6)}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Клик по точке трека: попап (на уровне карты) + плейхед на эту точку
|
// Клик по точке трека: инфо-панель + плейхед на эту точку
|
||||||
const seekToPoint = (p: GpsTrackPoint) => {
|
const seekToPoint = (p: GpsTrackPoint) => {
|
||||||
|
setSelectedPoint(p);
|
||||||
setPlayTs(new Date(p.recordedAt).getTime());
|
setPlayTs(new Date(p.recordedAt).getTime());
|
||||||
setPlayEpoch((e) => e + 1);
|
setPlayEpoch((e) => e + 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Раскраска трека по скорости (включена по умолчанию)
|
// Раскраска трека по скорости (включена по умолчанию)
|
||||||
const [colorize, setColorize] = useState(true);
|
const [colorize, setColorize] = useState(true);
|
||||||
|
// Выбранная кликом точка трека — инфо-панель поверх карты (вместо balloon карты)
|
||||||
|
const [selectedPoint, setSelectedPoint] = useState<GpsTrackPoint | null>(null);
|
||||||
|
|
||||||
// Сегменты трека, окрашенные по скорости в начальной точке сегмента.
|
// Сегменты трека, окрашенные по скорости в начальной точке сегмента.
|
||||||
// При > 800 точек прореживаем до ~800 для раскраски (базовая полилиния
|
// При > 800 точек прореживаем до ~800 для раскраски (базовая полилиния
|
||||||
@@ -324,7 +322,6 @@ export function GpsRoutesTab() {
|
|||||||
kind: 'dot' as const,
|
kind: 'dot' as const,
|
||||||
color: '#64748b',
|
color: '#64748b',
|
||||||
course: p.course ?? undefined,
|
course: p.course ?? undefined,
|
||||||
popup: pointPopupHtml(p),
|
|
||||||
onClick: () => seekToPoint(p),
|
onClick: () => seekToPoint(p),
|
||||||
noCluster: true,
|
noCluster: true,
|
||||||
zIndex: 2,
|
zIndex: 2,
|
||||||
@@ -399,12 +396,34 @@ export function GpsRoutesTab() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<GpsMap
|
<div className="relative">
|
||||||
bounds={bounds}
|
<GpsMap
|
||||||
polylines={mapPolylines}
|
bounds={bounds}
|
||||||
markers={mapMarkers}
|
polylines={mapPolylines}
|
||||||
className="h-[55vh] min-h-[350px] w-full rounded-md overflow-hidden border border-border"
|
markers={mapMarkers}
|
||||||
/>
|
className="h-[55vh] min-h-[350px] w-full rounded-md overflow-hidden border border-border"
|
||||||
|
/>
|
||||||
|
{/* Инфо-панель выбранной точки трека (своя, не balloon карты) */}
|
||||||
|
{selectedPoint && (
|
||||||
|
<div className="absolute top-2 left-2 z-[1002] bg-background/95 border border-border rounded-md shadow-md p-2.5 text-xs space-y-1 max-w-[240px]">
|
||||||
|
<div className="flex items-center justify-between gap-2">
|
||||||
|
<span className="font-medium">{pointTime(selectedPoint)}</span>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="text-muted-foreground hover:text-foreground px-1"
|
||||||
|
onClick={() => setSelectedPoint(null)}
|
||||||
|
aria-label="Закрыть"
|
||||||
|
>
|
||||||
|
✕
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div>Скорость: <b>{selectedPoint.speed != null ? `${Math.round(selectedPoint.speed)} км/ч` : '—'}</b></div>
|
||||||
|
{selectedPoint.course != null && <div>Направление: {Math.round(selectedPoint.course)}°</div>}
|
||||||
|
<div className="text-muted-foreground">{selectedPoint.lat.toFixed(6)}, {selectedPoint.lng.toFixed(6)}</div>
|
||||||
|
<div className="text-muted-foreground">Плейхед установлен на эту точку</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Легенда раскраски трека по скорости */}
|
{/* Легенда раскраски трека по скорости */}
|
||||||
{colorizeEnabled && (
|
{colorizeEnabled && (
|
||||||
|
|||||||
Reference in New Issue
Block a user