目次
サンプル・プログラムの実行例

サンプル・プログラム
photomap.php | サンプル・プログラム本体 |
pahooGeoCode.php | 住所・緯度・経度に関わるクラス pahooGeoCode。 使い方は「PHPで住所・ランドマークから最寄り駅を求める」「PHPで住所・ランドマークから緯度・経度を求める」などを参照。include_path が通ったディレクトリに配置すること。 |
バージョン | 更新日 | 内容 |
---|---|---|
1.1.0 | 2025/08/13 | .pahooEnv導入 |
1.0 | 2022/03/06 | 初版 |
バージョン | 更新日 | 内容 |
---|---|---|
6.8.0 | 2025/08/10 | アクセスキーなどを ".env" に分離 |
6.7.1 | 2025/07/26 | jsLine_Gmap() - bug-fix |
6.7.0 | 2025/07/20 | drawJSmap,drawGMap -- 引数 $markerLevel 追加 |
6.6.0 | 2025/07/19 | drawJSmap,drawGMap,drawLeaflet -- マップ中心マーカー表示引数を追加 |
6.5.0 | 2025/06/14 | GoogleMaps JavaScript APIの変更に対応 |
準備:GDライブラリ
準備:PHP の https対応


Windowsでは、"php.ini" の下記の行を有効化する。
extension=php_openssl.dllLinuxでは --with-openssl=/usr オプションを付けて再ビルドする。→OpenSSLインストール手順

これで準備は完了だ。
準備:pahooInputData 関数群

