前提・実現したいこと
現在、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>

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/03/27 01:07
2019/03/29 15:14