質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google API

Googleは多種多様なAPIを提供していて、その多くはウェブ開発者向けのAPIです。それらのAPIは消費者に人気なGoogleのサービス(Google Maps, Google Earth, AdSense, Adwords, Google Apps,YouTube等)に基づいています。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Google マップ

Google Mapは、Google社がオンラインで提供している地図・ローカル検索サービスです。GIS(Geographic Information System:地理情報システム)の中の「WebGIS」に該当します。地図・航空写真・地形の表示方式があり、それぞれユーザーが縮尺を調整して表示させることができます。地域の情報サービスを検索する機能やルート検索の機能も搭載されています。

Q&A

解決済

1回答

1153閲覧

Google Maps APIのマーカーデータをスプレッドシートから読み込む方法

jzx100ts

総合スコア28

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google API

Googleは多種多様なAPIを提供していて、その多くはウェブ開発者向けのAPIです。それらのAPIは消費者に人気なGoogleのサービス(Google Maps, Google Earth, AdSense, Adwords, Google Apps,YouTube等)に基づいています。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Google マップ

Google Mapは、Google社がオンラインで提供している地図・ローカル検索サービスです。GIS(Geographic Information System:地理情報システム)の中の「WebGIS」に該当します。地図・航空写真・地形の表示方式があり、それぞれユーザーが縮尺を調整して表示させることができます。地域の情報サービスを検索する機能やルート検索の機能も搭載されています。

0グッド

0クリップ

投稿2019/03/26 17:44

編集2019/03/29 15:32

前提・実現したいこと

現在、GASによるウェブアプリケーション上で、GoogleMapを使って複数のマーカーを設置し、吹き出しも動くようになりました。
複数のマーカーデータはスクリプト内に直接記述されているのですが、設置したい複数のマーカーデータは日々位置と情報を変えたいので、スプレッドシートに保存してある情報からマーカーデータを読み込むようにしたいと思っております。

現在は下記の状態で、var locationsに入れた4件のマーカーデータに基づき、マーカーが設置できています。

HTMLファイル(map.html)

<!DOCTYPE html> <html> <head> <base target="_top"> <style type="text/css"> #map{ height: 900px; width: 90%;} </style> </head> <body> <script type="text/javascript"> function initMap() { var locations = [ ['しぶや<br><a href="http://www.yahoo.co.jp">やふー</a>', 35.658319, 139.700922], ['はらじゅく<br><a href="http://www.google.co.jp">ぐーぐる</a>', 35.669276, 139.702762], ['おもてさんどう<br><a href="http://www.apple.co.jp">あぽ</a>', 35.665435, 139.711565], ['えびす<br><a href="http://www.amazon.co.jp">あま</a>', 35.647915, 139.709687 ] ]; var map = new google.maps.Map(document.getElementById('map'), { zoom: 15, center: new google.maps.LatLng(locations[0][1], locations[0][2]), mapTypeId: google.maps.MapTypeId.ROADMAP }); var infowindow = new google.maps.InfoWindow; var marker, i; for (i = 0; i < locations.length; i++) { marker = new google.maps.Marker({ position: new google.maps.LatLng(locations[i][1], locations[i][2]), map: map }); google.maps.event.addListener(marker, 'click', (function(marker, i) { return function() { infowindow.setContent(locations[i][0]); infowindow.setContent(locations[i][0]); infowindow.open(map, marker); } })(marker, i)); } } </script> <script async defer src="https://maps.googleapis.com/maps/api/js?key=***&callback=initMap"> </script> <div id="map"></div> </body> </html>

コード.gs

