one of the functionality of the app is to
scan a qr code ->
fetch user current location ->
check that location matches with a geofence or with in geofence ->
if so complete desginated task or else show error to user saying u r offsite
in the ios devices frequently this offsite issue is thrown even tho they are inside the geofence not in android
how can i resolve and make IOS also smooth and android ?
do i have to make any precise change for IOS?
ill add my logic down below
void _verifyGeoScanWithLatLong(String scanResult) async {
if (null == _userInfo.userInfoDetails!.site!.geofence ||
_userInfo.userInfoDetails!.site!.geofence!.trim().isEmpty) {
AppSnackBar.show('Site is not properly configured',
icon: AppSnackBarIcon.SUCCESS);
return;
}
_appProgressBar.showProgress();
//here fetches the user current location
final Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high);
// add that to geoPoints by spiliting that line of string
List<GeoPoint> fencingList =
getPathFromPoly(_userInfo.userInfoDetails!.site!.geofence!);
// checks weather within fence or not
bool isWithinFencing = isPointInPolygon(
GeoPoint(latitude: position.latitude, longitude: position.longitude),
fencingList,
);
_appProgressBar.hideProgress();
if (isWithinFencing) {
_verifyNeoScanAndSubmitLocation(scanResult, position);
} else {
ConfirmationDialog.show(
context,
title: 'Scan Failed',
description: 'You are off Site',
positiveButtonText: 'Scan More',
negativeButtonText: 'Done',
isDismissible: false,
onPositiveClick: () {
Future.delayed(Duration.zero, () async {
result = null;
await controller?.resumeCamera();
});
},
onNegativeClick: () {
Future.delayed(Duration.zero, () {
locator<NavigationService>().back();
});
},
);
}
}
adding the method to parse string lat long to geopoints
List<GeoPoint> getPathFromPoly(String polygon) {
List<GeoPoint> geoList = [];
var points = polygon.split('),(');
points[0] = points[0].replaceAll('(', '');
final length = points.length - 1;
points[length] = points[length].replaceAll(')', '');
for (int i = 0; i < points.length; i++) {
var latLng = points[i].split(',');
GeoPoint geoPoint = GeoPoint(
latitude: double.parse(latLng[0]), longitude: double.parse(latLng[1]));
geoList.add(geoPoint);
}
return geoList;
}
adding the method to check weather this geopoint is inside the geofence
bool isPointInPolygon(GeoPoint tap, List<GeoPoint> vertices) {
var intersectCount = 0;
for (int i = 0; i < vertices.length - 1; i++) {
if (_rayCastIntersect(tap, vertices[i], vertices[i + 1])) {
intersectCount++;
}
}
return ((intersectCount % 2) == 1); // odd = inside, even = outside;
}
bool _rayCastIntersect(GeoPoint tap, GeoPoint vertA, GeoPoint vertB) {
final aY = vertA.latitude;
final bY = vertB.latitude;
final aX = vertA.longitude;
final bX = vertB.longitude;
final pY = tap.latitude;
final pX = tap.longitude;
if (aY > pY && bY > pY || aY < pY && bY < pY || aX < pX && bX < pX) {
return false;
// a and b can't both be above or below pt.y, and a or
// b must be east of pt.x
}
final m = (aY - bY) / (aX - bX); // Rise over run
final bee = -aX * m + aY; // y = mx + b
final x = (pY - bee) / m; // algebra is neat!
return x > pX;
}
these are the logics i used do i have to use any other logic or what more can i do to solve this frequent event of location not being precise on ios
note: in the device which had issue location precise is enabled as well as location permission to app is enabled and kept as always.
i tried restarting phone to check will it fetch latest location
updated geolocator package