You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
mapbox-sdk/Unity/Location/Logging/LocationLogReader.cs

167 lines
4.8 KiB

6 months ago
namespace Mapbox.Unity.Location
{
using Mapbox.Utils;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using UnityEngine;
/// <summary>
/// Parses location data and returns Location objects.
/// </summary>
public class LocationLogReader : LocationLogAbstractBase, IDisposable
{
public LocationLogReader(byte[] contents)
{
MemoryStream ms = new MemoryStream(contents);
_textReader = new StreamReader(ms);
}
private bool _disposed;
private TextReader _textReader;
#region idisposable
~LocationLogReader()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposeManagedResources)
{
if (!_disposed)
{
if (disposeManagedResources)
{
if (null != _textReader)
{
#if !NETFX_CORE
_textReader.Close();
#endif
_textReader.Dispose();
_textReader = null;
}
}
_disposed = true;
}
}
#endregion
/// <summary>
/// Returns 'Location' objects from the data passed in. Loops through the data.
/// </summary>
/// <returns>'Location' objects and loops through the data.</returns>
public IEnumerator<Location> GetLocations()
{
while (true)
{
string line = string.Empty;
while (1 == 1)
{
line = _textReader.ReadLine();
// rewind if end of log (or last empty line) reached
if (null == line || string.IsNullOrEmpty(line))
{
((StreamReader)_textReader).BaseStream.Position = 0;
((StreamReader)_textReader).DiscardBufferedData();
continue;
}
// skip comments
if (line.StartsWith("#")) { continue; } else { break; }
}
string[] tokens = line.Split(Delimiter.ToCharArray());
//simple safety net: check if number of columns matches
if (tokens.Length != HeaderNames.Length)
{
Debug.LogError("unsupported log file");
yield return new Location();
}
Location location = new Location();
location.IsLocationServiceEnabled = bool.Parse(tokens[(int)LogfileColumns.LocationServiceEnabled]);
location.IsLocationServiceInitializing = bool.Parse(tokens[(int)LogfileColumns.LocationServiceInitializing]);
location.IsLocationUpdated = bool.Parse(tokens[(int)LogfileColumns.LocationUpdated]);
location.IsUserHeadingUpdated = bool.Parse(tokens[(int)LogfileColumns.UserHeadingUpdated]);
location.Provider = tokens[(int)LogfileColumns.LocationProvider];
location.ProviderClass = tokens[(int)LogfileColumns.LocationProviderClass];
DateTime dtDevice;
string dtDeviceTxt = tokens[(int)LogfileColumns.UtcTimeDevice];
if (DateTime.TryParseExact(dtDeviceTxt, "yyyyMMdd-HHmmss.fff", _invariantCulture, DateTimeStyles.AssumeUniversal, out dtDevice))
{
location.TimestampDevice = UnixTimestampUtils.To(dtDevice);
}
DateTime dtLocation;
string dtLocationTxt = tokens[(int)LogfileColumns.UtcTimeOfLocation];
if (DateTime.TryParseExact(dtLocationTxt, "yyyyMMdd-HHmmss.fff", _invariantCulture, DateTimeStyles.AssumeUniversal, out dtLocation))
{
location.Timestamp = UnixTimestampUtils.To(dtLocation);
}
double lat;
string latTxt = tokens[(int)LogfileColumns.Latitude];
double lng;
string lngTxt = tokens[(int)LogfileColumns.Longitude];
if (
!double.TryParse(latTxt, NumberStyles.Any, _invariantCulture, out lat)
|| !double.TryParse(lngTxt, NumberStyles.Any, _invariantCulture, out lng)
)
{
location.LatitudeLongitude = Vector2d.zero;
}
else
{
location.LatitudeLongitude = new Vector2d(lat, lng);
}
float accuracy;
location.Accuracy = float.TryParse(tokens[(int)LogfileColumns.Accuracy], NumberStyles.Any, _invariantCulture, out accuracy) ? accuracy : 0;
float userHeading;
location.UserHeading = float.TryParse(tokens[(int)LogfileColumns.UserHeading], NumberStyles.Any, _invariantCulture, out userHeading) ? userHeading : 0;
float deviceOrientation;
location.DeviceOrientation = float.TryParse(tokens[(int)LogfileColumns.DeviceOrientation], NumberStyles.Any, _invariantCulture, out deviceOrientation) ? deviceOrientation : 0;
float speed;
location.SpeedMetersPerSecond = float.TryParse(tokens[(int)LogfileColumns.Speed], NumberStyles.Any, _invariantCulture, out speed) ? speed / 3.6f : (float?)null;
bool hasGpsFix;
location.HasGpsFix = bool.TryParse(tokens[(int)LogfileColumns.HasGpsFix], out hasGpsFix) ? hasGpsFix : (bool?)null;
int satellitesUsed;
location.SatellitesUsed = int.TryParse(tokens[(int)LogfileColumns.SatellitesUsed], out satellitesUsed) ? satellitesUsed : (int?)null;
int satellitesInView;
location.SatellitesInView = int.TryParse(tokens[(int)LogfileColumns.SatellitesInView], out satellitesInView) ? satellitesInView : (int?)null;
yield return location;
}
}
}
}