C#.Netを使用したコンソール気象ユーティリティ

5日間の天気予報を取得し始めるには、何を取得して学ぶ必要がありますか? 





まず、気象データプロバイダーを決定します。次に、データがどのような形式で提供され、C#プログラミング言語を使用してデータを収集および表示する方法を分析します。 





気象データプロバイダーとしてAccuweatherサービスを選択しました。無料アカウントでは現在、1日あたり50件のリクエストが許可されています。これは、1日に数回気象データを表示するのに十分です(友人と共有することもできます!)。 





登録するには、次のリンクをたどってください:https//developer.accuweather.com登録後、「新しいアプリを追加」ボタンをクリックして、短いフォームに記入する必要があります。その結果、後で更新されたデータを受け取ることができる個人のApiKeyを受け取ります。 





それから楽しみが始まります。情報がどのように、どのような形式で提供され、特定の都市の気象データを受信するために何が必要かを分析します。 





「APIリファレンス」セクションでは、最初のリストが「ロケーションAPIセクションに設定されているので、始めましょう。将来的には、GETリクエストで都市の名前を取得して送信することはできないとすぐに言います。これを行うには、最初に特定の都市のロケーションキーを取得する必要があります。この値は数値の形式で表示され、都市ごとに一意です。 





そのため、Locations APIセクションでは、CitySearchメソッドに関心があります。その簡単な説明を読みました。検索テキストに一致する都市の配列の情報を返します。都市の名前を含む配列が返されることにすぐに注意してください。 





ローカライズされたデータを受信する場合は、リクエストのページに、関心のある都市の名前であるApiKeyを挿入し、RUを入力します。 





ページ下の「このリクエストを送信」ボタンをクリックすると、実行結果が表示されます。私の場合、次のようになります。





[
  {
    "Version": 1,
    "Key": "292332",
    "Type": "City",
    "Rank": 21,
    "LocalizedName": "Chelyabinsk",
    "EnglishName": "Chelyabinsk",
    "PrimaryPostalCode": "",
    "Region": {
      "ID": "ASI",
      "LocalizedName": "Asia",
      "EnglishName": "Asia"
    },
    "Country": {
      "ID": "RU",
      "LocalizedName": "Russia",
      "EnglishName": "Russia"
    },
    "AdministrativeArea": {
      "ID": "CHE",
      "LocalizedName": "Chelyabinsk",
      "EnglishName": "Chelyabinsk",
      "Level": 1,
      "LocalizedType": "Oblast",
      "EnglishType": "Oblast",
      "CountryID": "RU"
    },
    "TimeZone": {
      "Code": "YEKT",
      "Name": "Asia/Yekaterinburg",
      "GmtOffset": 5,
      "IsDaylightSaving": false,
      "NextOffsetChange": null
    },
    "GeoPosition": {
      "Latitude": 55.16,
      "Longitude": 61.403,
      "Elevation": {
        "Metric": {
          "Value": 233,
          "Unit": "m",
          "UnitType": 5
        },
        "Imperial": {
          "Value": 764,
          "Unit": "ft",
          "UnitType": 0
        }
      }
    },
    "IsAlias": false,
    "SupplementalAdminAreas": [
      {
        "Level": 2,
        "LocalizedName": "Chelyabinsk",
        "EnglishName": "Chelyabinsk"
      }
    ],
    "DataSets": [
      "AirQualityCurrentConditions",
      "AirQualityForecasts",
      "Alerts",
      "ForecastConfidence"
    ]
  }
]
      
      



ご覧のとおり、1つの都市から配列を返しました。同じ名前の都市が2つ以上ある場合、結果はどのようになりますか。





