niedziela, 7 stycznia 2018

C# - JSON aplikacja pogodowa V2.0

W tym poście chciałbym zmodyfikować ostatnio przedstawiony program aplikacji pogodowej. Zmianie ulegnie tutaj wygląd aplikacji, do której dołożę grafiki oraz zmienię sposób wyświetlania informacji. Dodatkowo zmienię sam wygląd kodu aby był bardziej czytelniejszy oraz uporządkowany.

[Źródło: https://docs.microsoft.com/en-us/dotnet/]

Wygląd aplikacji:


Aplikacja wygląda następująco:


Podstawowy tryb pozwala na wybranie miasta poprzez wpisanie bądź wybranie z dostępnej listy. Po wyświetleniu informacji przedstawiane informacje np. pogoda, pozycja, ciśnienie czy wilgotność. Czas wschodu oraz zachodu słońca określany jest na czas bieżący na komputerze.


Drugi tryb po zaznaczeniu opcji Display Decode JSON pozwala na wyświetlanie wszystkich otrzymanych danych. 

Kod programu:


Przesyłanie zapytania o pogodę:

  1. public static JsonWeatherReport getJsonData(string url)
  2. {
  3.     using (WebClient client = new WebClient())
  4.     {
  5.         string receiveJson = client.DownloadString(url);
  6.         JsonWeatherReport weather;
  7.         weather = JsonConvert.DeserializeObject<JsonWeatherReport>(receiveJson);
  8.         return weather;
  9.     }
  10. }

Tworzenie adresu do przesłania wykonywane jest za pomocą dwóch funkcji:

  1. public static string makeRequestUrl(string cityID)
  2. {
  3.     string requestAddr = FORECAST_CLEAR + cityID + APIKEY;
  4.     return requestAddr;
  5. }
  6. public static string makeRequestUrlWhenCityOutOfList(string cityName)
  7. {
  8.     /*
  9.         To ask with city name
  10.         : http://api.openweathermap.org/data/2.5/weather?q=<cityName><,country>&APPID=<appidKey>
  11.         <cityName> - name of the city need to be add
  12.         <,country> - name of the country is not need to add to url
  13.         <appid key> - need to be add
  14.     */
  15.     string requestAddr = FORECAST_CLEAR + "q=" + cityName + "&" + APIKEY;
  16.     return requestAddr;
  17. }

Pierwsza wysyła dane wykorzystując numer podanego miasta, druga wysyła zapytanie po nazwie miasta. Dla drugiego przypadku w kontrolce ComboBox należy umieścić albo samą nazwę miasta np. Warszawa, lub nazwę wraz z krajem Warszawa,pl.

Dane pomiędzy poszczególnymi otwarciami są zapisywane w ustawieniach projektu:

  1. private void saveDataBetweenOpen()
  2. {
  3.     Properties.Settings.Default.countryRTBData = countriesComboBox.Text.ToString();
  4.     Properties.Settings.Default.Save();
  5. }

Aby je odzyskać podczas uruchamiania programu wywoływana jest instrukcja przypisujące te dane do kontrolki ComboBox.

  1. countriesComboBox.Text = Properties.Settings.Default.countryRTBData.ToString();

Dane zapisywane są w kontrolkach Label. Każda z nich odpowiada za wyświetlenie innych informacji:

  1. public void updateWeatherLabels(JsonWeatherReport weatherData)
  2. {
  3.     setLabelVisibleStatus(true);
  4.     coordsLabel.Text = "Long: " + System.Convert.ToString(weatherData.Coord.Lon) + " ; Lati: " +System.Convert.ToString(weatherData.Coord.Lat);
  5.     cityCountryLabel.Text = weatherData.Name + ", " + weatherData.Sys.Country;
  6.     tempLabel.Text = System.Convert.ToString(weatherData.Main.Temp) + " °K / " + System.Convert.ToString(Math.Truncate((weatherData.Main.Temp- 273) * 100) / 100) + " °C";
  7.     humidityLabel.Text = "Humidity: " + System.Convert.ToString(weatherData.Main.Humidity) + "%";
  8.     pressureLabel.Text = "Pressure: " + System.Convert.ToString(weatherData.Main.Pressure);
  9.     sunriseLabel.Text = "Sunrise: " + System.Convert.ToString(helpFunctions.UnixTimeStampToDateTime(weatherData.Sys.Sunrise));
  10.     sunsetLabel.Text = "Sunset: " + System.Convert.ToString(helpFunctions.UnixTimeStampToDateTime(weatherData.Sys.Sunset));
  11.     weatherLabel.Text = weatherData.Weather[0].Main;
  12. }

Ostatnim elementem obsługującym dane jest PictureBox wyświetla on ikonę ze strony openWeatherApp.

  1. private void getAndSetWeatherIconInPicture(JsonWeatherReport weatherData)
  2. {
  3.     string requestURL = "http://openweathermap.org/img/w/" + weatherData.Weather[0].Icon + ".png";
  4.     var request = WebRequest.Create(requestURL);
  5.     using (var response = request.GetResponse())
  6.     using (var stream = response.GetResponseStream())
  7.     {
  8.         weatherImaPicBox.Image = Bitmap.FromStream(stream);
  9.     }
  10. }

Wyszukiwanie podanego miasta odbywa się w zdarzeniu od wciśnięcia przycisku:

  1. private void readBtn_Click(object sender, EventArgs e)
  2. {
  3.     if(checkIfWrongDataInRitchTxtBox() == true)
  4.     {
  5.         return;
  6.     }
  7.     saveDataBetweenOpen();
  8.     bool status = SelectedCity.getCityId(countriesComboBox.Text.ToString());
  9.     string getDataUrl = "";
  10.     if (status == false)
  11.     {
  12.         /* there is no city like that in city buffer */
  13.         getDataUrl = weatherUrl.makeRequestUrlWhenCityOutOfList(countriesComboBox.Text.ToString());
  14.     }
  15.     else
  16.     {
  17.         /* there is a city */
  18.         getDataUrl = weatherUrl.makeRequestUrl(SelectedCity.LastSelectedCity);
  19.     }
  20.     jsonWeatherRichTxtBox.Clear();
  21.     JsonWeatherReport weather = weatherUrl.getJsonData(getDataUrl);
  22.     if(weather == null)
  23.     {
  24.         MessageBox.Show("Wrong city name! Check writed data.""Wrong city name", MessageBoxButtons.OK, MessageBoxIcon.Error);
  25.         return;
  26.     }
  27.     updateControls(weather);
  28.     getAndSetWeatherIconInPicture(weather);
  29. }

Obsługa CheckBox wygląda następująco:

  1. private void displJsonDataCheckBox_CheckedChanged(object sender, EventArgs e)
  2. {
  3.     if (checkBoxCheckedCheck())
  4.     {
  5.         jsonWeatherRichTxtBox.Enabled = true;      
  6.         this.Size = new Size(windowSize.windowWithJsonDataWidth, windowSize.windowWithJsonDataLength);
  7.     }
  8.     else
  9.     {
  10.         jsonWeatherRichTxtBox.Enabled = false;
  11.         this.Size = new Size(windowSize.windowWithoutJsonDataWidht, windowSize.windowWithoutJsonDataLength);
  12.     }
  13. }

Kod powyżej najpierw sprawdza czy CheckBox jest uruchomiony, jeśli tak to uruchamiana jest kontrolka wyświetlająca informacje z odebranymi danymi JSON.

Cały projekt można pobrać z dysku Google pod tym linkiem.