A quick way to get access to weather conditions.
Why choose this library?
basic:
- 🚲 Easy to use - you only need the APIKEY.
- 🏝 Built-in geocoding - search for locations by assumed names or by coordinates.
- 🩺 Various units of measurement - speed, temperature, pressure and cardinal points.
- 🌤 There are original weather icons.
advanced: (Click to open)
- 🔮 At least one release application is already based on this package. Therefore, there is an additional guarantee of security and timely updates of this package.
- 🔓 There is a method for checking your api for correctness.
- 🧱 It is very easy to customize data models. Create your own data models and take only what you need from the built-in ones.
- 🧾 The code is well documented and each class is labeled and decoded. There are unit tests for the main functions of the package.
- 🦺 Safe unpacking of types. If the server stops outputting values - your weather model will have a null field and the application will not crash.
- 🔧 This package has no unnecessary dependencies and contains minimal code. Also, all platforms are supported.
Let's agree to designate Openweathermap as OWM.
The library uses the following site endpoints openweathermap.org:
api.openweathermap.org {/path/endpoint} |
A {Class.method} that uses this endpoint | See more |
---|---|---|
/data/2.5/weather | WeatherService.currentWeatherByLocation |
current |
/data/2.5/onecall | WeatherService.oneCallWeatherByLocation |
one-call-api |
/data/3.0/onecall | WeatherService.oneCallWeatherByLocation |
one-call-3 |
/geo/1.0/direct | GeocodingService.getLocationByCityName |
geocoding-direct |
/geo/1.0/reverse | GeocodingService.getLocationByCoordinates |
geocoding-reverse |
- 🌦 weather_pack
- Endpoints openweathermap.org
- Table of Contents
- Installing
- Getting Started
- Usage weather service
- Usage geocoding service
- Usage units measure
- Exception handling
- Usage custom client
- Usage weather icons
- API key testing
- Resources
- Author
- Support
- Add dependency to your
pubspec.yaml
:dependencies: weather_pack: ^<latest_version>
- Run the command:
flutter pub get
- Use in your code:
import 'package:weather_pack/weather_pack.dart';
- *Additionally, pull package locally to examine
example
folder:flutter pub unpack
weather_in_console
- Dart console applicationcreate_code_for_readme
- all examples from current manualexample
- easy use
The easiest way to get the current weather:
Future<void> main() async {
const api = 'YOUR_APIKEY'; // TODO: change to your openweathermap APIkey
final wService = WeatherService(api);
// get the current weather in Amsterdam
final WeatherCurrent currently = await wService.currentWeatherByLocation(
latitude: 52.374, longitude: 4.88969);
print(currently);
}
You can also change the request language:
final lang = WeatherLanguage.arabic;
final wService = WeatherService(api, language: lang);
Supported languages: (Click to open)
- Afrikaans
- Albanian
- Arabic
- Azerbaijani
- Bulgarian
- Catalan
- Czech
- Danish
- German
- Greek
- English
- Basque
- Persian
- Farsi
- Finnish
- French
- Galician
- Hebrew
- Hindi
- Croatian
- Hungarian
- Indonesian
- Italian
- Japanese
- Korean
- Latvian
- Latvian
- Macedonian
- Norwegian
- Dutch
- Polish
- Portuguese
- Português Brasil
- Romanian
- Russian
- Swedish
- Slovak
- Slovenian
- Spanish
- Serbian
- Thai
- Turkish
- Ukrainian
- Vietnamese
- Chinese Simplified
- Chinese Traditional
- Zulu
According to OWM service (See more):
You can use the
lang
parameter to get the output in your language.Translation is applied for the
city name
anddescription
fields.
Now there are two weather models - WeatherCurrent
and WeatherOneCall
.
WeatherOneCall
includes:
WeatherCurrent
List<WeatherHourly>
List<WeatherMinutely>
List<WeatherDaily>
List<WeatherAlert>
How to use?
You can get the weather in the following way:
Future<void> getOnecallWeatherWays({String api = 'Your_APIkey'}) async {
final wService2_5 = WeatherService(api, oneCallApi: OneCallApi.api_2_5);
final WeatherOneCall onecall2_5 = await wService2_5.oneCallWeatherByLocation(
latitude: 52.374, longitude: 4.88969);
print(onecall2_5);
// if you use the "One Call API 3.0" subscription that...
final wService3_0 = WeatherService(api, oneCallApi: OneCallApi.api_3_0);
final WeatherOneCall onecall3_0 = await wService3_0.oneCallWeatherByLocation(
latitude: 52.374, longitude: 4.88969);
print(onecall3_0);
}
Why do you only use the weather search by coordinates?
According to the website OWM:
Please use Geocoder API if you need automatic convert city names and zip-codes to geo coordinates and the other way around.
Please note that built-in geocoder has been deprecated. Although it is still available for use, bug fixing and updates are no longer available for this functionality.
GeocodingService
is a service for easy location search when working with geographical names
and coordinates. Supports both the direct and reverse methods:
- Direct geocoding converts the specified name of a location or zip/post code into the exact geographical coordinates;
- Reverse geocoding converts the geographical coordinates into the names of the nearby locations;
You can find out more at this link: Geocoding API OpenWeather
How to use?
Create GeocodingService
in the following way:
final String cityName = 'suggested location name';
final String apiKey = 'your api key for OWM';
final GeocodingService gService = GeocodingService(apiKey);
To find using place names use direct geocoding:
final List<PlaceGeocode> places = await gService.getLocationByCityName(cityName);
or use reverse geocoding
final List<PlaceGeocode> places = await gService.getLocationByCoordinates(
latitude: 52.374, longitude: 4.88969);
By default, all weather models, e.g. WeatherCurrent
, have measurable values of type double
.
To display the data in a convenient format, it is necessary use the conversion method value
or valueToString
:
void worksTempUnits({
double temp = 270.78, // ex. received from [WeatherCurrent.temp]
int precision = 3,
Temp unitsMeasure = Temp.celsius,
}) {
// The default temperature is measured in Kelvin of the `double` type.
// We need the temperature to be displayed in Celsius to 3 decimal places
print(unitsMeasure.value(temp, precision)); // `-2.37` type `double`
print(unitsMeasure.valueToString(temp, precision)); // `-2.370` type `String`
// if precision is 0:
print(unitsMeasure.value(temp, 0)); // `-2.0` type `double`
print(unitsMeasure.valueToString(temp, 0)); // `-2` type `String`
}
By and large, the valueToString()
method is needed to display correctly in ui,
and the value()
method is for accurate calculations.
There are several units of measurement:
Units of measure | Class | Supported units | Conversion |
---|---|---|---|
Temperature | Temp |
kelvin, celsius, fahrenheit | + |
Speed | Speed |
ms, mph, kph | + |
Pressure | Pressure |
hectoPa, mbar, mmHg, kPa, atm, inHg | + |
Cardinal points | SideOfTheWorld |
n, ne, e, se, s, sw, w, nw | +(another) |
💡 Tip: The SideOfTheWorld
enum contains a static method fromDegrees()
for converting degrees
to cardinal directions.
Each of the methods in the WeatherService
and GeocodingService
services can throw an OwmApiException
exception. You can process them as follows:
void exceptionHandling() async {
final wService = WeatherService('bRoKen_aPi');
WeatherCurrent? current;
try {
current =
await wService.currentWeatherByLocation(latitude: 1, longitude: 1);
} on OwmApiException catch (e, s) {
print(e.code);
print(e.message);
print(s);
}
}
For GeocodingService
and WeatherService
you can create a custom OWMBuilder
for debugging and logging cases:
class OWMBuilderCustom extends OWMBuilder {
/// We output the url to the console for debugging and logging
@override
Future<T> getData<T>(
{required Uri uri, required T Function(dynamic data) builder}) {
print(uri);
return super.getData(uri: uri, builder: builder);
}
}
void workOwmBuilder({
String api = 'your_apikey',
}) async {
final customOWMBuilder = OWMBuilderCustom();
final gService = GeocodingService(api, owmBuilder: customOWMBuilder);
final List<PlaceGeocode> places = await gService.getLocationByCoordinates(
latitude: 52.374, longitude: 4.88969);
print(places);
}
For OWMTestService
you can create a custom Client
. A more low-level way, would require an explicit dependency on the http
package:
class CustomClient extends IOClient {
/// We output the url to the console
@override
Future<Response> get(Uri url, {Map<String, String>? headers}) {
print(url);
return super.get(url, headers: headers);
}
}
/// We output the url to the console for debugging
void workCustomClient({
String api = 'your_apikey',
}) async {
final customClient = CustomClient();
final testService = OWMTestService(api, customClient);
final bool isValidKey = await testService.isValidApikey();
print(isValidKey);
}
You can use weather icons provided by the OWM service. See more about weather conditions.
Icons are stored locally in this package at the path assets/weather_icons/
.
They are ordered according to Declaring resolution-aware image assets.
This reflects the following correspondences:
100*100 - in default(implied resolution @1)
200x200 - @2
300x300 - @3
400x400 - @4
with the preservation of image quality.
How to use?
Get the weather icon in a safe way:
Image getWeatherIcon(String weatherIcon) {
return Image.asset(
ImagePathWeather.getPathWeatherIcon(weatherIcon),
filterQuality: FilterQuality.high, // optional
package: ImagePathWeather.packageName,
);
}
or to process it completely by hand:
Widget getWeatherIcon(WeatherCurrent weather) {
return Image.asset(
'assets/weather_icons/${weather.weatherIcon}.png', // icon path
package: 'weather_pack', // name package
filterQuality: FilterQuality.high, // optional
errorBuilder: (c, e, s) => Text(e), // will return the widget in case of an error
);
}
In this case, you can use the best quality regardless of platform resolution by specifying @4
to path:
'assets/weather_icons/@4/$weatherIcon.png'
It is possible to test the API key.
To do this, the OWMTestService
class has a method isValidApikeyForOneCall
:
/// If the apikey is valid, `OWMApiTest` methods will return `true`
Future<void> testAPIkey({
String testedAPIkey = 'your_apikey',
}) async {
// checking key for geocoding service and for (fetching WeatherCurrent)
final bool isValid = await OWMTestService(testedAPIkey).isValidApikey();
// checking key for "One Call API 2.5" service (fetching WeatherOneCall)
final bool isValidOneCall2 = await OWMTestService(testedAPIkey)
.isValidApikeyForOneCall(OneCallApi.api_2_5);
// or
// checking key for "One Call by Call 3.0" service (fetching WeatherOneCall)
final bool isValidOneCall3 = await OWMTestService(testedAPIkey)
.isValidApikeyForOneCall(OneCallApi.api_3_0);
}
- folder
example
. There is a simple example of how to use the basic functions of the package, as well as a console mini-application without using flutter
Feel free to suggest materials for inclusion in this list ^_~
You can contact me or check out my activities on the following platforms:
Made with ❤️. Enjoy it!
Feel free to contribute to this project.
If you find a bug or want a feature, but don't know how to fix/implement it, please fill an issue.
If you fixed a bug or implemented a feature, please send a pull request. Use dev
branch for this.