示例#1
0
        /// <summary>
        /// Tests app resource URI as key in dictionies
        /// </summary>
        public void TestKeyInDictionary()
        {
            // set up
            var uri1 = new AppResourceUri(AppResourceUri.ResourceType.FindMeSpotPos, "xxx");
            var uri2 = new AppResourceUri(AppResourceUri.ResourceType.GarminInreachPos, "yyy");
            var uri3 = new AppResourceUri(AppResourceUri.ResourceType.GarminInreachPos, "yyy");

            var dict = new Dictionary <AppResourceUri, int>();

            // run + check
            Assert.IsFalse(dict.Any(), "there must be no items in the dictionary");

            dict[uri1] = 42;
            Assert.IsTrue(dict.Any(), "there must be an item in the dictionary");
            Assert.IsTrue(dict.ContainsKey(uri1), "dict must contain value for uri1");
            Assert.IsFalse(dict.ContainsKey(uri2), "dict must not contain value for uri1");

            dict[uri2] = 64;
            Assert.AreEqual(2, dict.Count, "there must be 2 items in the dictionary");

            dict[uri3] = 128;
            Assert.AreEqual(2, dict.Count, "there must still be 2 items in the dictionary");

            Assert.AreEqual(42, dict[uri1], "value of key with uri 1 must match");
            Assert.AreEqual(128, dict[uri2], "value of key with uri 2 must match");
            Assert.AreEqual(128, dict[uri3], "value of key with uri 3 must match");
        }
        /// <summary>
        /// Retrieves current live track points
        /// </summary>
        /// <param name="trackName">track name to use</param>
        /// <param name="appResourceUri">app resource uri to use</param>
        /// <returns>loaded live track</returns>
        private static async Task <Track> GetLiveTrack(string trackName, AppResourceUri appResourceUri)
        {
            var dataService = DependencyService.Get <IDataService>();

            LiveTrackQueryResult result = await dataService.GetLiveTrackDataAsync(
                appResourceUri.ToString(),
                null);

            var track = new Track
            {
                Id            = result.Data.ID,
                Name          = trackName ?? result.Data.Name,
                Description   = HtmlConverter.Sanitize(result.Data.Description),
                IsFlightTrack = true,
                IsLiveTrack   = true,
                Color         = "ff8000",
                TrackPoints   = result.Data.TrackPoints.Select(
                    trackPoint => new TrackPoint(
                        latitude: trackPoint.Latitude,
                        longitude: trackPoint.Longitude,
                        altitude: trackPoint.Altitude,
                        null)
                {
                    Time = result.Data.TrackStart.AddSeconds(trackPoint.Offset),
                }).ToList()
            };

            track.CalculateStatistics();

            return(track);
        }
示例#3
0
        /// <summary>
        /// Checks next request date if a new request can be made; when not, returns cache entry
        /// when available.
        /// </summary>
        /// <param name="uri">live waypoint ID</param>
        /// <returns>
        /// query result from cache, or null when there's no request in cache or when a request
        /// can be made online
        /// </returns>
        private LiveWaypointQueryResult CheckCache(AppResourceUri uri)
        {
            if (this.IsNextRequestPossible(uri))
            {
                return(null);
            }

            // ask cache
            string id = uri.ToString();

            LiveWaypointData cachedData;

            lock (this.lockCacheAndQueue)
            {
                cachedData = this.liveWaypointCache.ContainsKey(id) ? this.liveWaypointCache[id] : null;
            }

            if (cachedData == null)
            {
                return(null);
            }

            return(new LiveWaypointQueryResult
            {
                Data = cachedData,
                NextRequestDate = this.GetNextRequestDate(uri)
            });
        }
