123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441 |
- using System.Collections;
- using UnityEngine;
- #if PLATFORM_ANDROID
- using UnityEngine.Android;
- #endif
- namespace ARLocation
- {
-
-
-
-
- public abstract class AbstractLocationProvider : ILocationProvider
- {
- protected double LowPassFilterFactor;
-
-
-
-
- public abstract string Name { get; }
-
-
-
-
- public LocationProviderOptions Options { get; set; }
-
-
-
-
- public LocationReading CurrentLocation { get; protected set; }
-
-
-
-
- public LocationReading LastLocation { get; protected set; }
- public LocationReading LastLocationRaw { get; protected set; }
-
-
-
-
- public LocationReading CurrentLocationRaw { get; protected set; }
-
-
-
-
- public HeadingReading CurrentHeading { get; protected set; }
-
-
-
-
- public HeadingReading LastHeading { get; protected set; }
-
-
-
-
- public LocationReading FirstLocation { get; protected set; }
-
-
-
-
- public LocationProviderStatus Status { get; protected set; }
-
-
-
-
-
- public bool IsEnabled { get; protected set; }
-
-
-
-
- public bool FirstReading { get; protected set; }
-
-
-
-
- public abstract bool IsCompassEnabled { get; }
-
-
-
-
- public float StartTime { get; protected set; }
-
-
-
- public bool Paused { get; protected set; }
- public int LocationUpdateCount { get; protected set; }
- public bool HasStarted => Status == LocationProviderStatus.Started;
- public bool ApplyCompassTiltCompensationOnAndroid { get; set; } = true;
- public double DistanceFromStartPoint
- {
- get { return LocationReading.HorizontalDistance(FirstLocation, CurrentLocation); }
- }
-
-
-
- public event LocationUpdatedDelegate LocationUpdated;
-
-
-
- public event CompassUpdateDelegate CompassUpdated;
- public event LocationEnabledDelegate LocationEnabled;
- public event LocationFailedDelegate LocationFailed;
- public event LocationUpdatedDelegate LocationUpdatedRaw;
-
-
-
-
-
- protected abstract LocationReading? ReadLocation();
-
-
-
-
-
- protected abstract HeadingReading? ReadHeading();
-
-
-
-
- protected abstract void RequestLocationAndCompassUpdates();
-
-
-
-
- protected abstract void UpdateLocationRequestStatus();
- protected AbstractLocationProvider()
- {
- IsEnabled = false;
- FirstReading = true;
- Paused = false;
- Status = LocationProviderStatus.Idle;
- }
- public virtual IEnumerator Start(uint maxWaitTime = 10000, uint delay = 0)
- {
-
- #if PLATFORM_ANDROID
- if (!Permission.HasUserAuthorizedPermission(Permission.FineLocation))
- {
- Permission.RequestUserPermission(Permission.FineLocation);
- }
- yield return new WaitForSeconds(1);
- #endif
- if (delay > 0)
- {
- yield return new WaitForSeconds(delay);
- }
- RequestLocationAndCompassUpdates();
- uint maxWait = maxWaitTime;
- UpdateLocationRequestStatus();
- while (Status == LocationProviderStatus.Initializing && maxWait > 0)
- {
-
- yield return new WaitForSeconds(1);
- maxWait--;
- UpdateLocationRequestStatus();
- }
- if (maxWait < 1)
- {
-
- LocationFailed?.Invoke("Timed out");
- yield break;
- }
- if (Status == LocationProviderStatus.Failed)
- {
-
- LocationFailed?.Invoke("Falied to initialize location updates.");
- yield break;
- }
- if (Status != LocationProviderStatus.Started)
- {
-
- LocationFailed?.Invoke("Unknown error initializing location updates.");
- yield break;
- }
-
- FirstReading = true;
- StartTime = Time.time;
- }
- public void ForceLocationUpdate()
- {
- LocationUpdated?.Invoke(CurrentLocation, LastLocation);
- LocationUpdatedRaw?.Invoke(CurrentLocationRaw, LastLocationRaw);
- }
- protected virtual void InnerOnEnabled()
- {
- }
- protected void EmitLocationUpdated()
- {
- LocationUpdated?.Invoke(CurrentLocation, LastLocation);
- }
- protected void EmitLocationUpdatedRaw()
- {
- LocationUpdatedRaw?.Invoke(CurrentLocationRaw, LastLocationRaw);
- }
- protected void EmitCompassUpdated()
- {
- CompassUpdated?.Invoke(CurrentHeading, LastHeading);
- }
- protected void UpdateLocation(LocationReading newLocation)
- {
- if (newLocation.timestamp == CurrentLocationRaw.timestamp)
- {
- return;
- }
- LastLocationRaw = CurrentLocationRaw;
- CurrentLocationRaw = newLocation;
- EmitLocationUpdatedRaw();
- if (!ShouldUpdateLocation(newLocation))
- {
- return;
- }
- LastLocation = CurrentLocation;
- CurrentLocation = newLocation;
- LocationUpdateCount++;
- EmitLocationUpdated();
- }
- protected void UpdateHeading(HeadingReading newHeading)
- {
- if (!ShouldUpdateHeading(newHeading))
- {
- return;
- }
- LastHeading = CurrentHeading;
- CurrentHeading = newHeading;
- EmitCompassUpdated();
- }
- protected bool ShouldUpdateHeading(HeadingReading newHeading)
- {
- if (newHeading.timestamp == CurrentHeading.timestamp)
- {
- return false;
- }
- return true;
- }
- protected bool ShouldUpdateLocation(LocationReading newLocation)
- {
- if (Paused)
- {
- return false;
- }
- if (newLocation.timestamp - CurrentLocation.timestamp < ((long) (Options.TimeBetweenUpdates * 1000)))
- {
- return false;
- }
- if (LocationReading.HorizontalDistance(newLocation, CurrentLocation) < Options.MinDistanceBetweenUpdates)
- {
- return false;
- }
- if ((newLocation.accuracy > Options.AccuracyRadius) && (Options.AccuracyRadius > 0))
- {
- return false;
- }
- return true;
- }
- public virtual void Update()
- {
- if (!HasStarted)
- {
- return;
- }
- var location = ReadLocation();
- var heading = ReadHeading();
- if (location == null || heading == null)
- {
-
- return;
- }
- if (FirstReading)
- {
- FirstLocation = location.Value;
- CurrentLocation = FirstLocation;
- CurrentLocationRaw = FirstLocation;
- CurrentHeading = heading.Value;
- IsEnabled = true;
- FirstReading = false;
- LocationEnabled?.Invoke();
- InnerOnEnabled();
- EmitCompassUpdated();
- EmitLocationUpdated();
- EmitLocationUpdatedRaw();
- return;
- }
- UpdateLocation(location.Value);
- UpdateHeading(heading.Value);
- }
- public void Restart()
- {
- LocationUpdateCount = 0;
- FirstReading = true;
- }
- public void ResetStartPoint()
- {
- FirstLocation = CurrentLocation;
- }
- public void SetCompassLowPassFactor(double factor)
- {
- LowPassFilterFactor = factor;
- }
- public string GetStatusString()
- {
- switch (Status)
- {
- case LocationProviderStatus.Idle:
- return "Idle";
- case LocationProviderStatus.Failed:
- return "Failed";
- case LocationProviderStatus.Initializing:
- return "Initializing";
- case LocationProviderStatus.Started:
- return "Started";
- }
- return "UnknownStatus";
- }
- public string GetInfoString()
- {
- return Name +
- "{ \n" +
- CurrentLocation + "\n" +
- CurrentHeading + "\n" +
- "Status = " + GetStatusString() + "\n" +
- "DistanceFromStartPoint = " + DistanceFromStartPoint + "\n" +
- "TimeSinceStart = " + (Time.time - StartTime) + "\n" +
- "}";
- }
- public void OnEnabled(LocationEnabledDelegate del)
- {
- LocationEnabled += del;
- if (IsEnabled)
- {
- del();
- }
- }
- public void OnFail(LocationFailedDelegate del)
- {
- LocationFailed += del;
- }
-
-
-
- public void Pause()
- {
- Paused = true;
- }
-
-
-
- public void Resume()
- {
- Paused = false;
- }
- }
- }
|