fix(gps): инфо-панель точки трека вместо balloon провайдера (время/скорость/направление + плейхед)
This commit is contained in:
@@ -259,22 +259,20 @@ export function GpsRoutesTab() {
|
||||
const displayedPoints = activePoints.filter((_, idx) => idx % trackPointsStep === 0);
|
||||
const pointsThinned = displayedPoints.length < activePoints.length;
|
||||
|
||||
// Попап точки трека: время, скорость (км/ч), направление, координаты
|
||||
const pointPopupHtml = (p: GpsTrackPoint): string => {
|
||||
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 pointTime = (p: GpsTrackPoint): string => new Date(p.recordedAt).toLocaleString('ru-RU');
|
||||
|
||||
// Клик по точке трека: попап (на уровне карты) + плейхед на эту точку
|
||||
// Клик по точке трека: инфо-панель + плейхед на эту точку
|
||||
const seekToPoint = (p: GpsTrackPoint) => {
|
||||
setSelectedPoint(p);
|
||||
setPlayTs(new Date(p.recordedAt).getTime());
|
||||
setPlayEpoch((e) => e + 1);
|
||||
};
|
||||
|
||||
// Раскраска трека по скорости (включена по умолчанию)
|
||||
const [colorize, setColorize] = useState(true);
|
||||
// Выбранная кликом точка трека — инфо-панель поверх карты (вместо balloon карты)
|
||||
const [selectedPoint, setSelectedPoint] = useState<GpsTrackPoint | null>(null);
|
||||
|
||||
// Сегменты трека, окрашенные по скорости в начальной точке сегмента.
|
||||
// При > 800 точек прореживаем до ~800 для раскраски (базовая полилиния
|
||||
@@ -324,7 +322,6 @@ export function GpsRoutesTab() {
|
||||
kind: 'dot' as const,
|
||||
color: '#64748b',
|
||||
course: p.course ?? undefined,
|
||||
popup: pointPopupHtml(p),
|
||||
onClick: () => seekToPoint(p),
|
||||
noCluster: true,
|
||||
zIndex: 2,
|
||||
@@ -399,12 +396,34 @@ export function GpsRoutesTab() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
<GpsMap
|
||||
bounds={bounds}
|
||||
polylines={mapPolylines}
|
||||
markers={mapMarkers}
|
||||
className="h-[55vh] min-h-[350px] w-full rounded-md overflow-hidden border border-border"
|
||||
/>
|
||||
<div className="relative">
|
||||
<GpsMap
|
||||
bounds={bounds}
|
||||
polylines={mapPolylines}
|
||||
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 && (
|
||||
|
||||
Reference in New Issue
Block a user