WordPressの地図にKML/GPXのGPSルートファイルを表示する Google Drive

ブログ

これまでの記事で、GPSルートを表示するテンプレートやショートコードを作成しました。

今回は、GoogleDriveなど外部に保存したGPSファイルにアクセスできるようにしたいと思います。

CORSエラー

そのまま外部サイトに保存したファイルURLを渡した場合、

Access to XMLHttpRequest at 'https:' from origin 'https://domaincom' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

というようなエラーが発生します。
このエラーを回避する方法はいくつかありますが、
今回は、proxy.phpを使う方法を紹介します。

proxy.phpの設置

まずは、サーバー上のテーマフォルダの中にproxy.phpファイルを作成します。
wp-content/themes/cocoon-child-master/proxy.phpのような場所になります。

以下のコードを記述して、自サイトのドメインをプロキシサーバーとして利用します。

<?php
$fileUrl = isset($_GET['url']) ? $_GET['url'] : null;

if (!$fileUrl) {
    http_response_code(400);
    echo "Error: No URL provided.";
    exit;
}

// リモートファイルを取得
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $fileUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$result = curl_exec($ch);
$contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
curl_close($ch);

// レスポンスのヘッダーを設定
header("Content-Type: $contentType");
echo $result;

ショートコード関数の修正

ショートコード関数を微修正します。
主な変更点は、引数にfile_type, file_nameを追加、mapの自動id割り振りになります。

引数の追加は、
file_typeは’kml’,’gpx’を指定して、どの形式のファイルを読み込むのか指定できるようにしました。
GoogleDriveなどの共有リンクだと、ファイル形式を認識できないためです。

file_nameはダウンロードする際のファイル名になります。
proxy.phpを使っている場合、指定しないとファイル名がproxy.phpになってしまいます。

mapのid割り振りは、同じページに複数のmapを作成する場合、idで分けないとエラーが発生するためです。

これらを反映したのが以下になります。


// GPS MAP View
function display_kml_gpx_map($atts) {
    $atts = shortcode_atts(
        array(
            'file' => '',
            'file_type' => '',
            'file_name' => '',
        ),
        $atts
    );

    if (empty($atts['file'])) {
        return '<p>ファイルパスを指定してください。</p>';
    }

    $file_url = esc_url($atts['file']);
    $file_type = esc_attr($atts['file_type']);
    $file_name = esc_attr($atts['file_name']);
    if (empty($file_name)) {
        $file_name = basename($file_url);
    }

    // 動的にユニークなIDを生成
    $map_id = 'map_' . uniqid();

    ob_start(); ?>
    <div id="<?php echo $map_id; ?>" style="height: 500px;"></div>
    <p>※地図の読み込みに時間がかかる場合があります。</p>
    <div style="margin: 20px 0;">
        <a href="<?php echo $file_url; ?>" download="<?php echo $file_name; ?>" class="button">ファイルをダウンロード</a>
    </div>
    <script>
    document.addEventListener('DOMContentLoaded', function () {
        var map = L.map('<?php echo $map_id; ?>').setView([35.68, 139.76], 15);

        L.tileLayer('https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png', {
            attribution: '&copy; <a href="https://maps.gsi.go.jp/development/ichiran.html" target="_blank">国土地理院</a>',
            maxZoom: 18,
            minZoom: 5
        }).addTo(map);

        var fileUrl = "<?php echo $file_url ; ?>";
        var layer;
        if ("<?php echo $file_type; ?>" === 'kml') {
            var kmlLayer = omnivore.kml(fileUrl)
                .on('ready', function () {
                    map.fitBounds(kmlLayer.getBounds());
                })
                .on('error', function (e) {
                    console.error('KML読み込みエラー:', e);
                })
                .addTo(map);
        } else if ("<?php echo $file_type; ?>" === 'gpx') {
            var gpxLayer = omnivore.gpx(fileUrl)
                .on('ready', function () {
                    map.fitBounds(gpxLayer.getBounds());
                })
                .on('error', function (e) {
                    console.error('GPX読み込みエラー:', e);
                })
                .addTo(map);
        } else {
            if (fileUrl.endsWith('.kml')) {
                var kmlLayer = omnivore.kml(fileUrl)
                    .on('ready', function () {
                        map.fitBounds(kmlLayer.getBounds());
                    })
                    .on('error', function (e) {
                        console.error('KML読み込みエラー:', e);
                    })
                    .addTo(map);
            } else if (fileUrl.endsWith('.gpx')) {
                var gpxLayer = omnivore.gpx(fileUrl)
                    .on('ready', function () {
                        map.fitBounds(gpxLayer.getBounds());
                    })
                    .on('error', function (e) {
                        console.error('GPX読み込みエラー:', e);
                    })
                    .addTo(map);
            } else {
                alert('対応していないファイル形式です。');
            }
        }
    });
    </script>

    <link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
    <script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-omnivore/0.3.4/leaflet-omnivore.min.js"></script>
    <?php
    return ob_get_clean();
}
add_shortcode('kml_gpx_map', 'display_kml_gpx_map');

ショートコードの使い方

例えば、GoogleDrive上でリンク共有したファイルの場合は、以下のようにして読み込めます。

    

※地図の読み込みに時間がかかる場合があります。

ドメイン名やテーマフォルダ名、ファイルのIDなどは変更してください。

GoogleDriveから読み込む場合、それなりに時間がかかります。

タイトルとURLをコピーしました