Lazarus Pascal İle Yahoo Hava Durumu Tahmini Nasıl Gösterilir?

Lazarus Pascal bilindiği platform bağımsız ve ücretsiz dağıtılan Pascal IDE olarak bilinir. Lazarus ile Windows, Mac ve Linux uygulamaları yapmak kolaydır.
Şimdi örnek olarak Lazarus ile Yahoo Hava Tahmin API leri kullanarak Lazarus ile uygulama yazıp nasıl gösteririz bir bakalım.
Yahoo SQL Benzeri Hava Tahmin Sorgulaması
Yahoo Hava Tahmin API sitesine girdiğinizde bildiğiniz SQL sorgu diline çok benzeyen bir YQL sorgulama dizilimi göreceksiniz.
Örnek olarak İstanbul için hava tahmini sorgulatmak için aşağıdaki göndermemiz gerekiyor.
SELECT * FROM weather.forecast WHERE woeid IN (SELECT woeid FROM geo.places(1) WHERE text="istanbul")
Burada İstanbul için hava tahmini almak isterken, Yahoo‘nun bir alt sorgu yaparak woe diye bilinen id’nin ne olduğunu bulmasını sağlıyoruz.
SELECT woeid FROM geo.places(1) WHERE text="istanbul"
Hava tahmini dönen değer: JSON veya XML
Yahoo tarafından verdiğimiz parametrelere göre sonucu JSON veya XML olarak seçebiliyoruz. Burada biz JSON kullanacağız.
Sorguyu gönderdiğimizde sorguyu gönderen URL aşağıdaki gibi olmaktadır.
https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22istanbul%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys
Şimdi Lazarus Pascal ile kodlarımızı yazmaya başlayalım. Öncelikle hava tahmin Unit olarak yazalım.
JSON verileri otomatik olarak ayrılacak ve bir kayıtta (TYahooForecast) saklanacaktır.Yahoo hava tahminini 10 günlük verdği için tek bir gün için ayrı TDayForecast ile günlük bakacağız.
TDayForcast = record code:string; date:string; day:string; high:string; low:string; text:string; end; TYahooForecast = record success:boolean; distance:string; pressure:string; speed:string; temperature:string; location_city:string; location_country:string; location_region:string; wind_chill:string; wind_direction:string; wind_speed:string; atmosphere_humidity:string; atmosphere_pressure:string; atmosphere_rising:string; atmosphere_visibility:string; astronomy_sunrise:string; astronomy_sunset:string; location_latitude:string; location_longitude:string; last_updated:string; current_code:string; current_date:string; current_temp:string; current_text:string; forecast: array [0..9] of TDayForcast; end;
Hva tahmini bilgisini almak için basitçe aşağıdakileri yazabiliriz.
// varsayılan olarak (Sisteminiz hangisi ayarlı ise Celsius/Fahrenheit) tmpData := GetYahooForecast('istanbul'); // Fahrenheit olarak istenirse tmpData := GetYahooForecast('istanbul','f'); // Celsius olarak istersek tmpData := GetYahooForecast('istanbul','c');
Herşeyin düzgün çalışıp veri geldiğini anlamak için aşağıdakini deneyelim:
if tmpData.success then begin with tmpData do begin memo1.lines.add('Uzaklık: '+distance); memo1.lines.add('Basınç: '+pressure); ... end; end else // VERİ GELMEMESİ DURUMUNDA YAPILACAKLAR
Görüldüğü üzere verilere ulaşmak çok kolay. Ancak unutmamalı ki gelen veriler 10 günlüktür. Yani bu durumda aşağıdaki gibi basit bir döngü ile gelen bilgileri parse edip 10 gün ayrı ayrı gösterebiliriz.
for Counter:=0 to 9 do begin memo1.lines.add('Kod: '+tmpdata.forecast[Counter].code); memo1.lines.add('Tarih: '+tmpdata.forecast[Counter].date); memo1.lines.add('Gün: ' +tmpdata.forecast[Counter].day); memo1.lines.add('Yüksek: '+tmpdata.forecast[Counter].high); memo1.lines.add('Düşük: ' +tmpdata.forecast[Counter].low); memo1.lines.add('Bilgi: '+tmpdata.forecast[Counter].text); end;
Burada TCP/IP üzerinden veri trafiği için ücretsiz olarak dağıtılan Synapse paketini kullanacağız. http://synapse.ararat.cz/lib/exe/fetch.php/file:synapse40.zip adresinden indirip zip dosyayı projenizin “/source/lib” kılasörü içine açınız.
Tüm kod aşağıdaki gibi olacaktır.
unit YahooWeather; { Unit to retrieve Yahoo Weather Forecast (C)2015 Hans Luijten, //www.tweaking4all.com Version 1.0 Uses: Synapse (http://synapse.ararat.cz/, fpjson (Comes with Lazarus) openssl (part of synapse, weather is retrieved with https://) Common use: GetYahooForecast(location); Retrieves current weather and weather forecast, and returns this in a record for easy access. } {$mode objfpc}{$H+} interface uses Classes, SysUtils, httpsend, ssl_openssl, fpjson, jsonparser; type TDayForcast = record code:string; date:string; day:string; high:string; low:string; text:string; end; TYahooForecast = record success:boolean; distance:string; pressure:string; speed:string; temperature:string; location_city:string; location_country:string; location_region:string; wind_chill:string; wind_direction:string; wind_speed:string; atmosphere_humidity:string; atmosphere_pressure:string; atmosphere_rising:string; atmosphere_visibility:string; astronomy_sunrise:string; astronomy_sunset:string; location_latitude:string; location_longitude:string; last_updated:string; current_code:string; current_date:string; current_temp:string; current_text:string; forecast: array [0..9] of TDayForcast; end; function GetYahooWeatherData(Location:string; AsJSON:boolean =true; TemperatureUnits:string = 'c'):string; function GetYahooForecast(Location:string; TemperatureUnits:string = 'c'):TYahooForecast; function YahooURLEncode(s: string): string; implementation { URLEncode Encodes string to be suitable as an URL. Example: myencodeURL:=YahooURLEncode(myURL); } function YahooURLEncode(s: string): string; var i: integer; source: PAnsiChar; begin result := ''; source := pansichar(s); for i := 1 to length(source) do if not (source[i - 1] in ['A'..'Z', 'a'..'z', '0'..'9', '-', '_', '~', '.', ':', '/']) then result := result + '%' + inttohex(ord(source[i - 1]), 2) else result := result + source[i - 1]; end; { Retrieve Yahoo Weather with forcast and place it in a record for easy access MyYahooForcast := GetYahooForecast('town,country',true,'c') } function GetYahooForecast(Location:string; TemperatureUnits:string = 'c'):TYahooForecast; var JSONData:TJSONData; RawData:string; tmpData:TYahooForecast; Counter:integer; begin RawData := GetYahooWeatherData(Location,true,TemperatureUnits); Counter:=0; while ((RawData='') or (pos('ERROR',RawData)>0)) and (Counter<3) do begin RawData := GetYahooWeatherData(Location,true,TemperatureUnits); inc(Counter); end; if ((RawData='') or (pos('ERROR',RawData)>0)) then tmpData.success:=false else begin JSONData := GetJSON(RawData); with tmpdata do begin success:=true; distance:=JSONData.FindPath('query.results.channel.units.distance').AsString; pressure:=JSONData.FindPath('query.results.channel.units.pressure').AsString; speed:=JSONData.FindPath('query.results.channel.units.speed').AsString; temperature:=JSONData.FindPath('query.results.channel.units.temperature').AsString; location_city:=JSONData.FindPath('query.results.channel.location.city').AsString; location_country:=JSONData.FindPath('query.results.channel.location.country').AsString; location_region:=JSONData.FindPath('query.results.channel.location.region').AsString; wind_chill:=JSONData.FindPath('query.results.channel.wind.chill').AsString; wind_direction:=JSONData.FindPath('query.results.channel.wind.direction').AsString; wind_speed:=JSONData.FindPath('query.results.channel.wind.speed').AsString; atmosphere_humidity:=JSONData.FindPath('query.results.channel.atmosphere.humidity').AsString; atmosphere_pressure:=JSONData.FindPath('query.results.channel.atmosphere.pressure').AsString; atmosphere_rising:=JSONData.FindPath('query.results.channel.atmosphere.rising').AsString; atmosphere_visibility:=JSONData.FindPath('query.results.channel.atmosphere.visibility').AsString; astronomy_sunrise:=JSONData.FindPath('query.results.channel.astronomy.sunrise').AsString; astronomy_sunset:=JSONData.FindPath('query.results.channel.astronomy.sunset').AsString; location_latitude:=JSONData.FindPath('query.results.channel.item.lat').AsString; location_longitude:=JSONData.FindPath('query.results.channel.item.long').AsString; last_updated:=JSONData.FindPath('query.results.channel.item.pubDate').AsString; current_code:=JSONData.FindPath('query.results.channel.item.condition.code').AsString; current_date:=JSONData.FindPath('query.results.channel.item.condition.date').AsString; current_temp:=JSONData.FindPath('query.results.channel.item.condition.temp').AsString; current_text:=JSONData.FindPath('query.results.channel.item.condition.text').AsString; for Counter:=0 to 9 do begin with tmpData.forecast[Counter] do begin code:=JSONData.FindPath('query.results.channel.item.forecast['+IntToStr(Counter)+'].code').AsString; date:=JSONData.FindPath('query.results.channel.item.forecast['+IntToStr(Counter)+'].date').AsString; day:=JSONData.FindPath('query.results.channel.item.forecast['+IntToStr(Counter)+'].day').AsString; high:=JSONData.FindPath('query.results.channel.item.forecast['+IntToStr(Counter)+'].high').AsString; low:=JSONData.FindPath('query.results.channel.item.forecast['+IntToStr(Counter)+'].low').AsString; text:=JSONData.FindPath('query.results.channel.item.forecast['+IntToStr(Counter)+'].text').AsString; end; end; end; end; GetYahooForecast := tmpData; end; { Retrieve Yahoo Weather information myString := GetYahooWeatherData('town,country',true,'c'); Location: typically use town,country, for example: 'osceola,wi.usa', 'amsterdam,netherlands', 'breda,nederland' AsJSON : return as a JSON string if TRUE, otherwise in XML format (JSON default) TemperatureUnits: 'c' for Celcius, and 'f' for Fahrentheit (C default) } function GetYahooWeatherData(Location:string; AsJSON:boolean =true; TemperatureUnits:string = 'c'):string; var HTTPSender : THTTPSend; tmpData : TStringList; resultString, resultFormat: String; begin if Location='' then GetYahooWeatherData:='ERROR: Missing Location' else begin if AsJSON then resultFormat := 'json' else resultFormat := 'xml'; tmpData := TStringList.Create; HTTPSender := THTTPSend.Create; try HTTPSender.HTTPMethod('GET', 'https://query.yahooapis.com/v1/public/yql?'+ 'q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20('+ // get forecast 'select%20woeid%20from%20geo.places(1)%20where%20text%3D%22'+YahooURLEncode(Location)+'%22)'+ // find location based on string '%20and%20u%3D%22'+TemperatureUnits+'%22'+ // force units (c or f) '&format='+resultFormat+'&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys'); if (HTTPSender.ResultCode >= 100) and (HTTPSender.ResultCode<=299) then tmpData.LoadFromStream(HTTPSender.Document) finally HTTPSender.Free; end; if tmpData.Text='' then resultString:='ERROR: Unable to retrieve data' else resultString:=tmpData.Text; tmpData.Free; GetYahooWeatherData := resultString; end; end; end.
Kodları indirmek için buraya tıklayınız.
Kaynak: https://www.tweaking4all.com/software-development/lazarus-development/yahoo-weather-forecast/