From 15ce7b7a1020beb96764420f85d922e25acf5ea9 Mon Sep 17 00:00:00 2001 From: Marc Rejohn Castillano Date: Wed, 18 Feb 2026 20:43:33 +0800 Subject: [PATCH] A more accurate geofencing --- lib/screens/workforce/workforce_screen.dart | 24 +++++++------ test/geofence_test.dart | 40 +++++++++++++++++++++ 2 files changed, 54 insertions(+), 10 deletions(-) create mode 100644 test/geofence_test.dart diff --git a/lib/screens/workforce/workforce_screen.dart b/lib/screens/workforce/workforce_screen.dart index ee9c4130..ab8b1666 100644 --- a/lib/screens/workforce/workforce_screen.dart +++ b/lib/screens/workforce/workforce_screen.dart @@ -407,16 +407,20 @@ class _ScheduleTile extends ConsumerWidget { ), ); - final isInside = geofence.hasPolygon - ? geofence.containsPolygon(position.latitude, position.longitude) - : geofence.hasCircle && - Geolocator.distanceBetween( - position.latitude, - position.longitude, - geofence.lat!, - geofence.lng!, - ) <= - geofence.radiusMeters!; + if (!geofence.hasPolygon) { + if (!context.mounted) return; + await _showAlert( + context, + title: 'Geofence missing', + message: 'Geofence polygon is not configured.', + ); + return; + } + + final isInside = geofence.containsPolygon( + position.latitude, + position.longitude, + ); if (!isInside) { if (!context.mounted) return; diff --git a/test/geofence_test.dart b/test/geofence_test.dart new file mode 100644 index 00000000..2cc0532d --- /dev/null +++ b/test/geofence_test.dart @@ -0,0 +1,40 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:tasq/models/app_settings.dart'; + +void main() { + // Polygon taken from user's KML (CRMC) + final polygonJson = [ + {"lat": 7.2025231, "lng": 124.2339774}, + {"lat": 7.2018791, "lng": 124.2334463}, + {"lat": 7.2013362, "lng": 124.2332049}, + {"lat": 7.2011393, "lng": 124.2332907}, + {"lat": 7.2009531, "lng": 124.2334195}, + {"lat": 7.200655, "lng": 124.2339344}, + {"lat": 7.2000749, "lng": 124.2348465}, + {"lat": 7.199501, "lng": 124.2357645}, + {"lat": 7.1990597, "lng": 124.2364595}, + {"lat": 7.1986557, "lng": 124.2371331}, + {"lat": 7.1992252, "lng": 124.237168}, + {"lat": 7.199494, "lng": 124.2372713}, + {"lat": 7.1997415, "lng": 124.2374604}, + {"lat": 7.1999383, "lng": 124.2377071}, + {"lat": 7.2001938, "lng": 124.2380934}, + {"lat": 7.2011411, "lng": 124.2364357}, + {"lat": 7.2025231, "lng": 124.2339774}, + ]; + + test('GeofenceConfig.fromJson parses polygon and containsPolygon works', () { + final cfg = GeofenceConfig.fromJson({"polygon": polygonJson}); + expect(cfg.hasPolygon, isTrue); + + // Point clearly inside the CRMC polygon + final insideLat = 7.2009; + final insideLng = 124.2360; + expect(cfg.containsPolygon(insideLat, insideLng), isTrue); + + // Point clearly outside (north of polygon) + final outsideLat = 7.2060; + final outsideLng = 124.2360; + expect(cfg.containsPolygon(outsideLat, outsideLng), isFalse); + }); +}