指定した緯度経度を中心にスポットデータを近い順に取得する
<?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> |
【参考】
https://qiita.com/yangci/items/dffaacf424ebeb1dd643