デザイン、システム、マーケティングなど
WEBサイトに関わることをまとめてます

カテゴリー
最近の投稿
月別カテゴリー

投稿日時: 2015年4月12日 カテゴリー: WordPress

[WordPress] MW Google Mapsで「近くのポイントを探す」機能を実装する

MW Google Mapsは投稿にGoogle Mapを簡単に設置できるプラグインです。
住所やUIからポインターを置く場所を決めれるので、お客さんでも扱いやすくすることができます。

「近くのポイントを探す」機能を実装する

今回はMW Google Mapsで登録したポイントを、郵便番号を入力して、郵便番号から一番近いポイントを表示するという機能の実装します。
MW Google Mapsの機能にはないので自分でプログラムを記述して実装することになります。

処理の流れは以下になります。

sc02

基本構成

今回はカスタム投稿タイプのアーカイブページに実装します。
urlは /map/ なので archive-post_map.php にプログラムを記述します。

郵便番号の位置をGeocodingから緯度・経度を取得するプログラム

まずは入力した郵便番号をGeocodingから緯度・経度を取得するところになります。

郵便番号入力フォームのコード

-

Geocodingから緯度・経度を取得するコード

// 3桁の郵便番号を取得
$zip1 = $_POST['zip1'];

// 4桁の郵便番号を取得
$zip2 = $_POST['zip2'];

// 郵便番号を含んだGeocodingのURLを変数に代入
// urlencodeはURLエンコード
$req = 'http://maps.google.com/maps/api/geocode/xml';
$req .= '?address='.urlencode($zip1.'-'.$zip2);
$req .= '&sensor=false';

// Geocodingから郵便番号に対する情報をxmlとして取得
// 参考:http://maps.google.com/maps/api/geocode/xml?address=460-0001&sensor=false
$xml = simplexml_load_file($req) or die('XML parsing error');

// 取得できたら緯度・経度の情報だけを取得する
if ($xml->status == 'OK') {
 $location = $xml->result->geometry->location;
 $lat = floatval($location->lat);
 $lng = floatval($location->lng);
}

登録されているポイントの緯度・経度を取得する

次はMW Google Mapsで登録した全マップ情報の緯度・経度を取得します。
MW Google Mapsの出力部部を解析するプログラム知識がないので、DBから直接取得したいと思います。

DBでどんな形式で登録されているか調べてみると「postmeta」テーブルに

で登録されていました。

地図情報がシリアライズされて登録されているので解除して緯度・経度を取得します。

// $wpdbを使用してDBに接続
// 「meta_key」フィールドが"_mw-google-maps"の「post_id」フィールド、「meta_value」フィールドの値を取得
$myrows = $wpdb->get_results("SELECT post_id, meta_value FROM テーブル名(wp_postmeta) WHERE meta_key='_mw-google-maps'");

// カウント変数を宣言
$count = 0;

// 取得した全マップ情報とIDを代入
foreach ($myrows as $myrow) {
 $meta_value[$count] = unserialize($myrow->meta_value); // シリアライズを解除
 $meta_value[$count]['post_id'] = $myrow->post_id;
 $count++;
}

郵便番号の緯度・経度と登録されている緯度・経度を計算して一番近いポイントを計算します。

まず、2つの緯度・経度の距離を算出する必要がありますが、いろいろな計算式があるようですが、今回は

の計算式を参考にします。

// 2点間の距離を算出する関数
function getPointsDistance($lat1, $lng1, $lat2, $lng2){
 $pi1 = pi();
 $lat1 = $lat1*$pi1/180;
 $lng1 = $lng1*$pi1/180;
 $lat2 = $lat2*$pi1/180;
 $lng2 = $lng2*$pi1/180;
 $deg = sin($lat1)*sin($lat2) + cos($lat1)*cos($lat2)*cos($lng2-$lng1);
 return round(6378140*(atan2(-$deg,sqrt(-$deg*$deg+1))+$pi1/2), 0);
}

// カウント変数を初期化
$count = 0;
// 変数の宣言
$address; $id; $math; $near;

// 郵便番号の緯度・経度と登録されている緯度・経度で一番近い距離のポイント情報を取得
foreach ($meta_value as $value) {
 // getPointsDistance(登録されている緯度・経度, 郵便番号の緯度経度)
 $math = getPointsDistance($value['latitude'], $value['longitude'], $lat, $lng);
 // 一つ目のポイントは基準として代入
 if($count == 0){ $near = $math; $address = $value['address']; $id = $value['post_id']; }
 // 代入されているポイント情報より距離が一番近いものを再代入する
 if($near-$math > 0){
  $near = $math;
  $id = $value['post_id'];
  $address = $value['address'];
 }						
 $count++;
}

一番近いポイントを表示させる

最後に取得したポイントの中から一番近いポイントを表示させます。

// 郵便番号が両方とも入力されていたらポイントを表示
if(isset($_POST['zip1']) && strlen($_POST['zip1']) && isset($_POST['zip2']) && strlen($_POST['zip2'])){
 echo '
お近くの駅は '.$address.' です。
';  echo do_shortcode('[mw-google-maps-multi ids="'.$id.'"]'); } // 郵便番号が入力されていなかったらエラーを表示 else {  echo '
郵便番号を入力してください。
';  echo do_shortcode('[mw-google-maps-multi]'); }

完成例はこちらです。

こちらのコードでは、非公開のマップ情報も取得しているので変更する必要があります。
また後日改定していきます。

参考サイト