示例#4
0
        /// <summary>
        /// Returns a test position, based on the current time
        /// </summary>
        /// <param name="uri">live waypoint ID to use</param>
        /// <returns>live waypoint query result</returns>
        private Task <LiveWaypointQueryResult> GetTestPosResult(AppResourceUri uri)
        {
            DateTimeOffset nextRequestDate = DateTimeOffset.Now + TimeSpan.FromMinutes(1.0);

            var mapPoint = new MapPoint(47.664601, 11.885455, 0.0);

            double timeAngleInDegrees = (DateTimeOffset.Now.TimeOfDay.TotalMinutes * 6.0) % 360;
            double timeAngle          = timeAngleInDegrees / 180.0 * Math.PI;

            mapPoint.Latitude  += 0.025 * Math.Sin(timeAngle);
            mapPoint.Longitude -= 0.025 * Math.Cos(timeAngle);

            return(Task.FromResult(
                       new LiveWaypointQueryResult
            {
                Data = new LiveWaypointData
                {
                    ID = uri.ToString(),
                    TimeStamp = DateTimeOffset.Now,
                    Longitude = mapPoint.Longitude,
                    Latitude = mapPoint.Latitude,
                    Altitude = mapPoint.Altitude.Value,
                    Name = "Live waypoint test position",
                    Description = "Hello from the Where-to-fly backend services!<br/>" +
                                  $"Next request date is {nextRequestDate.ToString()}",
                    DetailsLink = string.Empty
                },
                NextRequestDate = nextRequestDate
            }));
        }
        /// <summary>
        /// Adds a new live waypoint resource URI
        /// </summary>
        /// <param name="uri">URI as string</param>
        /// <param name="appResourceUri">app resource URI</param>
        /// <returns>task to wait on</returns>
        private static async Task AddLiveWaypoint(string uri, AppResourceUri appResourceUri)
        {
            var    rawUri       = new Uri(uri);
            string waypointName = "Live Waypoint";

            if (!string.IsNullOrEmpty(rawUri.Fragment))
            {
                waypointName =
                    System.Net.WebUtility.UrlDecode(rawUri.Fragment.TrimStart('#'));
            }

            Location liveWaypoint = await GetLiveWaypointLocation(waypointName, appResourceUri);

            if (!await ShowAddLiveWaypointDialog(liveWaypoint))
            {
                return;
            }

            await StoreLiveWaypoint(liveWaypoint);

            App.ShowToast("Live waypoint was loaded.");

            await NavigationService.GoToMap();

            await App.UpdateLastShownPositionAsync(liveWaypoint.MapLocation);

            App.MapView.AddLocation(liveWaypoint);

            App.MapView.ZoomToLocation(liveWaypoint.MapLocation);
        }
        /// <summary>
        /// Opens app resource URI, e.g. a live waypoint
        /// </summary>
        /// <param name="uri">app resource URI to open</param>
        /// <returns>task to wait on</returns>
        public static async Task OpenAsync(string uri)
        {
            try
            {
                var appResourceUri = new AppResourceUri(uri);

                if (!appResourceUri.IsValid)
                {
                    await App.Current.MainPage.DisplayAlert(
                        Constants.AppTitle,
                        "Not a valid Where-to-fly weblink: " + uri,
                        "OK");

                    return;
                }

                if (!appResourceUri.IsTrackResourceType)
                {
                    await AddLiveWaypoint(uri, appResourceUri);
                }
                else
                {
                    await AddLiveTrack(uri, appResourceUri);
                }
            }
            catch (Exception ex)
            {
                App.LogError(ex);

                await App.Current.MainPage.DisplayAlert(
                    Constants.AppTitle,
                    "Error while opening weblink: " + ex.Message,
                    "OK");
            }
        }
示例#7
0
        /// <summary>
        /// Gets query result for a Find Me SPOT live waypoint ID
        /// </summary>
        /// <param name="uri">live waypoint ID</param>
        /// <returns>live waypoint query result</returns>
        private async Task <LiveWaypointQueryResult> GetFindMeSpotPosResult(AppResourceUri uri)
        {
            var liveWaypointData = await this.findMeSpotTrackerService.GetDataAsync(uri);

            return(new LiveWaypointQueryResult
            {
                Data = liveWaypointData,
                NextRequestDate = this.findMeSpotTrackerService.GetNextRequestDate(uri)
            });
        }
示例#8
0
        public void TestLiveWaypointData()
        {
            // set up
            var dataService = new FindMeSpotTrackerDataService();
            var uri         = new AppResourceUri(AppResourceUri.ResourceType.FindMeSpotPos, "xxx");

            // run
            var liveWaypointData = dataService.GetDataAsync(uri).Result;

            // check
            Assert.AreEqual(uri.ToString(), liveWaypointData.ID, "requested ID and app resource URI");
        }