[
  {
    "Version": 1,
    "Key": "294021",
    "Type": "City",
    "Rank": 10,
    "LocalizedName": "",
    "EnglishName": "Moscow",
    "PrimaryPostalCode": "",
    "Region": {
      "ID": "ASI",
      "LocalizedName": "",
      "EnglishName": "Asia"
    },
    "Country": {
      "ID": "RU",
      "LocalizedName": "",
      "EnglishName": "Russia"
    },
    "AdministrativeArea": {
      "ID": "MOW",
      "LocalizedName": "",
      "EnglishName": "Moscow",
      "Level": 1,
      "LocalizedType": "  ",
      "EnglishType": "Federal City",
      "CountryID": "RU"
    },
    "TimeZone": {
      "Code": "MSK",
      "Name": "Europe/Moscow",
      "GmtOffset": 3,
      "IsDaylightSaving": false,
      "NextOffsetChange": null
    },
    "GeoPosition": {
      "Latitude": 55.752,
      "Longitude": 37.619,
      "Elevation": {
        "Metric": {
          "Value": 155,
          "Unit": "m",
          "UnitType": 5
        },
        "Imperial": {
          "Value": 508,
          "Unit": "ft",
          "UnitType": 0
        }
      }
    },
    "IsAlias": false,
    "SupplementalAdminAreas": [
      {
        "Level": 2,
        "LocalizedName": "Tsentralny",
        "EnglishName": "Tsentralny"
      }
    ],
    "DataSets": [
      "AirQualityCurrentConditions",
      "AirQualityForecasts",
      "Alerts",
      "ForecastConfidence"
    ]
  },
  {
    "Version": 1,
    "Key": "1397263",
    "Type": "City",
    "Rank": 85,
    "LocalizedName": "",
    "EnglishName": "Moskwa",
    "PrimaryPostalCode": "",
    "Region": {
      "ID": "EUR",
      "LocalizedName": "",
      "EnglishName": "Europe"
    },
    "Country": {
      "ID": "PL",
      "LocalizedName": "",
      "EnglishName": "Poland"
    },
    "AdministrativeArea": {
      "ID": "10",
      "LocalizedName": " ",
      "EnglishName": "Łódź",
      "Level": 1,
      "LocalizedType": "",
      "EnglishType": "Voivodship",
      "CountryID": "PL"
    },
    "TimeZone": {
      "Code": "CET",
      "Name": "Europe/Warsaw",
      "GmtOffset": 1,
      "IsDaylightSaving": false,
      "NextOffsetChange": "2021-03-28T01:00:00Z"
    },
    "GeoPosition": {
      "Latitude": 51.816,
      "Longitude": 19.657,
      "Elevation": {
        "Metric": {
          "Value": 238,
          "Unit": "m",
          "UnitType": 5
        },
        "Imperial": {
          "Value": 780,
          "Unit": "ft",
          "UnitType": 0
        }
      }
    },
    "IsAlias": false,
    "SupplementalAdminAreas": [
      {
        "Level": 2,
        "LocalizedName": "- ",
        "EnglishName": "Łódź East"
      },
      {
        "Level": 3,
        "LocalizedName": "",
        "EnglishName": "Nowosolna"
      }
    ],
    "DataSets": [
      "AirQualityCurrentConditions",
      "AirQualityForecasts",
      "Alerts",
      "ForecastConfidence",
      "FutureRadar",
      "MinuteCast",
      "Radar"
    ]
  },
  {
    "Version": 1,
    "Key": "580845",
    "Type": "City",
    "Rank": 85,
    "LocalizedName": "",
    "EnglishName": "Moskva",
    "PrimaryPostalCode": "",
    "Region": {
      "ID": "ASI",
      "LocalizedName": "",
      "EnglishName": "Asia"
    },
    "Country": {
      "ID": "RU",
      "LocalizedName": "",
      "EnglishName": "Russia"
    },
    "AdministrativeArea": {
      "ID": "KIR",
      "LocalizedName": "",
      "EnglishName": "Kirov",
      "Level": 1,
      "LocalizedType": "",
      "EnglishType": "Republic",
      "CountryID": "RU"
    },
    "TimeZone": {
      "Code": "MSK",
      "Name": "Europe/Moscow",
      "GmtOffset": 3,
      "IsDaylightSaving": false,
      "NextOffsetChange": null
    },
    "GeoPosition": {
      "Latitude": 57.968,
      "Longitude": 49.104,
      "Elevation": {
        "Metric": {
          "Value": 207,
          "Unit": "m",
          "UnitType": 5
        },
        "Imperial": {
          "Value": 678,
          "Unit": "ft",
          "UnitType": 0
        }
      }
    },
    "IsAlias": false,
    "SupplementalAdminAreas": [
      {
        "Level": 2,
        "LocalizedName": "Verkhoshizhemsky",
        "EnglishName": "Verkhoshizhemsky"
      }
    ],
    "DataSets": [
      "AirQualityCurrentConditions",
      "AirQualityForecasts",
      "Alerts",
      "ForecastConfidence"
    ]
  },
  {
    "Version": 1,
    "Key": "2488304",
    "Type": "City",
    "Rank": 85,
    "LocalizedName": "",
    "EnglishName": "Moskva",
    "PrimaryPostalCode": "",
    "Region": {
      "ID": "ASI",
      "LocalizedName": "",
      "EnglishName": "Asia"
    },
    "Country": {
      "ID": "RU",
      "LocalizedName": "",
      "EnglishName": "Russia"
    },
    "AdministrativeArea": {
      "ID": "PSK",
      "LocalizedName": "",
      "EnglishName": "Pskov",
      "Level": 1,
      "LocalizedType": "",
      "EnglishType": "Oblast",
      "CountryID": "RU"
    },
    "TimeZone": {
      "Code": "MSK",
      "Name": "Europe/Moscow",
      "GmtOffset": 3,
      "IsDaylightSaving": false,
      "NextOffsetChange": null
    },
    "GeoPosition": {
      "Latitude": 57.449,
      "Longitude": 29.185,
      "Elevation": {
        "Metric": {
          "Value": 161,
          "Unit": "m",
          "UnitType": 5
        },
        "Imperial": {
          "Value": 528,
          "Unit": "ft",
          "UnitType": 0
        }
      }
    },
    "IsAlias": false,
    "SupplementalAdminAreas": [
      {
        "Level": 2,
        "LocalizedName": "Porkhovsky",
        "EnglishName": "Porkhovsky"
      }
    ],
    "DataSets": [
      "AirQualityCurrentConditions",
      "AirQualityForecasts",
      "Alerts",
      "Radar"
    ]
  },
  {
    "Version": 1,
    "Key": "580847",
    "Type": "City",
    "Rank": 85,
    "LocalizedName": "",
    "EnglishName": "Moskva",
    "PrimaryPostalCode": "",
    "Region": {
      "ID": "ASI",
      "LocalizedName": "",
      "EnglishName": "Asia"
    },
    "Country": {
      "ID": "RU",
      "LocalizedName": "",
      "EnglishName": "Russia"
    },
    "AdministrativeArea": {
      "ID": "TVE",
      "LocalizedName": "",
      "EnglishName": "Tver'",
      "Level": 1,
      "LocalizedType": "",
      "EnglishType": "Oblast",
      "CountryID": "RU"
    },
    "TimeZone": {
      "Code": "MSK",
      "Name": "Europe/Moscow",
      "GmtOffset": 3,
      "IsDaylightSaving": false,
      "NextOffsetChange": null
    },
    "GeoPosition": {
      "Latitude": 56.918,
      "Longitude": 32.163,
      "Elevation": {
        "Metric": {
          "Value": 251,
          "Unit": "m",
          "UnitType": 5
        },
        "Imperial": {
          "Value": 823,
          "Unit": "ft",
          "UnitType": 0
        }
      }
    },
    "IsAlias": false,
    "SupplementalAdminAreas": [
      {
        "Level": 2,
        "LocalizedName": "Penovsky",
        "EnglishName": "Penovsky"
      }
    ],
    "DataSets": [
      "AirQualityCurrentConditions",
      "AirQualityForecasts",
      "Alerts"
    ]
  }
]
      
      



