LCOV - code coverage report
Current view: top level - lib/data/devices - geolocator_device.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 20 33 60.6 %
Date: 2020-06-26 11:36:11 Functions: 0 0 -

          Line data    Source code
       1             : import 'dart:math' as math;
       2             : 
       3             : import 'package:app_pym/core/error/exceptions.dart';
       4             : import 'package:flutter/foundation.dart';
       5             : import 'package:geolocator/geolocator.dart';
       6             : import 'package:injectable/injectable.dart';
       7             : 
       8             : abstract class GeolocatorDevice {
       9             :   /// Get a stream of positions
      10             :   Stream<Position> get positions;
      11             : 
      12             :   /// Returns bearing between coordinates in radians
      13             :   ///
      14             :   /// Arguments are in degrees
      15             :   double bearingBetween(
      16             :     num startLatitude,
      17             :     num startLongitude,
      18             :     num endLatitude,
      19             :     num endLongitude,
      20             :   );
      21             : 
      22             :   /// Returns current permission level
      23             :   Future<GeolocationStatus> checkGeolocationPermissionStatus();
      24             : 
      25             :   /// Returns distance between coordinates in meters
      26             :   ///
      27             :   /// Arguments are in degrees
      28             :   double distanceBetween(
      29             :     num startLatitude,
      30             :     num startLongitude,
      31             :     num endLatitude,
      32             :     num endLongitude,
      33             :   );
      34             : }
      35             : 
      36             : @prod
      37             : @LazySingleton(as: GeolocatorDevice)
      38             : class GeolocatorDeviceImpl implements GeolocatorDevice {
      39             :   final Geolocator geolocator;
      40             : 
      41           1 :   const GeolocatorDeviceImpl({@required this.geolocator});
      42             : 
      43             :   @override
      44           1 :   Stream<Position> get positions async* {
      45             :     final GeolocationStatus permissionStatus =
      46           2 :         await checkGeolocationPermissionStatus();
      47           1 :     if (permissionStatus == GeolocationStatus.granted) {
      48           3 :       yield* geolocator.getPositionStream();
      49             :     } else {
      50           1 :       throw PermissionException("Permission Geolocation not granted.");
      51             :     }
      52             :   }
      53             : 
      54           1 :   @override
      55             :   double bearingBetween(
      56             :     num startLatitude,
      57             :     num startLongitude,
      58             :     num endLatitude,
      59             :     num endLongitude,
      60             :   ) {
      61           1 :     final num startLongRad = startLongitude.toRadians();
      62           1 :     final num startLatRad = startLatitude.toRadians();
      63           1 :     final num endLongRad = endLongitude.toRadians();
      64           1 :     final num endLatRad = endLatitude.toRadians();
      65             : 
      66           1 :     final num dLon = endLongRad - startLongRad;
      67           3 :     final double y = math.sin(dLon) * math.cos(endLatRad);
      68           4 :     final double x = math.cos(startLatRad) * math.sin(endLatRad) -
      69           5 :         math.sin(startLatRad) * math.cos(endLatRad) * math.cos(dLon);
      70           1 :     return math.atan2(y, x);
      71             :   }
      72             : 
      73           1 :   @override
      74             :   Future<GeolocationStatus> checkGeolocationPermissionStatus() =>
      75           2 :       geolocator.checkGeolocationPermissionStatus();
      76             : 
      77           0 :   @override
      78             :   double distanceBetween(
      79             :     num startLatitude,
      80             :     num startLongitude,
      81             :     num endLatitude,
      82             :     num endLongitude,
      83             :   ) {
      84             :     const earthRadius = 6371e3; // Metres
      85           0 :     final startLongRad = startLongitude * math.pi / 180;
      86           0 :     final endLongRad = endLongitude * math.pi / 180;
      87           0 :     final startLatRad = startLatitude * math.pi / 180;
      88           0 :     final endLatRad = endLatitude * math.pi / 180;
      89             : 
      90           0 :     final dLon = endLongRad - startLongRad;
      91           0 :     final dLat = endLatRad - startLatRad;
      92             : 
      93           0 :     final a = math.pow(math.sin(dLat / 2), 2) +
      94           0 :         math.cos(startLatRad) *
      95           0 :             math.cos(endLatRad) *
      96           0 :             math.pow(math.sin(dLon / 2), 2);
      97             : 
      98           0 :     final c = 2 * math.asin(math.sqrt(a));
      99             : 
     100           0 :     return earthRadius * c;
     101             :   }
     102             : }
     103             : 
     104             : extension on num {
     105           1 :   num toRadians() {
     106           2 :     return this * math.pi / 180;
     107             :   }
     108             : }

Generated by: LCOV version 1.13