示例#9
0
        /// <summary>
        /// Gets query result for a Garmin inReach live waypoint ID
        /// </summary>
        /// <param name="uri">live waypoint Id</param>
        /// <returns>live waypoint query result</returns>
        private async Task <LiveWaypointQueryResult> GetGarminInreachPosResult(AppResourceUri uri)
        {
            string mapShareIdentifier = uri.Data;

            var liveWaypointData = await this.garminInreachService.GetDataAsync(mapShareIdentifier);

            return(new LiveWaypointQueryResult
            {
                Data = liveWaypointData,
                NextRequestDate = this.garminInreachService.GetNextRequestDate(mapShareIdentifier)
            });
        }
示例#10
0
        /// <summary>
        /// Parses a raw live waypoint ID and returns an AppResourceId object from it
        /// </summary>
        /// <param name="rawId">raw live waypoint ID</param>
        /// <returns>live waypoint ID as AppResourceUri object</returns>
        private static AppResourceUri GetAndCheckLiveWaypointId(string rawId)
        {
            string id  = System.Net.WebUtility.UrlDecode(rawId);
            var    uri = new AppResourceUri(id);

            if (!uri.IsValid)
            {
                throw new ArgumentException("invalid live waypoint ID", nameof(rawId));
            }

            return(uri);
        }
示例#11
0
        public void TestSerializeDeserialize()
        {
            // set up
            var uri = new AppResourceUri("where-to-fly://GarminInreachPos/yyy");

            // run
            string         json = JsonConvert.SerializeObject(uri);
            AppResourceUri uri2 = JsonConvert.DeserializeObject <AppResourceUri>(json);

            // check
            Assert.IsTrue(uri2.IsValid, "deserialized uri must be valid");
            Assert.AreEqual(uri, uri2, "uris must be equal");
        }
示例#12
0
        public void TestCreateUriFromTypeAndData()
        {
            // run
            var uri1 = new AppResourceUri(AppResourceUri.ResourceType.FindMeSpotPos, "xxx");
            var uri2 = new AppResourceUri(AppResourceUri.ResourceType.GarminInreachPos, "yyy");

            // check
            Assert.IsTrue(uri1.IsValid, "uri1 must be valid");
            Assert.IsTrue(uri2.IsValid, "uri2 must be valid");

            Assert.AreEqual("where-to-fly://findmespotpos/xxx", uri1.ToString(), "uri text and ToString() result must match");
            Assert.AreEqual("where-to-fly://garmininreachpos/yyy", uri2.ToString(), "uri text and ToString() result must match");
        }
示例#13
0
        /// <summary>
        /// Opens app resource URI, e.g. a live waypoint
        /// </summary>
        /// <param name="uri">app resource URI to open</param>
        /// <returns>task to wait on</returns>
        public static async Task Open(string uri)
        {
            try
            {
                var appResourceUri = new AppResourceUri(uri);

                if (!appResourceUri.IsValid)
                {
                    await App.Current.MainPage.DisplayAlert(
                        Constants.AppTitle,
                        "Not a valid Where-to-fly weblink: " + uri,
                        "OK");

                    return;
                }

                var    rawUri       = new Uri(uri);
                string waypointName = "Live Waypoint";
                if (!string.IsNullOrEmpty(rawUri.Fragment))
                {
                    waypointName =
                        System.Net.WebUtility.UrlDecode(rawUri.Fragment.TrimStart('#'));
                }

                var liveWaypoint = await GetLiveWaypointLocation(waypointName, appResourceUri);

                if (!await ShowAddLiveWaypointDialog(liveWaypoint))
                {
                    return;
                }

                await StoreLiveWaypoint(liveWaypoint);

                App.ShowToast("Live waypoint was loaded.");

                await NavigationService.Instance.NavigateAsync(Constants.PageKeyMapPage, animated : true);

                App.ZoomToLocation(liveWaypoint.MapLocation);
                App.UpdateMapLocationsList();
            }
            catch (Exception ex)
            {
                App.LogError(ex);

                await App.Current.MainPage.DisplayAlert(
                    Constants.AppTitle,
                    "Error while opening weblink: " + ex.Message,
                    "OK");
            }
        }