, . , Key, . .





, , . , C#. , C# VSCodium. OpenSuSe Leap 15.2.





, ApiKey, , ApiKey , ApiKey .





, UserApi:





namespace habraweatherappconsole
{
    public class UserApi
    {
        public string UserApiProperty { get;set; }
    }
}
      
      



, , :





        /// <summary>
        ///      APIKey  
        /// </summary>
        public static void ReadUserApiToLocalStorage()
        {
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(ObservableCollection<UserApi>));

            try
            {
                using (StreamReader sr = new StreamReader("UserApi.xml"))
                {
                    userApiList = xmlSerializer.Deserialize(sr) as ObservableCollection<UserApi>;
                }
            }

            catch(Exception ex)
            {
                /*      .  ,     
                /     .       - -    
                /          ?
                */
            }
        }
      
      



, XML , , , XML.





. , , . , Json . , .





, :





    "Version": 1,
    "Key": "292332",
    "Type": "City",
    "Rank": 21,
    "LocalizedName": "Chelyabinsk",
    "EnglishName": "Chelyabinsk",
    "PrimaryPostalCode": "",

      
      



API , , , ( , ) , . , , - .





, :





    public class RootBasicCityInfo    {
        public int Version { get; set; } 
        public string Key { get; set; } 
        public string Type { get; set; } 
        public int Rank { get; set; } 
        public string LocalizedName { get; set; } 
        public string EnglishName { get; set; } 
        public string PrimaryPostalCode { get; set; } 

      
      



, json :





      "Region": {
        "ID": "ASI",
        "LocalizedName": "",
        "EnglishName": "Asia"
      },
      "Country": {
        "ID": "RU",
        "LocalizedName": "",
        "EnglishName": "Russia"
      },
      "AdministrativeArea": {
        "ID": "MOW",
        "LocalizedName": "",
        "EnglishName": "Moscow",
        "Level": 1,
        "LocalizedType": "  ",
        "EnglishType": "Federal City",
        "CountryID": "RU"
      },

      
      



, Region, Country, AdministrativeArea :





public class Region    {
        public string ID { get; set; } 
        public string LocalizedName { get; set; } 
        public string EnglishName { get; set; } 
    }

    public class Country    {
        public string ID { get; set; } 
        public string LocalizedName { get; set; } 
        public string EnglishName { get; set; } 
    }

    public class AdministrativeArea    {
        public string ID { get; set; } 
        public string LocalizedName { get; set; } 
        public string EnglishName { get; set; } 
        public int Level { get; set; } 
        public string LocalizedType { get; set; } 
        public string EnglishType { get; set; } 
        public string CountryID { get; set; } 
    }

      
      



:





    public class RootBasicCityInfo    {
        public int Version { get; set; } 
        public string Key { get; set; } 
        public string Type { get; set; } 
        public int Rank { get; set; } 
        public string LocalizedName { get; set; } 
        public string EnglishName { get; set; } 
        public string PrimaryPostalCode { get; set; } 
        public Region Region { get; set; } 
        public Country Country { get; set; } 
        public AdministrativeArea AdministrativeArea { get; set; } 
        public TimeZone TimeZone { get; set; } 
        public GeoPosition GeoPosition { get; set; } 
        public bool IsAlias { get; set; } 
        public List<SupplementalAdminArea> SupplementalAdminAreas { get; set; } 
        public List<string> DataSets { get; set; } 
    }

      
      



, , :





using System;
using System.Collections.ObjectModel;
using System.Net;
using System.Text.Json;

using static System.Console;

namespace habraweatherappconsole
{
    /// <summary>
    ///     
    ///       .
    /// </summary>
    public static class SearchCity
    {
        /// <summary>
        ///      .
        ///       
        ///       MainMenu.
        /// </summary>
        /// <param name="formalCityName"></param>
        public static void GettingListOfCitiesOnRequest(string formalCityName)
        {
            //  ApiKey  
            string apiKey = UserApiManager.userApiList[0].UserApiProperty;
            try
            {
                string jsonOnWeb = $"http://dataservice.accuweather.com/locations/v1/cities/search?apikey={apiKey}&q={formalCityName}";

                WebClient webClient = new WebClient();
                string prepareString = webClient.DownloadString(jsonOnWeb);

                ObservableCollection<RootBasicCityInfo> rbci = JsonSerializer.Deserialize<ObservableCollection<RootBasicCityInfo>>(prepareString);

                DataRepo.Printeceivedities(rbci);
            }
            catch (Exception ex)
            {
                WriteLine("   ."
                + " : \n" + 
                "*    \n"
                + "*    \n"
                + " : \n"
                + ex.Message);
            }

        }
    }
}
      
      



, :





        /// <summary>
        ///       
        /// (     ,  1).
        /// </summary>
        /// <param name="formalListOfCityes"></param>
        public static void Printeceivedities (ObservableCollection<RootBasicCityInfo> formalListOfCityes)
        {
            string pattern = "=====\n" + "  : {0}\n" + "  : {1}\n"
            + " :  {2} \n" + ": {3}\n" + " : {4}\n"
            + ": {5}\n" + "====\n";
            int numberInList = 0;

            foreach (var item in formalListOfCityes)
            {
                WriteLine(pattern, numberInList.ToString(),
                item.EnglishName, item.LocalizedName, item.Country.LocalizedName,
                item.AdministrativeArea.LocalizedName, item.AdministrativeArea.LocalizedType);
                numberInList++;
            }

            Write ("     : ");
            int num = Convert.ToInt32(Console.ReadLine());

            try
            {
                listOfCityForMonitorWeather.Add(formalListOfCityes[num]);
            }

            catch (Exception ex)
            {
                WriteLine(",   .\n");
                WriteLine(ex.Message);
            }
            WriteListOfCityMonitoring();
        }

      
      



, ( APIKey)





         /// <summary>
        ///       
        ///   .
        /// </summary>
        private static void WriteListOfCityMonitoring()
        {
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(ObservableCollection<RootBasicCityInfo>));

            using (StreamWriter sw = new StreamWriter("RootBasicCityInfo.xml"))
            {
                xmlSerializer.Serialize(sw, listOfCityForMonitorWeather);
            }
        }

      
      



