Node-REDで地図の表示とwhat3wordsAPI連携【ハンズオン資料】

この記事は、2020/10/20（火）に開催のイベント[「Node-REDで色々試すハンズオン Tec-Nomad ・ ビジュアルプログラミング交流会 コラボ」](https://visualprogramming.connpass.com/event/188685/)のハンズオン資料として準備したものです。
![f1fb292647e080fbcaf4002246bc3c63.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480279/9f8c8a52-27ef-35f2-9e78-c01388d0bc0c.png)

ハンズオンでは、3名の講師（ @youtoy  さん、 @kmaepu さん、自分）がそれぞれ Node-RED を利用した異なる内容を取り扱います。また Node-RED を利用する環境に [enebular（エネブラー）](https://www.enebular.com/ja/)を用います。

# What3wordsとは？
ジオコーディング技術の一つで、新しい位置の示し方です。
地球上を3メートル角のマス目に区切り、3つの単語でそのマスの位置を表します。

例えば東京タワーの位置は
「けんぶつ・このは・はかり」
![スクリーンショット 2020-10-17 17.11.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480279/871b670f-517b-cd22-eaca-1f19e4cfde6b.png)

## ディズニーランドもディズニーリゾートも同じ住所
人類はずいぶん長いこと位置を示すのに「住所」というものを使ってきましたが、
住所って実はすごく曖昧ですよね。
ディズニーランドもディズニーリゾートも同じ一つの住所が割り当てられています。

What3wordsのようなジオコーディング技術を使えば、3メートル角単位で位置を指定できます。
簡単な3つの単語で構成されているため子供でも覚えやすそうです。
ディズニーランドや広い建物内でUber Eatsのようなサービスが使えるようになるかも！？

# 今日のゴール
![マイドキュメント (51) 2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480279/cf8b65ac-7325-f8bf-2fc9-41759bdd9156.jpeg)


# What3Words APIを叩いてみる
下記のようにノードを配置します
左から、injectionノード、http requestノード、jsonノード、debugノードです。
![スクリーンショット 2020-10-17 18.11.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480279/8684f288-af02-ec70-c184-32dd2e59c664.png)

## injectノード
ペイロードの種類をJSONに設定し、JSONエディタに下記を入力
※API KEYは↓から登録をして取得してください。
[What3Words APIはこちら](https://what3words.com/ja/products/public-api/)

```json
{
    "words": "りんご・たぬき・ごはん",
    "key": "取得したAPI KEYを入力してください"
}

```
## http requestノード
URL: `https://api.what3words.com/v3/convert-to-coordinates`
「msg.payloadをクエリパラメータに追加」にチェックを入れてください
![スクリーンショット 2020-10-17 18.15.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480279/9646f694-9ac0-ae56-21ee-d322cd966d16.png)

injectノードを押して、結果が戻ってくれば成功です！
![スクリーンショット 2020-10-17 18.18.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480279/5e170a0b-c2f9-3c7f-bde9-8bf8222ca6f1.png)

# World Mapノードで地図を表示する

## World Mapノードをインストール
設定→パレット→`node-red-contrib-web-worldmap`で検索し、インストール
![スクリーンショット 2020-10-17 18.48.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480279/019e9870-c52d-1e2b-f480-431203375b34.png)

![スクリーンショット 2020-10-17 18.49.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480279/c1aa9349-229d-12d9-caee-fc9778aadf7a.png)
左上から、changeノード x2、functionノード、worldmapノード、debugノード

## changeノードその１
What3words APIから取得した緯度経度を格納します。
![スクリーンショット 2020-10-17 18.51.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480279/405edaea-6b18-0c3d-f19e-c5599ebf5e10.png)
上から
`result.lat`
`payload.coordinates.lat`
`result.lon`
`payload.coordinates.lng`
`result.name`
`payload.words`

緯度 latitudeの略は「lat」で共通なのですが、
経度 longitudeは「lon」派と「lng」派がいて、紛らわしいですね...

## changeノードその2
payloadの内容をresultに格納します。
![スクリーンショット 2020-10-17 18.54.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480279/d6109d60-2430-7b9a-dfbe-83a6716640b2.png)

## functionノード
```json
msg.payload.layer = "What3Words";
msg.payload.icon = ":face_with_raised_eyebrow:";
msg.payload.iconColor = "orange";

return msg;

```

msg.payload.iconは、ピンのデザインです。
`face_with_raised_eyebrow`は眉毛を上げてる顔アイコン。
好きなものに変更してください。
:apple:→`:apple:` 
:bear: →`:bear:`
:bee: → `:bee:`
などなど

## World Mapノード
Web Pathを`worldmap`に変更してください。
![スクリーンショット 2020-10-17 18.58.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480279/0d1bd512-6524-1eee-3269-80ca3e209ad1.png)

# アクセスしてみる
`Node-REDのエンドポイント/worldmap` にアクセスしてください。
エンドポイントは「i」アイコンから確認ができます。
![スクリーンショット 2020-10-17 17.46.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480279/f27d06bc-a5fa-dae0-ff20-a0218b17beae.png)

injectノードを押して、アイコンが表示されたら成功です！
うまく動かない場合、地図をリロードするとうまくいくことがあります。
![スクリーンショット 2020-10-17 19.02.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480279/1f4f1373-ec74-0ab6-0a33-5a8489153619.png)

# 完成品

```json
[{"id":"ffb31cec.d1dc8","type":"tab","label":"フロー 1","disabled":false,"info":""},{"id":"b7ec3c49.1805f","type":"inject","z":"ffb31cec.d1dc8","name":"パラメーター","topic":"","payload":"{\"words\":\"りんご・たぬき・ごはん\",\"key\":\"YOUR API KEY\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":220,"wires":[["bf5eb9d9.acc3c8"]]},{"id":"bf5eb9d9.acc3c8","type":"http request","z":"ffb31cec.d1dc8","name":"","method":"GET","ret":"txt","paytoqs":true,"url":"https://api.what3words.com/v3/convert-to-coordinates","tls":"","persist":false,"proxy":"","authType":"","x":350,"y":220,"wires":[["eaf44955.a7d5d8"]]},{"id":"d80a36ff.512dd8","type":"change","z":"ffb31cec.d1dc8","name":"緯度経度","rules":[{"t":"set","p":"result.lat","pt":"msg","to":"payload.coordinates.lat","tot":"msg"},{"t":"set","p":"result.lon","pt":"msg","to":"payload.coordinates.lng","tot":"msg"},{"t":"set","p":"result.name","pt":"msg","to":"payload.words","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":380,"wires":[["d3eaaf.74ccd55"]]},{"id":"406d805d.ecacb","type":"debug","z":"ffb31cec.d1dc8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":730,"y":580,"wires":[]},{"id":"eaf44955.a7d5d8","type":"json","z":"ffb31cec.d1dc8","name":"","property":"payload","action":"","pretty":false,"x":510,"y":220,"wires":[["d80a36ff.512dd8","a53215bd.94b408"]]},{"id":"d302430b.0e73c","type":"worldmap","z":"ffb31cec.d1dc8","name":"","lat":"","lon":"","zoom":"1","cluster":"","maxage":"","hiderightclick":"false","coords":"none","path":"worldmap","x":770,"y":460,"wires":[]},{"id":"d2d750f3.fd715","type":"function","z":"ffb31cec.d1dc8","name":"パラメーター設定","func":"msg.payload.layer = \"What3Words\";\nmsg.payload.icon = \":face_with_raised_eyebrow:\";\nmsg.payload.iconColor = \"orange\";\n\nreturn msg;","outputs":1,"noerr":0,"x":530,"y":500,"wires":[["406d805d.ecacb","d302430b.0e73c"]]},{"id":"d3eaaf.74ccd55","type":"change","z":"ffb31cec.d1dc8","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"result","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":540,"y":380,"wires":[["d2d750f3.fd715"]]},{"id":"a53215bd.94b408","type":"debug","z":"ffb31cec.d1dc8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":690,"y":220,"wires":[]}]
```