Skip to content

Commit

Permalink
#49 Update tracking with home-area
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanwerfling committed Nov 15, 2024
1 parent 7606384 commit 96fe079
Show file tree
Hide file tree
Showing 9 changed files with 394 additions and 50 deletions.
127 changes: 125 additions & 2 deletions lib/Controllers/LocationController.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,51 @@ import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:geolocator/geolocator.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:mwpaapp/Controllers/PrefController.dart';
import 'package:mwpaapp/Db/DBHelper.dart';
import 'package:mwpaapp/Models/TourPref.dart';
import 'package:mwpaapp/Models/TrackingAreaHome.dart';
import 'package:mwpaapp/Services/EventManagerService.dart';
import 'package:mwpaapp/Settings/Preference.dart';
import 'package:mwpaapp/Util/UtilLocation.dart';
import 'package:mwpaapp/Util/UtilSighting.dart';
import 'package:mwpaapp/Util/UtilTourFId.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:uuid/uuid.dart';

import '../Models/TourTracking.dart';

/// LocationController
class LocationController extends GetxController {

/// geoloactor android
final GeolocatorPlatform geolocatorAndroid = GeolocatorPlatform.instance;

/// stream subscription
StreamSubscription<Position>? _positionStreamSubscription;

/// is location init
bool isLocationInit = false;

/// Location timer
Timer? locationTimer;

/// Current position
Position? currentPosition;

/// Current position count
int positionCount = 0;

/// Home Area Points (Polygon)
List<UtilLocationDouble> homeArea = [];

/// a tour by home area
TourPref? homeAreaToru;

/// event manager for updates
final EventManagerService updateEvent = EventManagerService();

@override
void onReady() {
super.onReady();
Expand Down Expand Up @@ -93,27 +121,122 @@ class LocationController extends GetxController {
altitude: position.altitude,
speed: position.speed,
speedAccuracy: position.speedAccuracy,
heading: position.heading
heading: position.heading,
altitudeAccuracy: position.altitudeAccuracy,
headingAccuracy: position.headingAccuracy
);

if (kDebugMode) {
print(tPosition.toString());
}

_setAndSavePosition(tPosition);
updateEvent.triggerEvent();
});
}

return true;
}

/// Reload the settings
Future<void> reloadSettings({bool reset = false}) async {
await _loadHomeArea();
}

/// load Home Area
Future<void> _loadHomeArea() async {
try {
homeArea = [];

final prefs = await SharedPreferences.getInstance();
final orgId = prefs.getInt(Preference.ORGID) ?? 0;

if (orgId > 0) {
List<Map<String, dynamic>> list = await DBHelper.queryTrackingAreaHome(orgId);

for (var cord in list) {
var tah = TrackingAreaHome.fromJson(cord);

if (tah.lat != null && tah.lon != null) {
var dCord = UtilLocationString(lat: tah.lat!, lon: tah.lon!).toLocationDouble();

homeArea.add(dCord);
}
}
}
} catch(e) {
if (kDebugMode) {
print('LocationController::_loadHomeArea:');
print(e);
}

rethrow;
}
}

