O que você precisa obter e aprender para começar a obter uma previsão do tempo para 5 dias?
Primeiro, escolha um provedor de dados meteorológicos. Em segundo lugar, para analisar de que forma os dados são fornecidos e como podemos coletá-los e exibi-los usando a linguagem de programação C #.
Escolhi o serviço Accuweather como meu provedor de dados meteorológicos. A conta gratuita atualmente permite 50 solicitações por dia. Isso é o suficiente para poder ver os dados meteorológicos várias vezes ao dia (você pode até compartilhá-los com um amigo!).
Para se inscrever, acesse o link: https://developer.accuweather.com . Após o registro, você precisa clicar no botão "Adicionar um novo aplicativo" e preencher um pequeno formulário. Como resultado, você receberá sua ApiKey pessoal com a qual poderá receber dados atualizados posteriormente.
Então a diversão começa. Analisaremos como e de que forma as informações chegam e o que é necessário para receber dados meteorológicos para uma determinada cidade.
Na seção "Referência da API", a primeira lista é definida para a seção " API de locais " com ela e vamos começar. Olhando para o futuro, direi imediatamente que você não pode simplesmente pegar e enviar o nome da cidade em uma solicitação GET. Para fazer isso, primeiro precisamos obter a Chave de Localização de uma cidade específica. Este valor é apresentado na forma de números e é único para cada cidade.
Portanto, na seção API de locais, estamos interessados no método City Search . Lemos uma breve descrição dele: Retorna informações para uma série de cidades que correspondem ao texto da pesquisa. Observe imediatamente que uma matriz com os nomes das cidades é retornada para nós.
Na página da solicitação, insira ApiKey, o nome da cidade de interesse e coloque RU, se quisermos receber dados localizados.
Após clicar no botão "Enviar esta solicitação" abaixo na página, você receberá o resultado da execução. No meu caso, é assim:
[
{
"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"
]
}
]
Como você pode ver, retornamos um array de uma cidade. Qual será o resultado se houver duas ou mais cidades com o mesmo nome:
[
{
"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 .
Em conclusão: neste artigo mostrei os principais pontos que foram necessários para que os dados meteorológicos fossem apresentados. O código-fonte completo do utilitário pode ser encontrado no GitLab e GitHub. Além disso, ficarei feliz com qualquer crítica ao caso e conselhos de programadores seniores.
https://gitlab.com/rammfire/habraweatherappconsole
https://github.com/rammfire/habraweatherappconsole
Obrigado pelo seu tempo, boa sorte!