[Work/Class/Google Maps APIの基礎/basic]

GoogleMaps APIの基礎 - マーカの情報をCSVから持ってくる

マーカーを大量に描画しようとする時,全てJavaScriptで書き下すのは非常に面倒くさい.そこでExcelやGoogleスプレッドシートで2次元テーブルの形でデータを作っておき,それをCSV形式でサーバにおいておき,それを読み込んできてマーカの情報として表示する.

CSVデータの読み込みには非同期処理(AJAX)を使う.XMLHttpRequestを使ったAjaxとfetchを参考にすること.

自販機とそこで売っている飲み物をまとめたCSVファイル vendor_data.csv は以下の通り

飲み物名称\自販機ID,m001,m002,m003,m004,m005,m006,m007,m008,m009,m010
すべて,1,1,1,1,1,1,1,1,1,1
FIRE,0,0,1,0,0,1,1,0,0,0
BOSS,0,0,0,0,1,0,0,0,1,0
GEORGIA,0,0,0,1,0,1,0,0,0,0
DyDo,0,0,1,0,0,0,1,1,0,0
WONDA,1,0,0,0,0,1,0,0,0,1
TULLY'S,0,1,0,0,0,0,0,0,0,0
ココア,0,0,0,0,0,0,0,1,0,0
生茶,0,0,1,0,0,0,1,0,0,0
麦茶,0,1,1,0,1,0,1,1,1,0
レモンティー,0,0,1,1,0,0,0,1,0,0
ミルクティー,1,0,1,0,1,0,1,1,1,0
爽健美茶,0,0,0,0,0,1,0,0,0,0
綾鷹,0,0,0,1,0,1,0,0,0,0
伊右衛門,0,0,0,0,1,0,0,0,1,0
自販機lat,35.61298,35.612963,35.613368,35.613168,35.613184,35.612488,35.610865,35.617523,35.617498,35.617628
自販機long,139.381036,139.381059,139.381978,139.381584,139.381563,139.382121,139.383056,139.385693,139.385877,139.386235

表示ボタンを配置してマーカ描画関数を呼び出すhtmlファイル vendor_map.html と,JavaScriptファイル fetc_csv.js

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <title>自販機をGoogle Mapsにマッピングする</title>
    <!-- Google Maps APIをWeb上から読んでくる -->
    <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js"></script>
    <!-- 自分で作ったJSファイル -->
    <script type="text/javascript" src="./fetch_csv.js"></script>

        <!-- とりあえずCSSを直接書いてしまう -->
    <style>
        html, body {
            height: 100%;
            margin: 0;
            padding: 0;
        }
        #map {
            /*
             div id=mapになってるdiv
             ここに地図
             高さ500ピクセル,幅は上位のdiv(ここではbody)の50%
            */
            height: 500px;
            width: 50%;
        }
    </style>

  </head>
  <body>
    <div id="select_button">
      <input type="button" value="全ての自販機" onclick="drawMarkers(0)" />
      <input type="button" value="キリンFIRE" onclick="drawMarkers(1)" />
      <input type="button" value="サントリーBOSS" onclick="drawMarkers(2)" />
      <input type="button" value="GEORGIA" onclick="drawMarkers(3)" />
      <input type="button" value="DyDo" onclick="drawMarkers(4)" />
      <input type="button" value="WONDA" onclick="drawMarkers(5)" />
      <input type="button" value="TULLY's" onclick="drawMarkers(6)" />
      <input type="button" value="ココア" onclick="drawMarkers(7)" />
      <input type="button" value="生茶" onclick="drawMarkers(8)" />
      <input type="button" value="麦茶" onclick="drawMarkers(9)" />
      <input type="button" value="レモンティー" onclick="drawMarkers(10)" />
      <input type="button" value="ミルクティー" onclick="drawMarkers(11)" />
      <input type="button" value="爽健美茶" onclick="drawMarkers(12)" />
      <input type="button" value="綾鷹" onclick="drawMarkers(13)" />
      <input type="button" value="伊右衛門" onclick="drawMarkers(14)" />

    </div>

    <div id="map"></div>
  </body>
 </html>
'use strict';
window.addEventListener('load', () => {
  // 地図の表示
  // ここから地図を表示する
  //地図表示に必要なパラメータを保持するconstオブジェクト
  const mapElement = {
// 南大沢駅の緯度経度を中心にして表示する
      center: {lat:35.614349, lng:139.379774},
      // ズームレベル
      zoom: 16
  };

  // 地図を保持するためのconstオブジェクトmyMapを宣言し,
  // GoogleMapsのコンストラクタの引数に,先に定義した地図表示に必要なパラメータを食わせる
  window.myMap =
      new google.maps.Map(document.getElementById('map'), mapElement);
  // コンストラクタが実行されると表示される


  // CSVデータを非同期で持ってくる
  fetch('./vendor_data.csv', {
    method: 'GET',
    mode: 'cors', //クロスオリジンポリシーを無視する
    credentials: 'same-origin' // 認証がある時はこのオプションを指定しておく
  }).then((response) => {
    // 成功したら,取得したファイルをテキストとして,次のthenに回す
    return response.text();
  }).then((text) => {
    // テキストデータとしてきた内容から,必要なデータを組み立てる
    // 読み込んだデータを1行ずつ格納する配列をグローバルで宣言する
  	window.drinkName = new Array();
  	window.drinkData = new Array();
  	window.latArray = new Array();
  	window.longArray = new Array();

  	// 読み込んだCSVデータの名前を変える
  	let csvData = text;

  	// CSVの全行を取得
    // 「改行」でスプリットすると,1行を単位とした配列に分かれる
  	let lines = csvData.split("\n");

  	for (let i = 0; i < lines.length; i++) {
  	    // 1行ごとの処理

  	    if (i >= 1 && i <= 15) { // 0行目を飛ばして,1行目から20行目まで
          // 1行をカンマでスプリットすると,CSVの1要素になる
  		    let aDrinkSet = lines[i].split(",");
  		    window.drinkName.push(aDrinkSet[0]);
  		    window.drinkData.push(aDrinkSet.slice(1));
  	    }
  	    else if (i == 16) { // 18行目はlat(緯度)
  		    window.latArray = lines[i].split(",").slice(1);
  	    }
  	    else if (i == 17) { // 19行目はlng(軽度)
  		    window.longArray = lines[i].split(",").slice(1);
  	    }
  	}


    // マーカを格納する配列を初期化する
    window.currentMarkerSet = new Array();

    // 飲み物のマーカーを表示する
    // 最初は0番目「全て」の自販機の意味
    drawMarkers(0);

  }).catch((error) => {
    // 何かエラーが起きたら,そのエラーコードを表示する
    alert("<p>" + "Faild to get CSV. Error code is: " + error + "</p>");
  });
});

function drawMarkers(drinkNumber){

    // まず最初に既表示のマーカーを消す
    for(let i=0; i< window.currentMarkerSet.length; i++){
	     window.currentMarkerSet[i].setMap(null);
    }
    window.currentMarkerSet = new Array();

    // マーカーを作る
    let aDrinkSet = window.drinkData[drinkNumber];
    for(let i=0; i<aDrinkSet.length; i++){
	     if(Number(aDrinkSet[i]) == 1){
	     let aVenderMarker = new google.maps.Marker({
		       position: {lat: Number(window.latArray[i]), lng: Number(window.longArray[i])},
		         map: window.myMap
	     });
	     window.currentMarkerSet.push(aVenderMarker);
	    }
    }
}