/// _setAndSavePosition
_setAndSavePosition(Position position) {
currentPosition = position;

var savePoint = false;
var tourFid = "";

PrefController prefController = Get.find<PrefController>();

if (prefController.prefToru != null) {
if ((prefController.prefToru!.use_home_area != null) && (prefController.prefToru!.use_home_area! > 0)) {
// track with home area ------------------------------------------------

if (homeArea.isNotEmpty) {
if (UtilLocationPolygon.isPointInPolygon(
UtilLocationDouble.positionToLocationDouble(currentPosition!),
homeArea)
) {
// at home area ----------------------------------------------------

if (homeAreaToru != null) {
prefController.prefToru?.tour_end = DateFormat("HH:mm").format(DateTime.now());
prefController.saveTour(prefController.prefToru!);

UtilSighting.setCurrentEndTour(UtilTourFid.createTTourFId(homeAreaToru!));
homeAreaToru = null;
}

positionCount = 0;
} else {
// out home area ---------------------------------------------------

if (homeAreaToru == null) {
homeAreaToru = TourPref(
vehicle_id: prefController.prefToru?.vehicle_id,
vehicle_driver_id: prefController.prefToru?.vehicle_driver_id,
date: DateFormat("yyyy-MM-dd").format(DateTime.now()),
tour_start: DateFormat("HH:mm").format(DateTime.now())
);

prefController.prefToru?.date = homeAreaToru?.date;
prefController.prefToru?.tour_start = homeAreaToru?.tour_start;

// save the new tour info for sighting
prefController.saveTour(prefController.prefToru!);
}

savePoint = true;
tourFid = UtilTourFid.createTTourFId(homeAreaToru!);
}
}

} else {
// track all -----------------------------------------------------------

savePoint = true;
tourFid = UtilTourFid.createTTourFId(prefController.prefToru!);
}
}

// save the point ----------------------------------------------------------

if (savePoint) {
DateTime cTime = DateTime.now();
var uuid = const Uuid();
String uuidStr = uuid.v4();
Expand All @@ -122,7 +245,7 @@ class LocationController extends GetxController {
DBHelper.insertTourTracking(
TourTracking(
uuid: uuidStr,
tour_fid: UtilTourFid.createTTourFId(prefController.prefToru!),
tour_fid: tourFid,
location: jsonEncode(currentPosition!.toJson()),
date: timeStr
)
Expand Down
4 changes: 4 additions & 0 deletions lib/Pages/EditTourPage.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:mwpaapp/Components/DefaultButton.dart';
import 'package:mwpaapp/Components/DynInput.dart';
import 'package:mwpaapp/Constants.dart';
import 'package:mwpaapp/Controllers/BeaufortController.dart';
import 'package:mwpaapp/Controllers/LocationController.dart';
import 'package:mwpaapp/Controllers/PrefController.dart';
import 'package:mwpaapp/Controllers/VehicleController.dart';
import 'package:mwpaapp/Controllers/VehicleDriverController.dart';
Expand All @@ -22,6 +23,7 @@ class _EditTourPageState extends State<EditTourPage> {
final PrefController _prefController = Get.find<PrefController>();
final VehicleController _vehicleController = Get.find<VehicleController>();
final VehicleDriverController _vehicleDriverController = Get.find<VehicleDriverController>();
final LocationController _locationController = Get.find<LocationController>();

late DynInput sightVehicle;
DynInputValue sightVehicleValue = DynInputValue();
Expand Down Expand Up @@ -79,6 +81,7 @@ class _EditTourPageState extends State<EditTourPage> {
super.initState();
}

/// save the settings
_saveTourToPref() async {
TourPref tour = TourPref(
vehicle_id: sightVehicle.dynValue?.getStrValueAsInt(),
Expand All @@ -93,6 +96,7 @@ class _EditTourPageState extends State<EditTourPage> {
);

await _prefController.saveTour(tour);
await _locationController.reloadSettings();

Get.back();
}
Expand Down
32 changes: 32 additions & 0 deletions lib/Pages/List/ListMap.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import 'package:map/map.dart';
import 'package:mwpaapp/Constants.dart';
import 'package:mwpaapp/Controllers/LocationController.dart';
import 'package:mwpaapp/Controllers/SightingController.dart';
import 'package:mwpaapp/Pages/List/Map/PolygonPainter.dart';
import 'package:mwpaapp/Util/UtilLocation.dart';
import 'package:mwpaapp/Util/UtilPosition.dart';
import 'package:mwpaapp/Util/UtilTileServer.dart';

Expand Down Expand Up @@ -144,6 +146,23 @@ class _ListMapState extends State<ListMap> {
builder: (context, transformer) {
List<Widget> markerWidgets = [];

// Home Area Polygon -----------------------------------------------

if (_locationController.homeArea.isNotEmpty) {
markerWidgets.add(
CustomPaint(
painter: PolygonPainter(
_convertToOffsets(
_locationController.homeArea,
transformer
)
)
)
);
}

// sighting markers ------------------------------------------------

for (var sighting in _sightingController.sightingList) {
if (sighting.location_begin != null) {
try {
Expand All @@ -166,6 +185,8 @@ class _ListMapState extends State<ListMap> {
}
}

// current position markers ----------------------------------------

if (position != null) {
markerWidgets.add(
_buildMarkerWidget(
Expand All @@ -180,6 +201,8 @@ class _ListMapState extends State<ListMap> {
);
}

// GPS Information -------------------------------------------------

Widget gpsInfo = Container();

gpsInfo = PositionedDirectional(
Expand Down Expand Up @@ -256,4 +279,13 @@ class _ListMapState extends State<ListMap> {
);
});
}

/// convert
List<Offset> _convertToOffsets(List<UtilLocationDouble> locations, MapTransformer transformer) {
return locations.map((location) {
final latLng = LatLng.degree(location.lat, location.lon);
return transformer.toOffset(latLng);
}).toList();
}

}
29 changes: 29 additions & 0 deletions lib/Pages/List/Map/PolygonPainter.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import 'package:flutter/material.dart';

/// Polygon Painter
class PolygonPainter extends CustomPainter {
final List<Offset> points;

PolygonPainter(this.points);

@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.blue.withOpacity(0.5)
..style = PaintingStyle.fill;

if (points.isNotEmpty) {
final path = Path()..moveTo(points.first.dx, points.first.dy);
for (final point in points.skip(1)) {
path.lineTo(point.dx, point.dy);
}
path.close();
canvas.drawPath(path, paint);
}
}

@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
Loading

0 comments on commit 96fe079

Please sign in to comment.