| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 | using System;using System.Threading.Tasks;using System.Linq;using Xamarin.Forms;using Xamarin.Essentials;namespace InABox.Mobile{    public class LocationServices    {        public delegate void LocationEvent(LocationServices sender);        public event LocationEvent OnLocationFound;        public delegate void LocationError(LocationServices sender, Exception error);        public event LocationError OnLocationError;        public TimeSpan ScanDelay { get; set; }        public double Latitude { get; private set; }        public double Longitude { get; private set; }        public String Address { get; private set; }        private bool bLocating = false;        public DateTime TimeStamp { get; private set; }        public LocationServices() : base()        {            TimeStamp = DateTime.MinValue;            ScanDelay = new TimeSpan(0, 0, 0);            Address = "Searching for GPS";        }        public bool RecentlyLocated        {            get            {                return (DateTime.Now.Subtract(TimeStamp).Ticks < ScanDelay.Ticks);            }        }        private double DistanceBetween(double sLatitude, double sLongitude, double eLatitude,                               double eLongitude)        {            var radiansOverDegrees = (Math.PI / 180.0);            var sLatitudeRadians = sLatitude * radiansOverDegrees;            var sLongitudeRadians = sLongitude * radiansOverDegrees;            var eLatitudeRadians = eLatitude * radiansOverDegrees;            var eLongitudeRadians = eLongitude * radiansOverDegrees;            var dLongitude = eLongitudeRadians - sLongitudeRadians;            var dLatitude = eLatitudeRadians - sLatitudeRadians;            var result1 = Math.Pow(Math.Sin(dLatitude / 2.0), 2.0) +                          Math.Cos(sLatitudeRadians) * Math.Cos(eLatitudeRadians) *                          Math.Pow(Math.Sin(dLongitude / 2.0), 2.0);            // Using 3956 as the number of miles around the earth            var result2 = 3956.0 * 2.0 *                          Math.Atan2(Math.Sqrt(result1), Math.Sqrt(1.0 - result1));            return result2;        }        public void GetLocation(bool skiprecentlylocated = false)        {            if (bLocating || RecentlyLocated)            {                if (!skiprecentlylocated)                    return;            }            bLocating = true;            // Don't reset this on every refresh, otherwise the final UI will randomly get "Searching for GPS" as the address            //Address = "Searching for GPS";            Task.Run(async () =>            {                bool bOK = await MobileUtils.IsPermitted(PermissionType.Location);                if (!bOK)                {                    Latitude = 0.0F;                    Longitude = 0.0F;                    TimeStamp = DateTime.MinValue;                    Address = "GPS Services Disabled";                    Device.BeginInvokeOnMainThread(() =>                    {                        OnLocationError?.Invoke(this, new Exception("Please enable GPS Services to continue"));                    });                    bOK = false;                    bLocating = false;                }                else                {                    try                    {                        var request = new GeolocationRequest(GeolocationAccuracy.Best, new TimeSpan(0, 0, 20));                        var location = await Geolocation.GetLocationAsync(request);                        if (location != null)                        {                            //if (location.IsFromMockProvider)                            //{                            //    Device.BeginInvokeOnMainThread(() =>                            //    {                            //        OnLocationError?.Invoke(this, new Exception("Mock GPS Location Detected!\nPlease correct and restart TimeBench."));                            //    });                            //}                            //else                            {                                Latitude = location.Latitude;                                Longitude = location.Longitude;                                TimeStamp = DateTime.Now;                                String sErr = "";                                Placemark address = null;                                try                                {                                    var addresses = await Geocoding.GetPlacemarksAsync(Latitude, Longitude);                                    double maxdist = double.MaxValue;                                    foreach (var cur in addresses.Where(x => !String.IsNullOrEmpty(x.Thoroughfare)))                                    {                                        var delta = Location.CalculateDistance(location, cur.Location, DistanceUnits.Kilometers);                                        if (delta < maxdist)                                        {                                            address = cur;                                            maxdist = delta;                                        }                                    }                                }                                                        catch (Exception ee2)                                {                                    sErr = ee2.Message;                                    //address = null;                                }                                if (address != null)                                    Address = String.Format("{0} {1} {2}", address.SubThoroughfare, address.Thoroughfare, address.Locality);                                else                                    Address = String.Format("Lat: {0}, Lng: {1}", Latitude, Longitude);                                if (location.IsFromMockProvider)                                    Address = "** " + Address;                                if (!String.IsNullOrEmpty(sErr))                                    Address = String.Format("{0} (ERROR: {1})", Address, sErr);                                Device.BeginInvokeOnMainThread(() =>                                {                                    OnLocationFound?.Invoke(this);                                });                                bLocating = false;                            }                        }                        else                        {                            Latitude = 0.00;                            Longitude = 0.00;                            TimeStamp = DateTime.MinValue;                            bLocating = false;                            Device.BeginInvokeOnMainThread(() =>                            {                                OnLocationError?.Invoke(this, new Exception("Unable to get GPS Location"));                            });                        }                    }                    catch (Exception e)                    {                        bLocating = false;                        Device.BeginInvokeOnMainThread(() =>                        {                            OnLocationError?.Invoke(this, e);                        });                    }                }                bLocating = false;            });        }    }}
 |