mirror of
https://github.com/FoggedLens/deflock-app.git
synced 2026-07-06 04:37:56 +02:00
more cameras -> nodes
This commit is contained in:
+18
-18
@@ -3,15 +3,15 @@ import 'dart:convert';
|
||||
import 'package:latlong2/latlong.dart';
|
||||
import 'package:flutter_map/flutter_map.dart' show LatLngBounds;
|
||||
import '../../models/osm_camera_node.dart';
|
||||
import '../../models/camera_profile.dart';
|
||||
import '../../models/node_profile.dart';
|
||||
import '../offline_area_service.dart';
|
||||
import '../offline_areas/offline_area_models.dart';
|
||||
|
||||
/// Fetch camera nodes from all offline areas intersecting the bounds/profile list.
|
||||
Future<List<OsmCameraNode>> fetchLocalCameras({
|
||||
/// Fetch surveillance nodes from all offline areas intersecting the bounds/profile list.
|
||||
Future<List<OsmCameraNode>> fetchLocalNodes({
|
||||
required LatLngBounds bounds,
|
||||
required List<CameraProfile> profiles,
|
||||
int? maxCameras,
|
||||
required List<NodeProfile> profiles,
|
||||
int? maxNodes,
|
||||
}) async {
|
||||
final areas = OfflineAreaService().offlineAreas;
|
||||
final Map<int, OsmCameraNode> deduped = {};
|
||||
@@ -20,24 +20,24 @@ Future<List<OsmCameraNode>> fetchLocalCameras({
|
||||
if (area.status != OfflineAreaStatus.complete) continue;
|
||||
if (!area.bounds.isOverlapping(bounds)) continue;
|
||||
|
||||
final nodes = await _loadAreaCameras(area);
|
||||
for (final cam in nodes) {
|
||||
// Deduplicate by camera ID, preferring the first occurrence
|
||||
if (deduped.containsKey(cam.id)) continue;
|
||||
final nodes = await _loadAreaNodes(area);
|
||||
for (final node in nodes) {
|
||||
// Deduplicate by node ID, preferring the first occurrence
|
||||
if (deduped.containsKey(node.id)) continue;
|
||||
// Within view bounds?
|
||||
if (!_pointInBounds(cam.coord, bounds)) continue;
|
||||
if (!_pointInBounds(node.coord, bounds)) continue;
|
||||
// Profile filter if used
|
||||
if (profiles.isNotEmpty && !_matchesAnyProfile(cam, profiles)) continue;
|
||||
deduped[cam.id] = cam;
|
||||
if (profiles.isNotEmpty && !_matchesAnyProfile(node, profiles)) continue;
|
||||
deduped[node.id] = node;
|
||||
}
|
||||
}
|
||||
|
||||
final out = deduped.values.take(maxCameras ?? deduped.length).toList();
|
||||
final out = deduped.values.take(maxNodes ?? deduped.length).toList();
|
||||
return out;
|
||||
}
|
||||
|
||||
// Try in-memory first, else load from disk
|
||||
Future<List<OsmCameraNode>> _loadAreaCameras(OfflineArea area) async {
|
||||
Future<List<OsmCameraNode>> _loadAreaNodes(OfflineArea area) async {
|
||||
if (area.cameras.isNotEmpty) {
|
||||
return area.cameras;
|
||||
}
|
||||
@@ -57,16 +57,16 @@ bool _pointInBounds(LatLng pt, LatLngBounds bounds) {
|
||||
pt.longitude <= bounds.northEast.longitude;
|
||||
}
|
||||
|
||||
bool _matchesAnyProfile(OsmCameraNode cam, List<CameraProfile> profiles) {
|
||||
bool _matchesAnyProfile(OsmCameraNode node, List<NodeProfile> profiles) {
|
||||
for (final prof in profiles) {
|
||||
if (_cameraMatchesProfile(cam, prof)) return true;
|
||||
if (_nodeMatchesProfile(node, prof)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool _cameraMatchesProfile(OsmCameraNode cam, CameraProfile profile) {
|
||||
bool _nodeMatchesProfile(OsmCameraNode node, NodeProfile profile) {
|
||||
for (final e in profile.tags.entries) {
|
||||
if (cam.tags[e.key] != e.value) return false; // All profile tags must match
|
||||
if (node.tags[e.key] != e.value) return false; // All profile tags must match
|
||||
}
|
||||
return true;
|
||||
}
|
||||
+9
-9
@@ -4,15 +4,15 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:latlong2/latlong.dart';
|
||||
import 'package:flutter_map/flutter_map.dart';
|
||||
|
||||
import '../../models/camera_profile.dart';
|
||||
import '../../models/node_profile.dart';
|
||||
import '../../models/osm_camera_node.dart';
|
||||
import '../../app_state.dart';
|
||||
import '../network_status.dart';
|
||||
|
||||
/// Fetches surveillance nodes from the Overpass OSM API for the given bounds and profiles.
|
||||
Future<List<OsmCameraNode>> camerasFromOverpass({
|
||||
Future<List<OsmCameraNode>> fetchOverpassNodes({
|
||||
required LatLngBounds bounds,
|
||||
required List<CameraProfile> profiles,
|
||||
required List<NodeProfile> profiles,
|
||||
UploadMode uploadMode = UploadMode.production,
|
||||
required int maxResults,
|
||||
}) async {
|
||||
@@ -24,8 +24,8 @@ Future<List<OsmCameraNode>> camerasFromOverpass({
|
||||
final query = _buildOverpassQuery(bounds, profiles, maxResults);
|
||||
|
||||
try {
|
||||
debugPrint('[camerasFromOverpass] Querying Overpass for surveillance nodes...');
|
||||
debugPrint('[camerasFromOverpass] Query:\n$query');
|
||||
debugPrint('[fetchOverpassNodes] Querying Overpass for surveillance nodes...');
|
||||
debugPrint('[fetchOverpassNodes] Query:\n$query');
|
||||
|
||||
final response = await http.post(
|
||||
Uri.parse(overpassEndpoint),
|
||||
@@ -33,7 +33,7 @@ Future<List<OsmCameraNode>> camerasFromOverpass({
|
||||
);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
debugPrint('[camerasFromOverpass] Overpass API error: ${response.body}');
|
||||
debugPrint('[fetchOverpassNodes] Overpass API error: ${response.body}');
|
||||
NetworkStatus.instance.reportOverpassIssue();
|
||||
return [];
|
||||
}
|
||||
@@ -42,7 +42,7 @@ Future<List<OsmCameraNode>> camerasFromOverpass({
|
||||
final elements = data['elements'] as List<dynamic>;
|
||||
|
||||
if (elements.length > 20) {
|
||||
debugPrint('[camerasFromOverpass] Retrieved ${elements.length} surveillance nodes');
|
||||
debugPrint('[fetchOverpassNodes] Retrieved ${elements.length} surveillance nodes');
|
||||
}
|
||||
|
||||
NetworkStatus.instance.reportOverpassSuccess();
|
||||
@@ -56,7 +56,7 @@ Future<List<OsmCameraNode>> camerasFromOverpass({
|
||||
}).toList();
|
||||
|
||||
} catch (e) {
|
||||
debugPrint('[camerasFromOverpass] Exception: $e');
|
||||
debugPrint('[fetchOverpassNodes] Exception: $e');
|
||||
|
||||
// Report network issues for connection errors
|
||||
if (e.toString().contains('Connection refused') ||
|
||||
@@ -70,7 +70,7 @@ Future<List<OsmCameraNode>> camerasFromOverpass({
|
||||
}
|
||||
|
||||
/// Builds an Overpass API query for surveillance nodes matching the given profiles within bounds.
|
||||
String _buildOverpassQuery(LatLngBounds bounds, List<CameraProfile> profiles, int maxResults) {
|
||||
String _buildOverpassQuery(LatLngBounds bounds, List<NodeProfile> profiles, int maxResults) {
|
||||
// Build node clauses for each profile
|
||||
final nodeClauses = profiles.map((profile) {
|
||||
// Convert profile tags to Overpass filter format
|
||||
Reference in New Issue
Block a user