LoginSignup
1
3

More than 3 years have passed since last update.

YOLP の WebAPI で1時間以内の降水予想と雨雲レーダー地図画像を取得する

Last updated at Posted at 2020-09-08

概要

  • YOLP (Yahoo! Open Local Platform) の Yahoo!ジオコーダAPI + 気象情報API + Yahoo!スタティックマップAPI を使用して1時間以内の降水予想と雨雲レーダー地図画像を取得する
  • 動作確認環境: Node.js v14.9.0 + node-fetch 2.6.1

node-fetch のインストール

$ npm i node-fetch

サンプルコード

'use strict'

const fs = require('fs')
const qs = require('querystring')
const fetch = require('node-fetch') // window.fetch 互換 Fetch API

// アプリケーションID
const APPID = 'YOUR_APPLICATION_ID'

// テキストにマッチした住所情報を取得する
async function getAddressLocation(text) {

  // URLを組み立てる
  const params = qs.stringify({
    appid: APPID, // アプリケーションID
    query: text, // 検索文字列
    al: 2, // 市区町村レベルの住所を検索
    exclude_seireishi: false, // 検索対象から政令指定都市レコードを除外するか
    results: 1, // 検索結果を1件以内に設定
    output: 'json' // レスポンスをJSONにする
  })
  const url = 'https://map.yahooapis.jp/geocode/V1/geoCoder?' + params

  // Yahoo!ジオコーダAPIをコールする
  const res = await fetch(url)
  if (!res.ok) {
    throw res
  }
  const json = await res.json()
  console.log(JSON.stringify(json, null, '  '))

  // 住所情報を取得する
  if (json.Feature && json.Feature.length != 0) {
    // ヒットした1つめの住所を使う
    var name = json.Feature[0].Name
    var ll = json.Feature[0].Geometry.Coordinates.split(',')
    var bbox = json.Feature[0].Geometry.BoundingBox
    return { address: name, lat: ll[1], lon: ll[0], bbox: bbox }
  } else {
    throw '住所にヒットしなかった'
  }
}

// 住所に紐ついた緯度経度とバウンディングボックスの4点の緯度経度をつなげた文字列を返す
function getCoordinatesFromBoundingBox(location) {
  var p = location.bbox.split(' ')
  var ll0 = p[0].split(',')
  var ll1 = p[1].split(',')
  var c =
    location.lon + ',' + location.lat + ' ' +
    ll0[0] + ',' + ll0[1] + ' ' +
    ll1[0] + ',' + ll0[1] + ' ' +
    ll0[0] + ',' + ll1[1] + ' ' +
    ll1[0] + ',' + ll1[1]
  return c
}

// 降水情報を取得する
async function getWeatherInfo(location) {

  // 雨の強さを取得したい緯度経度(10点まで可)を指定
  // フォーマット: 経度,緯度 経度,緯度 経度,緯度 経度,緯度 ... 
  // 経度・緯度の順番でコンマ区切り
  // 経度・緯度毎に半角スペース区切り
  const coordinates = getCoordinatesFromBoundingBox(location)

  // URLを組み立てる
  var params = qs.stringify({
    coordinates: coordinates,
    appid: APPID, // アプリケーションID
    output: 'json' // レスポンスをJSONにする
  })
  const url = 'https://map.yahooapis.jp/weather/V1/place?' + params

  // 気象情報APIをコールする
  const res = await fetch(url)
  if (!res.ok) {
    throw res
  }
  const json = await res.json()
  console.log(JSON.stringify(json, null, '  '))
  return json
}

// 降水情報をテキストに変換する
function getWeatherText(weather, location) {
  var ame = false // 雨が降るか否か
  // 1箇所でも雨が降る場所があるか
  for (var feature of weather.Feature) {
    for (var w of feature.Property.WeatherList.Weather) {
      if (w.Rainfall > 0) { // 降水強度が0より大きいか
        ame = true
        break
      }
    }
  }
  if (ame) {
    return location.address + "では、1時間以内に雨が降りそうです。"
  } else {
    return location.address + "では、1時間以内には雨が降らないようです。"
  }
}

// 地図画像を取得する
async function getMapImage(location) {

  // URLを組み立てる
  var params = qs.stringify({
    width: 800,
    height: 600,
    lat: location.lat,
    lon: location.lon,
    z: 12, // ズームレベル
    overlay: 'type:rainfall', // 現在時刻の雨雲レーダーを表示
    style: 'base:monotone', // モノトーンスタイル
    appid: APPID, // アプリケーションID
  })
  const url = 'https://map.yahooapis.jp/map/V1/static?' + params

  // Yahoo!スタティックマップAPIをコールする
  const res = await fetch(url)
  if (!res.ok) {
    throw res
  }
  return Buffer.from(await res.arrayBuffer())
}

