Blow Up by Black Swan

GAS(Google Apps Script) – Googleマップのマイマップデータをxml経由でスプレッドシートに表示するWebアプリを作ってみた

前回、前々回でGASに関する記事を書きましたが、今回はそれらをまとめて作ったwebアプリについて記事にしました。GoogleマップのマイマップからエクスポートしたkmlデータをGASで作ったサイトにアップロードすることで、自動でファイル形式の変更、xmlデータの解析、スプレッドシートへの転記を行うプログラムです。ファイル形式の変換、xmlデータの解析と以前の2つの要素が入っています。同じ事例は少ないかもしれませんが、似た事例はたくさんあるかとは思いますので、この記事が参考になれば幸いです。

1. プログラムの流れと使用データ

1-1. プログラムの流れ

今回のプログラムの流れは次のようになります。

  1. webアプリからPOSTされたkmlファイルを取得
  2. kmlファイル形式をblob経由でxmlファイルに変換
  3. xmlファイルを解析
  4. 解析したデータを保存するスプレッドシートを作成
  5. 解析したデータをスプレッドシートに記述

1-2. 使用データ

今回使用するkmlファイルは前々回のブログでも紹介した次のようなデータになります。

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
  <Document>
    <name>My Castles</name>
    <Style id="icon-************-normal">
      <IconStyle>
        <color>ffd18802</color>
        <scale>1</scale>
        <Icon>
          <href>images/icon-1.png</href>
        </Icon>
      </IconStyle>
      <LabelStyle>
        <scale>0</scale>
      </LabelStyle>
    </Style>
    <Style id="icon-**********-highlight">
      <IconStyle>
(省略)
    </Style>
    <StyleMap id="icon-*******************">
      <Pair>
        <key>normal</key>
        <styleUrl>#icon-*******************-normal</styleUrl>
      </Pair>
      <Pair>
        <key>highlight</key>
        <styleUrl>#icon-*******************-highlight</styleUrl>
      </Pair>
    </StyleMap>
    <Placemark>
      <name>五稜郭</name>
      <description>2017年</description>
      <styleUrl>#icon-*******************</styleUrl>
      <Point>
        <coordinates>
          140.7569254,41.7976385,0
        </coordinates>
      </Point>
    </Placemark>
(省略)
  </Document>
</kml>

2. プログラム

今回は2つのファイルを作成しています。サーバサイド側となる”main.gs”ファイルとフロント側になる”index.html”です。それぞれのファイルの内容は次のようになります。

2-1. main.gs

function doGet() {
  return HtmlService.createHtmlOutputFromFile('index').setTitle('xml changer');
}

function changeXml(formObject) {

    // 1. webアプリからPOSTされたkmlファイルを取得
    var fileBytes = formObject.myFile.getBytes();
    
    // 2. kmlファイル形式をblob経由でxmlファイルに変換
    var xmlBlob = Utilities.newBlob(fileBytes, 'application/xml', 'new.xml')
    var baseAry = [['No.','城名', '訪問年']]

  
    // 3. XMLファイルを解析
    var xmlDocs = XmlService.parse(xmlBlob.getDataAsString());
    var ns = XmlService.getNamespace("", "http://www.opengis.net/kml/2.2");
    var doc = xmlDocs.getRootElement().getChild('Document', ns);
    var fileName = doc.getChildText('name', ns);
    Logger.log('name: '+fileName);
    var placemarks = doc.getChildren('Placemark', ns);
    var secondAry = [];
    for (var i = 0; i < placemarks.length; i++) {
      var nameBlock = placemarks[i].getChildText('name', ns);
      var desBlock = placemarks[i].getChildText('description', ns);
      // Logger.log(desBlock);
      var ary = [i+1, nameBlock, desBlock];
      baseAry.push(ary);
    }
    
    // 4. 解析したデータを保存するスプレッドシートを作成
    var ss = SpreadsheetApp.create(fileName);
  
    // 5. 解析したデータをスプレッドシートに記述
    var sheet = ss.getActiveSheet();
    var rows = baseAry.length;
    var cols = baseAry[0].length;
    sheet.getRange(1,1,rows,cols).setValues(baseAry);
}

doGet関数は、webページの画面となるindex.htmlを呼び出す役割をします。changeXml関数は、POSTされたkmlファイルをxmlデータに変換した上で解析し、スプレッドシートに転記します。ポイントとしては、ファイル形式を変換するときに新しいblobファイルを作成してそこにバイトデータを写すこと、xmlを解析するときにデフォルトのnamespaceも明示的に指定していることです。これは前回前々回の記事で記載しました。

2-2. index.html

もう1つのファイルはdoGet関数で呼び出されるindex.htmlファイルです。これは非同期でファイルがPOSTされるようになっています。このファイルについてはほとんど下記の参考サイトを参考にしていますので、そちらも参考にして頂ければと思います。

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script>
      // すべてのフォームをイベントリスナーに登録する
      function preventFormSubmit() {
        var forms = document.querySelectorAll('form');
        for (var i = 0; i < forms.length; i++) {
          forms[i].addEventListener('submit', function(event) {
            event.preventDefault();
          });
        }
      }
      window.addEventListener('load', preventFormSubmit);
      function readFile(formObject) {
        // GASで定義した関数を呼び出す
        google.script.run.withSuccessHandler(updateView).changeXml(formObject);
      }
      function updateView() {
        alert('変換できました。');
      }
    </script>
    <style>
    </style>
  </head>
  <body>
    <form id="myForm" onsubmit="readFile(this)" enctype="multipart/form-data" style="text-align:center;">
      ファイルを選択してからアップロードしてください<br><br>
      <input name="myFile" type="file" /><br><br>
      <input id="upload" type="submit" value="スプレッドシートに変換" />
    </form>
  </body>
</html>

google.script.run>クラスは、クライアント側(今回であればブラウザで表示されるこのindex.htmlファイル)に配置するもので、非同期処理を行うためのものです。またwithSuccessHandlerメソッドを使用することで、非同期処理が成功した際にアラート画面がブラウザに表示されるようにしています(Class google.script.run (Client-side API) – Apps Script)。

3. プログラムを試してみる

それでは実際にプログラムを試してみます。「公開」タブから「webアプリケーションで導入…」を選択し公開します。公開した時のアドレスにアクセスすると次のような画面が表示されます。公開方法については次のサイトが参考になります。

kml-xml-changer-ss1

ここにファイルを添付し、「スプレッドシートに変換」ボタンを押します。完了するとアラートボタンが出てきて、完了したことを教えてくれます。

kml-xml-changer-ss2

グーグルドライブのルートフォルダに行くとアップロードしたファイル名のスプレッドシートができています。今回であれば次のようなスプレッドシートが完成しています。

kml-xml-changer-ss3

4. 最後に

以上がファイル形式の変換とxmlの解析、スプレッドシートへの転記までを行うプログラムです。今回はkmlファイルからxmlファイルへの変換、xmlファイルの解析という少しマニアックな内容になっていますが、要所を変更することで色々な応用事例が可能ではないかと思います。これを参考に色々なアプリを作ってみて頂けたら幸いです。読んで頂き、ありがとうございました。