Example #1
0
        /// <summary>
        /// Standard click event to get advice based on a move request
        /// </summary>
        private void HResultGet_Click(object sender, RoutedEventArgs e)
        {
            Task.Run(() =>
            {
                //Check if old and new house are found
                if ((p1.Item1 == 0 && p1.Item2 == 0) ||
                    (p2.Item1 == 0 && p2.Item2 == 0))
                {
                    Dispatcher.Invoke(new Action(() =>
                    {
                        //Reset everything
                        routeGeometry = new LineString();

                        MemoryLayer memoryLayer = (MemoryLayer)MyMapControl.Map.Layers.FindLayer("Route Layer").ElementAt(0);
                        memoryLayer.DataSource  = CreateMemoryProvider();
                        memoryLayer.ClearCache();
                        memoryLayer.ViewChanged(true, memoryLayer.Envelope, 1);
                        MyMapControl.Map.ViewChanged(true);

                        hResult.Text = "Get address coordinates first!";
                    }), DispatcherPriority.ContextIdle);
                }
                else
                {
                    Dispatcher.Invoke(new Action(() =>
                    {
                        //Disable the button to avoid parallel calls
                        hResultGet.IsEnabled = false;
                    }), DispatcherPriority.ContextIdle);
                    try
                    {
                        //Get route from old to new house
                        var route = GetRoute(p1, p2).Result;
                        if (route != null && route.Count > 1)
                        {
                            //Get distance and duration of moving from one house to another
                            var meta = route[route.Count - 1];
                            route.RemoveAt(route.Count - 1);
                            //Compose moving duration string
                            string duration = "Expected moving duration - " +
                                              Math.Floor(meta.Y / 60.0 / 60.0)
                                              .ToString(CultureInfo.InvariantCulture) +
                                              " hours, " +
                                              Math.Floor(meta.Y / 60.0 - Math.Floor(meta.Y / 60.0 / 60.0) * 60.0)
                                              .ToString(CultureInfo.InvariantCulture) +
                                              " minutes, " +
                                              Math.Floor(meta.Y - Math.Floor(meta.Y / 60.0 / 60.0) * 60.0 * 60.0 - Math.Floor(meta.Y / 60.0) * 60.0)
                                              .ToString(CultureInfo.InvariantCulture) +
                                              " seconds. ";
                            //Get weather forecast for next 5 days at old house
                            var weather = GetForecast(p1).Result;
                            //Get individual forecast list
                            //Take only forecasts during working hours (8 to 22)
                            //Order by weather condition ids: https://openweathermap.org/weather-conditions, (generally higher ids are better)
                            //Then order by temperature, (generally higher temperature is better)
                            //Get element 0, which is the best
                            var bestT = weather.list
                                        .Where(a =>
                            {
                                var atime = FromSecondsSinceUnixEpoch(a.dt);
                                return(atime.Hour > 8 && atime.Hour < 22);
                            })
                                        .OrderByDescending(a => a.weather[0].id)
                                        .ThenByDescending(a => a.main.temp)
                                        .ElementAt(0);
                            //Compose forecast string
                            string forecast = "Best time to move within 5 days - " +
                                              FromSecondsSinceUnixEpoch(bestT.dt).ToString("dddd, dd MMMM yyyy HH:mm", CultureInfo.InvariantCulture) +
                                              " because then weather will be " + bestT.weather[0].main.ToLowerInvariant() +
                                              ", " + bestT.weather[0].description.ToLowerInvariant() + " to be exact; " +
                                              "expected temparature - " + Math.Floor(bestT.main.temp).ToString(CultureInfo.InvariantCulture) + " degrees Celsius. ";

                            Dispatcher.Invoke(new Action(() =>
                            {
                                //Use LINQ to convert geographical points to screen ones
                                routeGeometry = new LineString(route.Select(
                                                                   a => SphericalMercator.FromLonLat(a.X, a.Y)));
                                //Find the specific map layer with routing data
                                MemoryLayer memoryLayer = (MemoryLayer)MyMapControl.Map.Layers.FindLayer("Route Layer").ElementAt(0);
                                //Create a new memory provider with our new route
                                memoryLayer.DataSource = CreateMemoryProvider();
                                //Clear render cache
                                memoryLayer.ClearCache();
                                //Inform layer of a data change, making it re-render the whole thing
                                memoryLayer.ViewChanged(true, memoryLayer.Envelope, 1);
                                //Inform map of a data change, making it re-render the whole thing
                                MyMapControl.Map.ViewChanged(true);
                                //Update advice text
                                hResult.Text = duration + forecast;
                            }), DispatcherPriority.ContextIdle);
                        }
                        else
                        {
                            Dispatcher.Invoke(new Action(() =>
                            {
                                //Same as higher but with an empty route
                                routeGeometry           = new LineString();
                                MemoryLayer memoryLayer = (MemoryLayer)MyMapControl.Map.Layers.FindLayer("Route Layer").ElementAt(0);
                                memoryLayer.DataSource  = CreateMemoryProvider();
                                memoryLayer.ClearCache();
                                memoryLayer.ViewChanged(true, memoryLayer.Envelope, 1);
                                MyMapControl.Map.ViewChanged(true);

                                hResult.Text = "Failed to find a path!";
                            }), DispatcherPriority.ContextIdle);
                        }
                    }
                    catch (Exception)
                    {
                        Dispatcher.Invoke(new Action(() =>
                        {
                            //Same as higher but with an empty route
                            routeGeometry           = new LineString();
                            MemoryLayer memoryLayer = (MemoryLayer)MyMapControl.Map.Layers.FindLayer("Route Layer").ElementAt(0);
                            memoryLayer.DataSource  = CreateMemoryProvider();
                            memoryLayer.ClearCache();
                            memoryLayer.ViewChanged(true, memoryLayer.Envelope, 1);
                            MyMapControl.Map.ViewChanged(true);

                            hResult.Text = "An error occured during advice gathering!";
                        }), DispatcherPriority.ContextIdle);
                    }
                    Dispatcher.Invoke(new Action(() =>
                    {
                        //Enable the Get Advice button for future use
                        hResultGet.IsEnabled = true;
                    }), DispatcherPriority.ContextIdle);
                }
            });
        }