示例#14
0
        public void TestCreateUriFromString()
        {
            // set up
            string uriText1 = "where-to-fly://FindMeSpotPos/xxx";
            string uriText2 = "where-to-fly://GarminInreachPos/yyy";

            // run
            var uri1 = new AppResourceUri(uriText1);
            var uri2 = new AppResourceUri(uriText2);

            // check
            Assert.IsTrue(uri1.IsValid, "uri1 must be valid");
            Assert.IsTrue(uri2.IsValid, "uri2 must be valid");

            Assert.IsTrue(uriText1.ToLowerInvariant() == uri1.ToString(), "uri text and ToString() result must match");
            Assert.IsTrue(uriText2.ToLowerInvariant() == uri2.ToString(), "uri text and ToString() result must match");
        }
示例#15
0
        /// <summary>
        /// Returns if next request is possible for the given app resource URI
        /// </summary>
        /// <param name="uri">live waypoint ID</param>
        /// <returns>
        /// true when web service request is possible, false when cache should be used
        /// </returns>
        private bool IsNextRequestPossible(AppResourceUri uri)
        {
            switch (uri.Type)
            {
            case AppResourceUri.ResourceType.FindMeSpotPos:
            case AppResourceUri.ResourceType.GarminInreachPos:
                DateTimeOffset nextRequestDate = this.GetNextRequestDate(uri);
                return(nextRequestDate <= DateTimeOffset.Now);

            case AppResourceUri.ResourceType.TestPos:
                return(true);    // request is always possible

            default:
                Debug.Assert(false, "invalid app resource URI type");
                return(false);
            }
        }
示例#16
0
        /// <summary>
        /// Gets actual live waypoint query result from web services
        /// </summary>
        /// <param name="uri">live waypoint ID</param>
        /// <returns>query result</returns>
        private async Task <LiveWaypointQueryResult> GetLiveWaypointQueryResult(AppResourceUri uri)
        {
            switch (uri.Type)
            {
            case AppResourceUri.ResourceType.FindMeSpotPos:
                return(await this.GetFindMeSpotPosResult(uri));

            case AppResourceUri.ResourceType.GarminInreachPos:
                return(await this.GetGarminInreachPosResult(uri));

            case AppResourceUri.ResourceType.TestPos:
                return(await this.GetTestPosResult(uri));

            default:
                Debug.Assert(false, "invalid app resource URI type");
                return(null);
            }
        }
示例#17
0
        /// <summary>
        /// Returns next request date for live waypoint in given ID
        /// </summary>
        /// <param name="uri">live waypoint ID</param>
        /// <returns>date time offset of next possible request for this ID</returns>
        private DateTimeOffset GetNextRequestDate(AppResourceUri uri)
        {
            switch (uri.Type)
            {
            case AppResourceUri.ResourceType.FindMeSpotPos:
                return(this.findMeSpotTrackerService.GetNextRequestDate(uri));

            case AppResourceUri.ResourceType.GarminInreachPos:
                return(this.garminInreachService.GetNextRequestDate(uri.Data));

            case AppResourceUri.ResourceType.TestPos:
                return(DateTimeOffset.Now + TimeSpan.FromMinutes(1.0));

            default:
                Debug.Assert(false, "invalid app resource URI type");
                return(DateTimeOffset.MaxValue);
            }
        }
示例#18
0
        /// <summary>
        /// Returns live waypoint data for given live waypoint ID. May throw an exception when the
        /// data is not readily available and must be fetched.
        /// </summary>
        /// <param name="rawId">live waypoint ID (maybe urlencoded)</param>
        /// <returns>live waypoint query result</returns>
        public async Task <LiveWaypointQueryResult> GetLiveWaypointData(string rawId)
        {
            AppResourceUri uri = GetAndCheckLiveWaypointId(rawId);

            LiveWaypointQueryResult result = this.CheckCache(uri);

            if (result != null)
            {
                return(result);
            }

            result = await this.GetLiveWaypointQueryResult(uri);

            if (result != null)
            {
                this.CacheLiveWaypointData(result.Data);
            }

            return(result);
        }
