これまでの記事で、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: '© <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から読み込む場合、それなりに時間がかかります。