PlacemakerとYahoo!地図Web APIを連携

Placemakerから取得するXMLとYahoo!地図Web APIを使用して、テキストから位置情報を抽出した結果を地図に表示する簡単なWebアプリケーションを作成してみよう。地図APIについてはYahoo!にも同様のサービスがあるが、日本の地図をあつかう場合はYahoo! Japanの地図APIのほうが都合がよいため、ここではYahoo! Japanの地図APIを利用する。

Yahoo! Japanのユーザ登録・アプリケーションIDを取得し、実装開始だ。

placemaker_map.php

<?php
$appid['Y_jp'] = 'Yahoo! Japan のアプリケーションID';
$appid['Y_en'] = 'Yahoo! のアプリケーションID';

function h($string)
{
    return htmlspecialchars(trim($string), ENT_QUOTES, 'UTF-8');
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="ja">

<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Placemaker x Yahoo!地図Web API</title>
<script type="text/javascript" src="./js/jquery-1.2.6.min.js"></script>
<script type="text/javascript" src="http://api.map.yahoo.co.jp/MapsService/js/V1/?appid=<?php echo $appid['Y_jp']; ?>"></script>
</head>

<body>
    <p>■ Placemaker x Yahoo!地図Web API</p>
    <table border="1" width="100%">
        <tr>
            <th>documentContent</th>
            <th><a href="http://developer.yahoo.co.jp/webapi/map/">Yahoo!地図Web API</a></th>
        </tr>
        <tr>
            <td align="center">
                <form action="./placemaker_map.php" accept-charset="utf-8" method="post">
                    <p>
                        <textarea type="text" name="documentContent" value="" style="height:200px;width:95%"><?php echo h($_POST['documentContent']) ?></textarea><br>
                        <input type="hidden" name="documentType" value="text/plain">
                        <input type="hidden" name="inputLanguage" value="jp">
                        <input type="hidden" name="outputType" value="xml">
                        <input type="hidden" name="appid" value="<?php echo $appid['Y_en']; ?>">

                        <input type="submit" value="submit">
                    </p>
                </form>
            </td>
            <td>
                <div id="map" style="width: 100%; height: 240px;"></div>
            </td>
        </tr>
    </table>
    <?php
    if (isset($_POST['documentContent']))
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, 'http://wherein.yahooapis.com/v1/document');
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($_POST));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        $result = simplexml_load_string(curl_exec($ch));
        curl_close ($ch);

        foreach ($result->document->placeDetails as $value)
        {
            $woeId = (string)$value->place->woeId;
            $record[$woeId]['name_en'] = (string)$value->place->name;
            $record[$woeId]['lat'] = (string)$value->place->centroid->latitude;
            $record[$woeId]['lon'] = (string)$value->place->centroid->longitude;
        }
        unset($value);

        foreach ($result->document->referenceList->reference as $value)
        {
            $name = (string)$value->text;
            $pregArray = preg_split('/ /', (string)$value->woeIds);
            foreach ($pregArray as $woeId)
            {
                $record[$woeId]['name_jp'] = $name;
            }
        }
        unset($pregArray, $value, $woeId);
        ?>

        <table border="1" width="100%">
            <tr>
                <th colspan="2">center</th>
                <th colspan="2">southWest</th>
                <th colspan="2">northEast</th>
            </tr>
            <tr>
                <td id="center_lat" align="center"><?php echo h($result->document->extents->center->latitude); ?></td>
                <td id="center_lon" align="center"><?php echo h($result->document->extents->center->longitude); ?></td>
                <td id="southWest_lat" align="center"><?php echo h($result->document->extents->southWest->latitude); ?></td>
                <td id="southWest_lon" align="center"><?php echo h($result->document->extents->southWest->longitude); ?></td>
                <td id="northEast_lat" align="center"><?php echo h($result->document->extents->northEast->latitude); ?></td>
                <td id="northEast_lon" align="center"><?php echo h($result->document->extents->northEast->longitude); ?></td>
            </tr>
        </table>

        <table border="1" width="100%">
            <tr>
                <th>woeID</th>
                <th>地名(日本語)</th>
                <th>地名(英語)</th>
                <th>緯度</th>
                <th>経度</th>
            </tr>
            <?php
            foreach ($record as $key => $value)
            {
            ?>
            <tr>
                <td class="woeID" align="center"><?php echo h($key); ?></td>
                <td class="name_jp"><?php echo h($value['name_jp']); ?></td>
                <td class="name_en"><?php echo h($value['name_en']); ?></td>
                <td class="lat" align="center"><?php echo h($value['lat']); ?></td>
                <td class="lon" align="center"><?php echo h($value['lon']); ?></td>
            </tr>
        <?php
        }
        ?>
        </table>

        <script type="text/javascript">
        <!--
        $(document).ready
        (
            function()
            {
                var latlng = new YLLPoint(parseFloat($('#center_lat').text()),parseFloat($('#center_lon').text()));
                var mapsctrl = new YahooMapsCtrl('map', latlng, 3);

                var addIconsArray = new Array();
                jQuery.each($('.woeID'), function(i)
                {
                    addIconsArray.push(
                    {
                        'id': $('.woeID:eq('+i+')').text(),
                        'pos': new YLLPoint($('.lat:eq('+i+')').text(),$('.lon:eq('+i+')').text()),
                        'popup':
                            $('.name_jp:eq('+i+')').text() + '<br>' +
                            $('.name_en:eq('+i+')').text() + '<br>' +
                            $('.lat:eq('+i+')').text() + ', ' + $('.lon:eq('+i+')').text() + '<br>' +
                        'woeID: ' + $('.woeID:eq('+i+')').text() + '<br>',
                        'type': 'L1'
                    });
                });

                mapsctrl.addIcons(addIconsArray);
            }
        );
        -->
        </script>

        <?php
    }
    ?>
</body>

</html>

レイアウト左上にPOSTするテキストを入力するためのボックス、右上にYahoo!地図Web API経由で取得する地図を配置。下部に取得した位置情報をリスト表示する。PlacemakerにcURLでPOST、返るXMLをSimpleXMLで加工・表示。jQueryのeachでリストより緯度経度を取得し、Yahoo!地図Web APIのaddIconsで複数場所のアイコンを生成している。

今度は実際に長めのテキストを入力してみよう。ここでは「【レビュー】UQ WiMAXの気になるエリアと通信速度を検証 - エリアマップを活用しよう」のテキストを使用した。

テキスト本文よりさまざまな位置情報を解析し、その結果をYahoo!地図Web APIを使用して表示した。アイコンにマウスをのせると、各種ロケーション情報についても表示する

紹介したプログラム内でおこなっていることは単純な内容だが、いとも簡単に地図と連携させたWebアプリケーションが実装できた。placeDetails内のweightやconfidenceも考慮すれば、さらにさまざまな用途で利用できるようになるだろう。なかなか2次利用がパッと思いつきにくいジャンルのWebサービスではあるが、使いこなせるようになっておいて損はないはずだ。位置情報に関するWebサービスはまだまだ出始めたばかり、今後の動向・発展に注目したい。