GlideとGASで静岡市の道路規制情報を表示するPWAアプリを作る

# はじめに
この記事は[静岡 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/shizuoka)の18日目の記事です。
生まれてこの方ずっと静岡にいますが、思えばイベント等に顔を出したこともなく、自社以外で静岡のPGやSEの方と交流することもなく生きてきたので、何かのきっかけになればいいなと思い参加しました！

とはいったものの、何を書いたらいいのやら・・・

このアドベントカレンダーのテーマ的には、

- プログラミングを使って静岡の課題を見つけたり、解決
- 静岡のIT系イベントの情報、参加レポート

のどちらか(もしくは両方)を書いている方が多いのですが、先に書いたように自分はイベントに参加した経験もないので、自然と前者のテーマで書くことになります。うーん・・・

とあれこれと頭を悩ませながら「静岡 IT」のようなワードでテーマ探しをしていると、静岡市の道路を対象に災害情報や規制情報を公開している[しずみちinfo](https://shizuokashi-road.appspot.com)というサービスを見つけました。
しずみちinfoでは公開内容をオープンデータとして提供しており、`WebAPI`を利用することで入手できるようです。
仕様等々に目を通してみると、かなり簡単に利用できるように作られているので、これを利用して何かを作ってみようと思い立ちました。

概要としては、最近勉強中の`Google Apps Script`(以下`GAS`)を使ってしずみちinfoのデータを`GoogleSpreadSheet`に取り込み、`GoogleSpreadSheet`を読み込ませることでノンプログラミングで`PWAアプリ`を作成できるサービス[Glide](https://www.glideapps.com)を利用し、静岡市内の道路規制情報を一覧表示する`PWAアプリ`を作ることにしました。

作成したPWAアプリは[こちら](https://iqgsx.glideapp.io)

<img width="381" alt="pwa.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435429/47709bb0-557e-a00f-3777-4de280d5d76a.png">


# 必要なもの

- Googleアカウント  
`GAS`のコーディングや`Glide`の利用のためGoogleアカウントは必須になります。
書き込み用のスプレッドシートと`GAS`のプロジェクトを作成しておきましょう。

# 技術Tips

以下、コアとなる要素部分の実装を抜粋しています。

## GASでAPIを実行する

1回のリクエストで取得できるデータ数に限りがあるため注意が必要です。 

```javascript
  // ページ数
  var page = 1;
  
  // しずみちinfo API
  var uri = 'https://openapi.city.shizuoka.jp/opendataapi/servicepoint/roadRegulation?row=100';
  var option = {
    'method': 'get',
    'contentType': 'application/json'
  }
  
  // API実行
  var response = UrlFetchApp.fetch(uri + "&page=" + page, option);
  
  // 取得データ
  var results = JSON.parse(response.getContentText()).Data.features;
  // 総ページ数
  var totalPage = JSON.parse(response.getContentText()).TotalPage;
 
  // 総ページ数に満たない場合はページ数を上げてリクエスト続行  
  while(page < totalPage) {
    page++;
    response = UrlFetchApp.fetch(uri + "&page=" + page, option);
    // 追加の取得結果をresultsに結合
    results = results.concat(JSON.parse(response.getContentText()).Data.features);
  }
```
これを1日1回毎朝実行し、取得結果を`GoogleSpreadSheet`に書き込みます。

ちなみに実行レスポンスはこんな感じで返ってきます。

```json
{
"Success": true,
"Data":{
"features":[{"id": 180, "properties":{"regulation_type": "全面通行止", "reason_detail": "崩土", /* 略 */}}], 
"type": "FeatureCollection"
},
"Error": null,
"TotalRecord": 155,
"TotalPage": 6,
"PageRecord": 30
}
```

今回は`features`内の`properties`を利用していきます。
`properties`の内容は以下のような構造です。

```json
"properties":{
"regulation_type": "全面通行止",
"reason_detail": "崩土",
"reason": "災害（土砂災害）",
"category": "災害等",
"road_name": "久保山線",
"start_address": "静岡市清水区由比入山",
"end_address": "静岡市清水区由比入山１５８３",
"mid_point_longitude": 138.557876587,
"mid_point_latitude": 35.151756287,
"start_date": "2014-10-08 16:00:00",
"end_date": null,
"clear_date": null,
"public_memo": null,
"timezone_onedayflag": null,
"timezone_timeperiodflag": null,
"timezones": null,
"timezone_comment": "",
"responsible_department_name": "清水道路整備課",
"responsible_department_tel": null,
"related_files":[],
"open_flag": "1",
"bigevent_id": null,
"deregulation_flag": "0"
}
```

技術的には以上で、特段珍しいことはしていないです。
あとは素直に取得した内容をスプレッドシートに記載するだけなので、参考にさせていただいた記事を貼るだけに留めます。

参考
- [GASでSpreadsheetを操作する自分的ベストプラクティス](https://qiita.com/ryan5500/items/e72eb205fbe006c2eb6f)
- [【GoogleAppsScript】スプレッドシート操作(セルへのデータ書き込み偏)](https://qiita.com/chihiro/items/20a54865c15966e807ee)

# Glideについて  
ざっくり言うとスプレッドシートをそのままPWAアプリ化できるサービスです。
PWAアプリはWebアプリでありながらネイティブアプリ特有の機能を使えるというナウいアプリです(雑)。

以下のような感じで、読み込ませたスプレッドシートのどのカラムをどこに表示させるかを指定するだけでアプリができあがります(プログラミングを全くしないのがすごい！)。

<img width="1665" alt="glide.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435429/cd3e56b2-a36a-93af-8efc-4f72d3254ddc.png">

しずみちinfoではアプリ用に各規制種別のアイコン画像が既に用意されていましたが、どちらかといえばマップにプロットする用のアイコンっぽかったので、今回は利用しないことにしました。

# おわりに
AdventCalendarに参加しようと思い立ったのが11月の下旬ごろで、そこから実際にPWAアプリとして公開してこの記事を書くまで、作業時間としては3日とかかりませんでした。
ただ、残念なことに私のデザインセンスがないため、ちょっと分かりにくい表示をしている箇所もちらほら見受けられます(そのあたりはコメントにてご指摘いただけるとありがたいです)。
私自身、`ReactNative`でスマホ向けアプリ開発の経験があり、画面数が少ないとはいえ同じ品質のものを作るとなると結構な時間がかかるので、Glideすげぇ！というのが今回の主な感想です。

ただ、簡単にアプリが作れる反面、スプレッドシートをDBとして使う関係上、正規化などができないため冗長な構成にならざるを得ないです。また、当然ですがアプリのフォーマットはGlide上で選択できるものに限られます。
それらの点が気にならない(もしくは気にする必要のない構成)ならかなり有益なサービスであるといえます。

ここまでご覧いただいてありがとうございました。
明日は[@cupperさん](https://qiita.com/cupper)です。