Skip to content

天气 Api 申请和定位显示天气

步骤:

  1. 申请高德地图 key 我的应用 | 高德控制台 (amap.com)

  2. 将高德地图 Api 地址增加到小程序 request 合法域名

    注意:测试号不支持

  3. 在 app.json 里增加

json
"permission": {
    "scope.userLocation": {
      "desc": "你的位置信息将用于小程序天气接口的效果展示"
    }
}

4、获取设置函数wx.getSetting 看是否授权定位

5、获取定位函数wx.getLocation 获取经纬度 : latitude 纬度 longitude 经度

6、通过高德地图逆地理编码接口传入经纬度获取地区编码 接口文档

7、高德地图天气查询接口传入地区编码查询天气并显示天气和位置 接口文档

8、回显位置和天气情况并显示天气图图标

申请高德地图 key

点击创建新应用

6-1

6-2

选择 web 服务 ip 白名单设置为空

6-3

添加到 request 合法域名 https://restapi.amap.com

处于安全性考虑,小程序官方对于数据接口的请求作出了如下两个限制:

  • 只能请求 https 类型的接口;
  • 必须将接口的域名添加到信任列表中

6-4

配置 request 合法域名

假设需要在自己的微信小程序中,希望请求https://www.escook.cn/域名下的接口

配置步骤:登录微信小程序管理后台 ⇒ 开发 ⇒ 开发设置 ⇒ 服务器域名 ⇒ 修改 request 合法域名

6-5

6-6

跳过 request 合法域名校验(上线无法使用)

如果仅仅提供了 http 协议的接口,暂时没有提供 https 协议的接口。

此时为了不耽误开发进度,我们可以在微信开发者工具中,临时开启「开发环境不校验请求域名、TLS 版本以及 HTTPS 证书」选项,跳过 request 合法域名校验。

6-7