示例#19
0
        public void TestEquality()
        {
            // set up
            var uri1 = new AppResourceUri(AppResourceUri.ResourceType.FindMeSpotPos, "xxx");
            var uri2 = new AppResourceUri(AppResourceUri.ResourceType.GarminInreachPos, "yyy");
            var uri3 = new AppResourceUri(AppResourceUri.ResourceType.GarminInreachPos, "yyy");

            // run
            Assert.AreEqual <object>(uri1, uri1, "same objects must be equal");
            Assert.AreNotEqual <object>(uri1, uri2, "different objects must be equal");
            Assert.AreEqual <object>(uri2, uri3, "different references must be equal");
            Assert.AreNotEqual <object>("hello", uri1, "different object types must not be equal");

            Assert.AreEqual <AppResourceUri>(uri1, uri1, "same objects must be equal");
            Assert.AreNotEqual <AppResourceUri>(uri1, uri2, "different objects must be equal");
            Assert.AreEqual <AppResourceUri>(uri2, uri3, "different references must be equal");
            Assert.AreNotEqual <AppResourceUri>(null, uri1, "object must not be equal to null");

            Assert.AreEqual(uri2.GetHashCode(), uri3.GetHashCode(), "hash codes of same objects must be equal");
        }
示例#20
0
        public void TestParseInvalidUris()
        {
            // run
            Assert.ThrowsException <ArgumentNullException>(() => new AppResourceUri(null));
            Assert.ThrowsException <ArgumentException>(() => new AppResourceUri(AppResourceUri.ResourceType.None, "123"));
            Assert.ThrowsException <ArgumentNullException>(() => new AppResourceUri(AppResourceUri.ResourceType.FindMeSpotPos, null));
            Assert.ThrowsException <UriFormatException>(() => new AppResourceUri(string.Empty));

            var uri1 = new AppResourceUri("https://github.com/");
            var uri2 = new AppResourceUri("where-to-fly://");
            var uri3 = new AppResourceUri("where-to-fly://xxx");
            var uri4 = new AppResourceUri("where-to-fly://findmespotpos/");

            // check
            Assert.IsFalse(uri1.IsValid, "uri must be invalid");
            Assert.IsFalse(uri2.IsValid, "uri must be invalid");
            Assert.IsFalse(uri3.IsValid, "uri must be invalid");
            Assert.IsFalse(uri4.IsValid, "uri must be invalid");

            Assert.AreEqual("invalid", uri1.ToString(), "invalid URI must return proper ToString() result");
        }
