実際に動かしてみる
では実際に動かしてみましょう。
今度はこちらのフローに注目します。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 つ読み込まれ、緯度・経度・メッセージ内容をもとにピンとして廃止されていきます。