查看是否授权过定位权限(该函数需要和下方获取定位经纬度函数一起使用-getLocation

js
getUserLocation() {
  let that = this;
  wx.getSetting({
    success: res => {
      console.log(res, JSON.stringify(res));
      // res.authSetting['scope.userLocation'] == undefined    表示 初始化进入该页面
      // res.authSetting['scope.userLocation'] == false    表示 非初始化进入该页面,且未授权
      // res.authSetting['scope.userLocation'] == true    表示 地理位置授权

      if (
        res.authSetting["scope.userLocation"] != undefined &&
        res.authSetting["scope.userLocation"] != true
      ) {
        wx.showModal({
          title: "请求授权当前位置",
          content: "需要获取您的地理位置,请确认授权",
          success: function (res) {
            if (res.cancel) {
              wx.showToast({
                title: "拒绝授权",
                icon: "none",
                duration: 1000,
              });
            } else if (res.confirm) {
              wx.openSetting({
                success: function (dataAu) {
                  if (dataAu.authSetting["scope.userLocation"] == true) {
                    wx.showToast({
                      title: "授权成功",
                      icon: "success",
                      duration: 1000,
                    });
                    //再次授权,调用wx.getLocation的API
                    that.getLocation();
                  } else {
                    wx.showToast({
                      title: "授权失败",
                      icon: "none",
                      duration: 1000,
                    });
                  }
                },
              });
            }
          },
        });
      } else if (res.authSetting["scope.userLocation"] == undefined) {
        //调用wx.getLocation的API
        that.getLocation();
      } else {
        //res.authSetting['scope.userLocation'] == true
        //调用wx.getLocation的API
        that.getLocation();
      }
    },
  });
}

获取定位经纬度函数

js
getLocation() {
  let that = this;
  wx.getLocation({
    type: "wgs84",
    success(res) {
      console.log("经纬度", res);
      if (res?.errMsg === "getLocation:ok") {
        /* ----------------通过经纬度获取地区编码---------------- */
        wx.request({
          url: "https://restapi.amap.com/v3/geocode/regeo?parameters",
          data: {
            key: KEY, //填入自己申请到的Key
            location: res.longitude + "," + res.latitude, //传入经纬度
          },
          header: {
            "content-type": "application/json",
          },
          success: function (res) {
            console.log("坐标转换和查询天气", res.data);
            wx.setStorageSync(
              "city",
              res.data.regeocode.addressComponent.adcode //地区编码
            );
            that.setData({
              location:
                res.data.regeocode.addressComponent.city +
                " " +
                res.data.regeocode.addressComponent.district,
            });

            wx.request({
              url: "https://restapi.amap.com/v3/weather/weatherInfo",
              data: {
                key: KEY, //填入自己申请到的Key
                city: res.data.regeocode.addressComponent.adcode, //传入地区编码
              },
              header: {
                "content-type": "application/json",
              },
              success: function (weather) {
                console.log("天气", weather.data);
                that.setData({
                  weatherNum: weather.data.lives[0].temperature, //温度
                  weatherText: weather.data.lives[0].weather, //天气描述 晴天 下雨天...
                  welcome: "欢迎欢迎!今天的天气是 " + weather.data.lives[0].weather, //欢迎语
                });
              },
            });
          },
        });
      }
    },
    fail(err) {
      console.log("获取经纬度错误信息,看到此提示信息请去文档网站右上角常见问题寻找答案", err);
    },
  });
}

回显位置和天气情况并显示天气图图标

上述变量中绑定的变量温度为 weatherNum 天气描述为 weatherText 显示 :

html
<view class="welcome">{{welcome}}</view>

<view class="weather-num" wx:if="{{weatherNum}}">{{weatherNum}}℃</view>

天气图标显示 :

6-8

html
<wxs src="../../wxs/tools.wxs" module="tools"></wxs>
<view>
  <image
    wx:if="{{weatherText === '晴'}}"
    class="weather"
    src="/images/weather/qing.png"
    mode="widthFix" />
  <image
    wx:if="{{tools.strIndexOf(weatherText,'雨')}}"
    class="weather"
    src="/images/weather/yu.png"
    mode="widthFix" />
  <image
    wx:if="{{tools.strIndexOf(weatherText,'雪')}}"
    class="weather"
    src="/images/weather/xue.png"
    mode="widthFix" />
  <image
    wx:if="{{weatherText === '多云'}}"
    class="weather"
    src="/images/weather/duoyun.png"
    mode="widthFix" />
  <image
    wx:if="{{weatherText === '阴'}}"
    class="weather"
    src="/images/weather/duoyun.png"
    mode="widthFix" />
  <image
    wx:if="{{weatherText === '雷'}}"
    class="weather"
    src="/images/weather/lei.png"
    mode="widthFix" />
  <image
    wx:if="{{weatherText === '冰雹'}}"
    class="weather"
    src="/images/weather/bingbao.png"
    mode="widthFix" />
</view>

考虑到天气可能是大雪/小雪、大雨/小雨等 和我们定义的雨、雪不一样 所以要引入一个函数 根据包含了 雨、雪的状态来显示相应的图

js
function strIndexOf(weatherText, text) {
  //str.indexOf("")的值为-1时表示不包含
  if (weatherText) {
    // console.log(weatherText, text);
    if (weatherText.indexOf(text) !== -1) {
      return true;
    } else {
      return false;
    }
  }
}

module.exports = {
  strIndexOf: strIndexOf,
};

//使用方法
strIndexOf(weatherText, "雨"); //weatherText中包含了雨则显示  雨/大雨/小雨/雷阵雨
strIndexOf(weatherText, "雪"); //weatherText中包含了雪则显示  雪/大雪/小雪

参考资料

有时候传入参数不当会导致接口报错 这里可以根据报错状态码查询问题

返回的天气文字描述对照表 列举了天气功能中所能返回的天气现象

powered by 天人之际工作室