Google Maps JavaScript APIを使ってWordPressページにルートマップを埋め込む(WordPress編）

# はじめに

https://qiita.com/xkogij/items/2554c37929caf6f6fc3c

で書いたGoogle Maps Javascript Apiについて、WordPress側でやったことを書きます。
この記事ではHTMLのformにhidden属性のinputタグ設定し、idとvalueでキーバリュー型の情報を格納しています。
こんな感じ

```html:
 <form id="">
            <input type="hidden" id="count" value="4" />
            <input type="hidden" id="p0-label" value="Start" />
            <input type="hidden" id="p0-title" value="Kamakura Station" />
            <input type="hidden" id="p0-latlng" value="35.319264, 139.550004" />
            <input type="hidden" id="p0-description" value="Tour starts from here" /> 
            <input type="hidden" id="p1-label" value="1" />
            <input type="hidden" id="p1-title" value="Tsurugaoka Hachimangu Shrine" />
            <input type="hidden" id="p1-latlng" value="35.326074, 139.556485" />
            <input type="hidden" id="p1-description"
                value="Built as a tutelary shrine for the Genji family in 1191, the most gorgeous shrine in Kamakura attracts millions of visitors for its history, culture, architecture and various traditional events." />
            <input type="hidden" id="p2-label" value="2" />
            <input type="hidden" id="p2-title" value="Hase-dera Temple" />
            <input type="hidden" id="p2-latlng" value="35.312416, 139.533042" />
            <input type="hidden" id="p2-description"
                value="This legendary old temple boasts of its large wooden gilded statue of Eleven-faced Goddess of Mercy, a beautiful Japanese-style garden and the nice view of the ocean from a terrace." />
            <input type="hidden" id="p3-label" value="3" />
            <input type="hidden" id="p3-title" value="the Great Buddha" />
            <input type="hidden" id="p3-latlng" value="35.315858, 139.535371" />
            <input type="hidden" id="p3-description"
                value="The Great Buddha, a National Treasure and a Symbol of Kamakura, was cast in bronze in the middle of the 13th C. The hollow interior of the statue is open to the public." />
        </form>
```

WordPressはphpとMySqlで動いているので、MySqlにルート設定用のテーブルをもたせ、functions.phpでデータを呼び出してformを生成しています。
また、使う際にはWordPressのショートコードを使うことでWordPressのPage作成時に簡単に地図が埋め込めるようにしました。

# DataBase
wp2_course、wp2_route、wp2_placeの３つのテーブルを使っています。プレサフィックスの"wp2_"はWordPress用のテーブルがすべてこの形式だったので真似しただけで、理由はないんですが、今思うと別に真似しなくても良かったような。

## wp2_course(コース設定用テーブル）
| 物理名 | データ型 | NULL | 既定値 | 説明 |
|:-:|:-:|:-:|:-:|:-|
| id | text  | no | なし | コース識別コード。<br/>ショートコードでどのルート表示するか指定します。 |
| zoom | int(11)  | yes | NULL | 地図の初期表示縮尺 |
| travelmode | varchar(10) | yes | NULL | WALKING:徒歩(既定値)<br/>DRIVING：車<br/>BICYCLING：自転車<br/>TRANSIT：公共交通機関 |
| maptypeid  | varchar(10)  | yes | NULL | ROADMAP:道路や建物などが表示される地図(既定値)<br/>SATELLITE：衛星写真<br/>HYBRID：ハイブリッド<br/>TERRAIN：地形情報地図 |

実際にはid以外ほぼNULLで使っています。
こんな感じ

| id | zoom | travelmode | maptypeid |
|:-:|:-:|:-:|:-:|
| K1 | NULL | NULL | NULL |
| YM1 | NULL | NULL | NULL |

## wp2_place(地点テーブル）
| 物理名 | データ型 | NULL | 既定値 | 説明 |
|:-:|:-:|:-:|:-:|:-:|
| name | varchar(50) | no | なし | 地点の物理名 |
| title | varchar(50) | no | なし | Markerクリック時のポップアップウィンドウのタイトル |
| latlang| geometry | no | なし | 緯度経度 |
| description| varchar(400)  | no | なし | Markerクリック時のポップアップウィンドウに表示する説明文 |
例：

| name | title | latlng | description |
|:-:|:-:|:-:|:-:|
| KAMAKURA_STATION | Kamakura Station | 'POINT(35.319264 139.550004)',0 | Tour starts from here. |
| HACHIMAN_GU | Tsurugaoka Hachimangu Shrine | 'POINT(35.326074 139.556485)',0 | Built as a tutelary shrine for the Genji family in 1191.|

## wp2_route(経路テーブル）
| 物理名 | データ型 | NULL | 既定値 | 説明 |
|:-:|:-:|:-:|:-:|:-|
| index | int(11) | no | なし | インデックス（Auto_Increment） |
| id | varchar(5) | no | なし | コースid |
| name | varchar(50) | no | なし | 地点の物理名 |
| order | int(11) | no | なし | 経路の順序 |
| label | varchar(10) | no | なし | Markerに表示するラベル。"-b-"とすると経路を分割する |
| marker | tinyint(1) | no | 1 | 1:マップ上にMarker生成する、0:Marker生成しない |
| skip | tinyint(1) | no | 0 | 1:経路に含める,0:経路に含めない |

marker/skipの組み合わせでこんな感じになります。

| marker | skip | 説明 |
|:-:|:-:|:-|
| 1 | 0 | (既定値)Marker生成して経路に含まれる |
| 0 | 0 | Markerなしの通過点となり、細かい経路設定が可能 |
| 1 | 1 | Markerのみで経路に含まれない  |
| 0 | 1 | この設定かつlabel="-b-"で分割に使用しています。  |

marker=0,skip=1の場合は最初使用しない組み合わせだったんですが、あとで経路を分割する必要が生じた際に使うことにしました。

例：

| index | id | name | order | label | marker | skip |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| 1| K1| KAMAKURA_STATION | 0 | Start | 1 | 0 |
| 2| K1| HACHIMAN_GU | 1 | 1 | 1 | 0 |
| 3| K1| HASE_DERA | 2 | 2 | 1 | 0 |
| 4| K1| GREAT_BUDDHA | 3 | 3 | 1 | 0 |

* 正直、placeとrouteはテーブル分けなくても良かったなって後で思いました。使うときはJoinして使うし、メンテナンス性があんまり良くなくて。
* courseテーブルもいらないっちゃいらなかったんですが・・・

# functions.php

WordPressに組み込むため、functions.phpを記述します。
最初はスクリプト登録用の手続き

```php:
<?php
add_action( 'wp_enqueue_scripts', 'theme_enqueue_styles' );
function theme_enqueue_styles() {
	    wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' );
	    wp_enqueue_style( 'child-style',
	        get_stylesheet_directory_uri() . '/style.css',
	        array('parent-style')
	    );
}
function register_script(){  //　登録の項目
        wp_register_script( 'maps', get_stylesheet_directory_uri() . '/js/maps.js', false, '', true);
        wp_register_script('googlemaps', '//maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&language=en&callback=initMap', array('maps'), '', true );
}
function add_script() {  // 装備の項目
        register_script();
        wp_enqueue_script('maps');
        wp_enqueue_script('googlemaps');
}
add_action('wp_enqueue_scripts', 'add_script');
```

次にマップ用の関数を作ります
テーブルから情報とってきてformを生成しています。
YOUR_API_KEYにはGoogle Maps Api使用する際に必要なキーを取得して埋め込んでください。

```php:
// 地図用
function gmap($atts) {
    //ショートコードパラメータからコース名取得
    extract(shortcode_atts(array(
        'course' => 'undefined',
        'height' => '480px',
    ), $atts));
    
    if($course=='undefined'){
        echo "[gmap course='???']course not defined";
        return;
    }

    // wpdbオブジェクト
    global $wpdb;
 
    // ★デバッグ用
    $wpdb->show_errors();    

    // コース取得用SQL
    $sql_course=$wpdb->prepare("
        SELECT c.id, c.travelmode, c.maptypeid, c.zoom 
        FROM wp2_course c 
        WHERE c.id='%s'
    ",$course);

    // ルート取得用SQL
    $sql_route=$wpdb->prepare("
        SELECT r.id, r.name, r.order, r.label, r.marker, r.skip, p.title, p.description, X( p.latlng ) AS x, Y( p.latlng ) AS y
        FROM wp2_route r
        JOIN wp2_place p ON r.name = p.name
        WHERE r.id = '%s'
        ORDER BY r.order
    ",$course);
    
    // クエリ実行
    $rows_course = $wpdb->get_results($sql_course);
    if($rows_course){
        $rows_route = $wpdb->get_results($sql_route);
        if($rows_route){
            $num = $wpdb->num_rows;
echo <<< EOM
            <form id="{$wpdb->id}">
            <input type="hidden" id="count" value="{$num}" />
EOM;
            foreach($rows_course as $row_course){
                if($row_course->travelmode!=null){
                    echo "<input type='hidden' id='travelmode' value='{$row_course->travelmode}' />";
                }
                if($row_course->maptypeid!=null){
                    echo "<input type='hidden' id='maptypeid' value='{$row_course->mapTypeId}' />";
                }
                if($row_course->zoom!=null){
                    echo "<input type='hidden' id='zoom' value='{$row_course->zoom}' />";
                }
            }
            $index=0;
            foreach($rows_route as $row ){
echo <<< EOM
                <input type="hidden" id="p{$index}-label" value="{$row->label}" />
                <input type="hidden" id="p{$index}-title" value="{$row->title}" />
                <input type="hidden" id="p{$index}-latlng" value="{$row->x}, {$row->y}" />
                <input type="hidden" id="p{$index}-description" value="{$row->description}" />
EOM;
                if($row->marker==0){
echo <<< EOM
                <input type="hidden" id="p{$index}-marker" value="{$row->marker}" />
EOM;
                }
                if($row->skip==1){
echo <<< EOM
                <input type="hidden" id="p{$index}-skip" value="{$row->skip}" />
EOM;
                }
                $index=$index+1;
            }
            echo "</form>";
//            echo "<div id='map' style='height: 480px'></div>";
        }
    }
    return "<div id='map' style='height: {$height}'></div>";
}
```

最後にショートコードを追加します。

```php:
add_shortcode('gmap', 'gmap');
```
# 使い方
WordPressダッシュボードのPagesでPageを作成し、本文に

```:
[gmap course="K1"]
```
というふうに記述します。
ここで"K1"はコースidで設定したものを指定します。