LoginSignup
18
31

【Google MAP】緯度・経度情報などをDBから読み込んでMAP表示させる(Ajax)

Last updated at Posted at 2019-06-11

はじめに・やりたいこと

  • Mapにピンを打ったり、その場所を表示するには、緯度・経度情報が必要になります。
  • プログラムの中に、緯度・経度の情報を直接書き込むのではなく、MySQLなどのDBに情報を保持して、そこからデータをSELECTし、処理をしたいなと思いました。
  • いろいろ調べ、AjaxでPHPプログラムを呼び出す、という方法にたどり着きました。
  • Google Mapのマーカーをまとめて表示する方法 MarkerClusterer を使用してみます。

前提

  • Google Map API keyの取得

使用技術

作成サイトイメージ

世界最大リストを作成する
(【例】世界最大の流量の滝:イグアスの滝 ・ 世界最大の流域面積の川:アマゾン川 など)

デモサイト
pic1.jpg

データベース

  • DBには、緯度・経度とともに、下記のような項目を設けます。

 ・クラスID/クラス名(分類)
 ・テキスト
 ・名前
 ・ステータス
 ・緯度/経度
 ・写真

db.jpg

コード(JavaScript/PHP)

  • 地図の表示部分
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>Up to World</title>
    <style>
     <!-- 省略 -->
    </style>
  </head>

  <body>
    <div id="header">Google Maps - 世界最大・世界最長リスト</div>
    <table>
      <tr>
        <td><div id="target"></div></td>
        <td><div id="sidebar"></div></td>
      </tr>
    </table>

    <!-- MarkerCluster -->
    <script src="https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/markerclusterer.js"></script>

    <!-- Google MAP API KEY -->
    <script src="https://maps.googleapis.com/maps/api/js?language=ja&region=JP&key=API keキーを指定する&callback=initMap" async defer></script>

    <script src="https://code.jquery.com/jquery-2.1.1.js" integrity="sha256-FA/0OOqu3gRvHOuidXnRbcmAWVcJORhz+pv3TX2+U6w=" crossorigin="anonymous"></script>

    <script>

      function initMap() {

        //マップ初期表示の位置設定
        var target = document.getElementById('target');
        var centerp = {lat: 37.67229496806523, lng: 137.88838989062504};

        //マップ表示
        map = new google.maps.Map(target, {
          center: centerp,
          zoom: 2,
        });

      };

      var markerD = [];

      // DB情報の取得(ajax)
      $(function(){
        $.ajax({
          type: "POST",
          url: "data.php",
          dataType: "json",
          success: function(data){
            markerD = data;
            setMarker(markerD);
          },
          error: function(XMLHttpRequest, textStatus, errorThrown){
            alert('Error : ' + errorThrown);
          }
        });
      });

      var map;
      var marker = [];
      var infoWindow = [];

      function setMarker(markerData) {

        // console.log(markerData);
        // console.log(markerData.length);

        //マーカー生成
        var sidebar_html = "";
        var icon;

        for (var i = 0; i < markerData.length; i++) {

          var latNum = parseFloat(markerData[i]['lat']);
          var lngNum = parseFloat(markerData[i]['lng']);

          // マーカー位置セット
          var markerLatLng = new google.maps.LatLng({
            lat: latNum,
            lng: lngNum
          });
          // マーカーアイコンのセット(行った所はアイコンを変える)
          if (markerData[i]['status'] === 'went'){
            icon = new google.maps.MarkerImage('./icon_color/went' + markerData[i]['classNo'] + '.png');
          } else {
            icon = new google.maps.MarkerImage('./icon_color/list' + markerData[i]['classNo'] + '.png');
          }
          // マーカーのセット
          marker[i] = new google.maps.Marker({
            position: markerLatLng,          // マーカーを立てる位置を指定
            map: map,                        // マーカーを立てる地図を指定
            icon: icon                       // アイコン指定
          });
          // 吹き出しの追加
          infoWindow[i] = new google.maps.InfoWindow({
            content: markerData[i]['class'] + '' + markerData[i]['name'] + '<br><br>' + markerData[i]['text'] + '<br><br>' + markerData[i]['img']
          });
          // サイドバー
          var wantStar;
          if(markerData[i]['status'] === 'went') {
            wantStar = '';
          } else if(markerData[i]['status'] === 'want') {
            wantStar = '';
          } else {
            wantStar = '';
          }
          sidebar_html += wantStar + '<a href="javascript:myclick(' + i + ')">' + markerData[i]['name'] + '<\/a><br />';
          // マーカーにクリックイベントを追加
          markerEvent(i);
        }

        // Marker clusterの追加
        var markerCluster = new MarkerClusterer(
          map,
          marker,
          {imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'}
        );

        // サイドバー
        document.getElementById("sidebar").innerHTML = sidebar_html;
      }

      var openWindow;

      function markerEvent(i) {
        marker[i].addListener('click', function() {
          myclick(i);
        });
      }

      function myclick(i) {
        if(openWindow){
          openWindow.close();
        }
        infoWindow[i].open(map, marker[i]);
        openWindow = infoWindow[i];
      }

    </script>

  </body>
</html>
  • DBアクセスしデータを返す
<?php

  //ヘッダー情報の設定
  header("Content-Type: application/json; charset=utf-8");

  $data = array();

  // DB接続情報
  $host = "host情報";
  $dbname = "db name情報";
  $user = "ユーザ情報";
  $pass = "パスワード";

  // DB接続情報設定・SQL準備・接続
  $dbh = new PDO('mysql:host=' . $host . 'dbname=' . $dbname . 'charset=utf8', $user, $pass);

  $sql = "select classNo, class, text, name, status, lat, lng, img from placedata";
  $sth = $dbh -> prepare($sql);
  $sth -> execute();

  //データを取得する
  $data = $sth -> fetchAll(PDO::FETCH_ASSOC);

  //jsonオブジェクト化
  echo json_encode($data);
?>

まとめ

  • いままでプログラム中に緯度・経度を直接記載していましたが、別だしすることができました。
  • 緯度・経度を外出しする方法として、DBでなくても、いろいろな方法があると思います。個人的には、Googleスプレッドシートがとても便利そうだな、と感じています。
  • 【参考】観測史上最速!GoogleスプレッドシートだけでAPIが作れる「Sheetson」

参考URL

18
31
0

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
18
31