Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- unit JD.Weather;
- (*
- ------------------------------------------------------------------------------
- XXXX XXXXXX XX XXXX XX XX XXXXXX XX
- XX XX XX XX XX XX XX XXX XXX XX XX
- XXXX XXXXX XXXXXX XX XX XX X XX XXXXX XX
- XX XX XX XX XX XX XX XX XX XX
- XX XX XXXXXX XX XX XXXX XX XX XXXXXX XX
- ------------------------------------------------------------------------------
- JD Weather
- by Jerry Dodge
- VERSION 2 (Replaces JD.Weather, JD.Weather.OpenWeatherMap, JD.Weather.WUnderground)
- Main Class:
- TJDWeather: TComponent
- Encapsulates entire API wrapper system to pull weather data from various
- different weather APIs.
- Features:
- - Adapts a standard structure to multiple different weather services
- - Dedicated thread to perform periodic checks on a given interval
- - Events triggered upon changes on conditions, forecast, alerts, and maps
- How to use:
- - Subscribe to one of the supported services
- - Acquire an API Key which authenticates your account
- - Select the service by assigning TJDWeather.Service
- - Enter your API Key by assigning TJDWeather.Key
- - Specify the frequency of each different weather information type
- NOTE: The numbers are seconds between calls
- IMPORTANT: Depending on which service you choose, your account will be likely
- limited to a certain number of requests in a given day. Therefore, it is
- very important to adjust these frequency properties to correspond with
- your particular account's capabilities. Sometimes, this may mean
- ten to twenty minutes between checks for weather, if your account
- has a low limit, or if you use the app in multiple places.
- - Select your desired location by assigning TJDWeather.LocationType
- - wlAutoIP: Automatically detects your location based on your IP Address
- - wlCityState: Assign City to "LocationDetail1" and State to "LocationDetail2"
- - wlZip: Assign Zip Code to "LocationDetail1"
- - wlCoords: Assign Longitude to "LocationDetail1" and Latitude to "LocationDetail2"
- NOTE: Format of each property must be with numeric digits such as:
- 45.9764
- -15.9724
- - Assign event handlers to the desired weather information
- NOTE: Weather information is actually provided when these events are fired.
- You are responsible to acquire a copy of the corresponding weather interface
- from the event handler's parameters and store your own reference.
- These interfaces are by default reference-counted.
- SUPPORTED WEATHER SERVICES:
- - Weather Underground https://www.wunderground.com/weather/api/d/docs?d=index
- - [Coming Soon] Open Weather Maps https://openweathermap.org/api
- - [Coming Soon] National Weather Service http://forecast-v3.weather.gov/documentation
- - [Coming Soon] Accu Weather http://apidev.accuweather.com/developers/
- - [Coming Soon] NOAA https://www.ncdc.noaa.gov/cdo-web/webservices/v2#gettingStarted
- TODO:
- - Implement "Supported..." functions to reflect what each service supports
- - Implement caching of weather data as to not fetch too often
- - Implement weather maps
- - Radar
- - Satellite
- - Radar AND Satellite Combined
- - Standardize the forecast formats
- - Hourly - X number of hours
- - Daily - X number of days
- - Summary - Half day, plain text
- - Finish implementing all services
- - OpenWeatherMap
- - Migrate from original API wrapper V1
- - Weather Underground
- - Detailed Forecast (Hourly/Daily)
- - Maps
- - National Weather Service
- - AccuWeather
- - NOAA
- *)
- interface
- uses
- System.Classes, System.SysUtils, System.Generics.Collections,
- Vcl.Graphics, Vcl.Imaging.Jpeg, Vcl.Imaging.PngImage, Vcl.Imaging.GifImg,
- SuperObject,
- IdHTTP;
- type
- TWeatherService = (wsOpenWeatherMap, wsWUnderground, wsNWS,
- wsNOAA, wsAccuWeather);
- TWeatherUnits = (wuKelvin, wuImperial, wuMetric);
- TWeatherAlertType = (waNone, waHurricaneStat, waTornadoWarn, waTornadoWatch, waSevThundWarn,
- waSevThundWatch, waWinterAdv, waFloodWarn, waFloodWatch, waHighWind, waSevStat,
- waHeatAdv, waFogAdv, waSpecialStat, waFireAdv, waVolcanicStat, waHurricaneWarn,
- waRecordSet, waPublicRec, waPublicStat);
- TWeatherAlertPhenomena = (wpWind, wpHeat, wpSmallCraft);
- //Interface Definitions
- {$REGION "Interface Definitions"}
- IWeatherLocation = interface
- function GetDisplayName: WideString;
- function GetCity: WideString;
- function GetState: WideString;
- function GetStateAbbr: WideString;
- function GetCountry: WideString;
- function GetCountryAbbr: WideString;
- function GetLongitude: Double;
- function GetLatitude: Double;
- function GetElevation: Double;
- function GetZipCode: WideString;
- property DisplayName: WideString read GetDisplayName;
- property City: WideString read GetCity;
- property State: WideString read GetState;
- property StateAbbr: WideString read GetStateAbbr;
- property Country: WideString read GetCountry;
- property CountryAbbr: WideString read GetCountryAbbr;
- property Longitude: Double read GetLongitude;
- property Latitude: Double read GetLatitude;
- property Elevation: Double read GetElevation;
- property ZipCode: WideString read GetZipCode;
- end;
- TWeatherConditionsProp = (cpPressureMB, cpPressureIn, cpWindDir, cpWindSpeed,
- cpHumidity, cpVisibility, cpDewPoint, cpHeatIndex, cpWindGust, cpWindChill,
- cpFeelsLike, cpSolarRad, cpUV, cpTemp, cpTempMin, cpTempMax, cpPrecip,
- cpIcon, cpCaption, cpDescription, cpStation, cpClouds,
- cpRain, cpSnow, cpSunrise, cpSunset);
- TWeatherConditionsProps = set of TWeatherConditionsProp;
- IWeatherConditions = interface
- function GetPicture: TPicture;
- function GetLocation: IWeatherLocation;
- function GetDateTime: TDateTime;
- function GetTemp: Single;
- function GetHumidity: Single;
- function GetPressure: Single;
- function GetCondition: WideString;
- function GetDescription: WideString;
- function GetWindDir: Single;
- function GetWindSpeed: Single;
- function GetVisibility: Single;
- function GetDewPoint: Single;
- function SupportedProps: TWeatherConditionsProps;
- property Picture: TPicture read GetPicture;
- property Location: IWeatherLocation read GetLocation;
- property DateTime: TDateTime read GetDateTime;
- property Temp: Single read GetTemp;
- property Humidity: Single read GetHumidity;
- property Pressure: Single read GetPressure;
- property Condition: WideString read GetCondition;
- property Description: WideString read GetDescription;
- property WindSpeed: Single read GetWindSpeed;
- property WindDir: Single read GetWindDir;
- property Visibility: Single read GetVisibility;
- property DewPoint: Single read GetDewPoint;
- end;
- TWeatherForecastProp = (fpPressureMB, fpPressureIn, fpWindDir, fpWindSpeed,
- fpHumidity, fpVisibility, fpDewPoint, fpHeatIndex, fpWindGust, fpWindChill,
- fpFeelsLike, fpSolarRad, fpUV, fpTemp, fpTempMin, fpTempMax, fpCaption,
- fpDescription, fpIcon, fpGroundPressure, fpSeaPressure, fpPrecip, fpURL, fpDaylight);
- TWeatherForecastProps = set of TWeatherForecastProp;
- IWeatherForecastItem = interface
- function GetPicture: TPicture;
- function GetDateTime: TDateTime;
- function GetTemp: Single;
- function GetTempMax: Single;
- function GetTempMin: Single;
- function GetHumidity: Single;
- function GetPressure: Single;
- function GetCondition: WideString;
- function GetDescription: WideString;
- function GetWindDir: Single;
- function GetWindSpeed: Single;
- function GetVisibility: Single;
- function GetDewPoint: Single;
- function SupportedProps: TWeatherForecastProps;
- property Picture: TPicture read GetPicture;
- property DateTime: TDateTime read GetDateTime;
- property Temp: Single read GetTemp;
- property TempMin: Single read GetTempMin;
- property TempMax: Single read GetTempMax;
- property Humidity: Single read GetHumidity;
- property Pressure: Single read GetPressure;
- property Condition: WideString read GetCondition;
- property Description: WideString read GetDescription;
- property WindSpeed: Single read GetWindSpeed;
- property WindDir: Single read GetWindDir;
- property Visibility: Single read GetVisibility;
- property DewPoint: Single read GetDewPoint;
- end;
- IWeatherForecast = interface
- function GetLocation: IWeatherLocation;
- function GetItem(const Index: Integer): IWeatherForecastItem;
- function Count: Integer;
- function MinTemp: Single;
- function MaxTemp: Single;
- property Location: IWeatherLocation read GetLocation;
- property Items[const Index: Integer]: IWeatherForecastItem read GetItem; default;
- end;
- IWeatherAlertZone = interface
- function GetState: WideString;
- function GetZone: WideString;
- property State: WideString read GetState;
- property Zone: WideString read GetZone;
- end;
- IWeatherAlertZones = interface
- function GetItem(const Index: Integer): IWeatherAlertZone;
- function Count: Integer;
- property Items[const Index: Integer]: IWeatherAlertZone read GetItem; default;
- end;
- IWeatherStormVertex = interface
- function GetLongitude: Double;
- function GetLatitude: Double;
- property Longitude: Double read GetLongitude;
- property Latitude: Double read GetLatitude;
- end;
- IWeatherStormVerticies = interface
- function GetItem(const Index: Integer): IWeatherStormVertex;
- function Count: Integer;
- property Items[const Index: Integer]: IWeatherStormVertex read GetItem; default;
- end;
- IWeatherAlertStorm = interface
- function GetDateTime: TDateTime;
- function GetDirection: Single;
- function GetSpeed: Single;
- function GetLongitude: Double;
- function GetLatitude: Double;
- function GetVerticies: IWeatherStormVerticies;
- property DateTime: TDateTime read GetDateTime;
- property Direction: Single read GetDirection;
- property Speed: Single read GetDirection;
- property Longitude: Double read GetLongitude;
- property Latitude: Double read GetLatitude;
- property Verticies: IWeatherStormVerticies read GetVerticies;
- end;
- TWeatherAlertProp = (apZones, apVerticies, apStorm, apType, apDescription,
- apExpires, apMessage, apPhenomena, apSignificance);
- TWeatherAlertProps = set of TWeatherAlertProp;
- IWeatherAlert = interface
- function GetAlertType: TWeatherAlertType;
- function GetDescription: WideString;
- function GetDateTime: TDateTime;
- function GetExpires: TDateTime;
- function GetMsg: WideString;
- function GetPhenomena: WideString;
- function GetSignificance: WideString;
- function GetZones: IWeatherAlertZones;
- function GetStorm: IWeatherAlertStorm;
- function SupportedFunctions: TWeatherAlertProps;
- property AlertType: TWeatherAlertType read GetAlertType;
- property Description: WideString read GetDescription;
- property DateTime: TDateTime read GetDateTime;
- property Expires: TDateTime read GetExpires;
- property Msg: WideString read GetMsg;
- property Phenomena: WideString read GetPhenomena;
- property Significance: WideString read GetSignificance;
- property Zones: IWeatherAlertZones read GetZones;
- property Storm: IWeatherAlertStorm read GetStorm;
- end;
- IWeatherAlerts = interface
- function GetItem(const Index: Integer): IWeatherAlert;
- function Count: Integer;
- property Items[const Index: Integer]: IWeatherAlert read GetItem; default;
- end;
- TWeatherMapType = (mpSatellite, mpRadar, mpSatelliteRadar, mpRadarClouds,
- mpClouds, mpTemp, mpTempChange, mpSnowCover, mpPrecip, mpAlerts, mpHeatIndex,
- mpDewPoint, mpWindChill, mpPressureSea, mpWind);
- TWeatherMapTypes = set of TWeatherMapType;
- IWeatherMaps = interface
- function GetMap(const MapType: TWeatherMapType): TPicture;
- function SupportedFunctions: TWeatherMapTypes;
- property Maps[const MapType: TWeatherMapType]: TPicture read GetMap;
- end;
- {$ENDREGION}
- //Interface Implementation Objects
- {$REGION "Interface Implementation Objects"}
- { Interface Implementation Objects }
- TJDWeatherThread = class;
- TWeatherLocation = class(TInterfacedObject, IWeatherLocation)
- private
- FDisplayName: WideString;
- FCity: WideString;
- FState: WideString;
- FStateAbbr: WideString;
- FCountry: WideString;
- FCountryAbbr: WideString;
- FLongitude: Double;
- FLatitude: Double;
- FElevation: Double;
- FZipCode: WideString;
- public
- constructor Create;
- destructor Destroy; override;
- public
- function GetDisplayName: WideString;
- function GetCity: WideString;
- function GetState: WideString;
- function GetStateAbbr: WideString;
- function GetCountry: WideString;
- function GetCountryAbbr: WideString;
- function GetLongitude: Double;
- function GetLatitude: Double;
- function GetElevation: Double;
- function GetZipCode: WideString;
- property DisplayName: WideString read GetDisplayName;
- property City: WideString read GetCity;
- property State: WideString read GetState;
- property StateAbbr: WideString read GetStateAbbr;
- property Country: WideString read GetCountry;
- property CountryAbbr: WideString read GetCountryAbbr;
- property Longitude: Double read GetLongitude;
- property Latitude: Double read GetLatitude;
- property Elevation: Double read GetElevation;
- property ZipCode: WideString read GetZipCode;
- end;
- TWeatherConditions = class(TInterfacedObject, IWeatherConditions)
- private
- FPicture: TPicture;
- FOwner: TJDWeatherThread;
- FLocation: TWeatherLocation;
- FDateTime: TDateTime;
- FTemp: Single;
- FHumidity: Single;
- FPressure: Single;
- FCondition: WideString;
- FDescription: WideString;
- FWindSpeed: Single;
- FWindDir: Single;
- FVisibility: Single;
- FDewPoint: Single;
- public
- constructor Create(AOwner: TJDWeatherThread);
- destructor Destroy; override;
- public
- function GetPicture: TPicture;
- function GetLocation: IWeatherLocation;
- function GetDateTime: TDateTime;
- function GetTemp: Single;
- function GetHumidity: Single;
- function GetPressure: Single;
- function GetCondition: WideString;
- function GetDescription: WideString;
- function GetWindDir: Single;
- function GetWindSpeed: Single;
- function GetVisibility: Single;
- function GetDewPoint: Single;
- function SupportedProps: TWeatherConditionsProps;
- property Picture: TPicture read GetPicture;
- property Location: IWeatherLocation read GetLocation;
- property DateTime: TDateTime read GetDateTime;
- property Temp: Single read GetTemp;
- property Humidity: Single read GetHumidity;
- property Pressure: Single read GetPressure;
- property Condition: WideString read GetCondition;
- property Description: WideString read GetDescription;
- property WindSpeed: Single read GetWindSpeed;
- property WindDir: Single read GetWindDir;
- property Visibility: Single read GetVisibility;
- property DewPoint: Single read GetDewPoint;
- end;
- TWeatherForecast = class;
- TWeatherForecastItem = class(TInterfacedObject, IWeatherForecastItem)
- private
- FOwner: TWeatherForecast;
- FPicture: TPicture;
- FDateTime: TDateTime;
- FTemp: Single;
- FTempMin: Single;
- FTempMax: Single;
- FHumidity: Single;
- FPressure: Single;
- FCondition: WideString;
- FDescription: WideString;
- FWindSpeed: Single;
- FWindDir: Single;
- FVisibility: Single;
- FDewPoint: Single;
- public
- constructor Create(AOwner: TWeatherForecast);
- destructor Destroy; override;
- public
- function GetPicture: TPicture;
- function GetDateTime: TDateTime;
- function GetTemp: Single;
- function GetTempMax: Single;
- function GetTempMin: Single;
- function GetHumidity: Single;
- function GetPressure: Single;
- function GetCondition: WideString;
- function GetDescription: WideString;
- function GetWindDir: Single;
- function GetWindSpeed: Single;
- function GetVisibility: Single;
- function GetDewPoint: Single;
- function SupportedProps: TWeatherForecastProps;
- property Picture: TPicture read GetPicture;
- property DateTime: TDateTime read GetDateTime;
- property Temp: Single read GetTemp;
- property TempMin: Single read GetTempMin;
- property TempMax: Single read GetTempMax;
- property Humidity: Single read GetHumidity;
- property Pressure: Single read GetPressure;
- property Condition: WideString read GetCondition;
- property Description: WideString read GetDescription;
- property WindSpeed: Single read GetWindSpeed;
- property WindDir: Single read GetWindDir;
- property Visibility: Single read GetVisibility;
- property DewPoint: Single read GetDewPoint;
- end;
- TWeatherForecast = class(TInterfacedObject, IWeatherForecast)
- private
- FOwner: TJDWeatherThread;
- FItems: TList<IWeatherForecastItem>;
- FLocation: TWeatherLocation;
- procedure Clear;
- public
- constructor Create(AOwner: TJDWeatherThread);
- destructor Destroy; override;
- public
- function GetLocation: IWeatherLocation;
- function GetItem(const Index: Integer): IWeatherForecastItem;
- function Count: Integer;
- function MinTemp: Single;
- function MaxTemp: Single;
- property Location: IWeatherLocation read GetLocation;
- property Items[const Index: Integer]: IWeatherForecastItem read GetItem; default;
- end;
- TWeatherStormVertex = class(TInterfacedObject, IWeatherStormVertex)
- private
- FLongitude: Double;
- FLatitude: Double;
- public
- function GetLongitude: Double;
- function GetLatitude: Double;
- property Longitude: Double read GetLongitude;
- property Latitude: Double read GetLatitude;
- end;
- TWeatherStormVerticies = class(TInterfacedObject, IWeatherStormVerticies)
- private
- FItems: TList<IWeatherStormVertex>;
- procedure Clear;
- public
- constructor Create;
- destructor Destroy; override;
- public
- function GetItem(const Index: Integer): IWeatherStormVertex;
- function Count: Integer;
- property Items[const Index: Integer]: IWeatherStormVertex read GetItem; default;
- end;
- TWeatherAlertStorm = class(TInterfacedObject, IWeatherAlertStorm)
- private
- FDateTime: TDateTime;
- FDirection: Single;
- FSpeed: Single;
- FLongitude: Double;
- FLatitude: Double;
- FVerticies: TWeatherStormVerticies;
- public
- constructor Create;
- destructor Destroy; override;
- public
- function GetDateTime: TDateTime;
- function GetDirection: Single;
- function GetSpeed: Single;
- function GetLongitude: Double;
- function GetLatitude: Double;
- function GetVerticies: IWeatherStormVerticies;
- property DateTime: TDateTime read GetDateTime;
- property Direction: Single read GetDirection;
- property Speed: Single read GetDirection;
- property Longitude: Double read GetLongitude;
- property Latitude: Double read GetLatitude;
- property Verticies: IWeatherStormVerticies read GetVerticies;
- end;
- TWeatherAlertZone = class(TInterfacedObject, IWeatherAlertZone)
- private
- FState: WideString;
- FZone: WideString;
- public
- function GetState: WideString;
- function GetZone: WideString;
- property State: WideString read GetState;
- property Zone: WideString read GetZone;
- end;
- TWeatherAlertZones = class(TInterfacedObject, IWeatherAlertZones)
- private
- FItems: TList<TWeatherAlertZone>;
- procedure Clear;
- public
- constructor Create;
- destructor Destroy; override;
- public
- function GetItem(const Index: Integer): IWeatherAlertZone;
- function Count: Integer;
- property Items[const Index: Integer]: IWeatherAlertZone read GetItem; default;
- end;
- TWeatherAlert = class(TInterfacedObject, IWeatherAlert)
- private
- FOwner: TJDWeatherThread;
- FAlertType: TWeatherAlertType;
- FDescription: WideString;
- FDateTime: TDateTime;
- FExpires: TDateTime;
- FMsg: WideString;
- FPhenomena: WideString;
- FSignificance: WideString;
- FZones: TWeatherAlertZones;
- FStorm: TWeatherAlertStorm;
- public
- constructor Create(AOwner: TJDWeatherThread);
- destructor Destroy; override;
- public
- function GetAlertType: TWeatherAlertType;
- function GetDescription: WideString;
- function GetDateTime: TDateTime;
- function GetExpires: TDateTime;
- function GetMsg: WideString;
- function GetPhenomena: WideString;
- function GetSignificance: WideString;
- function GetZones: IWeatherAlertZones;
- function GetStorm: IWeatherAlertStorm;
- function SupportedFunctions: TWeatherAlertProps;
- property AlertType: TWeatherAlertType read GetAlertType;
- property Description: WideString read GetDescription;
- property DateTime: TDateTime read GetDateTime;
- property Expires: TDateTime read GetExpires;
- property Msg: WideString read GetMsg;
- property Phenomena: WideString read GetPhenomena;
- property Significance: WideString read GetSignificance;
- property Zones: IWeatherAlertZones read GetZones;
- property Storm: IWeatherAlertStorm read GetStorm;
- end;
- TWeatherAlerts = class(TInterfacedObject, IWeatherAlerts)
- private
- FItems: TList<IWeatherAlert>;
- procedure Clear;
- public
- constructor Create;
- destructor Destroy; override;
- public
- function GetItem(const Index: Integer): IWeatherAlert;
- function Count: Integer;
- property Items[const Index: Integer]: IWeatherAlert read GetItem; default;
- end;
- TMapArray = array[TWeatherMapType] of TPicture;
- TWeatherMaps = class(TInterfacedObject, IWeatherMaps)
- private
- FOwner: TJDWeatherThread;
- FMaps: TMapArray;
- public
- constructor Create(AOwner: TJDWeatherThread);
- destructor Destroy; override;
- public
- function GetMap(const MapType: TWeatherMapType): TPicture;
- function SupportedFunctions: TWeatherMapTypes;
- property Maps[const MapType: TWeatherMapType]: TPicture read GetMap;
- end;
- {$ENDREGION}
- //Service Threads
- {$REGION "Service Threads"}
- { Service Specific Thread Base }
- TJDWeatherLocationType = (wlZip, wlCityState, wlCoords, wlAutoIP);
- TWeatherConditionsEvent = procedure(Sender: TObject; const Conditions: IWeatherConditions) of object;
- TWeatherForecastEvent = procedure(Sender: TObject; const Forecast: IWeatherForecast) of object;
- TWeatherAlertEvent = procedure(Sender: TObject; const Alert: IWeatherAlerts) of object;
- TWeatherMapEvent = procedure(Sender: TObject; const Image: IWeatherMaps) of object;
- TJDWeather = class;
- TWeatherThreadFunction = (tfConditionByZip, tfConditionByCoords, tfConditionByCity,
- tfConditionByIP, tafForecastByZip, tfForecastByCoords, tfForecastByCity, tfForecastByIP,
- tfAlertsByZip, tfAlertsByCoords, tfAlertsByCity, tfAlertsByIP, tfMapsByZip,
- tfMapsByCoords, tfMapsByCity, tfMapsByIP);
- TWeatherThreadFunctions = set of TWeatherThreadFunction;
- TJDWeatherThread = class(TThread)
- private
- FOwner: TJDWeather;
- FWeb: TIdHTTP;
- FConditions: TWeatherConditions;
- FLastConditions: TDateTime;
- FForecast: TWeatherForecast;
- FLastForecast: TDateTime;
- FMaps: TWeatherMaps;
- FLastMaps: TDateTime;
- FAlerts: TWeatherAlerts;
- FLastAlerts: TDateTime;
- FOnConditions: TWeatherConditionsEvent;
- FOnForecast: TWeatherForecastEvent;
- FOnAlerts: TWeatherAlertEvent;
- FOnMaps: TWeatherMapEvent;
- procedure CheckConditions;
- procedure CheckForecast;
- procedure CheckAlerts;
- procedure CheckMaps;
- function LoadPicture(const U: String; const P: TPicture): Boolean;
- protected
- procedure Execute; override;
- procedure Process;
- procedure SYNC_DoOnConditions;
- procedure SYNC_DoOnForecast;
- procedure SYNC_DoOnAlerts;
- procedure SYNC_DoOnMaps;
- public
- constructor Create(AOwner: TJDWeather); reintroduce;
- destructor Destroy; override;
- public
- property OnConditions: TWeatherConditionsEvent read FOnConditions write FOnConditions;
- property OnForecast: TWeatherForecastEvent read FOnForecast write FOnForecast;
- property OnAlerts: TWeatherAlertEvent read FOnAlerts write FOnAlerts;
- property OnMaps: TWeatherMapEvent read FOnMaps write FOnMaps;
- public
- function Support: TWeatherThreadFunctions; virtual; abstract;
- function GetUrl: String; virtual; abstract;
- function DoConditions(Conditions: TWeatherConditions): Boolean; virtual; abstract;
- function DoForecast(Forecast: TWeatherForecast): Boolean; virtual; abstract;
- function DoAlerts(Alerts: TWeatherAlerts): Boolean; virtual; abstract;
- function DoMaps(Maps: TWeatherMaps): Boolean; virtual; abstract;
- end;
- { Service Specific Thread Implementation }
- { OpenWeatherMap Service }
- TOWMEndpoint = (oeConditions, oeForecast, oeAlerts, oeMaps);
- TOWMWeatherThread = class(TJDWeatherThread)
- public
- function GetEndpointUrl(const Endpoint: TOWMEndpoint): String;
- public
- function Support: TWeatherThreadFunctions; override;
- function GetUrl: String; override;
- function DoConditions(Conditions: TWeatherConditions): Boolean; override;
- function DoForecast(Forecast: TWeatherForecast): Boolean; override;
- function DoAlerts(Alerts: TWeatherAlerts): Boolean; override;
- function DoMaps(Maps: TWeatherMaps): Boolean; override;
- end;
- { Weather Underground Service }
- TWUEndpoint = (weAlerts, weAlmanac, weAstronomy, weConditions,
- weCurrentHurricane, weForecast, weForecast10Day, weGeoLookup, weHistory,
- weHourly, weHourly10Day, wePlanner, weRawTide, weTide, weWebCams, weYesterday,
- weRadar, weSatellite, weRadarSatellite);
- TWUForecastType = (wfSummary, wfDetail);
- TWUWeatherThread = class(TJDWeatherThread)
- public
- procedure FillConditions(const O: ISuperObject; Conditions: TWeatherConditions);
- procedure FillForecast(const O: ISuperObject; Forecast: TWeatherForecast; const ForecastType: TWUForecastType);
- procedure FillAlerts(const O: ISuperObject; Alerts: TWeatherAlerts);
- procedure FillMaps(const O: ISuperObject; Maps: TWeatherMaps);
- function GetEndpointUrl(const Endpoint: TWUEndpoint): String;
- public
- function Support: TWeatherThreadFunctions; override;
- function GetUrl: String; override;
- function DoConditions(Conditions: TWeatherConditions): Boolean; override;
- function DoForecast(Forecast: TWeatherForecast): Boolean; override;
- function DoAlerts(Alerts: TWeatherAlerts): Boolean; override;
- function DoMaps(Maps: TWeatherMaps): Boolean; override;
- end;
- { National Weather Service }
- TNWSWeatherThread = class(TJDWeatherThread)
- public
- public
- function Support: TWeatherThreadFunctions; override;
- function GetUrl: String; override;
- function DoConditions(Conditions: TWeatherConditions): Boolean; override;
- function DoForecast(Forecast: TWeatherForecast): Boolean; override;
- function DoAlerts(Alerts: TWeatherAlerts): Boolean; override;
- function DoMaps(Maps: TWeatherMaps): Boolean; override;
- end;
- { NOAA Service}
- TNOAAEndpoint = (noeDatasets, noeDataCategories, noeDataTypes, noeLocationCategories,
- noeLocations, noeStations, noeData);
- TNOAAWeatherThread = class(TJDWeatherThread)
- public
- function GetEndpointUrl(const Endpoint: TNOAAEndpoint): String;
- public
- function Support: TWeatherThreadFunctions; override;
- function GetUrl: String; override;
- function DoConditions(Conditions: TWeatherConditions): Boolean; override;
- function DoForecast(Forecast: TWeatherForecast): Boolean; override;
- function DoAlerts(Alerts: TWeatherAlerts): Boolean; override;
- function DoMaps(Maps: TWeatherMaps): Boolean; override;
- end;
- { AccuWeather Service }
- TAWEndpoint = (aeLocations, aeConditions, aeAlerts, aeDailyIndices,
- aeAlarms, aeClimo, aeTropical, aeTidal, aeDaily, aeHourly, aeImagery,
- aeTranslate, aeLocal);
- TAWWeatherThread = class(TJDWeatherThread)
- private
- FLocationKey: String;
- FLocationType: TJDWeatherLocationType;
- FLocation1: String;
- FLocation2: String;
- FLocation: ISuperObject;
- function Get(const U: String): ISuperObject;
- public
- function GetEndpointUrl(const Endpoint: TAWEndpoint;
- const S: String): String;
- procedure InvalidateLocation;
- procedure CheckLocation;
- public
- function Support: TWeatherThreadFunctions; override;
- function GetUrl: String; override;
- function DoConditions(Conditions: TWeatherConditions): Boolean; override;
- function DoForecast(Forecast: TWeatherForecast): Boolean; override;
- function DoAlerts(Alerts: TWeatherAlerts): Boolean; override;
- function DoMaps(Maps: TWeatherMaps): Boolean; override;
- end;
- {$ENDREGION}
- //Main Component
- {$REGION "Main Component"}
- { Main Component }
- TJDWeather = class(TComponent)
- private
- FThread: TJDWeatherThread;
- FService: TWeatherService;
- FActive: Boolean;
- FConditionFreq: Integer;
- FForecastFreq: Integer;
- FMapsFreq: Integer;
- FAlertsFreq: Integer;
- FOnConditions: TWeatherConditionsEvent;
- FOnForecast: TWeatherForecastEvent;
- FOnAlerts: TWeatherAlertEvent;
- FOnMaps: TWeatherMapEvent;
- FKey: String;
- FLocationType: TJDWeatherLocationType;
- FLocationDetail2: String;
- FLocationDetail1: String;
- FUnits: TWeatherUnits;
- procedure EnsureThread;
- procedure DestroyThread;
- procedure ThreadConditions(Sender: TObject; const Conditions: IWeatherConditions);
- procedure ThreadForecast(Sender: TObject; const Forecast: IWeatherForecast);
- procedure ThreadAlerts(Sender: TObject; const Alert: IWeatherAlerts);
- procedure ThreadMaps(Sender: TObject; const Maps: IWeatherMaps);
- procedure SetService(const Value: TWeatherService);
- procedure SetConditionFreq(const Value: Integer);
- procedure SetForecastFreq(const Value: Integer);
- procedure SetActive(const Value: Boolean);
- procedure SetMapsFreq(const Value: Integer);
- procedure SetKey(const Value: String);
- procedure SetLocationType(const Value: TJDWeatherLocationType);
- procedure SetLocationDetail1(const Value: String);
- procedure SetLocationDetail2(const Value: String);
- procedure SetAlertsFreq(const Value: Integer);
- procedure SetUnits(const Value: TWeatherUnits);
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- published
- property Service: TWeatherService read FService write SetService;
- property Active: Boolean read FActive write SetActive;
- property ConditionFreq: Integer read FConditionFreq write SetConditionFreq;
- property ForecastFreq: Integer read FForecastFreq write SetForecastFreq;
- property MapsFreq: Integer read FMapsFreq write SetMapsFreq;
- property AlertsFreq: Integer read FAlertsFreq write SetAlertsFreq;
- property Key: String read FKey write SetKey;
- property LocationType: TJDWeatherLocationType read FLocationType write SetLocationType;
- property LocationDetail1: String read FLocationDetail1 write SetLocationDetail1;
- property Units: TWeatherUnits read FUnits write SetUnits;
- property LocationDetail2: String read FLocationDetail2 write SetLocationDetail2;
- property OnConditions: TWeatherConditionsEvent read FOnConditions write FOnConditions;
- property OnForecast: TWeatherForecastEvent read FOnForecast write FOnForecast;
- property OnAlerts: TWeatherAlertEvent read FOnAlerts write FOnAlerts;
- property OnMaps: TWeatherMapEvent read FOnMaps write FOnMaps;
- end;
- {$ENDREGION}
- implementation
- uses
- DateUtils, StrUtils, Math;
- //Common Object Implementation
- {$REGION "Common Object Implementation"}
- { TWeatherLocation }
- constructor TWeatherLocation.Create;
- begin
- end;
- destructor TWeatherLocation.Destroy;
- begin
- inherited;
- end;
- function TWeatherLocation.GetCity: WideString;
- begin
- Result:= FCity;
- end;
- function TWeatherLocation.GetCountry: WideString;
- begin
- Result:= FCountry;
- end;
- function TWeatherLocation.GetCountryAbbr: WideString;
- begin
- Result:= FCountryAbbr;
- end;
- function TWeatherLocation.GetDisplayName: WideString;
- begin
- Result:= FDisplayName;
- end;
- function TWeatherLocation.GetElevation: Double;
- begin
- Result:= FElevation;
- end;
- function TWeatherLocation.GetLatitude: Double;
- begin
- Result:= FLatitude;
- end;
- function TWeatherLocation.GetLongitude: Double;
- begin
- Result:= FLongitude;
- end;
- function TWeatherLocation.GetState: WideString;
- begin
- Result:= FState;
- end;
- function TWeatherLocation.GetStateAbbr: WideString;
- begin
- Result:= FStateAbbr;
- end;
- function TWeatherLocation.GetZipCode: WideString;
- begin
- Result:= FZipCode;
- end;
- { TWeatherConditions }
- constructor TWeatherConditions.Create(AOwner: TJDWeatherThread);
- begin
- FOwner:= AOwner;
- FLocation:= TWeatherLocation.Create;
- FLocation._AddRef;
- FPicture:= TPicture.Create;
- end;
- destructor TWeatherConditions.Destroy;
- begin
- FPicture.Free;
- FLocation._Release;
- FLocation:= nil;
- inherited;
- end;
- function TWeatherConditions.GetCondition: WideString;
- begin
- Result:= FCondition;
- end;
- function TWeatherConditions.GetDateTime: TDateTime;
- begin
- Result:= FDateTime;
- end;
- function TWeatherConditions.GetDescription: WideString;
- begin
- Result:= FDescription;
- end;
- function TWeatherConditions.GetDewPoint: Single;
- begin
- Result:= FDewPoint;
- end;
- function TWeatherConditions.GetHumidity: Single;
- begin
- Result:= FHumidity;
- end;
- function TWeatherConditions.GetLocation: IWeatherLocation;
- begin
- Result:= FLocation;
- end;
- function TWeatherConditions.GetPicture: TPicture;
- begin
- Result:= FPicture;
- end;
- function TWeatherConditions.GetPressure: Single;
- begin
- Result:= FPressure;
- end;
- function TWeatherConditions.GetTemp: Single;
- begin
- Result:= FTemp;
- end;
- function TWeatherConditions.GetVisibility: Single;
- begin
- Result:= FVisibility;
- end;
- function TWeatherConditions.GetWindDir: Single;
- begin
- Result:= FWindDir;
- end;
- function TWeatherConditions.GetWindSpeed: Single;
- begin
- Result:= FWindSpeed;
- end;
- function TWeatherConditions.SupportedProps: TWeatherConditionsProps;
- begin
- case FOwner.FOwner.FService of
- wsOpenWeatherMap: Result:= [cpPressureMb, cpWindDir, cpWindSpeed,
- cpVisibility, cpHumidity, cpCaption, cpDescription, cpClouds,
- cpRain, cpSnow, cpSunrise, cpSunset, cpTemp, cpTempMin, cpTempMax];
- wsWUnderground: Result:= [cpPressureMB, cpPressureIn, cpWindDir,
- cpWindSpeed, cpHumidity, cpVisibility, cpDewPoint, cpHeatIndex,
- cpWindGust, cpWindChill, cpFeelsLike, cpSolarRad, cpUV, cpTemp,
- cpTempMin, cpTempMax, cpPrecip, cpIcon, cpCaption, cpDescription,
- cpStation];
- wsAccuWeather: Result:= [
- ];
- wsNWS: Result:= [
- ];
- wsNOAA: Result:= [
- ];
- end;
- end;
- { TWeatherForecastItem }
- constructor TWeatherForecastItem.Create(AOwner: TWeatherForecast);
- begin
- FOwner:= AOwner;
- FPicture:= TPicture.Create;
- end;
- destructor TWeatherForecastItem.Destroy;
- begin
- FPicture.Free;
- inherited;
- end;
- function TWeatherForecastItem.GetCondition: WideString;
- begin
- Result:= FCondition;
- end;
- function TWeatherForecastItem.GetDateTime: TDateTime;
- begin
- Result:= FDateTime;
- end;
- function TWeatherForecastItem.GetDescription: WideString;
- begin
- Result:= FDescription;
- end;
- function TWeatherForecastItem.GetDewPoint: Single;
- begin
- Result:= FDewPoint;
- end;
- function TWeatherForecastItem.GetHumidity: Single;
- begin
- Result:= FHumidity;
- end;
- function TWeatherForecastItem.GetPicture: TPicture;
- begin
- Result:= FPicture;
- end;
- function TWeatherForecastItem.GetPressure: Single;
- begin
- Result:= FPressure;
- end;
- function TWeatherForecastItem.GetTemp: Single;
- begin
- Result:= FTemp;
- end;
- function TWeatherForecastItem.GetTempMax: Single;
- begin
- Result:= FTempMax;
- end;
- function TWeatherForecastItem.GetTempMin: Single;
- begin
- Result:= FTempMin;
- end;
- function TWeatherForecastItem.GetVisibility: Single;
- begin
- Result:= FVisibility;
- end;
- function TWeatherForecastItem.GetWindDir: Single;
- begin
- Result:= FWindDir;
- end;
- function TWeatherForecastItem.GetWindSpeed: Single;
- begin
- Result:= FWindSpeed;
- end;
- function TWeatherForecastItem.SupportedProps: TWeatherForecastProps;
- begin
- case FOwner.FOwner.FOwner.FService of
- wsOpenWeatherMap: Result:= [fpPressureMB, fpWindDir, fpWindSpeed,
- fpHumidity, fpTemp, fpTempMin, fpTempMax, fpCaption, fpDescription,
- fpIcon, fpGroundPressure, fpSeaPressure];
- wsWUnderground: begin
- Result:= [fpWindDir, fpWindSpeed, fpHumidity, fpTemp, fpTempMin,
- fpTempMax, fpCaption, fpDescription, fpIcon];
- end;
- wsAccuWeather: Result:= [fpIcon, fpCaption, fpTemp, fpPrecip,
- fpURL, fpDaylight];
- wsNWS: Result:= [
- ];
- wsNOAA: Result:= [
- ];
- end;
- end;
- { TWeatherForecast }
- constructor TWeatherForecast.Create(AOwner: TJDWeatherThread);
- begin
- FOwner:= AOwner;
- FItems:= TList<IWeatherForecastItem>.Create;
- FLocation:= TWeatherLocation.Create;
- FLocation._AddRef;
- end;
- procedure TWeatherForecast.Clear;
- var
- X: Integer;
- begin
- for X := 0 to FItems.Count-1 do begin
- FItems[X]._Release;
- end;
- FLocation._Release;
- FLocation:= nil;
- FItems.Clear;
- end;
- destructor TWeatherForecast.Destroy;
- begin
- Clear;
- FItems.Free;
- inherited;
- end;
- function TWeatherForecast.Count: Integer;
- begin
- Result:= FItems.Count;
- end;
- function TWeatherForecast.GetItem(const Index: Integer): IWeatherForecastItem;
- begin
- Result:= FItems[Index];
- end;
- function TWeatherForecast.GetLocation: IWeatherLocation;
- begin
- Result:= FLocation;
- end;
- function TWeatherForecast.MaxTemp: Single;
- var
- X: Integer;
- begin
- Result:= -9999999;
- for X := 0 to FItems.Count-1 do begin
- if FItems[X].Temp > Result then
- Result:= FItems[X].Temp;
- end;
- end;
- function TWeatherForecast.MinTemp: Single;
- var
- X: Integer;
- begin
- Result:= 9999999;
- for X := 0 to FItems.Count-1 do begin
- if FItems[X].Temp < Result then
- Result:= FItems[X].Temp;
- end;
- end;
- { TWeatherStormVertex }
- function TWeatherStormVertex.GetLatitude: Double;
- begin
- Result:= FLatitude;
- end;
- function TWeatherStormVertex.GetLongitude: Double;
- begin
- Result:= FLongitude;
- end;
- { TWeatherStormVerticies }
- constructor TWeatherStormVerticies.Create;
- begin
- FItems:= TList<IWeatherStormVertex>.Create;
- end;
- destructor TWeatherStormVerticies.Destroy;
- begin
- Clear;
- FItems.Free;
- inherited;
- end;
- function TWeatherStormVerticies.Count: Integer;
- begin
- Result:= FItems.Count;
- end;
- procedure TWeatherStormVerticies.Clear;
- var
- X: Integer;
- begin
- for X := 0 to FItems.Count-1 do begin
- FItems[X]._Release;
- end;
- FItems.Clear;
- end;
- function TWeatherStormVerticies.GetItem(
- const Index: Integer): IWeatherStormVertex;
- begin
- Result:= FItems[Index];
- end;
- { TWeatherAlertStorm }
- constructor TWeatherAlertStorm.Create;
- begin
- FVerticies:= TWeatherStormVerticies.Create;
- FVerticies._AddRef;
- end;
- destructor TWeatherAlertStorm.Destroy;
- begin
- FVerticies._Release;
- FVerticies:= nil;
- inherited;
- end;
- function TWeatherAlertStorm.GetDateTime: TDateTime;
- begin
- Result:= FDateTime;
- end;
- function TWeatherAlertStorm.GetDirection: Single;
- begin
- Result:= FDirection;
- end;
- function TWeatherAlertStorm.GetLatitude: Double;
- begin
- Result:= FLatitude;
- end;
- function TWeatherAlertStorm.GetLongitude: Double;
- begin
- Result:= FLongitude;
- end;
- function TWeatherAlertStorm.GetSpeed: Single;
- begin
- Result:= FSpeed;
- end;
- function TWeatherAlertStorm.GetVerticies: IWeatherStormVerticies;
- begin
- Result:= FVerticies;
- end;
- { TWeatherAlertZone }
- function TWeatherAlertZone.GetState: WideString;
- begin
- Result:= FState;
- end;
- function TWeatherAlertZone.GetZone: WideString;
- begin
- Result:= FZone;
- end;
- { TWeatherAlertZones }
- constructor TWeatherAlertZones.Create;
- begin
- FItems:= TList<TWeatherAlertZone>.Create;
- end;
- destructor TWeatherAlertZones.Destroy;
- begin
- Clear;
- FItems.Free;
- inherited;
- end;
- procedure TWeatherAlertZones.Clear;
- var
- X: Integer;
- begin
- for X := 0 to FItems.Count-1 do begin
- FItems[X]._Release;
- end;
- FItems.Clear;
- end;
- function TWeatherAlertZones.Count: Integer;
- begin
- Result:= FItems.Count;
- end;
- function TWeatherAlertZones.GetItem(const Index: Integer): IWeatherAlertZone;
- begin
- Result:= FItems[Index];
- end;
- { TWeatherAlert }
- constructor TWeatherAlert.Create(AOwner: TJDWeatherThread);
- begin
- FOwner:= AOwner;
- FZones:= TWeatherAlertZones.Create;
- FZones._AddRef;
- FStorm:= TWeatherAlertStorm.Create;
- FStorm._AddRef;
- end;
- destructor TWeatherAlert.Destroy;
- begin
- FStorm._Release;
- FStorm:= nil;
- FZones._Release;
- FZones:= nil;
- inherited;
- end;
- function TWeatherAlert.SupportedFunctions: TWeatherAlertProps;
- begin
- case FOwner.FOwner.FService of
- wsOpenWeatherMap: Result:= [];
- wsWUnderground: Result:= [apZones, apVerticies, apStorm, apType, apDescription,
- apExpires, apMessage, apPhenomena, apSignificance];
- wsAccuWeather: Result:= [];
- wsNWS: Result:= [];
- wsNOAA: Result:= [];
- end;
- end;
- function TWeatherAlert.GetAlertType: TWeatherAlertType;
- begin
- Result:= FAlertType;
- end;
- function TWeatherAlert.GetDateTime: TDateTime;
- begin
- Result:= FDateTime;
- end;
- function TWeatherAlert.GetDescription: WideString;
- begin
- Result:= FDescription;
- end;
- function TWeatherAlert.GetExpires: TDateTime;
- begin
- Result:= FExpires;
- end;
- function TWeatherAlert.GetMsg: WideString;
- begin
- Result:= FMsg;
- end;
- function TWeatherAlert.GetPhenomena: WideString;
- begin
- Result:= FPhenomena;
- end;
- function TWeatherAlert.GetSignificance: WideString;
- begin
- Result:= FSignificance;
- end;
- function TWeatherAlert.GetStorm: IWeatherAlertStorm;
- begin
- Result:= FStorm;
- end;
- function TWeatherAlert.GetZones: IWeatherAlertZones;
- begin
- Result:= FZones;
- end;
- { TWeatherAlerts }
- constructor TWeatherAlerts.Create;
- begin
- FItems:= TList<IWeatherAlert>.Create;
- end;
- destructor TWeatherAlerts.Destroy;
- begin
- Clear;
- FItems.Free;
- inherited;
- end;
- function TWeatherAlerts.Count: Integer;
- begin
- Result:= FItems.Count;
- end;
- procedure TWeatherAlerts.Clear;
- var
- X: Integer;
- begin
- for X := 0 to FItems.Count-1 do begin
- FItems[X]._Release;
- end;
- FItems.Clear;
- end;
- function TWeatherAlerts.GetItem(const Index: Integer): IWeatherAlert;
- begin
- Result:= FItems[Index];
- end;
- { TWeatherMaps }
- constructor TWeatherMaps.Create(AOwner: TJDWeatherThread);
- var
- X: TWeatherMapType;
- begin
- for X := Low(TMapArray) to High(TMapArray) do begin
- FMaps[X]:= TPicture.Create;
- end;
- end;
- destructor TWeatherMaps.Destroy;
- var
- X: TWeatherMapType;
- begin
- for X := Low(TMapArray) to High(TMapArray) do begin
- FMaps[X].Free;
- end;
- inherited;
- end;
- function TWeatherMaps.GetMap(const MapType: TWeatherMapType): TPicture;
- begin
- Result:= FMaps[MapType];
- end;
- function TWeatherMaps.SupportedFunctions: TWeatherMapTypes;
- begin
- case Self.FOwner.FOwner.FService of
- wsOpenWeatherMap: Result:= [mpClouds, mpPrecip, mpPressureSea,
- mpWind, mpTemp, mpSnowCover];
- wsWUnderground: Result:= [mpSatellite, mpRadar, mpSatelliteRadar];
- wsAccuWeather: Result:= [];
- wsNWS: Result:= [];
- wsNOAA: Result:= [];
- end;
- end;
- {$ENDREGION}
- //Base Weather Thread
- {$REGION "Base Weather Thread"}
- { TJDWeatherThread }
- constructor TJDWeatherThread.Create(AOwner: TJDWeather);
- begin
- inherited Create(True);
- FOwner:= AOwner;
- FWeb:= TIdHTTP.Create(nil);
- FLastConditions:= 0;
- FLastForecast:= 0;
- FLastAlerts:= 0;
- FLastMaps:= 0;
- end;
- destructor TJDWeatherThread.Destroy;
- begin
- if Assigned(FConditions) then
- FConditions._Release;
- FConditions:= nil;
- if Assigned(FForecast) then
- FForecast._Release;
- FForecast:= nil;
- if Assigned(FAlerts) then
- FAlerts._Release;
- FAlerts:= nil;
- if Assigned(FMaps) then
- FMaps._Release;
- FMaps:= nil;
- FWeb.Free;
- inherited;
- end;
- procedure TJDWeatherThread.CheckConditions;
- var
- R: Boolean;
- begin
- try
- if Assigned(FConditions) then
- FConditions._Release;
- FConditions:= TWeatherConditions.Create(Self);
- FConditions._AddRef;
- R:= DoConditions(FConditions);
- if R then begin
- Synchronize(SYNC_DoOnConditions);
- end else begin
- FConditions._Release;
- FConditions:= nil;
- end;
- except
- end;
- end;
- procedure TJDWeatherThread.CheckForecast;
- var
- R: Boolean;
- begin
- try
- if Assigned(FForecast) then
- FForecast._Release;
- FForecast:= TWeatherForecast.Create(Self);
- FForecast._AddRef;
- R:= DoForecast(FForecast);
- if R then begin
- Synchronize(SYNC_DoOnForecast);
- end else begin
- FForecast._Release;
- FForecast:= nil;
- end;
- except
- end;
- end;
- procedure TJDWeatherThread.CheckAlerts;
- var
- R: Boolean;
- begin
- try
- if Assigned(FAlerts) then
- FAlerts._Release;
- FAlerts:= TWeatherAlerts.Create;
- FAlerts._AddRef;
- R:= DoAlerts(FAlerts);
- if R then begin
- Synchronize(SYNC_DoOnAlerts);
- end else begin
- FAlerts._Release;
- FAlerts:= nil;
- end;
- except
- end;
- end;
- procedure TJDWeatherThread.CheckMaps;
- var
- R: Boolean;
- begin
- try
- if Assigned(FMaps) then
- FMaps._Release;
- FMaps:= TWeatherMaps.Create(Self);
- FMaps._AddRef;
- R:= DoMaps(FMaps);
- if R then begin
- Synchronize(SYNC_DoOnMaps);
- end else begin
- FMaps._Release;
- FMaps:= nil;
- end;
- except
- end;
- end;
- procedure TJDWeatherThread.Process;
- function TimePast(const DT: TDateTime; const Freq: Integer): Boolean;
- var
- N: TDateTime;
- begin
- N:= DateUtils.IncSecond(DT, Freq);
- Result:= Now >= N;
- end;
- begin
- if Terminated then Exit;
- if TimePast(FLastConditions, FOwner.FConditionFreq) then
- CheckConditions;
- if Terminated then Exit;
- if TimePast(FLastForecast, FOwner.FForecastFreq) then
- CheckForecast;
- if Terminated then Exit;
- if TimePast(FLastAlerts, FOwner.FAlertsFreq) then
- CheckAlerts;
- if Terminated then Exit;
- if TimePast(FLastMaps, FOwner.FMapsFreq) then
- CheckMaps;
- if Terminated then Exit;
- Sleep(1);
- end;
- procedure TJDWeatherThread.Execute;
- begin
- while not Terminated do begin
- try
- Process;
- except
- on E: Exception do begin
- //TODO
- end;
- end;
- end;
- end;
- function TJDWeatherThread.LoadPicture(const U: String; const P: TPicture): Boolean;
- var
- S: TMemoryStream;
- I: TGifImage;
- begin
- Result:= False;
- try
- S:= TMemoryStream.Create;
- try
- FWeb.Get(U, S);
- S.Position:= 0;
- I:= TGifImage.Create;
- try
- I.LoadFromStream(S);
- P.Assign(I);
- Result:= True;
- finally
- I.Free;
- end;
- finally
- S.Free;
- end;
- except
- end;
- end;
- procedure TJDWeatherThread.SYNC_DoOnConditions;
- begin
- if Assigned(FOnConditions) then
- FOnConditions(Self, FConditions);
- end;
- procedure TJDWeatherThread.SYNC_DoOnForecast;
- begin
- if Assigned(FOnForecast) then
- FOnForecast(Self, FForecast);
- end;
- procedure TJDWeatherThread.SYNC_DoOnAlerts;
- begin
- if Assigned(FOnAlerts) then
- FOnAlerts(Self, FAlerts);
- end;
- procedure TJDWeatherThread.SYNC_DoOnMaps;
- begin
- if Assigned(FOnMaps) then
- FOnMaps(Self, FMaps);
- end;
- {$ENDREGION}
- //Open Weather Maps
- {$REGION "Open Weather Map Thread"}
- { TOWMWeatherThread }
- function TOWMWeatherThread.Support: TWeatherThreadFunctions;
- begin
- Result:= [tfConditionByZip, tfConditionByCoords, tfConditionByCity,
- tfConditionByIP, tafForecastByZip, tfForecastByCoords, tfForecastByCity,
- tfForecastByIP, tfMapsByZip, tfMapsByCoords, tfMapsByCity,
- tfMapsByIP];
- end;
- function TOWMWeatherThread.GetEndpointUrl(const Endpoint: TOWMEndpoint): String;
- begin
- case Endpoint of
- oeConditions: Result:= 'weather';
- oeForecast: Result:= 'forecast';
- oeAlerts: Result:= 'alerts'; //TODO
- oeMaps: Result:= 'maps'; //TODO
- end;
- Result:= GetUrl + Result + '?appid='+FOwner.Key;
- case FOwner.FUnits of
- wuKelvin: ;
- wuImperial: Result:= Result + '&units=imperial';
- wuMetric: Result:= Result + '&units=metric';
- end;
- end;
- function TOWMWeatherThread.GetUrl: String;
- begin
- Result:= 'http://api.openweathermap.org/data/2.5/';
- end;
- function TOWMWeatherThread.DoAlerts(Alerts: TWeatherAlerts): Boolean;
- begin
- Result:= False;
- //NOT SUPPORTED
- end;
- function TOWMWeatherThread.DoConditions(
- Conditions: TWeatherConditions): Boolean;
- begin
- Result:= False;
- end;
- function TOWMWeatherThread.DoForecast(Forecast: TWeatherForecast): Boolean;
- begin
- Result:= False;
- end;
- function TOWMWeatherThread.DoMaps(Maps: TWeatherMaps): Boolean;
- begin
- Result:= False;
- end;
- {$ENDREGION}
- //Weather Underground
- {$REGION "Weather Underground Thread"}
- { TWUWeatherThread }
- function TWUWeatherThread.Support: TWeatherThreadFunctions;
- begin
- Result:= [tfConditionByZip, tfConditionByCoords, tfConditionByCity,
- tfConditionByIP, tafForecastByZip, tfForecastByCoords, tfForecastByCity, tfForecastByIP,
- tfAlertsByZip, tfAlertsByCoords, tfAlertsByCity, tfAlertsByIP,
- tfMapsByZip, tfMapsByCoords, tfMapsByCity, tfMapsByIP];
- end;
- function TWUWeatherThread.GetUrl: String;
- begin
- Result:= 'http://api.wunderground.com/api/'+FOwner.Key+'/';
- end;
- function TWUWeatherThread.GetEndpointUrl(const Endpoint: TWUEndpoint): String;
- var
- S: String;
- begin
- case Endpoint of
- weAlerts: S:= 'alerts';
- weAlmanac: S:= 'almanac';
- weAstronomy: S:= 'astronomy';
- weConditions: S:= 'conditions';
- weCurrentHurricane: S:= 'currenthurricane';
- weForecast: S:= 'forecast';
- weForecast10Day: S:= 'forecast10day';
- weGeoLookup: S:= 'geolookup';
- weHistory: S:= 'history';
- weHourly: S:= 'hourly';
- weHourly10Day: S:= 'hourly10day';
- wePlanner: S:= 'planner';
- weRawTide: S:= 'rawtide';
- weTide: S:= 'tide';
- weWebCams: S:= 'webcams';
- weYesterday: S:= 'yesterday';
- weRadar: S:= 'radar';
- weSatellite: S:= 'satellite';
- weRadarSatellite: S:= 'radar/satellite';
- end;
- Result:= GetUrl + S + '/q/';
- end;
- function TWUWeatherThread.DoConditions(Conditions: TWeatherConditions): Boolean;
- var
- U: String;
- S: String;
- O: ISuperObject;
- begin
- Result:= False;
- try
- U:= GetEndpointUrl(TWUEndpoint.weConditions);
- case FOwner.FLocationType of
- wlZip: U:= U + FOwner.FLocationDetail1+'.json';
- wlCityState: U:= U + FOwner.FLocationDetail2+'/'+FOwner.FLocationDetail1+'.json';
- wlCoords: U:= U + FOwner.FLocationDetail1+','+FOwner.FLocationDetail2+'.json';
- wlAutoIP: U:= U + 'autoip.json';
- end;
- S:= FWeb.Get(U);
- O:= SO(S);
- FillConditions(O, Conditions);
- Result:= True;
- except
- on E: Exception do begin
- end;
- end;
- end;
- function TWUWeatherThread.DoForecast(Forecast: TWeatherForecast): Boolean;
- var
- U: String;
- S: String;
- O: ISuperObject;
- begin
- Result:= False;
- try
- U:= GetEndpointUrl(TWUEndpoint.weForecast);
- case FOwner.FLocationType of
- wlZip: U:= U + FOwner.FLocationDetail1+'.json';
- wlCityState: U:= U + FOwner.FLocationDetail2+'/'+FOwner.FLocationDetail1+'.json';
- wlCoords: U:= U + FOwner.FLocationDetail1+','+FOwner.FLocationDetail2+'.json';
- wlAutoIP: U:= U + 'autoip.json';
- end;
- S:= FWeb.Get(U);
- O:= SO(S);
- FillForecast(O, Forecast, TWUForecastType.wfSummary);
- Result:= True;
- except
- on E: Exception do begin
- end;
- end;
- end;
- function TWUWeatherThread.DoAlerts(Alerts: TWeatherAlerts): Boolean;
- var
- U: String;
- S: String;
- O: ISuperObject;
- begin
- Result:= False;
- try
- U:= GetEndpointUrl(TWUEndpoint.weAlerts);
- case FOwner.FLocationType of
- wlZip: U:= U + FOwner.FLocationDetail1+'.json';
- wlCityState: U:= U + FOwner.FLocationDetail2+'/'+FOwner.FLocationDetail1+'.json';
- wlCoords: U:= U + FOwner.FLocationDetail1+','+FOwner.FLocationDetail2+'.json';
- wlAutoIP: U:= U + 'autoip.json';
- end;
- S:= FWeb.Get(U);
- O:= SO(S);
- FillAlerts(O, Alerts);
- Result:= True;
- except
- on E: Exception do begin
- end;
- end;
- end;
- function TWUWeatherThread.DoMaps(Maps: TWeatherMaps): Boolean;
- var
- S: TMemoryStream;
- U: String;
- I: TGifImage;
- procedure GetMap(const EP: TWUEndpoint; const MT: TWeatherMapType);
- begin
- U:= GetEndpointUrl(EP);
- case FOwner.FLocationType of
- wlZip: U:= U + FOwner.FLocationDetail1+'.gif';
- wlCityState: U:= U + FOwner.FLocationDetail2+'/'+FOwner.FLocationDetail1+'.gif';
- wlCoords: U:= U + FOwner.FLocationDetail1+','+FOwner.FLocationDetail2+'.gif';
- wlAutoIP: U:= U + 'autoip.gif';
- end;
- FWeb.Get(U, S);
- S.Position:= 0;
- I.LoadFromStream(S);
- S.Clear;
- S.Position:= 0;
- Maps.FMaps[MT].Assign(I);
- end;
- begin
- Result:= False;
- try
- S:= TMemoryStream.Create;
- try
- I:= TGifImage.Create;
- try
- GetMap(weRadar, mpRadar);
- GetMap(weSatellite, mpSatellite);
- GetMap(weRadarSatellite, mpSatelliteRadar);
- Result:= True;
- finally
- I.Free;
- end;
- finally
- S.Free;
- end;
- except
- end;
- end;
- procedure TWUWeatherThread.FillAlerts(const O: ISuperObject;
- Alerts: TWeatherAlerts);
- var
- A: TSuperArray;
- Tmp: Int64;
- I: TWeatherAlert;
- Obj: ISuperObject;
- X: Integer;
- function LD(const O: ISuperObject; const N: String): Double;
- var
- T: String;
- begin
- T:= O.S[N];
- Result:= StrToFloatDef(T, 0);
- end;
- begin
- A:= O.A['alerts'];
- if not Assigned(A) then Exit;
- for X := 0 to A.Length-1 do begin
- Obj:= A.O[X];
- I:= TWeatherAlert.Create(Self);
- try
- I.FAlertType:= TWeatherAlertType.waNone; // Obj.S['type']; //TODO
- I.FDescription:= Obj.S['description'];
- Tmp:= StrToIntDef(Obj.S['date_epoch'], 0);
- I.FDateTime:= UnixToDateTime(Tmp);
- Tmp:= StrToIntDef(Obj.S['expires_epoch'], 0);
- I.FExpires:= UnixToDateTime(Tmp);
- I.FMsg:= Obj.S['message'];
- I.FPhenomena:= Obj.S['phenomena'];
- I.FSignificance:= Obj.S['significance'];
- //Zones
- //Storm
- finally
- Alerts.FItems.Add(I);
- end;
- end;
- end;
- procedure TWUWeatherThread.FillConditions(const O: ISuperObject; Conditions: TWeatherConditions);
- var
- OB, L: ISuperObject;
- function LD(const O: ISuperObject; const N: String): Double;
- var
- T: String;
- begin
- T:= O.S[N];
- Result:= StrToFloatDef(T, 0);
- end;
- begin
- OB:= O.O['current_observation'];
- if not Assigned(OB) then Exit;
- L:= OB.O['display_location'];
- if not Assigned(L) then Exit;
- Conditions.FLocation.FDisplayName:= L.S['full'];
- Conditions.FLocation.FCity:= L.S['city'];
- Conditions.FLocation.FState:= L.S['state_name'];
- Conditions.FLocation.FStateAbbr:= L.S['state'];
- Conditions.FLocation.FCountry:= L.S['country'];
- Conditions.FLocation.FCountryAbbr:= L.S['country_iso3166'];
- Conditions.FLocation.FLongitude:= LD(L, 'longitude');
- Conditions.FLocation.FLatitude:= LD(L, 'latitude');
- Conditions.FLocation.FElevation:= LD(L, 'elevation');
- Conditions.FLocation.FZipCode:= L.S['zip'];
- case FOwner.FUnits of
- wuKelvin: begin
- //Not Supported
- end;
- wuImperial: begin
- Conditions.FTemp:= OB.D['temp_f'];
- Conditions.FVisibility:= LD(OB, 'visibility_mi');
- Conditions.FDewPoint:= OB.D['dewpoint_f'];
- end;
- wuMetric: begin
- Conditions.FTemp:= OB.D['temp_c'];
- Conditions.FVisibility:= LD(OB, 'visibility_km');
- Conditions.FDewPoint:= OB.D['dewpoint_c'];
- end;
- end;
- Conditions.FDateTime:= Now; //TODO
- Conditions.FHumidity:= LD(OB, 'relative_humidity');
- Conditions.FPressure:= LD(OB, 'pressure_mb');
- Conditions.FCondition:= OB.S['weather'];
- Conditions.FDescription:= OB.S['weather'];
- Conditions.FWindSpeed:= OB.D['wind_mph'];
- Conditions.FWindDir:= OB.D['wind_degrees'];
- LoadPicture(OB.S['icon_url'], Conditions.FPicture);
- end;
- procedure TWUWeatherThread.FillForecast(const O: ISuperObject; Forecast: TWeatherForecast;
- const ForecastType: TWUForecastType);
- var
- OB: ISuperObject;
- A: TSuperArray;
- I: TWeatherForecastItem;
- X: Integer;
- function CombineDateTime: String;
- var
- O: ISuperObject;
- begin
- O:= OB.O['date'];
- Result:= O.S['month'] + '/';
- Result:= Result + O.S['day'] + '/';
- Result:= Result + O.S['year'] + ' ';
- Result:= Result + O.S['hour']+':';
- Result:= Result + O.S['min']+':';
- Result:= Result + O.S['sec']+' ';
- Result:= Result + O.S['ampm'];
- end;
- function LD(const O: ISuperObject; const N: String): Double;
- var
- T: String;
- begin
- T:= O.S[N];
- Result:= StrToFloatDef(T, 0);
- end;
- begin
- OB:= O.O['forecast'];
- if not Assigned(OB) then begin
- Exit;
- end;
- case ForecastType of
- TWUForecastType.wfSummary: begin
- OB:= OB.O['txt_forecast'];
- end;
- TWUForecastType.wfDetail: begin
- OB:= OB.O['simpleforecast'];
- end;
- end;
- if not Assigned(OB) then begin
- Exit;
- end;
- A:= OB.A['forecastday'];
- if not Assigned(A) then begin
- Exit;
- end;
- for X := 0 to A.Length-1 do begin
- OB:= A.O[X];
- I:= TWeatherForecastItem.Create(Forecast);
- try
- case ForecastType of
- TWUForecastType.wfSummary: begin
- I.FDateTime:= Now;
- I.FCondition:= OB.S['title'];
- I.FDescription:= OB.S['fcttext'];
- LoadPicture(OB.S['icon_url'], I.FPicture);
- end;
- TWUForecastType.wfDetail: begin
- case FOwner.FUnits of
- wuKelvin: begin
- //NOT SUPPORTED - Calculate?
- I.FWindSpeed:= OB.O['avewind'].D['kph'];
- end;
- wuImperial: begin
- I.FTempMin:= StrToFloatDef(OB.O['low'].S['farenheit'], 0);
- I.FTempMax:= StrToFloatDef(OB.O['high'].S['farenheit'], 0);
- I.FWindSpeed:= OB.O['avewind'].D['mph'];
- end;
- wuMetric: begin
- I.FTempMin:= StrToFloatDef(OB.O['low'].S['celsius'], 0);
- I.FTempMax:= StrToFloatDef(OB.O['high'].S['celsius'], 0);
- I.FWindSpeed:= OB.O['avewind'].D['kph'];
- end;
- end;
- I.FDateTime:= StrToDateTimeDef(CombineDateTime, 0);
- I.FTemp:= I.FTempMax; //TODO
- I.FHumidity:= OB.D['avehumidity'];
- I.FPressure:= 0;
- I.FCondition:= OB.S['conditions'];
- I.FDescription:= OB.S['conditions'];
- I.FWindDir:= OB.O['avewind'].D['degrees'];
- I.FVisibility:= 0;
- I.FDewPoint:= 0;
- LoadPicture(OB.S['icon_url'], I.FPicture);
- end;
- end;
- finally
- Forecast.FItems.Add(I);
- end;
- end;
- end;
- procedure TWUWeatherThread.FillMaps(const O: ISuperObject; Maps: TWeatherMaps);
- begin
- end;
- {$ENDREGION}
- //National Weather Service
- {$REGION "National Weather Service Thread"}
- { TNWSWeatherThread }
- function TNWSWeatherThread.Support: TWeatherThreadFunctions;
- begin
- Result:= [tfConditionByZip, tfConditionByCoords, tfConditionByCity,
- tfConditionByIP, tafForecastByZip, tfForecastByCoords, tfForecastByCity, tfForecastByIP,
- tfAlertsByZip, tfAlertsByCoords, tfAlertsByCity, tfAlertsByIP, tfMapsByZip,
- tfMapsByCoords, tfMapsByCity, tfMapsByIP];
- end;
- function TNWSWeatherThread.GetUrl: String;
- begin
- Result:= ''; //TODO
- end;
- function TNWSWeatherThread.DoAlerts(Alerts: TWeatherAlerts): Boolean;
- begin
- Result:= False;
- end;
- function TNWSWeatherThread.DoConditions(
- Conditions: TWeatherConditions): Boolean;
- begin
- Result:= False;
- end;
- function TNWSWeatherThread.DoForecast(Forecast: TWeatherForecast): Boolean;
- begin
- Result:= False;
- end;
- function TNWSWeatherThread.DoMaps(Maps: TWeatherMaps): Boolean;
- begin
- Result:= False;
- end;
- {$ENDREGION}
- //NOAA
- {$REGION "NOAA Thread"}
- { TNOAAWeatherThread }
- function TNOAAWeatherThread.Support: TWeatherThreadFunctions;
- begin
- Result:= [tfConditionByZip, tfConditionByCoords, tfConditionByCity,
- tfConditionByIP, tafForecastByZip, tfForecastByCoords, tfForecastByCity, tfForecastByIP,
- tfAlertsByZip, tfAlertsByCoords, tfAlertsByCity, tfAlertsByIP, tfMapsByZip,
- tfMapsByCoords, tfMapsByCity, tfMapsByIP];
- end;
- function TNOAAWeatherThread.GetUrl: String;
- begin
- Result:= 'http://www.ncdc.noaa.gov/cdo-web/api/v2/';
- end;
- function TNOAAWeatherThread.GetEndpointUrl(
- const Endpoint: TNOAAEndpoint): String;
- begin
- Result:= GetUrl;
- case Endpoint of
- noeDatasets: Result:= Result + 'datasets/';
- noeDataCategories: Result:= Result + 'datacategories/';
- noeDataTypes: Result:= Result + 'datatypes/';
- noeLocationCategories: Result:= Result + 'locationcategories/';
- noeLocations: Result:= Result + 'locations/';
- noeStations: Result:= Result + 'stations/';
- noeData: Result:= Result + 'data/';
- end;
- end;
- function TNOAAWeatherThread.DoAlerts(Alerts: TWeatherAlerts): Boolean;
- begin
- Result:= False;
- end;
- function TNOAAWeatherThread.DoConditions(
- Conditions: TWeatherConditions): Boolean;
- begin
- Result:= False;
- end;
- function TNOAAWeatherThread.DoForecast(Forecast: TWeatherForecast): Boolean;
- begin
- Result:= False;
- end;
- function TNOAAWeatherThread.DoMaps(Maps: TWeatherMaps): Boolean;
- begin
- Result:= False;
- end;
- {$ENDREGION}
- //AccuWeather
- {$REGION "AccuWeather Thread"}
- { TAWWeatherThread }
- function TAWWeatherThread.Support: TWeatherThreadFunctions;
- begin
- Result:= [tfConditionByZip, tfConditionByCoords, tfConditionByCity,
- tfConditionByIP, tafForecastByZip, tfForecastByCoords, tfForecastByCity, tfForecastByIP,
- tfAlertsByZip, tfAlertsByCoords, tfAlertsByCity, tfAlertsByIP, tfMapsByZip,
- tfMapsByCoords, tfMapsByCity, tfMapsByIP];
- end;
- function TAWWeatherThread.GetEndpointUrl(const Endpoint: TAWEndpoint;
- const S: String): String;
- begin
- case Endpoint of
- aeLocations: Result:= 'locations/v1/';
- aeConditions: Result:= 'currentconditions/v1/';
- aeAlerts: Result:= 'alerts/v1/';
- aeDailyIndices: Result:= 'indices/v1/';
- aeAlarms: Result:= 'alarms/v1/';
- aeClimo: Result:= 'climo/v1/';
- aeTropical: Result:= 'tropical/v1/';
- aeTidal: Result:= 'tidal/v1/';
- aeDaily: Result:= 'forecasts/v1/daily/';
- aeHourly: Result:= 'forecasts/v1/hourly/';
- aeImagery: Result:= 'imagery/v1/';
- aeTranslate: Result:= 'translations/v1/';
- aeLocal: Result:= 'localweather/v1/';
- end;
- Result:= GetUrl + Result;
- Result:= Result + S + '.json?apikey='+FOwner.Key;
- //http://api.accuweather.com/alerts/v1/334907.json?apikey={your key}&details=true
- //http://api.accuweather.com/locations/v1/cities/geoposition/search.json?q=40.59, -73.58&apikey={your key}
- // http://api.accuweather.com/
- // locations/
- // v1/cities/geoposition/search
- // .json
- // ?apikey={your key}
- // &q=40.59, -73.58
- end;
- function TAWWeatherThread.GetUrl: String;
- begin
- Result:= 'http://apidev.accuweather.com/';
- end;
- procedure TAWWeatherThread.CheckLocation;
- var
- U: String;
- S: String;
- O: ISuperObject;
- begin
- if FLocationKey <> '' then Exit;
- //TODO: Connect to API and identify location
- //Save location identifier to FLocationKey
- case FOwner.FLocationType of
- wlZip: U:= GetEndpointUrl(TAWEndpoint.aeLocations,
- 'poastalcodes/search')+'&q='+FLocation1;
- wlCityState: U:= GetEndpointUrl(TAWEndpoint.aeLocations,
- 'cities/US/search')+'&q='+FLocation1+','+FLocation2;
- wlCoords: U:= GetEndpointUrl(TAWEndpoint.aeLocations,
- 'cities/geoposition/search')+'&q='+FLocation1+','+FLocation2;
- wlAutoIP: U:= GetEndpointUrl(TAWEndpoint.aeLocations,
- 'cities/ipaddress')+'&q='+FLocation1;
- end;
- S:= FWeb.Get(U);
- O:= SO(S);
- if Assigned(O) then begin
- FLocation:= O;
- FLocationKey:= O.S['Key'];
- end;
- end;
- procedure TAWWeatherThread.InvalidateLocation;
- begin
- FLocationKey:= '';
- end;
- function TAWWeatherThread.Get(const U: String): ISuperObject;
- var
- S: String;
- begin
- Result:= nil;
- S:= FWeb.Get(U);
- Result:= SO(S);
- end;
- function TAWWeatherThread.DoAlerts(Alerts: TWeatherAlerts): Boolean;
- var
- U: String;
- S1, S2: String;
- O: ISuperObject;
- begin
- Result:= False;
- S1:= FOwner.FLocationDetail1;
- S2:= FOwner.FLocationDetail2;
- if FOwner.FLocationType <> FLocationType then begin
- FLocationType:= FOwner.FLocationType;
- InvalidateLocation;
- end;
- if S1 <> FLocation1 then begin
- FLocation1:= S1;
- InvalidateLocation;
- end;
- if S2 <> FLocation2 then begin
- FLocation2:= S2;
- InvalidateLocation;
- end;
- CheckLocation;
- U:= Self.GetEndpointUrl(TAWEndpoint.aeAlerts, FLocationKey);
- O:= Get(U);
- //TODO: Populate alerts structure
- end;
- function TAWWeatherThread.DoConditions(Conditions: TWeatherConditions): Boolean;
- begin
- Result:= False;
- end;
- function TAWWeatherThread.DoForecast(Forecast: TWeatherForecast): Boolean;
- begin
- Result:= False;
- end;
- function TAWWeatherThread.DoMaps(Maps: TWeatherMaps): Boolean;
- begin
- Result:= False;
- end;
- {$ENDREGION}
- //Main TJDWeather Component
- {$REGION "Main TJDWeather Component"}
- { TJDWeather }
- constructor TJDWeather.Create(AOwner: TComponent);
- begin
- inherited;
- FLocationType:= wlAutoIP;
- FService:= wsWUnderground;
- EnsureThread;
- FConditionFreq:= 300;
- FForecastFreq:= 300;
- FAlertsFreq:= 300;
- FMapsFreq:= 300;
- FUnits:= wuImperial;
- end;
- destructor TJDWeather.Destroy;
- begin
- DestroyThread;
- inherited;
- end;
- procedure TJDWeather.EnsureThread;
- begin
- if csDesigning in ComponentState then Exit;
- //If thread is not already created, create it now.
- //Depending on the chosen service, it will create the
- //service-specific thread.
- if FThread = nil then begin
- case FService of
- wsOpenWeatherMap: FThread:= TOWMWeatherThread.Create(Self);
- wsWUnderground: FThread:= TWUWeatherThread.Create(Self);
- wsNWS: FThread:= TNWSWeatherThread.Create(Self);
- wsAccuWeather: FThread:= TAWWeatherThread.Create(Self);
- wsNOAA: FThread:= TNOAAWeatherThread.Create(Self);
- end;
- FThread.OnConditions:= ThreadConditions;
- FThread.OnForecast:= ThreadForecast;
- FThread.OnMaps:= ThreadMaps;
- FThread.OnAlerts:= ThreadAlerts;
- FThread.Start;
- end;
- end;
- procedure TJDWeather.DestroyThread;
- begin
- if Assigned(FThread) then begin
- FThread.Terminate;
- FThread:= nil;
- end;
- end;
- procedure TJDWeather.ThreadConditions(Sender: TObject; const Conditions: IWeatherConditions);
- begin
- if Assigned(FOnConditions) then
- FOnConditions(Self, Conditions);
- end;
- procedure TJDWeather.ThreadForecast(Sender: TObject; const Forecast: IWeatherForecast);
- begin
- if Assigned(FOnForecast) then
- FOnForecast(Self, Forecast);
- end;
- procedure TJDWeather.ThreadMaps(Sender: TObject; const Maps: IWeatherMaps);
- begin
- if Assigned(FOnMaps) then
- FOnMaps(Self, Maps);
- end;
- procedure TJDWeather.ThreadAlerts(Sender: TObject; const Alert: IWeatherAlerts);
- begin
- if Assigned(FOnAlerts) then
- FOnAlerts(Self, Alert);
- end;
- procedure TJDWeather.SetActive(const Value: Boolean);
- begin
- if Value then begin
- if not FActive then begin
- FActive:= True;
- EnsureThread;
- end;
- end else begin
- if FActive then begin
- FActive:= False;
- DestroyThread;
- end;
- end;
- end;
- procedure TJDWeather.SetAlertsFreq(const Value: Integer);
- begin
- FAlertsFreq := Value;
- end;
- procedure TJDWeather.SetConditionFreq(const Value: Integer);
- begin
- FConditionFreq := Value;
- end;
- procedure TJDWeather.SetForecastFreq(const Value: Integer);
- begin
- FForecastFreq:= Value;
- end;
- procedure TJDWeather.SetKey(const Value: String);
- begin
- FKey := Value;
- end;
- procedure TJDWeather.SetLocationDetail1(const Value: String);
- begin
- FLocationDetail1 := Value;
- end;
- procedure TJDWeather.SetLocationDetail2(const Value: String);
- begin
- FLocationDetail2 := Value;
- end;
- procedure TJDWeather.SetLocationType(const Value: TJDWeatherLocationType);
- begin
- FLocationType := Value;
- end;
- procedure TJDWeather.SetMapsFreq(const Value: Integer);
- begin
- FMapsFreq := Value;
- end;
- procedure TJDWeather.SetService(const Value: TWeatherService);
- begin
- //Changing service requires swapping out thread class
- //This switching is the core of multiple services in a single common structure
- //Each inherited thread implementation must be specific to the chosen service
- if Value <> FService then begin
- if FActive then begin
- raise Exception.Create('Cannot change service while active.');
- end else begin
- DestroyThread;
- FService := Value;
- EnsureThread;
- end;
- end;
- end;
- procedure TJDWeather.SetUnits(const Value: TWeatherUnits);
- begin
- FUnits := Value;
- //TODO: Invalidate all info
- end;
- {$ENDREGION}
- end.
Advertisement
Add Comment
Please, Sign In to add comment