概要
- 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時間以内に雨が降りそうです。