Online tracking, deviceidentityservice

This commit is contained in:
2026-06-23 15:21:20 +02:00
parent 65b355edd9
commit aa78c7bb6f
13 changed files with 850 additions and 33 deletions
@@ -85,13 +85,37 @@ class MapSurveyView extends GetView<MapSurveyController> {
layers: [
const ImportedLayerOverlay(),
// Track polyline
Obx(() {
final inTrackMode = controller.mode.value == MapSurveyMode.track;
if (!inTrackMode) return const SizedBox.shrink();
final ids = TrackingController.to.overlayTrackIds;
if (ids.isEmpty) return const SizedBox.shrink();
final polylines = ids
.map((id) {
final pts = TrackingController.to.getCoordsFor(id);
if (pts.isEmpty) return null;
return Polyline(
points: pts,
color: Colors.blue.withOpacity(0.75),
strokeWidth: 2.5,
borderColor: Colors.white.withOpacity(0.4),
borderStrokeWidth: 1.0,
);
})
.whereType<Polyline>()
.toList();
if (polylines.isEmpty) return const SizedBox.shrink();
return PolylineLayer(polylines: polylines);
}),
Obx(() {
final isTracking = TrackingController.to.isRecording.value;
final inTrackMode = controller.mode.value == MapSurveyMode.track;
if (!isTracking && !inTrackMode) {
return const SizedBox.shrink();
} else {
return _buildTrackLayer();
return _buildTrackLayer1();
}
}),
Obx(() {
@@ -175,10 +199,37 @@ class MapSurveyView extends GetView<MapSurveyController> {
NoteItemLabelLayer(
controller: controller,
),
Obx(() {
final tracks = controller.teamTrackPoints;
if (tracks.isEmpty) return const SizedBox.shrink();
return PolylineLayer(
polylines: tracks.entries.map((e) {
final colors = [
Colors.blue,
Colors.purple,
Colors.teal,
Colors.indigo,
Colors.cyan,
Colors.deepPurple
];
final color = colors[e.key.hashCode.abs() % colors.length];
return Polyline(
points: e.value,
color: color.withValues(alpha: 0.7),
strokeWidth: 2.5);
}).toList(),
);
}),
Obx(() {
final markers =
List<Marker>.from(controller.teamTrackMarkers.values);
if (markers.isEmpty) return const SizedBox.shrink();
return MarkerLayer(markers: markers);
}),
Obx(() {
final isGpsActive = GnssService.to.activeConnectionType.value !=
GnssConnectionType.none;
if (isGpsActive) {
if (isGpsActive && controller.mode.value != MapSurveyMode.track) {
return MarkerLayer(
markers: controller.currentLocationMarker.toList());
}
@@ -276,6 +327,43 @@ class MapSurveyView extends GetView<MapSurveyController> {
]);
});
}
Widget _buildTrackLayer1() {
return Obx(() {
final ctrl = TrackingController.to;
final points = ctrl.livePoints.toList();
if (points.isEmpty) return const SizedBox.shrink();
return Stack(children: [
// 1. Track vonal
PolylineLayer(polylines: [
Polyline(
points: points,
color: Colors.red.withOpacity(0.85),
strokeWidth: 3.0,
),
]),
// 2. Markerek a vonal felett
MarkerLayer(markers: [
// Kezdőpont — zöld
Marker(
point: points.first,
child: const Icon(Icons.flag, color: Colors.green, size: 28),
),
// Utolsó pont — piros (ha van legalább 2 pont)
if (points.length > 1)
Marker(
point: points.last,
child: _PulsingDot(
color: TrackingController.to.isPaused.value
? Colors.orange
: Colors.blue,
),
),
]),
]);
});
}
}
class _ModeSelector extends GetView<MapSurveyController> {
@@ -302,6 +390,58 @@ class _ModeSelector extends GetView<MapSurveyController> {
}
}
class _PulsingDot extends StatefulWidget {
final Color color;
const _PulsingDot({required this.color});
@override
State<_PulsingDot> createState() => _PulsingDotState();
}
class _PulsingDotState extends State<_PulsingDot>
with SingleTickerProviderStateMixin {
late AnimationController _anim;
late Animation<double> _scale;
@override
void initState() {
super.initState();
_anim = AnimationController(
vsync: this, duration: const Duration(milliseconds: 1000))
..repeat(reverse: true);
_scale = Tween(begin: 0.8, end: 1.1)
.animate(CurvedAnimation(parent: _anim, curve: Curves.easeInOut));
}
@override
void dispose() {
_anim.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return ScaleTransition(
scale: _scale,
child: Container(
width: 8,
height: 8,
decoration: BoxDecoration(
color: widget.color,
shape: BoxShape.circle,
border: Border.all(color: Colors.white, width: 2),
boxShadow: [
BoxShadow(
color: widget.color.withOpacity(0.5),
blurRadius: 4,
spreadRadius: 2)
],
),
),
);
}
}
class _StakeoutPanel extends GetView<MapSurveyController> {
const _StakeoutPanel();