Пример #1
0
        public static double DistanceInMeters(GPSLatLong latLong1, GPSLatLong latLong2)
        {
            return(DistanceTo(latLong1.Latitude, latLong1.Longitude, latLong2.Latitude, latLong2.Longitude));

            // https://stackoverflow.com/questions/6366408/calculating-distance-between-two-latitude-and-longitude-geocoordinates
            double DistanceTo(double lat1, double lon1, double lat2, double lon2, Unit unit = Unit.Meters)
            {
                double rlat1  = Math.PI * lat1 / 180.0;
                double rlat2  = Math.PI * lat2 / 180.0;
                double theta  = lon1 - lon2;
                double rtheta = Math.PI * theta / 180.0;

                double dist = Math.Sin(rlat1) * Math.Sin(rlat2) + Math.Cos(rlat1) *
                              Math.Cos(rlat2) * Math.Cos(rtheta);

                dist = Math.Acos(dist);
                dist = dist * 180.0 / Math.PI;
                dist = dist * 60.0 * 1.1515;

                switch (unit)
                {
                case Unit.Meters:        return(dist * 1609.344);

                case Unit.Kilometers:    return(dist * 1.609344);

                case Unit.NauticalMiles: return(dist * 0.8684);

                case Unit.Miles:         return(dist);

                default:                 return(dist);
                }
            }
        }
Пример #2
0
        public static GPSLatLong MoveTowards(GPSLatLong fromLatLong, GPSLatLong toLatLong, double speed, double deltaTime)
        {
            var newPosition = Vector2d.MoveTowards(fromLatLong.ToVector2d(), toLatLong.ToVector2d(), speed * deltaTime);

            return(new GPSLatLong
            {
                Latitude = newPosition.x,
                Longitude = newPosition.y,
            });
        }
        public void StartGpsService()
        {
            this.StopGpsService();

            if (Application.isEditor && this.waitForUnityRemote == false)
            {
                this.serviceCoroutine = this.StartCoroutine(StartGpsServiceEditorCoroutine());
            }
            else if (Application.isEditor || Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer)
            {
                this.serviceCoroutine = this.StartCoroutine(StartGpsServiceCoroutine());
            }
            else
            {
                Debug.LogError($"GPSManager Encountered Unknown Platform {Application.platform}");
            }

            IEnumerator StartGpsServiceEditorCoroutine()
            {
                if (this.printDebugOutput)
                {
                    Debug.Log("GPSManager.StartGpsServiceEditorCoroutine");
                }

                this.serviceState = GPSServiceState.StartingUp;

                if (this.hasEditorLatLongBeenSet == false)
                {
                    var debugStartLocationsCount = this.debugStartLocations?.Count;

                    if (debugStartLocationsCount == null || debugStartLocationsCount == 0)
                    {
                        Debug.LogError("GPSManager has no debug start locations to work with.");
                        yield break;
                    }

                    GPSLatLong latLong = this.debugStartLocations[0].LatLong;

                    if (debugStartLocationsCount > 1)
                    {
                        // TODO [bgish]: Let user pick a location
                    }

                    this.editorLatLong = new GPSLatLong
                    {
                        Latitude  = latLong.Latitude,
                        Longitude = latLong.Longitude,
                    };

                    this.hasEditorLatLongBeenSet = true;
                }

                this.serviceState = GPSServiceState.Running;

                while (true)
                {
                    this.CurrentRawLatLong = this.editorLatLong;
                    yield return(WaitForUtil.Seconds(this.smoothMovementInEdtior ? 0.02f : this.updateFrequencyInSeconds));
                }
            }

            IEnumerator StartGpsServiceCoroutine()
            {
                this.serviceState = GPSServiceState.StartingUp;

                if (Application.isEditor && this.waitForUnityRemote)
                {
#if UNITY_EDITOR
                    while (UnityEditor.EditorApplication.isRemoteConnected == false)
                    {
                        yield return(null);
                    }
#endif

                    yield return(WaitForUtil.Seconds(5.0f));
                }

                // TODO [bgish]: Need to not do this look if we're just running in editor and this.waitForUnityRemote == false
                while (true)
                {
                    bool isGpsEnabled = GPSUtil.IsGpsEnabledByUser();

                    if (isGpsEnabled == false)
                    {
                        GPSUtil.AskForPermissionToUseGPS();
                        yield return(WaitForUtil.Seconds(1.0f));

                        isGpsEnabled = GPSUtil.IsGpsEnabledByUser();
                    }

                    if (isGpsEnabled)
                    {
                        break;
                    }
                    else if (this.appMustUseGps == false)
                    {
                        Debug.LogError("Unable to start GPS Manage.  The user doesn't have permissions.");
                        this.StopGpsService();
                        break;
                    }
                    else
                    {
                        var gpsRequired = LostMessages.GpsIsRequiredRetryOrQuitApp();

                        yield return(gpsRequired);

                        if (gpsRequired.Value == YesNoResult.No)
                        {
                            Platform.QuitApplication();
                        }
                    }
                }

                // Start service before querying location
                UnityEngine.Input.location.Start(10.0f, 10.0f);

                // Wait until service initializes
                int maxWait = 15;
                while (UnityEngine.Input.location.status == LocationServiceStatus.Initializing && maxWait > 0)
                {
                    yield return(new WaitForSecondsRealtime(1));

                    maxWait--;
                }

                // Editor has a bug which doesn't set the service status to Initializing. So extra wait in Editor.
                if (Application.isEditor)
                {
                    int editorMaxWait = 15;
                    while (UnityEngine.Input.location.status == LocationServiceStatus.Stopped && editorMaxWait > 0)
                    {
                        yield return(new WaitForSecondsRealtime(1));

                        editorMaxWait--;
                    }
                }

                // Service didn't initialize in 15 seconds
                if (maxWait < 1)
                {
                    // TODO Failure
                    Debug.LogFormat("Timed out");
                    this.StopGpsService();
                    yield break;
                }

                // Connection has failed
                if (UnityEngine.Input.location.status != LocationServiceStatus.Running)
                {
                    // TODO Failure
                    Debug.LogFormat("Unable to determine device location. Failed with status {0}", UnityEngine.Input.location.status);
                    this.StopGpsService();
                    yield break;
                }
                else
                {
                    this.serviceState = GPSServiceState.Running;

                    while (true)
                    {
                        this.CurrentRawLatLong = GPSUtil.GetGPSLatLong();
                        yield return(WaitForUtil.Seconds(this.updateFrequencyInSeconds));
                    }
                }
            }
        }