· 6 years ago · Nov 29, 2019, 09:40 AM
1-- DESCRIPTION:
2 A weather app that features:
3 - A list view of cities (retrieved from a local database)
4 - A weather forecast that display data for today, tomorrow and after tomorrow
5 - Weather icons are displayed according to weather condition
6
7-- GET SOURCE FROM:
8 https://github.com/iacabezasbaculima/WPFWeatherApp
9
10-- METHOD TO RUN HTTP REQUEST TO FETCH WEATHER DATA FROM openweathermaps.org AND PARSE XML DATA
11public async Task<IEnumerable<WeatherForecast>> GetForecastAsync(string location)
12 {
13 if (location == null) throw new ArgumentNullException("Location can't be null.");
14 if (location == string.Empty) throw new ArgumentException("Location can't be an empty string.");
15
16 var query = $"forecast?q={location}&type=accurate&units=metric&mode=xml&appid={_APP_KEY}";
17
18 var response = await _client.GetAsync(query);
19
20 switch (response.StatusCode)
21 {
22 case HttpStatusCode.Unauthorized:
23 throw new Exception("Invalid API key.");
24 case HttpStatusCode.NotFound:
25 throw new Exception("Location not found.");
26 case HttpStatusCode.OK:
27 var s = await response.Content.ReadAsStringAsync();
28 var x = XElement.Load(new StringReader(s));
29
30 var data = x.Descendants("time").Select(w => new WeatherForecast
31 {
32 City = w.Parent.Parent.Element("location").Element("name").Value,
33 Country = w.Parent.Parent.Element("location").Element("country").Value,
34 Date = DateTime.Parse(w.Attribute("from").Value),
35 SunSet = DateTime.Parse(w.Parent.Parent.Element("sun").Attribute("set").Value.Substring(11,8)),
36 SunRise = DateTime.Parse(w.Parent.Parent.Element("sun").Attribute("rise").Value.Substring(11,8)),
37 Description = w.Element("symbol").Attribute("name").Value,
38 ImageId = w.Element("symbol").Attribute("var").Value,
39 WindSpeed = double.Parse(w.Element("windSpeed").Attribute("mps").Value),
40 CurrentTemperature = double.Parse(w.Element("temperature").Attribute("value").Value),
41 MaxTemperature = double.Parse(w.Element("temperature").Attribute("max").Value),
42 MinTemperature = double.Parse(w.Element("temperature").Attribute("min").Value),
43 Pressure = int.Parse(w.Element("pressure").Attribute("value").Value),
44 Humidity = int.Parse(w.Element("humidity").Attribute("value").Value)
45 });
46 return data;
47 default:
48 throw new NotImplementedException(response.StatusCode.ToString());
49 }
50 }
51-- METHOD THAT RUNS API CALL FETCH WEATHER DATA AND UPDATE UI ELEMENTS
52public async Task GetWeather(string location)
53 {
54 try
55 {
56 #region Get and Filter Weather Data
57 double maxtemp;
58 double mintemp;
59 switch (_searchFor)
60 {
61 case OpenWeatherMapService.QueryType.SINGLE_DAY:
62 currentWeather = await service.GetSingleForecastAsync(location);
63 forecast.Add(currentWeather);
64 break;
65 case OpenWeatherMapService.QueryType.FIVE_DAYS:
66 var weather = await service.GetForecastAsync(location);
67 currentWeather = weather.First();
68
69 maxtemp = weather.Where(i => i.Date.Day == TimeOfDay.Tomorrow.Day).Where(i => i.Date.TimeOfDay == TimeOfDay.Midday.TimeOfDay).First().CurrentTemperature;
70 mintemp = weather.Where(i => i.Date.Day == TimeOfDay.Tomorrow.Day).Where(i => i.Date.TimeOfDay == TimeOfDay.NinePM.TimeOfDay).First().CurrentTemperature;
71 wTomorrow = weather.Where(i => i.Date.Day == TimeOfDay.Tomorrow.Day).FirstOrDefault();
72 wTomorrow.MaxTemperature = maxtemp > mintemp ? Math.Round(maxtemp) : Math.Round(mintemp);
73 wTomorrow.MinTemperature = mintemp < maxtemp ? Math.Round(mintemp) : Math.Round(maxtemp);
74
75 maxtemp = weather.Where(i => i.Date.Day == TimeOfDay.AfterTomorrow.Day).Where(i => i.Date.TimeOfDay == TimeOfDay.Midday.TimeOfDay).First().CurrentTemperature;
76 mintemp = weather.Where(i => i.Date.Day == TimeOfDay.AfterTomorrow.Day).Where(i => i.Date.TimeOfDay == TimeOfDay.NinePM.TimeOfDay).First().CurrentTemperature;
77 wAfterTomorrow = weather.Where(i => i.Date.Day == TimeOfDay.AfterTomorrow.Day).First();
78 wTomorrow.MaxTemperature = maxtemp > mintemp ? Math.Round(maxtemp) : Math.Round(mintemp);
79 wTomorrow.MinTemperature = mintemp < maxtemp ? Math.Round(mintemp) : Math.Round(maxtemp);
80
81 maxtemp = weather.Where(i => i.Date.Day == TimeOfDay.Today.Day).Where(i => i.Date.TimeOfDay == TimeOfDay.Midday.TimeOfDay).First().CurrentTemperature;
82 mintemp = weather.Where(i => i.Date.Day == TimeOfDay.Today.Day).Where(i => i.Date.TimeOfDay == TimeOfDay.NinePM.TimeOfDay).First().CurrentTemperature;
83 currentWeather = weather.Where(i => i.Date.Day == TimeOfDay.Today.Day).First();
84 currentWeather.MaxTemperature = maxtemp > mintemp ? Math.Round(maxtemp) : Math.Round(mintemp);
85 currentWeather.MinTemperature = mintemp < maxtemp ? Math.Round(mintemp) : Math.Round(maxtemp);
86 break;
87 }
88 #endregion
89
90 #region Update UI
91 CityName.Text = currentWeather.City;
92 WeatherIcon.Source = new BitmapImage(new Uri($"{_iconFolderPath}{currentWeather.ImageId}@2x.png"));
93 Description.Text = currentWeather.Description.First().ToString().ToUpper() + currentWeather.Description.Substring(1);
94 Date.Text = currentWeather.Date.ToString("MM/dd/yyyy");
95 Temp.Text = $"{Math.Round(currentWeather.CurrentTemperature).ToString()}";
96 MaxTemp.Text = $"{Math.Round(currentWeather.MaxTemperature).ToString()}{"\u00B0"}";
97 MinTemp.Text = $"{Math.Round(currentWeather.MinTemperature).ToString()}{"\u00B0"}";
98 WindSpeed.Text = $"{currentWeather.WindSpeed.ToString()} m/s";
99 Humidity.Text = $"{currentWeather.Humidity} %";
100 Pressure.Text = $"{currentWeather.Pressure} hPa";
101
102 // Tomorrow UI
103 TomorrowDay.Text = wTomorrow.Date.DayOfWeek.ToString().Substring(0,3);
104 TomorrowDate.Text = wTomorrow.Date.ToString("dd/MM");
105 TomorrowTemp.Text = $"{Math.Round(wTomorrow.MaxTemperature).ToString()} / {Math.Round(wTomorrow.MinTemperature).ToString()}";
106 TomorrowIcon.Source = new BitmapImage(new Uri($"{_iconFolderPath}{wTomorrow.ImageId}@2x.png"));
107 // AfterTomorrow UI
108 AfterTomorrowDay.Text = wAfterTomorrow.Date.DayOfWeek.ToString().Substring(0, 3);
109 AfterTomorrowDate.Text = wAfterTomorrow.Date.ToString("dd/MM");
110 AfterTomorrowTemp.Text = $"{Math.Round(wAfterTomorrow.MaxTemperature).ToString()} / {Math.Round(wAfterTomorrow.MinTemperature).ToString()}";
111 AfterTomorrowIcon.Source = new BitmapImage(new Uri($"{_iconFolderPath}{wAfterTomorrow.ImageId}@2x.png"));
112
113 var inputCity = new Location { City = location };
114 // Check if a city already exists in the list before we add it
115 bool check = cityList.Any(i => i.City == inputCity.City);
116
117 #endregion
118
119 #region Adding City To Database
120 if (!check)
121 {
122 using (var db = new WeatherEntities())
123 {
124 db.Locations.Add(inputCity);
125 db.SaveChanges();
126 lv_cities.ItemsSource = null;
127 cityList.Add(inputCity);
128 lv_cities.ItemsSource = cityList;
129 lv_cities.DisplayMemberPath = "City";
130 }
131 }
132 #endregion
133
134 #region Swap Panels
135 CityListPanel.Visibility = Visibility.Collapsed;
136 ForecastPanel.Visibility = Visibility.Visible;
137 #endregion
138 }
139 catch (Exception ex)
140 {
141 throw new Exception(ex.Message);
142 }
143 }