AR + GPS Location  3.0.0
All Classes Namespaces Functions Variables Properties Events Pages
AbstractLocationProvider.cs
1 using System.Collections;
2 using UnityEngine;
3 
4 #if PLATFORM_ANDROID
5 using UnityEngine.Android;
6 #endif
7 
8 namespace ARLocation
9 {
15  {
16  protected double LowPassFilterFactor;
17 
22  public abstract string Name { get; }
23 
28  public LocationProviderOptions Options { get; set; }
29 
34  public LocationReading CurrentLocation { get; protected set; }
35 
40  public LocationReading LastLocation { get; protected set; }
41 
42  public LocationReading LastLocationRaw { get; protected set; }
43 
48  public LocationReading CurrentLocationRaw { get; protected set; }
49 
54  public HeadingReading CurrentHeading { get; protected set; }
55 
60  public HeadingReading LastHeading { get; protected set; }
61 
66  public LocationReading FirstLocation { get; protected set; }
67 
72  public LocationProviderStatus Status { get; protected set; }
73 
79  public bool IsEnabled { get; protected set; }
80 
85  public bool FirstReading { get; protected set; }
86 
91  public abstract bool IsCompassEnabled { get; }
92 
97  public float StartTime { get; protected set; }
98 
102  public bool Paused { get; protected set; }
103 
104  public int LocationUpdateCount { get; protected set; }
105  public bool HasStarted => Status == LocationProviderStatus.Started;
106  public bool ApplyCompassTiltCompensationOnAndroid { get; set; } = true;
107 
108  public double DistanceFromStartPoint
109  {
110  get { return LocationReading.HorizontalDistance(FirstLocation, CurrentLocation); }
111  }
112 
116  public event LocationUpdatedDelegate LocationUpdated;
117 
121  public event CompassUpdateDelegate CompassUpdated;
122 
123  public event LocationEnabledDelegate LocationEnabled;
124  public event LocationFailedDelegate LocationFailed;
125  public event LocationUpdatedDelegate LocationUpdatedRaw;
131  protected abstract LocationReading? ReadLocation();
132 
138  protected abstract HeadingReading? ReadHeading();
139 
144  protected abstract void RequestLocationAndCompassUpdates();
145 
150  protected abstract void UpdateLocationRequestStatus();
151 
152  protected AbstractLocationProvider()
153  {
154  IsEnabled = false;
155  FirstReading = true;
156  Paused = false;
157  Status = LocationProviderStatus.Idle;
158  }
159 
160  public virtual IEnumerator Start(uint maxWaitTime = 10000, uint delay = 0)
161  {
162  // Debug.Log("[AbstractLocationProvider]: Starting...");
163 
164 #if PLATFORM_ANDROID
165  if (!Permission.HasUserAuthorizedPermission(Permission.FineLocation))
166  {
167  Permission.RequestUserPermission(Permission.FineLocation);
168  }
169 
170  yield return new WaitForSeconds(1);
171 #endif
172 
173  if (delay > 0)
174  {
175  yield return new WaitForSeconds(delay);
176  }
177 
179  uint maxWait = maxWaitTime;
181  while (Status == LocationProviderStatus.Initializing && maxWait > 0)
182  {
183  // Debug.Log("[AbstractLocationProvider]: Wait... " + maxWait);
184 
185  yield return new WaitForSeconds(1);
186  maxWait--;
188  }
189 
190  if (maxWait < 1)
191  {
192  // Debug.LogError("[AbstractLocationProvider]: Timed out.");
193 
194  LocationFailed?.Invoke("Timed out");
195 
196  yield break;
197  }
198 
199  if (Status == LocationProviderStatus.Failed)
200  {
201  // Debug.LogError("[AbstractLocationProvider]: Falied to initialize location updates.");
202 
203  LocationFailed?.Invoke("Falied to initialize location updates.");
204 
205  yield break;
206  }
207 
208  if (Status != LocationProviderStatus.Started)
209  {
210  // Debug.LogError("[AbstractLocationProvider]: Unknown error initializing location updates. " + Status);
211 
212  LocationFailed?.Invoke("Unknown error initializing location updates.");
213 
214  yield break;
215  }
216 
217  // Debug.Log("[AbstractLocationProvider]: Started!");
218 
219  FirstReading = true;
220  StartTime = Time.time;
221  }
222 
223  public void ForceLocationUpdate()
224  {
226  LocationUpdatedRaw?.Invoke(CurrentLocationRaw, LastLocationRaw);
227  }
228 
229  protected virtual void InnerOnEnabled()
230  {
231 
232  }
233 
234 
235  protected void EmitLocationUpdated()
236  {
238  }
239 
240  protected void EmitLocationUpdatedRaw()
241  {
242  LocationUpdatedRaw?.Invoke(CurrentLocationRaw, LastLocationRaw);
243  }
244 
245  protected void EmitCompassUpdated()
246  {
248  }
249 
250  protected void UpdateLocation(LocationReading newLocation)
251  {
252  if (newLocation.timestamp == CurrentLocationRaw.timestamp)
253  {
254  return;
255  }
256 
257  LastLocationRaw = CurrentLocationRaw;
258  CurrentLocationRaw = newLocation;
259 
260  EmitLocationUpdatedRaw();
261 
262  if (!ShouldUpdateLocation(newLocation))
263  {
264  return;
265  }
266 
268  CurrentLocation = newLocation;
269 
270  LocationUpdateCount++;
271 
272  EmitLocationUpdated();
273  }
274 
275  protected void UpdateHeading(HeadingReading newHeading)
276  {
277  if (!ShouldUpdateHeading(newHeading))
278  {
279  return;
280  }
281 
283 
284  CurrentHeading = newHeading;
285 
286  EmitCompassUpdated();
287  }
288 
289  protected bool ShouldUpdateHeading(HeadingReading newHeading)
290  {
291  if (newHeading.timestamp == CurrentHeading.timestamp)
292  {
293  return false;
294  }
295 
296  return true;
297  }
298 
299  protected bool ShouldUpdateLocation(LocationReading newLocation)
300  {
301  if (Paused)
302  {
303  return false;
304  }
305 
306  if (newLocation.timestamp - CurrentLocation.timestamp < ((long) (Options.TimeBetweenUpdates * 1000)))
307  {
308  return false;
309  }
310 
311  if (LocationReading.HorizontalDistance(newLocation, CurrentLocation) < Options.MinDistanceBetweenUpdates)
312  {
313  return false;
314  }
315 
316  if ((newLocation.accuracy > Options.AccuracyRadius) && (Options.AccuracyRadius > 0))
317  {
318  return false;
319  }
320 
321 
322  return true;
323  }
324 
325  public virtual void Update()
326  {
327  if (!HasStarted)
328  {
329  return;
330  }
331 
332  var location = ReadLocation();
333  var heading = ReadHeading();
334 
335  if (location == null || heading == null)
336  {
337  // Debug.Log("[AbstractLocationProvider]: Null reading");
338  return;
339  }
340 
341  if (FirstReading)
342  {
343  FirstLocation = location.Value;
346  CurrentHeading = heading.Value;
347 
348  IsEnabled = true;
349  FirstReading = false;
350 
351  LocationEnabled?.Invoke();
352  InnerOnEnabled();
353 
354  EmitCompassUpdated();
355  EmitLocationUpdated();
356  EmitLocationUpdatedRaw();
357 
358  return;
359  }
360 
361  UpdateLocation(location.Value);
362  UpdateHeading(heading.Value);
363  }
364 
365  public void Restart()
366  {
367  LocationUpdateCount = 0;
368  FirstReading = true;
369  }
370 
371  public void ResetStartPoint()
372  {
374  }
375 
376  public void SetCompassLowPassFactor(double factor)
377  {
378  LowPassFilterFactor = factor;
379  }
380 
381  public string GetStatusString()
382  {
383  switch (Status)
384  {
385  case LocationProviderStatus.Idle:
386  return "Idle";
387  case LocationProviderStatus.Failed:
388  return "Failed";
389  case LocationProviderStatus.Initializing:
390  return "Initializing";
391  case LocationProviderStatus.Started:
392  return "Started";
393  }
394 
395  return "UnknownStatus";
396  }
397 
398  public string GetInfoString()
399  {
400  return Name +
401  "{ \n" +
402  CurrentLocation + "\n" +
403  CurrentHeading + "\n" +
404  "Status = " + GetStatusString() + "\n" +
405  "DistanceFromStartPoint = " + DistanceFromStartPoint + "\n" +
406  "TimeSinceStart = " + (Time.time - StartTime) + "\n" +
407  "}";
408  }
409 
410  public void OnEnabled(LocationEnabledDelegate del)
411  {
412  LocationEnabled += del;
413 
414  if (IsEnabled)
415  {
416  del();
417  }
418  }
419 
420  public void OnFail(LocationFailedDelegate del)
421  {
422  LocationFailed += del;
423  }
424 
428  public void Pause()
429  {
430  Paused = true;
431  }
432 
436  public void Resume()
437  {
438  Paused = false;
439  }
440  }
441 }
ARLocation.AbstractLocationProvider.LastLocation
LocationReading LastLocation
Gets or sets the previous location.
Definition: AbstractLocationProvider.cs:40
ARLocation.AbstractLocationProvider.IsCompassEnabled
abstract bool IsCompassEnabled
If true, the provider has a functioning magnetic compass sensor.
Definition: AbstractLocationProvider.cs:91
ARLocation.AbstractLocationProvider.FirstLocation
LocationReading FirstLocation
The start point, i.e., the first measured location.
Definition: AbstractLocationProvider.cs:66
ARLocation.AbstractLocationProvider.Status
LocationProviderStatus Status
Gets or sets the current status of the location provider.
Definition: AbstractLocationProvider.cs:72
ARLocation.LocationProviderOptions.TimeBetweenUpdates
float TimeBetweenUpdates
The minimum desired update time, in seconds.
Definition: ILocationProvider.cs:15
ARLocation.AbstractLocationProvider.ReadHeading
abstract ? HeadingReading ReadHeading()
Reads the heading from the device; should be implemented by each provider.
ARLocation.AbstractLocationProvider.Name
abstract string Name
The name of the location provider.
Definition: AbstractLocationProvider.cs:22
ARLocation.AbstractLocationProvider.IsEnabled
bool IsEnabled
If true, the location provider is enablied and getting regular location updated from the device.
Definition: AbstractLocationProvider.cs:79
ARLocation.AbstractLocationProvider.CurrentLocation
LocationReading CurrentLocation
Gets or sets the current location.
Definition: AbstractLocationProvider.cs:34
ARLocation.LocationProviderOptions.MinDistanceBetweenUpdates
double MinDistanceBetweenUpdates
The minimum distance between consecutive location updates, in meters.
Definition: ILocationProvider.cs:21
ARLocation.AbstractLocationProvider.FirstReading
bool FirstReading
If true, the first reading has not occured yet.
Definition: AbstractLocationProvider.cs:85
ARLocation.AbstractLocationProvider.RequestLocationAndCompassUpdates
abstract void RequestLocationAndCompassUpdates()
Requests the location and compass updates from the device; should be implemented by each provider.
ARLocation.AbstractLocationProvider.UpdateLocationRequestStatus
abstract void UpdateLocationRequestStatus()
Updates the location service status from the device; should be implemented by each provider.
ARLocation.AbstractLocationProvider
Abstract location provider. All concrete location provider implementations should derive from this.
Definition: AbstractLocationProvider.cs:15
ARLocation.ILocationProvider
Definition: ILocationProvider.cs:52
ARLocation.AbstractLocationProvider.CurrentLocationRaw
LocationReading CurrentLocationRaw
Gets or sets the previous raw location reading.
Definition: AbstractLocationProvider.cs:48
ARLocation.AbstractLocationProvider.LastHeading
HeadingReading LastHeading
The previous heading reading.
Definition: AbstractLocationProvider.cs:60
ARLocation.LocationProviderOptions
Definition: ILocationProvider.cs:10
ARLocation.AbstractLocationProvider.Options
LocationProviderOptions Options
The options of the location provider.
Definition: AbstractLocationProvider.cs:28
ARLocation.AbstractLocationProvider.LocationUpdated
LocationUpdatedDelegate LocationUpdated
Event for when a new location data is received.
Definition: AbstractLocationProvider.cs:116
ARLocation.AbstractLocationProvider.ReadLocation
abstract ? LocationReading ReadLocation()
Reads the location from the device; should be implemented by each provider.
ARLocation.LocationReading.timestamp
long timestamp
Epoch time in ms
Definition: LocationReading.cs:15
ARLocation.AbstractLocationProvider.Pause
void Pause()
Pauses location updates
Definition: AbstractLocationProvider.cs:428
ARLocation.HeadingReading
Definition: HeadingReading.cs:5
ARLocation.LocationProviderOptions.AccuracyRadius
double AccuracyRadius
The minimum accuracy of accepted location measurements, in meters.
Definition: ILocationProvider.cs:30
ARLocation.AbstractLocationProvider.CompassUpdated
CompassUpdateDelegate CompassUpdated
Event for when a new compass data is received.
Definition: AbstractLocationProvider.cs:121
ARLocation.AbstractLocationProvider.Paused
bool Paused
If true, location updates are paused.
Definition: AbstractLocationProvider.cs:102
ARLocation.AbstractLocationProvider.Resume
void Resume()
Resumes location updates
Definition: AbstractLocationProvider.cs:436
ARLocation.LocationReading
Definition: LocationReading.cs:5
ARLocation
Definition: ARLocationConfigInspector.cs:7
ARLocation.AbstractLocationProvider.CurrentHeading
HeadingReading CurrentHeading
The current heading reading.
Definition: AbstractLocationProvider.cs:54
ARLocation.AbstractLocationProvider.StartTime
float StartTime
The start time of the location provider.
Definition: AbstractLocationProvider.cs:97