前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Flutter 多端天气预报APP第二弹 —— 城市定位以及城市代码的转换

Flutter 多端天气预报APP第二弹 —— 城市定位以及城市代码的转换

作者头像
繁依Fanyi
发布2024-03-20 15:27:47
1080
发布2024-03-20 15:27:47
举报

获取当前位置

在获取当前位置的过程中,我们使用了Flutter的Geolocator库。这个库不仅仅可以获取设备的经纬度,还能提供更多有关设备位置的信息。例如,我们可以获取设备的海拔高度、速度、方向等。在实际应用中,根据需求可以灵活运用这些功能,比如实现高度相关的气象应用或运动追踪应用等。下面是获取当前位置的代码:

代码语言:javascript
复制
  Future<Position?> getCurrentLocation() async {
    try {
      return await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
    } catch (e) {
      // 处理定位失败的情况
      print("Error getting location: $e");
      return null;
    }
  }

这个函数通过Geolocator.getCurrentPosition方法获取设备的当前位置,desiredAccuracy参数用于指定定位的精确度。我们通过try-catch块捕获异常,以确保在定位失败时能够 graceful 地处理。

完成之后,我们输出获取到的地理位置信息,来看一看自己是否函数是否能够正常使用;下面编写一个函数来查看我们的输出:

代码语言:javascript
复制
Future<void> printCurrentLocation() async{

    try {

      Position? position = await Geolocator.getCurrentPosition();
      print(position);
    } catch (error) {
      print('Error fetching weather data: $error');
      // 处理异常,显示错误信息
    }
  }

可以看到,控制台可以正常输出我们的位置。

当前位置经纬度转 Location ID

获得当前位置的经纬度后,我们要将其转换为可用于和风天气API的城市代码,这样才能够填充之前请求天气的 location 参数。下面是我找到的和风天气的经纬度转城市代码的api,

https://geoapi.qweather.com/v2/city/lookup?location=116.41,39.92&key=$apiKeye

请求后的内容如下:

代码语言:javascript
复制
{
    "code": "200",
    "location": [
        {
            "name": "东城",
            "id": "101011600",
            "lat": "39.91755",
            "lon": "116.41876",
            "adm2": "北京",
            "adm1": "北京市",
            "country": "中国",
            "tz": "Asia/Shanghai",
            "utcOffset": "+08:00",
            "isDst": "0",
            "type": "city",
            "rank": "35",
            "fxLink": "https://www.qweather.com/weather/dongcheng-101011600.html"
        }
    ],
    "refer": {
        "sources": [
            "QWeather"
        ],
        "license": [
            "QWeather Developers License"
        ]
    }
}

简要把各个字段列成表格,表格中 location 属性下的 id 就是我们想要的内容:

字段

描述

code

API响应的状态码。

location

包含有关位置的详细信息的数组。

- name

位置的名称(例如:“东城”)。

- id

位置的唯一标识符(例如:“101011600”)。

- lat

位置的纬度坐标(例如:“39.91755”)。

- lon

位置的经度坐标(例如:“116.41876”)。

- adm2

行政区划级别2(例如:“北京”)。

- adm1

行政区划级别1(例如:“北京市”)。

- country

位置所在国家(例如:中国)。

- tz

位置的时区(例如:“Asia/Shanghai”)。

- utcOffset

位置的UTC偏移量(例如:“+08:00”)。

- isDst

夏令时指示符(例如:"0"表示无夏令时)。

- type

位置的类型(例如:“city”)。

- rank

位置的排名(例如:“35”)。

- fxLink

查看位置天气详情的链接。

refer

附加信息和参考资料。

- sources

数据来源数组(例如:[“QWeather”])。

- license

QWeather开发者许可证信息。

编写代码通过 api 将经纬度转换成 location id。提醒一下大家,和风天气的这个api最多只支持经纬度小数点后两位,所以在之前的定位过程中可以不用选择高精度。

代码语言:javascript
复制
Future<String?> getCityCodeFromLocation() async{

    try {
      // 经纬度
      String latitude = "39.91";
      String longitude = "116.41";

      Position? position = await Geolocator.getCurrentPosition();
      latitude = position.latitude.toStringAsFixed(2);
      longitude = position.longitude.toStringAsFixed(2);

      // 构建 API 请求的 URL
      String apiUrl =
          'https://geoapi.qweather.com/v2/city/lookup?location=$longitude,$latitude&key=$apiKey';

      // 发送 HTTP GET 请求
      http.Response response = await http.get(Uri.parse(apiUrl));

      if (response.statusCode == 200) {
        // 解析 JSON 响应
        Map<String, dynamic> data = json.decode(response.body);

        // 获取 Location ID
        String locationId = data['location'][0]['id'].toString();
        print(locationId);	// 输出一下看看
        return locationId;
        
      } else {
        print("Error getting Location ID");
        return null;
      }
    } catch (e) {
      
      print("Error getting Location ID");
      return null;
      
    }
  }

通过http库发送HTTP GET请求到和风天气的城市查询API,获取对应经纬度的城市信息,并提取出城市代码。运行后可以看到输出的城市代码:

然后再传回到 getWeatherData() 中,

代码语言:javascript
复制
Future<Map<String, dynamic>> getWeatherData() async {


    String? locationId = await getCityCodeFromLocation();
    String url = 'https://devapi.qweather.com/v7/weather/3d?location=$locationId&key=$apiKey';
    Uri uri = Uri.parse(url);
    var response = await http.get(uri);

    if (response.statusCode == 200) {
      return json.decode(response.body);
    } else {
      throw Exception('Failed to load weather data');
    }
  }

编译运行一下,和我所在位置的气候一模一样,Success😀!

结语

在本博客中,我们详细介绍了如何使用Geolocator库获取设备当前位置,以及如何将地理位置转换为城市代码。这些功能不仅提升了用户体验,还使得我们的应用更具实用性。在下一篇博客中,我们将探讨在Android应用中可能涉及的权限问题,以及如何处理这些权限。

后面,可能还会考虑一些实际应用,比如频繁地请求同一位置的天气信息可能是不必要的。可以考虑使用缓存机制,将已经获取到的天气信息存储在本地,避免重复请求。这既能提高应用的性能,又能减轻服务器负担。

希望这篇博客对你有所帮助。如果你有任何问题或建议,请随时留言。感谢你的阅读!

作者信息 作者 : 繁依Fanyi CSDN: https://techfanyi.blog.csdn.net 掘金:https://juejin.cn/user/4154386571867191

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-03-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 获取当前位置
  • 当前位置经纬度转 Location ID
  • 结语
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档