. , - 5 .





Json , , , .





Accuweather 1 , 5, 10 15 . json . Get .





, json :





  "Headline": {
    "EffectiveDate": "2021-02-23T07:00:00+03:00",
    "EffectiveEpochDate": 1614052800,
    "Severity": 3,
    "Text": "  : ",
    "Category": "cold",
    "EndDate": "2021-02-24T19:00:00+03:00",
    "EndEpochDate": 1614182400,
    "MobileLink": "http://m.accuweather.com/ru/ru/moscow/294021/extended-weather-forecast/294021?unit=c",
    "Link": "http://www.accuweather.com/ru/ru/moscow/294021/daily-weather-forecast/294021?unit=c"
  },
  "DailyForecasts": [
    {
      "Date": "2021-02-23T07:00:00+03:00",
      "EpochDate": 1614052800,
      "Temperature": {
        "Minimum": {
          "Value": -24.4,
          "Unit": "C",
          "UnitType": 17
        },
        "Maximum": {
          "Value": -20.6,
          "Unit": "C",
          "UnitType": 17
        }
      },
      "Day": {
        "Icon": 31,
        "IconPhrase": "",
        "HasPrecipitation": false
      },
      "Night": {
        "Icon": 31,
        "IconPhrase": "",
        "HasPrecipitation": false
      },
      "Sources": [
        "AccuWeather"
      ],
      "MobileLink": "http://m.accuweather.com/ru/ru/moscow/294021/daily-weather-forecast/294021?day=1&unit=c",
      "Link": "http://www.accuweather.com/ru/ru/moscow/294021/daily-weather-forecast/294021?day=1&unit=c"
    },

      
      



, :





    public class DailyForecast    {
        public DateTime Date { get; set; } 
        public int EpochDate { get; set; } 
        public Temperature Temperature { get; set; } 
        public Day Day { get; set; } 
        public Night Night { get; set; } 
        public List<string> Sources { get; set; } 
        public string MobileLink { get; set; } 
        public string Link { get; set; } 
    }
    

     public class RootWeather    {
        public Headline Headline { get; set; } 
        public List<DailyForecast> DailyForecasts { get; set; } 
    }

      
      



, ( ) . , , , :





            string pattern = "=====\n" + "  : {0}\n" + "  : {1}\n"
            + " :  {2} \n" + ": {3}\n" + " : {4}\n"
            + ": {5}\n" + "====\n";
            int numberInList = 0;

            foreach (var item in DataRepo.listOfCityForMonitorWeather)
            {
                WriteLine(pattern, numberInList.ToString(),
                item.EnglishName, item.LocalizedName, item.Country.LocalizedName,
                item.AdministrativeArea.LocalizedName, item.AdministrativeArea.LocalizedType);
                numberInList++;
            }
            
            bool ifNotExists = false;
            string cityKey = null;
            int num = 0;
            do
            {
                ifNotExists = false;
                Write("    : ");
                num = Convert.ToInt32(Console.ReadLine());
                
                if (num < 0 || num > DataRepo.listOfCityForMonitorWeather.Count - 1)
                {
                    WriteLine("  .   .");
                    ifNotExists = true;
                }
            } while(ifNotExists);
            
            cityKey = DataRepo.listOfCityForMonitorWeather[num].Key;

      
      



:





 //  ApiKey  
            string apiKey = UserApiManager.userApiList[0].UserApiProperty;
            
            string jsonUrl = $"http://dataservice.accuweather.com/forecasts/v1/daily/5day/{cityKey}?apikey={apiKey}&language=ru&metric=true";

            jsonUrl = webClient.DownloadString(jsonUrl);

            RootWeather weatherData = JsonSerializer.Deserialize<RootWeather>(jsonUrl);

            string patternWeather = "=====\n" + ": {0}\n" + " : {1}\n"
            +" : {2}\n" + "  : {3}\n" + "  : {4}\n" + "====\n";

            foreach (var item in weatherData.DailyForecasts)
            {
                WriteLine(patternWeather, item.Date, item.Temperature.Minimum.Value,
                item.Temperature.Maximum.Value, item.Day.IconPhrase, item.Night.IconPhrase);
            }
      
      



5 .





結論:この記事では、気象データを表示するために必要な要点を示しました。ユーティリティの完全なソースコードは、GitLabとGitHubにあります。また、この事件に対する批判や上級プログラマーからのアドバイスをいただければ幸いです。





お時間をいただきありがとうございます、頑張ってください!








All Articles