More camera -> node, notifications for approaching

This commit is contained in:
stopflock
2025-09-29 19:22:22 -05:00
parent 6b5f05d036
commit 71fa212d71
28 changed files with 737 additions and 72 deletions
+54
View File
@@ -0,0 +1,54 @@
import 'package:latlong2/latlong.dart';
class OsmNode {
final int id;
final LatLng coord;
final Map<String, String> tags;
OsmNode({
required this.id,
required this.coord,
required this.tags,
});
Map<String, dynamic> toJson() => {
'id': id,
'lat': coord.latitude,
'lon': coord.longitude,
'tags': tags,
};
factory OsmNode.fromJson(Map<String, dynamic> json) {
final tags = <String, String>{};
if (json['tags'] != null) {
(json['tags'] as Map<String, dynamic>).forEach((k, v) {
tags[k.toString()] = v.toString();
});
}
return OsmNode(
id: json['id'] is int ? json['id'] as int : int.tryParse(json['id'].toString()) ?? 0,
coord: LatLng((json['lat'] as num).toDouble(), (json['lon'] as num).toDouble()),
tags: tags,
);
}
bool get hasDirection =>
tags.containsKey('direction') || tags.containsKey('camera:direction');
double? get directionDeg {
final raw = tags['direction'] ?? tags['camera:direction'];
if (raw == null) return null;
// Keep digits, optional dot, optional leading sign.
final match = RegExp(r'[-+]?\d*\.?\d+').firstMatch(raw);
if (match == null) return null;
final numStr = match.group(0);
final val = double.tryParse(numStr ?? '');
if (val == null) return null;
// Normalize: wrap negative or >360 into 0359 range.
final normalized = ((val % 360) + 360) % 360;
return normalized;
}
}