Google Map上にGeoJSONデータを表示する

Standard

指定した緯度経度を中心にスポットデータを近い順に取得する

<?php
require_once( $_SERVER['DOCUMENT_ROOT'] . '/wp-load.php' );
global $wpdb;
$_latitude = floatval($_GET['latitude']);
$_longitude = floatval($_GET['longitude']);
// 自分の座標を取ってないなら、東京の座標を初期化する
if(empty($_latitude) || empty($_longitude)){
  $_latitude = 35.6812405; // 緯度
  $_longitude = 139.7649361; // 経度
}
$limit=10;
//WordPressのカスタムフィールドを使う
$sql=<<< EOF
select ID,post_title,latitude,longitude,
  (
    6371 * acos( -- kmの場合は6371、mileの場合は3959
      cos(radians($_latitude))
      * cos(radians(latitude))
      * cos(radians(longitude) - radians($_longitude))
      + sin(radians($_latitude))
      * sin(radians(latitude))
    )
  ) AS distance
from 
(
  SELECT post.ID,post.post_title,mate1.meta_value as latitude,mate2.meta_value as longitude
  FROM wp_posts AS post
  INNER JOIN wp_postmeta as mate1
    ON mate1.post_id=post.ID and mate1.meta_key='lat'
  INNER JOIN wp_postmeta as mate2
    ON mate2.post_id=post.ID and mate2.meta_key='lng'
  WHERE post.post_type='custom'
  GROUP BY post.ID LIMIT $limit
) as ichi ORDER BY distance LIMIT $limit
EOF;
$geojson = array( 'type' => 'FeatureCollection', 'features' => array());
$results = $wpdb->get_results( $sql );
foreach($results as $row) {
    $id = $row->ID;
    $title = $row->post_title;
    $lat=$row->latitude;
    $lng=$row->longitude;
    $distance=$row->distance;
    $address=get_field( "所在地", $id );
    $picture=wp_get_attachment_image_url( get_field( "サブ画像", $id ) );    
    $marker = array(
        'type' => 'Feature',
        'properties' => array(
          'id' => $id,
          'name' => $title,
          'address' => $address,
          'title' => $title,
          'distance' => $distance,
          'picture' => $picture,
          'marker-color' => '#f00',
          'marker-size' => 'small'
        ),
        'geometry' => array(
          'type' => 'Point',
          'coordinates' => array( 
            $lat,
            $lng
          )
        )
    );
    array_push($geojson['features'], $marker);   
}
header("Access-Control-Allow-Origin: *");
echo json_encode($geojson);
<?php
$_latitude = floatval($_GET['latitude']);
$_longitude = floatval($_GET['longitude']);
// 自分の座標を取ってないなら、東京の座標を初期化する
if(empty($_latitude) || empty($_longitude)){
  $_latitude = 35.6812405; // 緯度
  $_longitude = 139.7649361; // 経度
}
?>
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>グーグルマップ</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"> 
  </head>
  <body>
    <div id="app" class="container">
      <div class="row">
        <div class="col">
          <div id="map" class="embed-responsive embed-responsive-16by9"></div>
        </div>
      </div>
      <div class="row">
        <div class="col">
          <ul class="list-group">
            <li class="list-group-item" :class="{'active': f.properties.id == activeIndex}" v-for="f in features" @click="openInfoWindows(f.properties.id);toggle(f.properties.id)">
            <img v-bind:src="f.properties.picture">
            {{ f.properties.name }}
            <br>
            {{ f.properties.address}}
            <br>
            {{ f.properties.distance }}
            <br>
            </li>
          </ul>
        </div>
      </div>
    </div>
    <!-- YOUR_API_KEYをご自身のAPIキーに置き換えます -->
    <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY" async defer></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
    <!-- map -->
    <script>
      const googleMap = new Vue({
        el: '#app',
        data: {
          map: null,
          features: [], // 場所ポイント
          infowindowAll: {}, // markerでのinfo windows
          activeIndex: null // Highlight selected li
        },
        methods: {
          // グーグルマップを初期化
          initMap() {
            //座標を初期化
            let location = {
                lat: <?=$_latitude?>,
                lng: <?=$_longitude?>
            };
            // マップを初期化
            this.map = new google.maps.Map(document.getElementById('map'), {
              zoomControl: 1,
              mapTypeControl: 0,
              scaleControl: 0,
              streetViewControl: 0,
              rotateControl: 0,
              fullscreenControl: 0,
              center: location,
              zoom: 12,
              mapTypeId: 'terrain'
            });
            var mymarker = new google.maps.Marker({
              position: new google.maps.LatLng(location.lat,location.lng),
              map: this.map,
              animation: google.maps.Animation.DROP,
              icon: {
                fillColor: "#FF0000",                //塗り潰し色
                fillOpacity: 0.6,                    //塗り潰し透過率
                path: google.maps.SymbolPath.CIRCLE, //円を指定
                scale: 20,                           //円のサイズ
                strokeColor: "#FF0000",              //枠の色
                strokeWeight: 1.0                    //枠の透過率
              },
              label: {
                text: '現在地',                       //ラベル文字
                color: '#FFFFFF',                    //文字の色
                fontSize: '12px'                     //文字のサイズ
              }
            });
            fetch('/wp-content/themes/my/map-geojson.php?latitude='+<?=$_latitude?>+'&longitude='+<?=$_longitude?>)
              .then(results => results.json())
              .then(result => {
                this.features = result.features;
                Array.prototype.forEach.call(this.features, r => {
                  let latLng = new google.maps.LatLng(r.geometry.coordinates[0], r.geometry.coordinates[1]);
                  let marker = new google.maps.Marker({
                    position: latLng,
                    map: this.map
                  });
                  let infowindow = new google.maps.InfoWindow({
                    content: `<h5>${r.properties.name}</h5><h6>${r.properties.address}</h6>`
                  });
                  marker.addListener('click', e => {
                    infowindow.open(this.map, marker);
                  });
                  this.map.addListener('click', function () {
                    infowindow.close();
                  });
                  this.infowindowAll[r.properties.id] = {
                    open: function() {
                      console.log("this.infowindowAll["+r.properties.id+"]");
                      infowindow.open(this.map, marker);
                    },
                    close: function() {
                      console.log("close this.infowindowAll[" + r.properties.id + "]");
                      infowindow.close();
                    }
                  };
                });
            });
          },
          openInfoWindows(id) {
            console.log("openInfoWindows("+id+")");
            this.infowindowAll[id].open();
            if(activeIndex!=null && activeIndex!=id){
              this.infowindowAll[activeIndex].close();
            }
          },
          toggle: function(index){
            this.activeIndex = index
          }
        },
        created() {
          window.addEventListener('load', () => {
            this.initMap();
          });
        }
      });
    </script>
  </body>
</html>

【参考】

Google Map上にGeoJSONデータを表示する

Google Maps API學習筆記-1:地圖、標記、客製樣式


https://qiita.com/yangci/items/dffaacf424ebeb1dd643

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.