function doGet(e) { var page=e.parameter["p"]; var p_map = 'map';//ファイル名 if (page == p_map) {//testサイト var htmlOutput = HtmlService.createTemplateFromFile(p_map).evaluate(); htmlOutput .setTitle('map') return htmlOutput; } }

発生している問題・エラーメッセージ

[ ['しぶや<br><a href="http://www.yahoo.co.jp">やふー</a>', 35.658319, 139.700922], ['はらじゅく<br><a href="http://www.google.co.jp">ぐーぐる</a>', 35.669276, 139.702762], ['おもてさんどう<br><a href="http://www.apple.co.jp">あぽ</a>', 35.665435, 139.711565], ['えびす<br><a href="http://www.amazon.co.jp">あま</a>', 35.647915, 139.709687 ] ]

上記の部分をスプレッドシートに保存されたデータから読み込みたいのですが実現できません。

試したこと

不勉強でお恥ずかしいのですが、とあるスプレッドシートに保存されているマーカーデータを随時var locationsに読み込むために、

var MarkerListSS = SpreadsheetApp.openById("SSID"); var MarkerListSH = MarkerListSS.getSheetByName("SheetName"); var MarkerListDATA = MarkerListSH.getDataRange().getValues(); var locations = []; for (var i = 0 ; i < MarkerListDATA.length ; i++ ) { temp_marker = [MarkerListDATA[i][0],MarkerListDATA[i][1],MarkerListDATA[i][2]]; locations.push(temp_marker); }

などとしてスプレッドシートに入力されているデータをlocationsに読み込んで使用したいのですが、上記のコードを<script>の中に記載すると、ページを開いても何も表示されないという状況です。それを削除してべた打ちの4件を入力するときちんとマップが表示されます。
HTMLファイルにいきなりこれを記載しても「SpreadsheetAppが定義されていない」ということで動かないのかと推測し、上記のものをコード.gsに関数の形で記載してみました。それでページを開くと、「その操作を実行するには承認が必要です。」となり、やはり地図は表示されません。
HTMLファイルに直接記述した最初のトライのときには「このアプリケーションは、Google ではなく、別のユーザーによって作成されたものです。不正行為を報告 - 利用規約」が表示され、地図だけが出ない状態でしたが、
コード.gsに関数を作って試した2回目のトライでは、GASのロゴと「その操作を実行するには承認が必要です。」だけが表示されました。
以下が2回目のトライで試したコードになります。

GAS

1コード.gs 2function GETMARKERLIST(){ 3 var MarkerListSS = SpreadsheetApp.openById("SSID"); 4 var MarkerListSH = MarkerListSS.getSheetByName("SheetName"); 5 var MarkerListDATA = MarkerListSH.getDataRange().getValues(); 6 7 var markerData=[]; 8 for (var i = 0 ; i < MarkerListDATA.length ; i++ ) 9 { 10 temp_marker = [MarkerListDATA[i][0],MarkerListDATA[i][1],MarkerListDATA[i][2]]; 11 markerData.push(temp_marker); 12 } 13 return markerData 14 } 15 16

html

1var locations = GETMARKERLIST();

ネットで情報を探しても、マーカーや吹き出しについての情報は見つかるのですが、Googleスプレッドシートに保存されている文字データやlatlangを読み込んで、マーカー設置のリストに使用している実例が見つからず、こちらで質問させていただきました。
感覚としてはそれほど難しいことでは無いのではないかと感じるものの、これまで独学でスプレッドシート周りのことを中心にGASを扱ってきましたので、
HTMLが絡んできたとたん、理解が追いついておりません。
コード.gsとHTMLファイルでコードを書き分ける意義などはわかっておらず、それが原因して行き詰まっているのかもと思っております。
私が大変初歩的な部分の理解ができていないのかもしれないと推察していますが、何卒ご教授いただけたら助かります。どうぞよろしくお願いいたします。

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

おかげさまで解決しましたので、解決済みのコードを記載致します。
マーカーリストを2つのスプレッドシートから読み込み、
それぞれのマーカーをスプレッドシートごとに色分けする内容となっております。

今回の問題点は、
クライアント側JS[HTMLファイルに記述したJSスクリプトinitMap()の内部]から
サーバー側関数[コード.gsに記載したGASスクリプト]を直接呼び出そうとしていたことでした。
それをするにはgoogle.script.runなどが用意されているようですが、
今回はhiroshi0240様がもっと簡単な「置換法」を教えてくださったので、すぐに解決しましたし、おかげで応用もすることができました。
正しい表現かどうかわかりませんが、
HTMLファイルを生成する前の段階で、サーバー側(GAS)の処理でマーカーデータをスプレッドシートから読み込み、
生成前のHTMLにマーカーデータを潜り込ませ(←ここが置換処理)、
そのデータに基づいてHTMLファイルを生成することで、
HTMLファイルのJS内部からサーバー側の処理を呼び出す必要はなくなった。というイメージです。

ゆくゆくはgoogle.script.runなども使いこなせるようになりたいと思います。

GAS

1function doGet(e) 2{ 3 var page=e.parameter["p"]; 4 var p_map = 'map';//ファイル名 5 6if (page == p_map) {//オートリロードGoogleMap 7 var markerdata = JSON.stringify(GETMARKERLIST());//GETMARKERLIST()の戻り値は配列オブジェクトなのでJSON 文字列に変換する 8 var markerdata2 = JSON.stringify(GETMARKERLIST2());//GETMARKERLIST()の戻り値は配列オブジェクトなのでJSON 文字列に変換する 9 var html = HtmlService.createHtmlOutputFromFile("map"); 10 var content = html.getContent().replace(/%markerdata%/, markerdata );//ここで置換を実施する 11 var content2 = content.replace(/%markerdata2%/, markerdata2 );//ここで置換を実施する 12 return HtmlService.createHtmlOutput(content2) 13 .setTitle('地図') 14 .setFaviconUrl('fav.png') 15 .addMetaTag('viewport', "width=device-width, initial-scale=1, user-scalable=yes"); 16 } 17} 18 19function GETMARKERLIST(){//グループ1のマーカー情報 スプレッドシートのA列にタイトル、B列に緯度、C列に経度を入力しておく 20 var MarkerListDATA = getData("****SSID****","MarkerList"); 21 var markerData=[]; 22 for (var i = 0 ; i < MarkerListDATA.length ; i++ ){ 23 var temp_marker = [MarkerListDATA[i][0],MarkerListDATA[i][1],MarkerListDATA[i][2]]; 24 markerData.push(temp_marker); 25 } 26 return markerData; 27} 28 29function GETMARKERLIST2(){//グループ2のマーカー情報 スプレッドシートのA列にタイトル、B列に緯度、C列に経度を入力しておく 30 var MarkerListDATA = getData("****SSID****","MarkerList2"); 31 var markerData=[]; 32 for (var i = 0 ; i < MarkerListDATA.length ; i++ ){ 33 var temp_marker = [MarkerListDATA[i][0],MarkerListDATA[i][1],MarkerListDATA[i][2]]; 34 markerData.push(temp_marker); 35 } 36 return markerData; 37} 38 39function getData(ssId,sheetName) { 40 // スプレッドシートの取得 41 var ss = SpreadsheetApp.openById(ssId); 42 // データの取得 43 var values = ss.getSheetByName(sheetName).getDataRange().getValues(); 44 45 return values; 46}

HTML

1<!DOCTYPE html> 2<html> 3 <head> 4 <base target="_top"> 5 <style type="text/css"> 6 #ARmap{ height: 620px; 7 width: 100%; 8 margin:0 auto;} 9 </style> 10 </head> 11 12 <body> 13 14<script type="text/javascript"> 15 16function initMap() { 17 var locations = %markerdata%;//ここがスプレッドシートの情報に置換される 18 var locations2 = %markerdata2%;//ここがスプレッドシートの情報に置換される 19 20 var map = new google.maps.Map(document.getElementById('ARmap'), { 21 zoom: 16, 22 center: new google.maps.LatLng(35.678244, 139.736343), 23 mapTypeId: google.maps.MapTypeId.ROADMAP 24 }); 25 26 var infowindow = new google.maps.InfoWindow; 27 var marker, i; 28 29 30 //マーカーの読み込み(グループ1) 31 for (i = 0; i < locations.length; i++) { 32 marker = new google.maps.Marker({ 33 position: new google.maps.LatLng(locations[i][1], locations[i][2]), 34 icon: 'http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=|00bfff|',//グループ2のマーカーの色指定 35 map: map 36 }); 37 38 google.maps.event.addListener(marker, 'click', (function(marker, i) { 39 return function() { 40 infowindow.setContent(locations[i][0]); 41 infowindow.setContent(locations[i][0]); 42 infowindow.open(map, marker); 43 } 44 })(marker, i)); 45 } 46 47 //マーカーの読み込み(グループ2) 48 for (i = 0; i < locations2.length; i++) { 49 marker = new google.maps.Marker({ 50 position: new google.maps.LatLng(locations2[i][1], locations2[i][2]), 51 icon: 'http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=|aaaaaa|',//グループ1のマーカーの色指定 52 map: map 53 }); 54 55 google.maps.event.addListener(marker, 'click', (function(marker, i) { 56 return function() { 57 infowindow.setContent(locations2[i][0]); 58 infowindow.setContent(locations2[i][0]); 59 infowindow.open(map, marker); 60 } 61 })(marker, i)); 62 } 63} 64</script> 65 66<script async defer 67 src="https://maps.googleapis.com/maps/api/js?key=xxxxxxxxxxxx&callback=initMap">//keyは自分のものを入力する 68</script> 69 70 71<div class="waku"> 72<h1>地図</h1> 73 <div id="ARmap"></div> 74</div> 75 76</body> 77</html>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

HTML表示させるまえに、対象の配列部分を置換させれば、どうでしょう。

gas

1var makerdata = GETMARKERLIST(); 2 var html = HtmlService.createHtmlOutputFromFile("map"); 3 var content = html.getContent().replace(/%makerdata%/, markerdata ); 4 return HtmlService.createHtmlOutput(content); 5}

HTML

1var locations = %makerdata%;

投稿2019/03/27 01:00

hiroshi0240

総合スコア640

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jzx100ts

2019/03/29 15:14

hiroshi0240様 今回は貴重な回答をお寄せいただき、本当にありがとうございました。 正直なところ回答をいただいた直後は何をしたらよいのかわからず回答を活かせないでいたのですが、 papinianus様のコメントなどを参考に色々と調べているうちに、HTMLファイルに記述してあるとしても<script></script>に挟まれたJSからコード.gsのGAS関数を直接呼び出すことができないことや、それをするためにgoogle.script.runという関数が存在することなどを知り、大前提となる重要な知識を持たないまま無茶な質問をしていたことに気づくことができました。(おかげさまで「GASのWebアプリでクライアント側JavaScriptからサーバー側の関数を呼び出す方法」というウェブ記事のタイトルの意味がだいぶ理解できるようになりました。)そのあたりが分かってきた頃に改めてhiroshi0240様の回答を見てみると、「HTML表示させるまえに」という表現があり、DOGETが呼び出された瞬間、つまりコード.gsが動いているうちに、スプレッドシートから情報を読み込むなどのGASの処理を実施する必要があるのかなとおぼろげにあたりをつけることができました。そんな感じでまだ完全には理解できていない状態ながらも、まずは回答通りにやってみようと思い、試行錯誤したところ、期待していた動作が実現しましたので感動してしまいました。 最終的な結果として、JSON.stringify()を使用してスプレッドシートから読み込んだJSONデータを変換する必要がありましたが、それをしてみるとhiroshi0240様が教えてくださった「HtmlOutput前置換法」によって無事に解決に至りました。読み込みたい情報が2つ、3つと増えた場合でも、置換を繰り返すことで自由に扱うこともできました。今回の質問から多くを学ぶことができ、コメントをくださったpapinianus様と、回答をくださったhiroshi0240様にとても感謝しています。本当にありがとうございました。また壁にぶつかったときはお知恵をお借りできれば嬉しく思います。引き続きどうぞよろしくお願いいたします。 無事に動いたコードを、質問部分に追記の形で記載させていただきます。 どなたかのお役に立てれば幸いです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問