実際に動かしてみる

では実際に動かしてみましょう。

今度はこちらのフローに注目します。Airtable 設定 → airtable ノード まわりは、先ほどチェックした Airtable データ取得と同じ仕組みです。
/osm という URL からアクセスがあると Airtable からデータを取得して OpenStreetMap の HTML を構築して、最後の http と書かれた http out ノードでブラウザに表示します。

いまエディタで起動している仕組みは、右上の i アイコンをクリックすると、どの URL で動いているかが確認できます。

クリックして表示された URL をクリックして、ブラウザの別タブで URL が表示されます。

Cannot GET / と出てしまうのは「正常」です。いまは /osm でなく / を見ようとしていて、何もないのでのでこのような表示になります。

では、ブラウザのアドレスバーで URL に /osm をつけて Enter キーを押してアクセスしましょう。

このように enebular で表示された OpenStreetMap に Airtable で設定した地点データがうまく反映されたものが表示されます!
(時間があれば)仕組みの説明

時間があれば今回の仕組みのお話をします。enebular の Web エディタで仕組みを見てみましょう。
こちらのフローが今回のメインの仕組みです。

[get] /osm と書かれた http in ノードです。これがあると HTTP GET リクエスト(ブラウザからのアクセスは GET リクエスト)で、Node-RED で立ち上がっているサーバー URL に /osm というパスでアクセスされたときに動作がはじまります。

こちらが Airtable から地図に配置するデータを取ってくる部分です。

Airtable 設定 を書かれたノードは change ノードです。隣の airtable ノードで実際にデータを取ってくるのですが、そのまえに指示を整えます。

ノードをダブルクリックするとこのような設定なっています。msg.paylod という値に、指示の JSON データを設定しています。

{
 "fields": [
 "Name",
 "Lat",
 "Long",
 "Message"
 ]
}
中身はこのような JSON データです。

このように、項目 firlds から、Name・Lat・Long・Message を取ってくる指示です。

airtable ノードで Airtable からデータを取得します。

ダブルクリックしてプロパティを表示してみます。Set API Key で、読み込む Base と API キーが設定されていれば、テーブル名に書かれたテーブルから Operation select ということでデータの中身を配列でまとめて取ってきます。

ここは実際の HTML を表示する部分です。airtable からデータが取得できていれば、そのデータを地図の HTML に割り振ります。

マップ 設定 という名前の change ノードでは、となりで HTML の実際のソースを表示するための、必要な値を指示しています。

msg.mspSetting というオブジェクトを作って準備をはじめます。
- msg.mapSetting.startLocationLat- 地図が最初に表示するときの緯度
 
- mapSetting.startLocationLong- 地図が最初に表示するときの経度
 
こちらを設定しています。

- msg.mapSetting.marker1LocationLat- 最初に表示されるピンの緯度
 
- msg.mapSetting.marker1LocationLong- 最初に表示されるピンの経度
 
- msg.mapSetting.marker1Message- 最初に表示されるピンのメッセージ
 
を設定しつつ、
- msg.mapSetting.baseData- これは手前で取得した Airtable データが msg.payload に入っているので、HTML 内に配列を伝えるために文字列にして msg.mapSetting.baseDataに割り当てています
 
- これは手前で取得した Airtable データが msg.payload に入っているので、HTML 内に配列を伝えるために文字列にして 

そして、いよいよ HTML 出力と書かれた template ノード。template ノードは HTML のような、長文のコードに対して、テンプレート機能を使ってうまくデータを流し込みます。
以下のような内容です。
<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css"
 integrity="sha256-kLaT2GOSpHechhsozzB+flnD+zUyjE2LlfWPgU04xyI="
 crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js"
 integrity="sha256-WBkoXOwTeyKclOHuWtc+i2uENFpDZ9YPdf5Hf+D7ewM="
 crossorigin=""></script>
<style>
 #map { height: 360px; }
</style>
</head>
<body>
<div id="map"></div>
<script></script>
</body>
</html>
説明します。
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css"
 integrity="sha256-kLaT2GOSpHechhsozzB+flnD+zUyjE2LlfWPgU04xyI="
 crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js"
 integrity="sha256-WBkoXOwTeyKclOHuWtc+i2uENFpDZ9YPdf5Hf+D7ewM="
 crossorigin=""></script>
こちらで地図ライブラリの Leaflet の準備をします。
<body>
<div id="map"></div>
bory タグの直後の <div id="map"></div> を狙って地図が表示しれます。以降の <script> タグでいろいろな設定をします。
// 直接 Airtable のデータを埋め込み
const baseData = {{{mapSetting.baseData}}};
console.log(baseData);
// マップの初期位置
let map = L.map('map', {
 center: [
 {{mapSetting.startLocationLat}},
 {{mapSetting.startLocationLong}}
 ],
 zoom: 16,
});
こちらが、手前の change ノードから値を {{}} や {{{}}} で囲われた名前で呼び出して、JavaScript に準備します。{{}} はテンプレートとしての通常のデータ呼び出し、 {{{}}} は通常では内容がエスケープしてしまうのを抑制して値を渡してくれます。
let map = L.map で、はじまる部分で、最初に地図がどの緯度経度で中央に表示されるかや、zoom で拡大値を設定してます。
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
 maxZoom: 19,
 attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);
こちらで実際に地図を表示しています。tile (実際の地図のビジュアル)を OpenStreetMap から読み込まれていることも分かりますね。
// マーカー 1 番目
let marker1 = L.marker(
 [
 {{mapSetting.marker1LocationLat}},
 {{mapSetting.marker1LocationLong}}
 ]
).addTo(map);
marker1.bindPopup("{{{mapSetting.marker1Message}}}").openPopup();
そして、Airtable のデータと関係なく、一番最初にピンを 1 つ配置する部分です。こちらも手前の change ノードで連絡された値を使ってます。
// Airtable Marker
for(let i = 0; i < baseData.length; i++){
 console.log(i);
 const item = baseData[i];
 const lat = Number(item.fields.Lat);
 const lon = Number(item.fields.Long);
 let marker = L.marker([lat, lon]).addTo(map);
 marker.bindPopup("<b>" + item.fields.Name + "</b><p>" + item.fields.Message + "</p>");
}
そして、最後が Airtable から受け取ったデータをループで配置していく部分です。Airtable の配列が 1 つ 1 つ読み込まれ、緯度・経度・メッセージ内容をもとにピンとして廃止されていきます。