(async () => {

  try {
    // コマンドライン引数を取得
    const text = process.argv[2]
    console.log('Input: ' + text)

    // 住所情報を取得
    const location = await getAddressLocation(text)

    // 降水情報を取得
    const weather = await getWeatherInfo(location)

    // 降水情報をテキストに変換
    const weatherText = getWeatherText(weather, location)
    console.log('Message: ' + weatherText)

    // 地図画像を取得
    const mapImage = await getMapImage(location)

    // 地図画像データをファイルに出力
    await fs.promises.writeFile('map.png', mapImage)

  } catch (err) {
    console.error(err)
  }
})()

実行結果

$ node app.js 福島市
Input: 福島市
{
  "ResultInfo": {
    "Count": 1,
    "Total": 1,
    "Start": 1,
    "Status": 200,
    "Description": "",
    "Copyright": "",
    "Latency": 0.016
  },
  "Feature": [
    {
      "Id": "07201",
      "Gid": "",
      "Name": "福島県福島市",
      "Geometry": {
        "Type": "point",
        "Coordinates": "140.47469440,37.76089730",
        "BoundingBox": "140.22998100,37.62433900 140.57092800,37.97664700"
      },
      "Category": [],
      "Description": "",
      "Style": [],
      "Property": {
        "Uid": "09564f93998c22a98d1921dbd866d75b73f7bd6a",
        "CassetteId": "b22fee69b0dcaf2c2fe2d6a27906dafc",
        "Yomi": "フクシマケンフクシマシ",
        "Country": {
          "Code": "JP",
          "Name": "日本"
        },
        "Address": "福島県福島市",
        "GovernmentCode": "07201",
        "AddressMatchingLevel": "2",
        "AddressType": "市"
      }
    }
  ]
}
{
  "ResultInfo": {
    "Count": 5,
    "Total": 5,
    "Start": 1,
    "Status": 200,
    "Latency": 0.049625,
    "Description": "",
    "Copyright": "(C) Yahoo Japan Corporation."
  },
  "Feature": [
    {
      "Id": "202009082115_140.47469_37.760897",
      "Name": "地点(140.47469,37.760897)の2020年09月08日 21時15分から60分間の天気情報",
      "Geometry": {
        "Type": "point",
        "Coordinates": "140.47469,37.760897"
      },
      "Property": {
        "WeatherAreaCode": 3610,
        "WeatherList": {
          "Weather": [
            {
              "Type": "observation",
              "Date": "202009082115",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082125",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082135",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082145",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082155",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082205",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082215",
              "Rainfall": 0
            }
          ]
        }
      }
    },
    {
      "Id": "202009082115_140.22998_37.624339",
      "Name": "地点(140.22998,37.624339)の2020年09月08日 21時15分から60分間の天気情報",
      "Geometry": {
        "Type": "point",
        "Coordinates": "140.22998,37.624339"
      },
      "Property": {
        "WeatherAreaCode": 3630,
        "WeatherList": {
          "Weather": [
            {
              "Type": "observation",
              "Date": "202009082115",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082125",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082135",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082145",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082155",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082205",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082215",
              "Rainfall": 0
            }
          ]
        }
      }
    },
    {
      "Id": "202009082115_140.57093_37.624339",
      "Name": "地点(140.57093,37.624339)の2020年09月08日 21時15分から60分間の天気情報",
      "Geometry": {
        "Type": "point",
        "Coordinates": "140.57093,37.624339"
      },
      "Property": {
        "WeatherAreaCode": 3610,
        "WeatherList": {
          "Weather": [
            {
              "Type": "observation",
              "Date": "202009082115",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082125",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082135",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082145",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082155",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082205",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082215",
              "Rainfall": 0
            }
          ]
        }
      }
    },
    {
      "Id": "202009082115_140.22998_37.976647",
      "Name": "地点(140.22998,37.976647)の2020年09月08日 21時15分から60分間の天気情報",
      "Geometry": {
        "Type": "point",
        "Coordinates": "140.22998,37.976647"
      },
      "Property": {
        "WeatherAreaCode": 3520,
        "WeatherList": {
          "Weather": [
            {
              "Type": "observation",
              "Date": "202009082115",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082125",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082135",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082145",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082155",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082205",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082215",
              "Rainfall": 0
            }
          ]
        }
      }
    },
    {
      "Id": "202009082115_140.57093_37.976647",
      "Name": "地点(140.57093,37.976647)の2020年09月08日 21時15分から60分間の天気情報",
      "Geometry": {
        "Type": "point",
        "Coordinates": "140.57093,37.976647"
      },
      "Property": {
        "WeatherAreaCode": 3420,
        "WeatherList": {
          "Weather": [
            {
              "Type": "observation",
              "Date": "202009082115",
              "Rainfall": 1.35
            },
            {
              "Type": "forecast",
              "Date": "202009082125",
              "Rainfall": 0.75
            },
            {
              "Type": "forecast",
              "Date": "202009082135",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082145",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082155",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082205",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "202009082215",
              "Rainfall": 0
            }
          ]
        }
      }
    }
  ]
}
Message: 福島県福島市では、1時間以内に雨が降りそうです。

map.png

参考資料

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3