当前位置: 首页 > 知识库问答 >
问题:

颤振OpenWeatherMap api获取预测

戚浩淼
2023-03-14

所以…我得到了一个调用Api,其中还包括7天的预测。我设法显示了当前的天气(温度和图标),但如何获得未来4天的天气预报?

我的API:https://api.openweathermap.org/data/2.5/onecall?lat=lat

我的型号:

class CurrentWeatherModel {
      final WeatherInfo weatherInfo;
      final double temp;
      const CurrentWeatherModel({
        required this.weatherInfo, required this.temp
      });
    
      factory CurrentWeatherModel.fromJson(json){
        return CurrentWeatherModel(
            weatherInfo: WeatherInfo.fromJson(json['weather'][0]),
          temp: json['temp'],
        );
      }
    }
    
    class HourlyWeatherModel {
      final double temp;
      final WeatherInfo weatherInfo;
      const HourlyWeatherModel(
          {
            required this.temp,
            required this.weatherInfo
          }
          );
    
      factory HourlyWeatherModel.fromJson(json){
        return HourlyWeatherModel(
            temp: json['temp'],
            weatherInfo: WeatherInfo.fromJson(json['weather'][0])
        );
      }
    }
    
    class DailyWeatherInfoModel {
      final TempModel dailyTemp;
      final WeatherInfo weatherInfo;
      final DateTime date;
      final int dt;
    
      const DailyWeatherInfoModel(
          {
            required this.dailyTemp,
            required this.weatherInfo,
            required this.date,
            required this.dt,
          }
          );
    
      factory DailyWeatherInfoModel.fromJson(json){
        return DailyWeatherInfoModel(
          dailyTemp: TempModel.fromJson(json['temp']),
          dt: json['dt'],
          date: DateTime.fromMillisecondsSinceEpoch(json['dt'] * 1000,
              isUtc: true),
            weatherInfo: WeatherInfo.fromJson(json['weather'][0]),
        );
      }
    }
    
    class TempModel {
      final double day;
      final double min;
      final double max;
      const TempModel(
          {
            required this.day,
            required this.min,
            required this.max
          }
          );
      factory TempModel.fromJson(json){
        return TempModel(
            day: json['day'],
            min: json['min'],
            max: json['max']
        );
      }
    }
    
    class WeatherInfo {
      final String? description;
      final String? icon;
      WeatherInfo({this.description, this.icon});
      factory WeatherInfo.fromJson(Map<String, dynamic> json) {
        final description = json['description'];
        final icon = json['icon'];
        return WeatherInfo(description: description, icon: icon);
      }
    }
    
    class WeatherForecastResponse {
    
      final CurrentWeatherModel current;
      final HourlyWeatherModel hourly;
      final DailyWeatherInfoModel daily;
    
      String get iconCurrentWeatherUrl{
        return 'https://merakiapp.be/wp-content/uploads/2022/04/${current.weatherInfo.icon}.png';
      }
    
      String get iconDailyWeatherUrl{
        return 'https://merakiapp.be/wp-content/uploads/2022/04/${daily.weatherInfo.icon}.png';
      }
    
      const  WeatherForecastResponse(
          {
            required this.current,
            required this.daily,
            required this.hourly
          }
          );
    
      factory WeatherForecastResponse.fromJson(json){
        return WeatherForecastResponse(
            current: CurrentWeatherModel.fromJson(json['current']),
            hourly: HourlyWeatherModel.fromJson(json['hourly'][0]),
            daily: DailyWeatherInfoModel.fromJson(json['daily'][0])
        );
      }
    }

我的回答是:

Future<WeatherForecastResponse> getForecast(double lat, double lon) async {
    try {
      String api = 'https://api.openweathermap.org/data/2.5/onecall';
      String appId = 'MyAPIKey';
      String units = 'metric';
      String cnt = '4';
      String url = '$api?lat=$lat&lon=$lon&cnt=$cnt&appid=$appId&units=$units';

      final response = await http.get(Uri.parse(url));
      final json = jsonDecode(response.body);
      return WeatherForecastResponse.fromJson(json);
    } catch (e) {
      rethrow;
    }
  }

响应对象:

void _currentWeather() async {
    await FirebaseFirestore.instance.collection('Users').doc(currentUser).get().then((value) => _userLocation = value.data()!['Location']);
    setState(() {
      lat = _userLocation.latitude;
      lon = _userLocation.longitude;
    });
    final response = await _dataWeatherService.getForecast(lat!, lon!);
    setState(() {
      temp = response.current.temp.round();
      weather = response.current.weatherInfo.description;
      icon = response.iconCurrentWeatherUrl;
    });
  }

  void _dailyForecast() async {
    final response = await _dataWeatherService.getForecast(lat!, lon!);
    setState(() {
      tempDaily = response.daily.dailyTemp.day.round();
      weatherDaily = response.daily.weatherInfo.description;
      iconDaily = response.iconDailyWeatherUrl;
      date = response.daily.date;
    });
}

来自OneCall API的JSON:

{
  "lat": 33.44,
  "lon": -94.04,
  "timezone": "America/Chicago",
  "timezone_offset": -21600,
  "current": {
    "dt": 1618317040,
    "sunrise": 1618282134,
    "sunset": 1618333901,
    "temp": 284.07,
    "feels_like": 282.84,
    "pressure": 1019,
    "humidity": 62,
    "dew_point": 277.08,
    "uvi": 0.89,
    "clouds": 0,
    "visibility": 10000,
    "wind_speed": 6,
    "wind_deg": 300,
    "weather": [
      {
        "id": 500,
        "main": "Rain",
        "description": "light rain",
        "icon": "10d"
      }
    ],
    "rain": {
      "1h": 0.21
    }
  },
    "minutely": [
    {
      "dt": 1618317060,
      "precipitation": 0.205
    },
    ...
  },
    "hourly": [
    {
      "dt": 1618315200,
      "temp": 282.58,
      "feels_like": 280.4,
      "pressure": 1019,
      "humidity": 68,
      "dew_point": 276.98,
      "uvi": 1.4,
      "clouds": 19,
      "visibility": 306,
      "wind_speed": 4.12,
      "wind_deg": 296,
      "wind_gust": 7.33,
      "weather": [
        {
          "id": 801,
          "main": "Clouds",
          "description": "few clouds",
          "icon": "02d"
        }
      ],
      "pop": 0
    },
    ...
  }
    "daily": [
    {
      "dt": 1618308000,
      "sunrise": 1618282134,
      "sunset": 1618333901,
      "moonrise": 1618284960,
      "moonset": 1618339740,
      "moon_phase": 0.04,
      "temp": {
        "day": 279.79,
        "min": 275.09,
        "max": 284.07,
        "night": 275.09,
        "eve": 279.21,
        "morn": 278.49
      },
      "feels_like": {
        "day": 277.59,
        "night": 276.27,
        "eve": 276.49,
        "morn": 276.27
      },
      "pressure": 1020,
      "humidity": 81,
      "dew_point": 276.77,
      "wind_speed": 3.06,
      "wind_deg": 294,
      "weather": [
        {
          "id": 500,
          "main": "Rain",
          "description": "light rain",
          "icon": "10d"
        }
      ],
      "clouds": 56,
      "pop": 0.2,
      "rain": 0.62,
      "uvi": 1.93
    },
    ...
    },
    "alerts": [
    {
      "sender_name": "NWS Tulsa",
      "event": "Heat Advisory",
      "start": 1597341600,
      "end": 1597366800,
      "description": "...HEAT ADVISORY REMAINS IN EFFECT FROM 1 PM THIS AFTERNOON TO\n8 PM CDT THIS EVENING...\n* WHAT...Heat index values of 105 to 109 degrees expected.\n* WHERE...Creek, Okfuskee, Okmulgee, McIntosh, Pittsburg,\nLatimer, Pushmataha, and Choctaw Counties.\n* WHEN...From 1 PM to 8 PM CDT Thursday.\n* IMPACTS...The combination of hot temperatures and high\nhumidity will combine to create a dangerous situation in which\nheat illnesses are possible.",
      "tags": [
        "Extreme temperature value"
        ]
    },
    ...
  ]

共有1个答案

张宣
2023-03-14

我会将您的< code > weatherforecasresponse 更改为一个< code > DailyWeatherInfoModel 列表,而不是一个模型。


class WeatherForecastResponse {
  final CurrentWeatherModel current;
  final HourlyWeatherModel hourly;
  final List<DailyWeatherInfoModel> daily;
...
}

然后在< code>fromJson构造函数中解析一个完整的列表

  factory WeatherForecastResponse.fromJson(json) {
    final dailyResponse = json['daily'] as List;
    final dailyForecastList = <DailyWeatherInfoModel>[];
    for (final day in dailyResponse) {
      dailyForecastList.add(DailyWeatherInfoModel.fromJson(day));
    }
    return WeatherForecastResponse(
        current: CurrentWeatherModel.fromJson(json['current']),
        hourly: HourlyWeatherModel.fromJson(json['hourly'][0]),
        daily: dailyForecastList);
  }

我还将在每个每日/每小时模型中放置图标url。这样,您就有了一个完整的DailyWeatherInfoModel列表,其中包含您所需的一切。

class DailyWeatherInfoModel {
  final TempModel dailyTemp;
  final WeatherInfo weatherInfo;
  final DateTime date;
  final int dt;
  final String iconUrl; // adding this

  const DailyWeatherInfoModel({
    required this.dailyTemp,
    required this.weatherInfo,
    required this.date,
    required this.dt,
    required this.iconUrl,
  });

  factory DailyWeatherInfoModel.fromJson(json) {
    final weatherInfo = WeatherInfo.fromJson(json['weather'][0]);
    final iconUrl =
        'https://merakiapp.be/wp-content/uploads/2022/04/${weatherInfo.icon}.png'; // init iconUrl here

    return DailyWeatherInfoModel(
      dailyTemp: TempModel.fromJson(json['temp']),
      dt: json['dt'],
      date: DateTime.fromMillisecondsSinceEpoch(json['dt'] * 1000, isUtc: true),
      weatherInfo: weatherInfo,
      iconUrl: iconUrl,
    );
  }
}

您也可以将相同的概念应用于每小时预测。

 类似资料:
  • 我有一个FutureBuilder(很高兴加载)从Firebase获取我的DocumentSnapshot列表,但问题是如果我推送/弹出屏幕,它会一遍又一遍地重建它。为了解决这个问题,我最终将它放在了上,但我有一个问题,我有时无法从中获取所有文档。 我有一个按钮可以启用国家/地区筛选和禁用,每次按下它几乎都会立即显示我的文档,例如,我总共筛选了11个国家/地区,筛选了5个国家/地区,但有时我不会全

  • 我可以使用“startAfter”和“limit”进行分页,但它有错误。 例如,在Firestore DB中,我有7条记录: 当页面大小为5时,第一页就可以了,因为我使用了: 它给了我1-5项。 当它加载第二页时,我使用了: 问题是第二页结果只有item7,item6消失了。“开始”也有同样的问题。 真希望它有“抵消”功能,有人有解决办法吗?

  • Xcode的输出:在文件中包含从 /Users/dani/development/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.3/ios/Classes/FLTURLLauncherPlugin.m: 7: /Users/dani/development/flutter/.pub-cache/hosted/pub.dart

  • 当我试图添加google_sign_in时,flutter_authcloud_firestore它给我带来了一个错误:” [✓] 颤振(通道稳定,v1.5.4-hotfix.2,Linux上,locale en_US.UTF-8)•颤振版本1.5。4-hotfix。2 at/home/ramu/Downloads/tools/颤振•框架版本7a4c33425d(4周前),2019-04-29 1

  • 我想问一下IOS的实施情况 当前场景:基本上,我已经在android平台上开发了该应用程序,现在我想将其转换为IOS平台。由于这是我的第一个应用程序,我真的需要一些有经验的声音来解决我面临的一些问题。 问题: 1-是否有任何简单的方法来检测当前使用的Widget是Android/IOS平台?我们如何才能确定特定的小部件是Android平台的,并且在IOS平台上不工作,反之亦然。 2 -如果我们以某

  • 当我创建flutter插件时,默认情况下插件类中有两个方法: 和 文件上的评论说: