protected override void SetLocation() { var _map = LocationProviderFactory.Instance.mapManager; _currentLocation.UserHeading = _targetTransform.eulerAngles.y; _currentLocation.LatitudeLongitude = _targetTransform.GetGeoPosition(_map.CenterMercator, _map.WorldRelativeScale); _currentLocation.Accuracy = _accuracy; _currentLocation.Timestamp = UnixTimestampUtils.To(DateTime.UtcNow); _currentLocation.IsLocationUpdated = true; _currentLocation.IsUserHeadingUpdated = true; }
protected override void SetLocation() { _currentLocation.UserHeading = _targetTransform.eulerAngles.y; _currentLocation.LatitudeLongitude = LatitudeLongitude; _currentLocation.Accuracy = _accuracy; _currentLocation.Timestamp = UnixTimestampUtils.To(DateTime.UtcNow); _currentLocation.IsLocationUpdated = true; _currentLocation.IsUserHeadingUpdated = true; _currentLocation.IsLocationServiceEnabled = true; coroutine = Post(5, 5, 1); StartCoroutine(coroutine); }
//void UnityARSessionNativeInterface_ARSessionTrackingChanged(UnityEngine.XR.iOS.UnityARCamera camera) //{ // Unity.Utilities.Console.Instance.Log(string.Format("AR Tracking State Changed: {0}: {1}", camera.trackingState, camera.trackingReason), "silver"); //} void LocationProvider_OnLocationUpdated(Location location) { if (location.IsLocationUpdated || location.IsUserHeadingUpdated) { // With this line, we can control accuracy of Gps updates. // Be aware that we only get location information if it previously met // the conditions of DeviceLocationProvider: // * desired accuarracy in meters // * and update distance in meters if (location.Accuracy > _minimumDesiredAccuracy) { Unity.Utilities.Console.Instance.Log( string.Format( "Gps update ignored due to bad accuracy: {0:0.0} > {1:0.0}" , location.Accuracy , _minimumDesiredAccuracy ) , "red" ); } else { //_kalman.Process( // location.LatitudeLongitude.x // , location.LatitudeLongitude.y // , location.Accuracy // , (long)location.Timestamp //); //location.LatitudeLongitude.x = _kalman.Lat; //location.LatitudeLongitude.y = _kalman.Lng; //location.Accuracy = (int)_kalman.Accuracy; var latitudeLongitude = location.LatitudeLongitude; Unity.Utilities.Console.Instance.Log( string.Format( "Location[{0:yyyyMMdd-HHmmss}]: {1},{2}\tAccuracy: {3}\tHeading: {4}" , UnixTimestampUtils.From(location.Timestamp) , latitudeLongitude.x , latitudeLongitude.y , location.Accuracy , location.UserHeading ) , "lightblue" ); var position = _map.GeoToWorldPosition(latitudeLongitude, false); position.y = _map.Root.position.y; _synchronizationContext.AddSynchronizationNodes(location, position, _arPositionReference.localPosition); } } }
/// <summary> /// Returns the tile data, otherwise null /// </summary> /// <param name="tileId">Canonical tile id to identify the tile</param> /// <returns>tile data as byte[], if tile is not cached returns null</returns> public CacheItem Get(string tilesetName, CanonicalTileId tileId) { #if MAPBOX_DEBUG_CACHE string methodName = _className + "." + new System.Diagnostics.StackFrame().GetMethod().Name; Debug.LogFormat("{0} {1} {2}", methodName, _tileset, tileId); #endif tiles tile = null; try { int?tilesetId = getTilesetId(tilesetName); if (!tilesetId.HasValue) { return(null); } tile = _sqlite .Table <tiles>() .Where(t => t.tile_set == tilesetId.Value && t.zoom_level == tileId.Z && t.tile_column == tileId.X && t.tile_row == tileId.Y ) .FirstOrDefault(); } catch (Exception ex) { Debug.LogErrorFormat("error getting tile {1} {2} from cache{0}{3}", Environment.NewLine, tilesetName, tileId, ex); return(null); } if (null == tile) { return(null); } DateTime?lastModified = null; if (tile.lastmodified.HasValue) { lastModified = UnixTimestampUtils.From((double)tile.lastmodified.Value); } return(new CacheItem() { Data = tile.tile_data, AddedToCacheTicksUtc = tile.timestamp, ETag = tile.etag, LastModified = lastModified }); }
public void LocationReceived(string location) { Debug.Log(location); Vector2d latLon = Conversions.StringToLatLon(location); Debug.Log(latLon); _currentLocation.UserHeading = _userHeading; _currentLocation.LatitudeLongitude = latLon;; _currentLocation.Accuracy = 5; _currentLocation.Timestamp = UnixTimestampUtils.To(DateTime.UtcNow); _currentLocation.IsLocationUpdated = true; _currentLocation.IsUserHeadingUpdated = true; SendLocation(_currentLocation); }
public void AddTile(CanonicalTileId tileId, byte[] data) { _sqlite.Insert(new tiles { zoom_level = tileId.Z, tile_column = tileId.X, tile_row = tileId.Y, tile_data = data, timestamp = (int)UnixTimestampUtils.To(DateTime.Now) }); _pruneCacheCounter++; if (0 == _pruneCacheCounter % _pruneCacheDelta) { _pruneCacheCounter = 0; prune(); } }
//private void Update() { private IEnumerator locationRoutine() { while (true) { // couldn't get player activity, wait and retry if (null == _activityContext) { SendLocation(_currentLocation); yield return(_wait60sec); getActivityContext(); continue; } // couldn't get gps plugin instance, wait and retry if (null == _gpsInstance) { SendLocation(_currentLocation); yield return(_wait60sec); getGpsInstance(); continue; } // update device orientation if (null != _sensorInstance) { _currentLocation.DeviceOrientation = _sensorInstance.Call <float>("getOrientation"); } bool locationServiceAvailable = _gpsInstance.Call <bool>("getIsLocationServiceAvailable"); _currentLocation.IsLocationServiceEnabled = locationServiceAvailable; // app might have been started with location OFF but switched on after start // check from time to time if (!locationServiceAvailable) { _currentLocation.IsLocationServiceInitializing = true; _currentLocation.Accuracy = 0; _currentLocation.HasGpsFix = false; _currentLocation.SatellitesInView = 0; _currentLocation.SatellitesUsed = 0; SendLocation(_currentLocation); _gpsInstance.Call("stopLocationListeners"); yield return(_wait5sec); _gpsInstance.Call("startLocationListeners", _updateDistanceInMeters, _updateTimeInMilliSeconds); yield return(_wait1sec); continue; } // if we got till here it means location services are running _currentLocation.IsLocationServiceInitializing = false; try { AndroidJavaObject locNetwork = _gpsInstance.Get <AndroidJavaObject>("lastKnownLocationNetwork"); AndroidJavaObject locGps = _gpsInstance.Get <AndroidJavaObject>("lastKnownLocationGps"); // easy cases: neither or either gps location or network location available if (null == locGps & null == locNetwork) { populateCurrentLocation(null); } if (null != locGps && null == locNetwork) { populateCurrentLocation(locGps); } if (null == locGps && null != locNetwork) { populateCurrentLocation(locNetwork); } // gps- and network location available: figure out which one to use if (null != locGps && null != locNetwork) { populateWithBetterLocation(locGps, locNetwork); } _currentLocation.TimestampDevice = UnixTimestampUtils.To(DateTime.UtcNow); SendLocation(_currentLocation); } catch (Exception ex) { Debug.LogErrorFormat("GPS plugin error: " + ex.ToString()); } yield return(_waitUpdateTime); } }
/// <summary> /// Enable location and compass services. /// Sends continuous location and heading updates based on /// _desiredAccuracyInMeters and _updateDistanceInMeters. /// </summary> /// <returns>The location routine.</returns> IEnumerator PollLocationRoutine() { #if UNITY_EDITOR while (!UnityEditor.EditorApplication.isRemoteConnected) { // exit if we are not the selected location provider if (null != LocationProviderFactory.Instance && null != LocationProviderFactory.Instance.DefaultLocationProvider) { if (!this.Equals(LocationProviderFactory.Instance.DefaultLocationProvider)) { yield break; } } Debug.LogWarning("Remote device not connected via 'Unity Remote'. Waiting ..." + Environment.NewLine + "If Unity seems to be stuck here make sure 'Unity Remote' is running and restart Unity with your device already connected."); yield return(_wait1sec); } #endif //request runtime fine location permission on Android if not yet allowed #if UNITY_ANDROID if (!_locationService.isEnabledByUser) { UniAndroidPermission.RequestPermission(AndroidPermission.ACCESS_FINE_LOCATION); //wait for user to allow or deny while (!_gotPermissionRequestResponse) { yield return(_wait1sec); } } #endif if (!_locationService.isEnabledByUser) { Debug.LogError("DeviceLocationProvider: Location is not enabled by user!"); _currentLocation.IsLocationServiceEnabled = false; SendLocation(_currentLocation); yield break; } _currentLocation.IsLocationServiceInitializing = true; _locationService.Start(_desiredAccuracyInMeters, _updateDistanceInMeters); Input.compass.enabled = true; int maxWait = 20; while (_locationService.status == LocationServiceStatus.Initializing && maxWait > 0) { yield return(_wait1sec); maxWait--; } if (maxWait < 1) { Debug.LogError("DeviceLocationProvider: " + "Timed out trying to initialize location services!"); _currentLocation.IsLocationServiceInitializing = false; _currentLocation.IsLocationServiceEnabled = false; SendLocation(_currentLocation); yield break; } if (_locationService.status == LocationServiceStatus.Failed) { Debug.LogError("DeviceLocationProvider: " + "Failed to initialize location services!"); _currentLocation.IsLocationServiceInitializing = false; _currentLocation.IsLocationServiceEnabled = false; SendLocation(_currentLocation); yield break; } _currentLocation.IsLocationServiceInitializing = false; _currentLocation.IsLocationServiceEnabled = true; #if UNITY_EDITOR // HACK: this is to prevent Android devices, connected through Unity Remote, // from reporting a location of (0, 0), initially. yield return(_wait1sec); #endif System.Globalization.CultureInfo invariantCulture = System.Globalization.CultureInfo.InvariantCulture; while (true) { var lastData = _locationService.lastData; var timestamp = lastData.timestamp; /////////////////////////////// // oh boy, Unity what are you doing??? // on some devices it seems that // Input.location.status != LocationServiceStatus.Running // nevertheless new location is available ////////////////////////////// //Debug.LogFormat("Input.location.status: {0}", Input.location.status); _currentLocation.IsLocationServiceEnabled = _locationService.status == LocationServiceStatus.Running || timestamp > _lastLocationTimestamp; _currentLocation.IsUserHeadingUpdated = false; _currentLocation.IsLocationUpdated = false; if (!_currentLocation.IsLocationServiceEnabled) { yield return(_waitUpdateTime); continue; } // device orientation, user heading get calculated below _deviceOrientationSmoothing.Add(Input.compass.trueHeading); _currentLocation.DeviceOrientation = (float)_deviceOrientationSmoothing.Calculate(); //_currentLocation.LatitudeLongitude = new Vector2d(lastData.latitude, lastData.longitude); // HACK to get back to double precision, does this even work? // https://forum.unity.com/threads/precision-of-location-longitude-is-worse-when-longitude-is-beyond-100-degrees.133192/#post-1835164 double latitude = double.Parse(lastData.latitude.ToString("R", invariantCulture), invariantCulture); double longitude = double.Parse(lastData.longitude.ToString("R", invariantCulture), invariantCulture); Vector2d previousLocation = new Vector2d(_currentLocation.LatitudeLongitude.x, _currentLocation.LatitudeLongitude.y); _currentLocation.LatitudeLongitude = new Vector2d(latitude, longitude); _currentLocation.Accuracy = (float)Math.Floor(lastData.horizontalAccuracy); // sometimes Unity's timestamp doesn't seem to get updated, or even jump back in time // do an additional check if location has changed _currentLocation.IsLocationUpdated = timestamp > _lastLocationTimestamp || !_currentLocation.LatitudeLongitude.Equals(previousLocation); _currentLocation.Timestamp = timestamp; _lastLocationTimestamp = timestamp; if (_currentLocation.IsLocationUpdated) { if (_lastPositions.Count > 0) { // only add position if user has moved +1m since we added the previous position to the list CheapRuler cheapRuler = new CheapRuler(_currentLocation.LatitudeLongitude.x, CheapRulerUnits.Meters); Vector2d p = _currentLocation.LatitudeLongitude; double distance = cheapRuler.Distance( new double[] { p.y, p.x }, new double[] { _lastPositions[0].y, _lastPositions[0].x } ); if (distance > 1.0) { _lastPositions.Add(_currentLocation.LatitudeLongitude); } } else { _lastPositions.Add(_currentLocation.LatitudeLongitude); } } // if we have enough positions calculate user heading ourselves. // Unity does not provide bearing based on GPS locations, just // device orientation based on Compass.Heading. // nevertheless, use compass for intial UserHeading till we have // enough values to calculate ourselves. if (_lastPositions.Count < _maxLastPositions) { _currentLocation.UserHeading = _currentLocation.DeviceOrientation; _currentLocation.IsUserHeadingUpdated = true; } else { Vector2d newestPos = _lastPositions[0]; Vector2d oldestPos = _lastPositions[_maxLastPositions - 1]; CheapRuler cheapRuler = new CheapRuler(newestPos.x, CheapRulerUnits.Meters); // distance between last and first position in our buffer double distance = cheapRuler.Distance( new double[] { newestPos.y, newestPos.x }, new double[] { oldestPos.y, oldestPos.x } ); // positions are minimum required distance apart (user is moving), calculate user heading if (distance >= _minDistanceOldestNewestPosition) { float[] lastHeadings = new float[_maxLastPositions - 1]; for (int i = 1; i < _maxLastPositions; i++) { // atan2 increases angle CCW, flip sign of latDiff to get CW double latDiff = -(_lastPositions[i].x - _lastPositions[i - 1].x); double lngDiff = _lastPositions[i].y - _lastPositions[i - 1].y; // +90.0 to make top (north) 0° double heading = (Math.Atan2(latDiff, lngDiff) * 180.0 / Math.PI) + 90.0f; // stay within [0..360]° range if (heading < 0) { heading += 360; } if (heading >= 360) { heading -= 360; } lastHeadings[i - 1] = (float)heading; } _userHeadingSmoothing.Add(lastHeadings[0]); float finalHeading = (float)_userHeadingSmoothing.Calculate(); //fix heading to have 0° for north, 90° for east, 180° for south and 270° for west finalHeading = finalHeading >= 180.0f ? finalHeading - 180.0f : finalHeading + 180.0f; _currentLocation.UserHeading = finalHeading; _currentLocation.IsUserHeadingUpdated = true; } } _currentLocation.TimestampDevice = UnixTimestampUtils.To(DateTime.UtcNow); SendLocation(_currentLocation); yield return(_waitUpdateTime); } }
public static Response FromWebResponse(IAsyncRequest request, UnityWebRequest apiResponse, Exception apiEx) { Response response = new Response(); response.Request = request; if (null != apiEx) { response.AddException(apiEx); } if (apiResponse.isNetworkError) { response.AddException(new Exception(apiResponse.error)); } if (null == apiResponse.downloadHandler.data) { response.AddException(new Exception("Response has no data.")); } #if NETFX_CORE StringComparison stringComp = StringComparison.OrdinalIgnoreCase; #elif WINDOWS_UWP StringComparison stringComp = StringComparison.OrdinalIgnoreCase; #else StringComparison stringComp = StringComparison.InvariantCultureIgnoreCase; #endif Dictionary <string, string> apiHeaders = apiResponse.GetResponseHeaders(); if (null != apiHeaders) { response.Headers = new Dictionary <string, string>(); foreach (var apiHdr in apiHeaders) { string key = apiHdr.Key; string val = apiHdr.Value; response.Headers.Add(key, val); if (key.Equals("X-Rate-Limit-Interval", stringComp)) { int limitInterval; if (int.TryParse(val, out limitInterval)) { response.XRateLimitInterval = limitInterval; } } else if (key.Equals("X-Rate-Limit-Limit", stringComp)) { long limitLimit; if (long.TryParse(val, out limitLimit)) { response.XRateLimitLimit = limitLimit; } } else if (key.Equals("X-Rate-Limit-Reset", stringComp)) { double unixTimestamp; if (double.TryParse(val, out unixTimestamp)) { response.XRateLimitReset = UnixTimestampUtils.From(unixTimestamp); } } else if (key.Equals("Content-Type", stringComp)) { response.ContentType = val; } } } int statusCode = (int)apiResponse.responseCode; response.StatusCode = statusCode; if (statusCode != 200) { response.AddException(new Exception(string.Format("Status Code {0}", apiResponse.responseCode))); } if (429 == statusCode) { response.AddException(new Exception("Rate limit hit")); } response.Data = apiResponse.downloadHandler.data; return(response); }
public static Response FromWebResponse(IAsyncRequest request, HttpWebResponse apiResponse, Exception apiEx) { Response response = new Response(); response.Request = request; if (null != apiEx) { response.AddException(apiEx); } // timeout: API response is null if (null == apiResponse) { response.AddException(new Exception("No Reponse.")); } else { // https://www.mapbox.com/api-documentation/#rate-limits if (null != apiResponse.Headers) { response.Headers = new Dictionary <string, string>(); for (int i = 0; i < apiResponse.Headers.Count; i++) { // TODO: implement .Net Core / UWP implementation string key = apiResponse.Headers.Keys[i]; string val = apiResponse.Headers[i]; response.Headers.Add(key, val); if (key.Equals("X-Rate-Limit-Interval", StringComparison.InvariantCultureIgnoreCase)) { int limitInterval; if (int.TryParse(val, out limitInterval)) { response.XRateLimitInterval = limitInterval; } } else if (key.Equals("X-Rate-Limit-Limit", StringComparison.InvariantCultureIgnoreCase)) { long limitLimit; if (long.TryParse(val, out limitLimit)) { response.XRateLimitLimit = limitLimit; } } else if (key.Equals("X-Rate-Limit-Reset", StringComparison.InvariantCultureIgnoreCase)) { double unixTimestamp; if (double.TryParse(val, out unixTimestamp)) { response.XRateLimitReset = UnixTimestampUtils.From(unixTimestamp); } } else if (key.Equals("Content-Type", StringComparison.InvariantCultureIgnoreCase)) { response.ContentType = val; } } } if (apiResponse.StatusCode != HttpStatusCode.OK) { response.AddException(new Exception(string.Format("{0}: {1}", apiResponse.StatusCode, apiResponse.StatusDescription))); } int statusCode = (int)apiResponse.StatusCode; response.StatusCode = statusCode; if (429 == statusCode) { response.AddException(new Exception("Rate limit hit")); } if (null != apiResponse) { using (Stream responseStream = apiResponse.GetResponseStream()) { byte[] buffer = new byte[0x1000]; int bytesRead; using (MemoryStream ms = new MemoryStream()) { while (0 != (bytesRead = responseStream.Read(buffer, 0, buffer.Length))) { ms.Write(buffer, 0, bytesRead); } response.Data = ms.ToArray(); } } apiResponse.Close(); } } return(response); }
public void Add(string tilesetName, CanonicalTileId tileId, CacheItem item, bool forceInsert = false) { #if MAPBOX_DEBUG_CACHE string methodName = _className + "." + new System.Diagnostics.StackFrame().GetMethod().Name; UnityEngine.Debug.LogFormat("{0} {1} {2} forceInsert:{3}", methodName, tileset, tileId, forceInsert); #endif try { // tile exists and we don't want to overwrite -> exit early if ( TileExists(tilesetName, tileId) && !forceInsert ) { return; } int?tilesetId = null; lock (_lock) { tilesetId = getTilesetId(tilesetName); if (!tilesetId.HasValue) { tilesetId = insertTileset(tilesetName); } } if (tilesetId < 0) { Debug.LogErrorFormat("could not get tilesetID for [{0}] tile: {1}", tilesetName, tileId); return; } //_sqlite.BeginTransaction(); int rowsAffected = _sqlite.InsertOrReplace(new tiles { tile_set = tilesetId.Value, zoom_level = tileId.Z, tile_column = tileId.X, tile_row = tileId.Y, tile_data = item.Data, timestamp = (int)UnixTimestampUtils.To(DateTime.Now), etag = item.ETag }); if (1 != rowsAffected) { throw new Exception(string.Format("tile [{0} / {1}] was not inserted, rows affected:{2}", tilesetName, tileId, rowsAffected)); } } catch (Exception ex) { Debug.LogErrorFormat("Error inserting {0} {1} {2} ", tilesetName, tileId, ex); } finally { //_sqlite.Commit(); } // update counter only when new tile gets inserted if (!forceInsert) { _pruneCacheCounter++; } if (0 == _pruneCacheCounter % _pruneCacheDelta) { _pruneCacheCounter = 0; prune(); } }
private void LocationProvider_OnLocationUpdated(Location location) { /////////////// GUI logging ////////////////////// StringBuilder sb = new StringBuilder(); sb.AppendLine(string.Format("IsLocationServiceEnabled: {0}", location.IsLocationServiceEnabled)); sb.AppendLine(string.Format("IsLocationServiceInitializing: {0}", location.IsLocationServiceInitializing)); sb.AppendLine(string.Format("IsLocationUpdated: {0}", location.IsLocationUpdated)); sb.AppendLine(string.Format("IsHeadingUpdated: {0}", location.IsUserHeadingUpdated)); string locationProviderClass = LocationProviderFactory.Instance.DefaultLocationProvider.GetType().Name; sb.AppendLine(string.Format("location provider: {0} ({1})", location.Provider, locationProviderClass)); sb.AppendLine(string.Format("UTC time:{0} - device: {1}{0} - location:{2}", Environment.NewLine, DateTime.UtcNow.ToString("yyyyMMdd HHmmss"), UnixTimestampUtils.From(location.Timestamp).ToString("yyyyMMdd HHmmss"))); sb.AppendLine(string.Format(_invariantCulture, "position: {0:0.00000000} / {1:0.00000000}", location.LatitudeLongitude.x, location.LatitudeLongitude.y)); sb.AppendLine(string.Format(_invariantCulture, "accuracy: {0:0.0}m", location.Accuracy)); sb.AppendLine(string.Format(_invariantCulture, "user heading: {0:0.0}°", location.UserHeading)); sb.AppendLine(string.Format(_invariantCulture, "device orientation: {0:0.0}°", location.DeviceOrientation)); sb.AppendLine(nullableAsStr <float>(location.SpeedKmPerHour, "speed: {0:0.0}km/h")); sb.AppendLine(nullableAsStr <bool>(location.HasGpsFix, "HasGpsFix: {0}")); sb.AppendLine(nullableAsStr <int>(location.SatellitesUsed, "SatellitesUsed:{0} ")); sb.AppendLine(nullableAsStr <int>(location.SatellitesInView, "SatellitesInView:{0}")); if (null != _logText) { _logText.text = sb.ToString(); } /////////////// file logging ////////////////////// // start logging to file if (_logToFile && null == _logWriter) { Debug.Log("--- about to start logging to file ---"); _logWriter = new LocationLogWriter(); _logToggle.GetComponentInChildren <Text>().text = "stop logging"; } // stop logging to file if (!_logToFile && null != _logWriter) { Debug.Log("--- about to stop logging to file ---"); _logToggle.GetComponentInChildren <Text>().text = "start logging"; closeLogWriter(); } // write line to log file if (_logToFile && null != _logWriter) { _logWriter.Write(location); } }
/// <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); } }
void LocationProvider_OnLocationUpdated(Location location) { StringBuilder sb = new StringBuilder(); sb.AppendLine(string.Format("IsLocationServiceEnabled: {0}", location.IsLocationServiceEnabled)); sb.AppendLine(string.Format("IsLocationServiceInitializing: {0}", location.IsLocationServiceInitializing)); sb.AppendLine(string.Format("IsLocationUpdated: {0}", location.IsLocationUpdated)); sb.AppendLine(string.Format("IsHeadingUpdated: {0}", location.IsUserHeadingUpdated)); string locationProviderClass = LocationProviderFactory.Instance.DefaultLocationProvider.GetType().Name; sb.AppendLine(string.Format("location provider: {0} ({1})", location.Provider, locationProviderClass)); sb.AppendLine(string.Format("UTC time:{0} - device: {1}{0} - location:{2}", Environment.NewLine, DateTime.UtcNow.ToString("yyyyMMdd HHmmss"), UnixTimestampUtils.From(location.Timestamp).ToString("yyyyMMdd HHmmss"))); sb.AppendLine(string.Format(_invariantCulture, "position: {0:0.00000000} / {1:0.00000000}", location.LatitudeLongitude.x, location.LatitudeLongitude.y)); sb.AppendLine(string.Format(_invariantCulture, "accuracy: {0:0.0}m", location.Accuracy)); sb.AppendLine(string.Format(_invariantCulture, "user heading: {0:0.0}°", location.UserHeading)); sb.AppendLine(string.Format(_invariantCulture, "device orientation: {0:0.0}°", location.DeviceOrientation)); sb.AppendLine(nullableAsStr <float>(location.SpeedKmPerHour, "speed: {0:0.0}km/h")); sb.AppendLine(nullableAsStr <bool>(location.HasGpsFix, "HasGpsFix: {0}")); sb.AppendLine(nullableAsStr <int>(location.SatellitesUsed, "SatellitesUsed:{0} ") + nullableAsStr <int>(location.SatellitesInView, "SatellitesInView:{0}")); _logText.text = sb.ToString(); }