25
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

GoogleDriveSpreadSheet上の住所一覧を地図にプロット

Last updated at Posted at 2014-06-20

事の発端

区から成人歯科健康診査のお知らせが届きました。診療費を補助してもらえる大変ありがたい精度なのですが、診療機関一覧は名前、住所、電話番号しか載ってません。できれば家から近い診療所にかかりたいと思い、一つ一つ地図にプロットしていたのですがいかんせん面倒くさい。そこで、GoogleDriveのSpreadSheetとGoogle Apps Scriptでこんなアプリを作ってみました。

アプリ作成

スプレッドシート

こんなスプレッドシートを書きます。ここでは新宿周辺のローソンの店舗を例にしてみました。
スクリーンショット 2014-06-20 21.29.46.png

スクリプト

スプレッドシート上の「ツール」メニュー→「スクリプトエディタ」を選択してスクリプトエディタを開きます。
スクリーンショット 2014-06-20 21.29.58.png

空のプロジェクトを作成してスクリプトエディタ上に以下のコードを記述して、適当な名前でプロジェクトを保存してください。

コード.gs
var WIDTH_CELL          = "B1";
var HEIGHT_CELL         = "B2";
var ZOOM_CELL           = "B3";
var CENTER_CELL         = "B4";
var DATA_START_ROW = 7;
var VISIBLE_COLUMN = 3;

// スプレッドシートを開いた時に自動的に実行される関数
function onOpen() {
  // メニューを作成
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [
    {
      name : "地図を作成",
      functionName : "createMap"
    },
    {
      name : "地図を削除",
      functionName : "resetMap"
    }
  ];
  spreadsheet.addMenu("地図作成メニュー", entries);
};

// 地図を作成メニューで実行する関数
function createMap(argSheet) {
  // 現在のシートを得る
  var sheet = SpreadsheetApp.getActiveSheet();
  
  // 各セルのパラメータを元に地図を作成
  var map = Maps.newStaticMap()
       .setLanguage("ja")
       .setSize(sheet.getRange(WIDTH_CELL).getValue(), sheet.getRange(HEIGHT_CELL).getValue())
       .setZoom(sheet.getRange(ZOOM_CELL).getValue())
       .setCenter(sheet.getRange(CENTER_CELL).getValue());

  // 住所にマーカーをプロットする
  var lastRow = sheet.getLastRow();
  for (var row = DATA_START_ROW; row <= lastRow; row++) {
    if (sheet.getRange(row, VISIBLE_COLUMN).getValue() == "") {
      continue;
    }
    map.addMarker(sheet.getRange(row, 2).getValue());
  }  
  
  // 地図をシートに挿入
  sheet.insertImage(map.getMapUrl(), 5, 1);
};

// 地図を削除メニューで実行する関数
function resetMap() {
  var spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
  
  // 現在のシートの名前を保存しておく
  var currentSheet = spreadSheet.getActiveSheet();
  var sheetName = currentSheet.getName();
  
  // 新しいシートを作成して値をコピーする
  var newSheet = spreadSheet.insertSheet();
  currentSheet.getRange("A:D").copyTo(newSheet.getRange("A:D"));
  
  // 現在のシートを削除
  spreadSheet.deleteSheet(currentSheet);
  
  // シートの名を復旧
  newSheet.setName(sheetName);
  
  // 新しいシートをアクティブにする
  newSheet.activate();
}

実行

地図を作成

スプレッドシートに戻り、ブラウザを更新してください。少しするとメニューバーに「地図作成メニュー」が出現します。

スクリーンショット 2014-06-20 21.34.11.png

「地図作成」メニュー→「地図を作成」を選びます。少しすると、指定した住所にマーカーが表示された地図が表示されます(最初は認証を求められるかも)。

スクリーンショット 2014-06-20 21.37.05.png

パラメータ変更

スプレッドシート上の「横幅」、「縦幅」、「倍率」、「中心」の値で、それぞれ地図の横幅、縦幅、倍率、中心を変更できます。「地図に表示」列の「◯」の有無でプロットする、しないを切り替えることができます。

試しに「倍率」を変更してメニューから先程と同様に「地図を作成」を実行すると、倍率が変わります。

地図を削除

先ほどの動作では地図を更新しているように
見えますが、実は元地図の上に新しい地図を重ねているだけです。試しに表示されている地図を削除してみてください。最初の地図が残っているのがわかると思います。

なぜこんなことになっているかというと、GoogleAppsScriptに画像削除のAPIが(探した限り)見当たらなかったからです。なので地図の作成を続けているとどんどん古い地図が溜まっていってしまいます。

そこで地図削除機能の登場です。「地図作成」メニュー→「地図を削除」を選択してください。地図が消えるはずです。
この機能は新しいシートに値部分だけを丸々コピーして元シートは削除するという荒業で実現しています。

反省点

グリグリしたかった

Google App Scriptから作成できるマップは「静的」なマップです。Goole EarthやGoogle Mapsのようにマウスでグリグリ動かせません。ちょっと使いづらいですね。

リアルタイムで更新したかった

現状だと、パラメータなどを変更したら毎回メニューを選択して更新する必要があります。一応、「トリガー」という機能で値が更新されたら地図を更新するということもできたのですが、GAS自体がそんなに早くないというのと、画像を削除できないので重くなる一方だったのでやめました。

Google Maps APIを使ったほうが良かったと思う

以上のことから、こういう用途ではGoogle Maps APIを使ったほうが良かったのかなと思います。よく知らないんですけどね。しかし、まぁGASの勉強になったので良かったです。

Qiita初投稿

全然関係ないですがこの投稿が自分のQiita初投稿で、あれやこれやと画像をアップロードしてみたのですが、あっという間に月の上限を超えてしまい全部アップロードできず・・・結局重要な数枚のみ残しました。未加工で思い画像をバシバシアップロードしちゃまずいんですね。色々なところに落とし穴はあるものです。

25
23
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?