Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

はじめに・やりたいこと

  • 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

yoshi_yast
個人開発初学者です。「1か月後の自分は他人である」・「自分の"やったこと"や"つまずき"はきっと誰かの役に立つ」・「アウトプットは最後は自分に返ってくる」ということを意識して個人の記録をOUTPUTしていきたいと思います。
https://anotherskyjp.site/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away