また、各種クラウドサービスに登録したときに取得するアカウント情報、アプリケーションパスワードなどを登録した .pahooEnv ファイルから読み込む関数 pahooLoadEnv を備えている。こちらについては、「各種クラウド連携サービス(WebAPI)の登録方法」をご覧いただきたい。
準備:pahooGeoCode クラス
pahooGeoCode.php
40: class pahooGeoCode {
41: public $items; // 検索結果格納用
42: public $error; // エラー・フラグ
43: public $errmsg; // エラー・メッセージ
44: public $hits; // 検索ヒット件数
45: public $webapi; // 直前に呼び出したWebAPI URL
46:
47: // -- 以下のデータは .env ファイルに記述可能
48: // Google Cloud Platform APIキー
49: // https://cloud.google.com/maps-platform/
50: // ※Google Maps APIを利用しないのなら登録不要
51: public $GOOGLE_API_KEY_1 = ''; // HTTPリファラ用
52: public $GOOGLE_API_KEY_2 = ''; // IP制限用
53: public $GOOGLE_MAP_ID = ''; // GoogleMaps ID
54:
55: // Yahoo! JAPAN Webサービス アプリケーションID
56: // https://e.developer.yahoo.co.jp/register
57: // ※Yahoo! JAPAN Webサービスを利用しないのなら登録不要
58: public $YAHOO_APPLICATION_ID = '';
59:
60: // OSM Nominatim Search API利用時に知らせるメールアドレス
61: // https://wiki.openstreetmap.org/wiki/JA:Nominatim#.E6.A4.9C.E7.B4.A2
62: // ※OSM Nominatim Search APIを利用しないのなら登録不要
63: public $NOMINATIM_EMAIL = '';
64:
65: // IP2Location.io APIキー
66: // https://www.ip2location.io/
67: // ※IP2Location.ioを利用しないのなら登録不要
68: public $IP2LOCATION_API_KEY = '';
PHPのクラスについては「PHPでクラスを使ってテキストの読みやすさを調べる」を参照されたい。

地図や住所検索として Google を利用するのであれば Google Cloud Platform APIキー とマップID が必要で、その入手方法は「Google Cloud Platform - WebAPIの登録方法」を、Yahoo!JAPAN を利用するのであれば Yahoo! JAPAN Webサービス アプリケーションIDが必要で、その入手方法は「Yahoo!JAPAN デベロッパーネットワーク - WebAPIの登録方法」を、IP2Location.ioを利用するのであれば「PHPでIPアドレスやホスト名から住所を求める」を、それぞれ参照されたい。

PHPのクラスについては「PHPでクラスを使ってテキストの読みやすさを調べる」を参照されたい。
準備:地図サービス(WebAPI)の選択
逆ジオコーディングサービスは、Google、Yahoo!JAPAN、HeartRails Geo API、簡易ジオコーディングサービスから選べる。あらかじめ、定数 REVGEOSERVICE に値を設定すること。
解説:初期設定
photomap.php
60: // マップの表示サイズ(単位:ピクセル)
61: define('MAP_WIDTH', 600);
62: define('MAP_HEIGHT', 400);
63: // マップID
64: define('MAPID', 'map_id');
65: // 初期値
66: define('DEF_LATITUDE', 35.4658); // 緯度
67: define('DEF_LONGITUDE', 139.6223); // 経度
68: define('DEF_TYPE', 'roadmap'); // マップタイプ
69: define('DEF_ZOOM', 13); // ズーム
解説:Exif情報から緯度・経度を取り出す
photomap.php
301: /**
302: * Exif情報から緯度・経度を取り出す
303: * @param array $exif Exif情報
304: * @return list(緯度,経度)/(FALSE,FALSE):取得失敗
305: */
306: function exif2location($exif) {
307: $pat = "/([0-9]+)\/([0-9]+)/ui";
308:
309: // Exif情報に緯度・経度があるかどうか
310: if (! isset($exif['GPSLatitude.0']) || ! isset($exif['GPSLongitude.0'])) {
311: return array(FALSE, FALSE);
312: }
313:
314: // 緯度の計算
315: $latitude = 0;
316: for ($i = 0; $i < 5; $i++) {
317: $key = 'GPSLatitude.' . (string)$i;
318: if (isset($exif[$key])) {
319: if (preg_match($pat, $exif[$key], $arr) > 0) {
320: $latitude += (float)$arr[1] / (float)$arr[2] / pow(60, $i);
321: }
322: }
323: }
324: // 北緯・南緯の計算
325: if (isset($exif['GPSLatitudeRef'])) {
326: if (! preg_match('/N/ui', $exif['GPSLatitudeRef']) > 0) {
327: $latitude = 0 - $latitude;
328: }
329: }
330:
331: // 経度の計算
332: $longitude = 0;
333: for ($i = 0; $i < 5; $i++) {
334: $key = 'GPSLongitude.' . (string)$i;
335: if (isset($exif[$key])) {
336: if (preg_match($pat, $exif[$key], $arr) > 0) {
337: $longitude += (float)$arr[1] / (float)$arr[2] / pow(60, $i);
338: }
339: }
340: }
341: // 東経・西経の計算
342: if (isset($exif['GPSLongitudeRef'])) {
343: if (! preg_match('/E/ui', $exif['GPSLongitudeRef']) > 0) {
344: $longitude = 0 - $longitude;
345: }
346: }
347:
348: return array($latitude, $longitude);
349: }
取得したExif情報(配列)から、マッピングしやすいように緯度・経度情報を取り出すユーザー関数が exif2location である。
解説:画像情報の一部をTABLE化する
photomap.php
435: /**
436: * 画像情報の一部をTABLE化する
437: * @param object $pgc pahooGeoCodeクラス
438: * @param array $exif Exif情報
439: * @param array $items 画像ファイル情報
440: * @return string HTMLタグ
441: */
442: function makeInfoTable($pgc, $exif, $items) {
443: $table = array(
444: // 画像形式 => 読み込み関数
445: IMAGETYPE_BMP => 'BMP',
446: IMAGETYPE_GIF => 'GIF',
447: IMAGETYPE_JPEG => 'JPEG',
448: IMAGETYPE_PNG => 'PNG',
449: IMAGETYPE_WEBP => 'WEBP'
450: );
451:
452: $html =<<< EOT
453: <table class="exiflist">
454:
455: EOT;
456:
457: // 撮影日時
458: $dt = getExifData('DateTimeOriginal', $exif);
459: if ($dt == FALSE) {
460: $dt = '(不明)';
461: } else {
462: $dt = preg_replace('/([0-9]+)[\:\-\/]([0-9]+)[\:\-\/]([0-9]+) ([0-9\:\-\/]+)/ui', '$1-$2-$3 $4', $dt);
463: }
464:
465: // 緯度・軽度
466: list($latitude, $longitude) = exif2location($exif);
467: if (($latitude != FALSE) && ($longitude != FALSE)) {
468: $latitudeRef = ($latitude >= 0) ? '北緯' : '南緯';
469: $longitudeRef = ($longitude >= 0) ? '東経' : '西経';
470: $latitudeStr = $latitudeRef . substr(deg2hexadec($latitude), 1);
471: $longitudeStr = $longitudeRef . substr(deg2hexadec($longitude), 1);
472: // 住所
473: $address = (($arr = $pgc->getAddress3($latitude, $longitude, REVGEOSERVICE)) == FALSE) ? '' : $arr['address'];
474: } else {
475: $latitudeStr = '(不明)';
476: $latitude = '---';
477: $longitudeStr = '(不明)';
478: $longitude = '---';
479: $address = '(不明)';
480: }
481:
482: // 画像形式
483: $imagetype = '';
484: if (isset($items['imagetype'])) {
485: foreach ($table as $key=>$val) {
486: if ($key == $items['imagetype']) {
487: $imagetype = $val;
488: break;
489: }
490: }
491: }
492: // 画像幅
493: $width = '';
494: if (isset($items['width'])) {
495: $width = $items['width'];
496: }
497: // 画像高さ
498: $height = '';
499: if (isset($items['height'])) {
500: $height = $items['height'];
501: }
502:
503: $html .=<<< EOT
504: <tr>
505: <td>緯度</td>
506: <td>{$latitudeStr}<br />({$latitude})</td>
507: </tr>
508: <tr>
509: <td>経度</td>
510: <td>{$longitudeStr}<br />({$longitude})</td>
511: </tr>
512: <tr>
513: <td>住所</td>
514: <td>{$address}</td>
515: </tr>
516: <tr>
517: <td>撮影日時</td>
518: <td>{$dt}</td>
519: </tr>
520: <tr>
521: <td>画像形式</td>
522: <td>{$imagetype}</td>
523: </tr>
524: <tr>
525: <td>画像サイズ</td>
526: <td>{$width}×{$height}ピクセル</td>
527: </tr>
528:
529: EOT;
530: $html .=<<< EOT
531: </table>
532:
533: EOT;
534: return $html;
535: }
緯度・経度から住所を求める仕組みは、「PHPで緯度・経度から住所を求める」をご覧いただきたい。
解説:ファイルのドロップ
file2img.php
73: <script>
74: /**
75: * ファイルのドロップ
76: * @param evt イベント
77: * @return なし
78: */
79: function handleFileSelect(evt) {
80: evt.stopPropagation();
81: evt.preventDefault();
82:
83: var files = evt.dataTransfer.files;
84: var output = [];
85:
86: document.getElementById('upload').files = files;
87: document.myform.submit();
88: }
89:
90: function handleDragOver(evt) {
91: evt.stopPropagation();
92: evt.preventDefault();
93: evt.dataTransfer.dropEffect = 'copy';
94: }
95:
96: function PageLoad(evt) {
97: var dropFrame = document.getElementById('DropFrame');
98: dropFrame.addEventListener('dragover', handleDragOver, false);
99: dropFrame.addEventListener('drop', handleFileSelect, false);
100: }
101: </script>

ファイルをドラッグする処理は、JavaScriptによって実現している。
ドラッグする場所はオブジェクトとして用意し、そのID名をあらかじめ変数 dropFrame に代入しておく。
関数 PageLoad は bodyタグをonLoadするときに実行すること。
参考サイト
- PHPでExif情報を表示する:ぱふぅ家のホームページ
- PHPで画像ファイルを読み込んでimgタグに埋め込む:ぱふぅ家のホームページ
- PHPでマップを利用して緯度・経度や住所を求める:ぱふぅ家のホームページ
- PHPで緯度・経度から住所を求める:ぱふぅ家のホームページ
- C++ で撮影場所をマッピング:ぱふぅ家のホームページ
(2025年8月13日).pahooEnv導入
(2025年6月14日)GoogleMaps JavaScript APIの変更に対応した.