Example #1
0
        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;
        }
Example #2
0
 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);
        }
Example #6
0
        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);
            }
        }
Example #9
0
        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);
        }
Example #10
0
        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();
            }
        }
Example #12
0
        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);
            }
        }
Example #13
0
        /// <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();
        }