示例#21
0
        /// <summary>
        /// GET handler when page parameters uri and name are passed to set a custom live waypoint
        /// to show in the page.
        /// </summary>
        /// <param name="uri">live waypoint uri to show</param>
        /// <param name="name">name of live waypoint to show</param>
        public void OnGet(string uri, string name)
        {
            if (string.IsNullOrEmpty(uri))
            {
                return;
            }

            var liveWaypointUri = new AppResourceUri(uri);

            if (liveWaypointUri.IsValid)
            {
                this.LiveTrackingInfoList = new List <LiveTrackingInfo>
                {
                    new LiveTrackingInfo
                    {
                        Name        = name ?? "Live Waypoint",
                        Uri         = liveWaypointUri.ToString(),
                        IsLiveTrack = liveWaypointUri.IsTrackResourceType,
                    }
                };
            }
        }
        /// <summary>
        /// Returns data for live waypoint with given app resource URI
        /// </summary>
        /// <param name="uri">live waypoint ID</param>
        /// <returns>live waypoint data</returns>
        public async Task <LiveWaypointData> GetDataAsync(AppResourceUri uri)
        {
            Debug.Assert(
                uri.Type == AppResourceUri.ResourceType.FindMeSpotPos,
                "app resource URI must be of FindMeSpotPos type!");

            string liveFeedId = uri.Data;

            Model.RootObject result = null;
            if (liveFeedId != "xxx")
            {
                result = await this.findMeSpotApi.GetLatest(liveFeedId);

                this.lastRequest = DateTimeOffset.Now;
            }
            else
            {
                // support for unit test
                string feedText = @"{""response"":{""feedMessageResponse"":{""count"":1,""feed"":{""id"":""abc123"",""name"":""name1"",""description"":""desc1"",""status"":""ACTIVE"",""usage"":0,""daysRange"":7,""detailedMessageShown"":true,""type"":""SHARED_PAGE""},""totalCount"":1,""activityCount"":0,""messages"":{""message"":{""@clientUnixTime"":""0"",""id"":942821234,""messengerId"":""0-123456"",""messengerName"":""Spot"",""unixTime"":1521991234,""messageType"":""UNLIMITED-TRACK"",""latitude"":48.12345,""longitude"":11.12345,""modelId"":""SPOT3"",""showCustomMsg"":""Y"",""dateTime"":""2018-03-26T20:52:00+0000"",""batteryState"":""GOOD"",""hidden"":0,""altitude"":1234}}}}}";
                result = Newtonsoft.Json.JsonConvert.DeserializeObject <Model.RootObject>(feedText);
            }

            var latestMessage = result.Response.FeedMessageResponse.Messages.Message;

            return(new LiveWaypointData
            {
                ID = uri.ToString(),
                TimeStamp = new DateTimeOffset(latestMessage.DateTime),
                Latitude = latestMessage.Latitude,
                Longitude = latestMessage.Longitude,
                Altitude = latestMessage.Altitude,
                Name = "FindMeSpot " + result.Response.FeedMessageResponse.Feed.Name,
                Description = FormatDescription(
                    result.Response.FeedMessageResponse.Feed,
                    latestMessage),
                DetailsLink = FormatSpotLink(liveFeedId),
            });
        }
        /// <summary>
        /// Adds a new live track resource URI
        /// </summary>
        /// <param name="uri">URI as string</param>
        /// <param name="appResourceUri">app resource URI</param>
        /// <returns>task to wait on</returns>
        private static async Task AddLiveTrack(string uri, AppResourceUri appResourceUri)
        {
            var    rawUri    = new Uri(uri);
            string trackName = "Live Track";

            if (!string.IsNullOrEmpty(rawUri.Fragment))
            {
                trackName =
                    System.Net.WebUtility.UrlDecode(rawUri.Fragment.TrimStart('#'));
            }

            Track liveTrack = await GetLiveTrack(trackName, appResourceUri);

            await StoreLiveTrack(liveTrack);

            App.ShowToast("Live track was loaded.");

            await NavigationService.GoToMap();

            App.MapView.AddTrack(liveTrack);

            App.MapView.ZoomToTrack(liveTrack);
        }
 /// <summary>
 /// Returns next possible request date for given MapShare identifier
 /// </summary>
 /// <param name="uri">live waypoint ID</param>
 /// <returns>next possible request date</returns>
 public DateTimeOffset GetNextRequestDate(AppResourceUri uri)
 {
     return(this.lastRequest.HasValue ? this.lastRequest.Value + TimeSpan.FromMinutes(1.0) : DateTimeOffset.Now);
 }
示例#25
0
        /// <summary>
        /// Retrieves current live waypoint map location
        /// </summary>
        /// <param name="waypointName">waypoint name to use</param>
        /// <param name="appResourceUri">app resource uri to use</param>
        /// <returns>map location, or invalid location when it couldn't be retrieved</returns>
        private static async Task <Location> GetLiveWaypointLocation(string waypointName, AppResourceUri appResourceUri)
        {
            var dataService = DependencyService.Get <IDataService>();

            LiveWaypointQueryResult result = await dataService.GetLiveWaypointDataAsync(appResourceUri.ToString());

            var mapPoint = new MapPoint(result.Data.Latitude, result.Data.Longitude, result.Data.Altitude);

            return(new Location
            {
                Id = result.Data.ID,
                Name = waypointName ?? result.Data.Name,
                MapLocation = mapPoint,
                Description = result.Data.Description.Replace("\n", "<br/>"),
                Type = LocationType.LiveWaypoint,
                InternetLink = appResourceUri.ToString()
            });
        }