目次
サンプル・プログラムの実行例
サンプル・プログラムのダウンロード
| mappingLaborForceParticipationRate.php | サンプル・プログラム |
| .pahooEnv | クラウドサービスを利用するためのアカウント情報などを記入する .env ファイル。 使い方は「各種クラウド連携サービス(WebAPI)の登録方法」を参照。include_path が通ったディレクトリに配置すること。 |
| pahooInputData.php | データ入力に関わる関数群。 使い方は「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。 |
| pahooGeoCode.php | 住所・緯度・経度に関わるクラス pahooGeoCode。 使い方は「PHPで住所・ランドマークから最寄り駅を求める」「PHPで住所・ランドマークから緯度・経度を求める」などを参照。include_path が通ったディレクトリに配置すること。 |
| jp.json | 都道府県境界を描くためのGeoJSONデータ。 使い方は「PHPで住所・ランドマークから最寄り駅を求める」「PHPで都道府県別の最低賃金の分布を地図上に描く」などを参照。pahooGeoCode.php と同じディレクトリに配置すること。 |
| バージョン | 更新日 | 内容 |
|---|---|---|
| 1.0.0 | 2025/10/13 | 初版 |
| バージョン | 更新日 | 内容 |
|---|---|---|
| 2.0.1 | 2025/08/11 | getParam() bug-fix |
| 2.0.0 | 2025/08/11 | pahooLoadEnv() 追加 |
| 1.9.0 | 2025/07/26 | getParam() 引数に$trim追加 |
| 1.8.1 | 2025/03/15 | validRegexPattern() debug |
| 1.8.0 | 2024/11/12 | validRegexPattern() 追加 |
| バージョン | 更新日 | 内容 |
|---|---|---|
| 6.9.0 | 2025/09/21 | jsPolygon, jsPolygon_Gmap, jsPolygon_Leaflet, loadGeoJSON, getPrefBorderList を追加 |
| 6.8.0 | 2025/08/10 | アクセスキーなどを ".pahooEnd" に分離 |
| 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 -- マップ中心マーカー表示引数を追加 |
準備:PHP の https対応
Windowsでは、"php.ini" の下記の行を有効化する。
extension=php_openssl.dllLinuxでは --with-openssl=/usr オプションを付けて再ビルドする。→OpenSSLインストール手順
これで準備は完了だ。
準備:pahooInputData 関数群
また、各種クラウドサービスに登録したときに取得するアカウント情報、アプリケーションパスワードなどを登録した .pahooEnv ファイルから読み込む関数 pahooLoadEnv を備えている。こちらについては、「各種クラウド連携サービス(WebAPI)の登録方法」をご覧いただきたい。
準備:pahooGeoCode クラス
pahooGeoCode.php
41: class pahooGeoCode {
42: public $items; // 検索結果格納用
43: public $error; // エラー・フラグ
44: public $errmsg; // エラー・メッセージ
45: public $hits; // 検索ヒット件数
46: public $webapi; // 直前に呼び出したWebAPI URL
47:
48: // 都道府県境界線データ
49: // SimpleMaps.com is a product of Pareto Software, LLC. © 2010-2025
50: // https://simplemaps.com/gis/country/jp
51: // ※各自の環境に合わせて設定すること
52: public $GeoJsonJP = __DIR__ . '/jp.json';
53:
54: // -- 以下のデータは .env ファイルに記述可能
55: // Google Cloud Platform APIキー
56: // https://cloud.google.com/maps-platform/
57: // ※Google Maps APIを利用しないのなら登録不要
58: public $GOOGLE_API_KEY_1 = ''; // HTTPリファラ用
59: public $GOOGLE_API_KEY_2 = ''; // IP制限用
60: public $GOOGLE_MAP_ID = ''; // GoogleMaps ID
61:
62: // Yahoo! JAPAN Webサービス アプリケーションID
63: // https://e.developer.yahoo.co.jp/register
64: // ※Yahoo! JAPAN Webサービスを利用しないのなら登録不要
65: public $YAHOO_APPLICATION_ID = '';
66:
67: // OSM Nominatim Search API利用時に知らせるメールアドレス
68: // https://wiki.openstreetmap.org/wiki/JA:Nominatim#.E6.A4.9C.E7.B4.A2
69: // ※OSM Nominatim Search APIを利用しないのなら登録不要
70: public $NOMINATIM_EMAIL = '';
71:
72: // IP2Location.io APIキー
73: // https://www.ip2location.io/
74: // ※IP2Location.ioを利用しないのなら登録不要
75: public $IP2LOCATION_API_KEY = '';
地図や住所検索として 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でクラスを使ってテキストの読みやすさを調べる」を参照されたい。
準備:各種定数など
mappingLaborForceParticipationRate.php
53: // 各種定数(START) ===========================================================
54:
55: // Spinner - jQuery UI を使用するかどうか
56: define('USESPINNER', TRUE);
57:
58: // 数値増減クリックで即計算するかどうか(TRUE:即計算,FALE:計算ボタンを用意)
59: define('ONCHANGE', FALSE);
60:
61: // 入力可能な西暦年
62: define('YEAR_MIN', 1950); // 最小値【変更不可】
63: define('YEAR_MAX', 2020); // 最大値【変更不可】
64: define('YEAR_INTERVAL', 5); // 年の間隔【変更不可】;国勢調査の年
65:
66: // 地図描画サービスの選択
67: // 0:Google
68: // 2:地理院地図・OSM
69: define('MAPSERVICE', 2);
70:
71: // マップの表示サイズ(単位:ピクセル)
72: define('MAP_WIDTH', 600);
73: define('MAP_HEIGHT', 700);
74: // マップID
75: define('MAPID', 'map_id');
76:
77: // 初期値
78: define('DEF_LONGITUDE', 135.4604252); // 中心座標(経度)
79: define('DEF_LATITUDE', 35.7883146); // (緯度)
80: define('DEF_TYPE', 'GSIBLANK'); // マップタイプ(地理院白地図)
81: define('DEF_ZOOM', 5); // ズーム
82: define('DEF_CATEGORY', 'world'); // カテゴリ
83:
84: // キャッシュ保持時間(分) 0:キャッシュしない
85: // 政府統計 e-Stat へのアクセス負荷軽減
86: define('LIFE_CACHE_DATA', (60 * 24 * 10));
87:
88: // キャッシュ・ディレクトリ
89: // 書き込み可能で,外部からアクセスされないディレクトリを指定してください.
90: define('DIR_CACHE_DATA', './pcache_estat/');
91:
92: // 政府統計 e-Stat 統計表ID
93: // 2020年国勢調査:時系列データ:人口の労働力状態,就業者の産業・職業
94: define('ESTAT_LaborForceParticipationRate', '0003412176');
95:
96: // APPID
97: if (isset($_ENV['PAHOO_ESTAR_APIKEY'])) {
98: define('ESTAT_APPID', $_ENV['PAHOO_ESTAR_APIKEY']);
99: } else {
100: define('ESTAT_APPID', '');
101: }
102:
103: // 各種定数(END) ===============================================================
表示する地図は、Googleマップ、地理院地図・オープンストリートマップ(OSM)から選べる。あらかじめ、定数 MAPSERVIC に値を設定すること。今回は地理院白地図を表示するよう、定数 DEF_TYPE に GSIBLAN を設定しているが、他の値でも構わない。
今回は、e-Stat 政府の統計窓口の API を使ってデータを引き出すため、APPID が必要となる。無料で取得できる。取得方法は、「e-Stat 政府統計の総合窓口 - 各種クラウド連携サービス(WebAPI)の登録方法」をご覧いただきたい。
就業率は、2020年(令和2年)の国勢調査で得られた時系列データの人口の労働力状態,就業者の産業・職業を利用する。詳しくは後述するが、e-Stat 政府の統計窓口 では統計表の1つ1つにID番号が割り振られており、これを定数 ESTAT_LaborForceParticipationRate に define しておく。
解説:データのメタ構造を取得
mappingLaborForceParticipationRate.php
318: /**
319: * 政府統計 e-Stat API を使ってデータのメタ構造を取得する
320: * @param string $appid APPID
321: * @param string $dataID データのID
322: * @return array 取得データ(JSONデコード)/FALSE:取得失敗
323: */
324: function getEstatMetaInfo($appid, $dataID) {
325: $url = "https://api.e-stat.go.jp/rest/3.0/app/json/getMetaInfo?appId={$appid}&statsDataId={$dataID}&lang=J";
326:
327: // インスタンス生成
328: $pcc = new pahooCache(LIFE_CACHE_DATA, DIR_CACHE_DATA);
329: // データ取得
330: $json = $pcc->load($url);
331: // インスタンス解放
332: $pcc = NULL;
333: // エラーチェック
334: if ($json === FALSE) return FALSE;
335:
336: // JSONデコード
337: return json_decode($json, TRUE);
338: }
mappingLaborForceParticipationRate.php
340: /**
341: * 政府統計 e-Stat API を使ってデータのメタ構造をHTML文書にする.
342: * @param string $appid APPID
343: * @param string $dataID データのID
344: * @return string HTML文書/FALSE:メタ構造の取得に失敗
345: */
346: function meta2html($appid, $dataID) {
347: $outstr = '';
348:
349: $data = getEstatMetaInfo($appid, $dataID);
350: if ($data === FALSE) return FALSE;
351:
352: // メタ情報を $meta に代入する.
353: $meta = $data['GET_META_INFO']['METADATA_INF'] ?? NULL;
354: if ($meta === NULL) return FALSE;
355:
356: $outstr .= "<h3>データID:{$dataID} のメタ構造</h3>\n";
357:
358: // TABLE_INF の解釈
359: $table = $meta['TABLE_INF'] ?? [];
360: if ($table) {
361: $statName = htmlspecialchars($table['STAT_NAME']['$'] ?? ($table['STAT_NAME'] ?? ''));
362: $govOrg = htmlspecialchars($table['GOV_ORG']['$'] ?? ($table['GOV_ORG'] ?? ''));
363: $title = htmlspecialchars($table['TITLE']['$'] ?? ($table['TITLE'] ?? ''));
364: $cycle = htmlspecialchars($table['CYCLE'] ?? '');
365: $openDate = htmlspecialchars($table['OPEN_DATE'] ?? '');
366: $updated = htmlspecialchars($table['UPDATED_DATE'] ?? '');
367:
368: $outstr .=<<< EOT
369: <table class="basicInfo">
370: <caption>基本情報</caption>
371: <tr><th>項目</th><th>値</th></tr>
372: <tr><th>統計名</th><td>{$statName}</td></tr>
373: <tr><th>所管機関</th><td>{$govOrg}</td></tr>
374: <tr><th>表題</th><td>{$title}</td></tr>
375: <tr><th>周期</th><td>{$cycle}</td></tr>
376: <tr><th>公開日</th><td>{$openDate}</td></tr>
377: <tr><th>更新日</th><td>{$updated}</td></tr>
378: </table>
379:
380: EOT;
381: }
382:
383: // CLASS_INF の解釈
384: $classInf = $meta['CLASS_INF']['CLASS_OBJ'] ?? [];
385: if ($classInf === NULL) return FALSE;
386: foreach ($classInf as $classObj) {
387: $id = $classObj['@id'] ?? '';
388: $name = $classObj['@name'] ?? '';
389: $desc = $classObj['@description'] ?? '';
390: $classList = $classObj['CLASS'] ?? [];
391:
392: // CLASS が単体オブジェクトの場合は配列にする
393: if ($classList && array_keys($classList) !== range(0, count($classList)-1)) {
394: $classList = [$classList];
395: }
396:
397: $outstr .= "<table class=\"classInfo\">\n";
398: $outstr .= '<caption>' . $name . ' (' . $id . ')</caption>';
399: if ($desc) {
400: $outstr .= '<tr><td colspan="5">' . nl2br(htmlspecialchars($desc)) . "</td></tr>\n";
401: }
402:
403: $outstr .= "<tr><th>コード</th><th>名称</th><th>レベル</th><th>親コード</th><th>単位</th></tr>\n";
404: foreach ($classList as $c) {
405: $code = htmlspecialchars($c['@code'] ?? '');
406: $cname = htmlspecialchars($c['@name'] ?? ($c['name'] ?? ''));
407: $level = htmlspecialchars($c['@level'] ?? '');
408: $parent = htmlspecialchars($c['@parentCode'] ?? '');
409: $unit = htmlspecialchars($c['@unit'] ?? '');
410: $outstr .= '<tr>';
411: $outstr .= '<td>' . $code . '</td>';
412: $outstr .= '<td>' . $cname . '</td>';
413: $outstr .= '<td>' . $level . '</td>';
414: $outstr .= '<td>' . $parent . '</td>';
415: $outstr .= '<td>' . $unit . '</td>';
416: $outstr .= "</tr>\n";
417: }
418: $outstr .= '</table>';
419: }
420:
421: return $outstr;
422: }
この関数は、統計表の種類(ID)によらず、共通して利用できる。就業率以外の統計表を白地図にマッピングしたいときにも利用できるだろう。
解説:e-Stat API を使ってデータを取得する
mappingLaborForceParticipationRate.php
424: /**
425: * 政府統計 e-Stat API を使ってデータを取得する
426: * @param string $appid APPID
427: * @param string $dataID データのID
428: * @return array 取得データ(JSONデコード)/FALSE:取得失敗
429: */
430: function getEstatData($appid, $dataID) {
431: $url = "https://api.e-stat.go.jp/rest/3.0/app/json/getStatsData?appId={$appid}&statsDataId={$dataID}";
432:
433: // インスタンス生成
434: $pcc = new pahooCache(LIFE_CACHE_DATA, DIR_CACHE_DATA);
435: // データ取得
436: $json = $pcc->load($url);
437: // インスタンス解放
438: $pcc = NULL;
439: // エラーチェック
440: if ($json === FALSE) return FALSE;
441:
442: // JSONデコード
443: return json_decode($json, TRUE);
444: }
得られた JSON形式データは配列にして返す。
mappingLaborForceParticipationRate.php
446: /**
447: * 指定年の各都道府県別の15歳以上労働力率を取得する
448: * @param int $year 取得したい年
449: * @return array(都道府県コード, 15歳以上人口)
450: */
451: function getLaborForceParticipationRate($year) {
452: $data = getEstatData(ESTAT_APPID, ESTAT_LaborForceParticipationRate);
453: if ($data === FALSE) return FALSE;
454:
455: // DATA 部分の取得
456: $statsData = $data['GET_STATS_DATA']['STATISTICAL_DATA'] ?? NULL;
457: if (!$statsData) return FALSE;
458:
459: $tabData = $statsData['DATA_INF']['VALUE'] ?? [];
460:
461: // 配列へ格納
462: $items = [];
463: foreach ($tabData as $d) {
464: $tabCode = $d['@tab'] ?? ''; // 表章項目コード
465: $timeCode = $d['@time'] ?? ''; // 年コード
466: $areaCode = $d['@area'] ?? ''; // 都道府県コード
467: $val = $d['$'] ?? 0;
468:
469: // 労働力率かつ指定年
470: if (($tabCode === '1240') && ($timeCode >= (sprintf('%04d', $year) . '000000'))) {
471: $prefId = (int)substr($areaCode, 0, 2);
472: $items[$prefId] = (float)$val;
473: }
474: }
475:
476: return $items;
477: }
前述の meta2html 関数で得られたメタ情報を元に、都道府県コードを添字に、労働力率を値として配列 $items に格納して返す。
解説:メイン・プログラム
mappingLaborForceParticipationRate.php
633: // データの取得
634: $items = getLaborForceParticipationRate($year);
635: if ($items === FALSE) {
636: $errmsg = 'データ取得に失敗しました';
637: } else {
638: // 都道府県テーブルに代入する
639: foreach ($items as $key=>$val) {
640: $prefTable[$key][2] = $val;
641: }
642:
643: // データの最大値と最小値を取得する.
644: list($min, $max) = getMinMaxInTable($prefTable);
645:
646: // 都道府県境界データをGeoJSON配列で取得する.
647: $prefBorderList = $pgc->getPrefBorderList();
648:
649: // 最低賃金を色分け表示するための多角形を生成する.
650: $jsPolygons = '';
651: foreach ($prefBorderList as $id=>$prefBorders) {
652: $color = getColorCode($prefTable[$id][2], $min, $max);
653: foreach ($prefBorders['geometry'] as $prefBorder) {
654: $jsPolygons .= $pgc->jsPolygon($prefBorder, $color, '0.6', 1, $color, '0.6', MAPSERVICE);
655: }
656: }
657:
658: // 白地図を描画するJavaScriptコードを生成する.
659: $mapid = MAPID;
660: $height = MAP_HEIGHT;
661: $jsmap = $pgc->drawJSMap(MAPID, DEF_LATITUDE, DEF_LONGITUDE, DEF_TYPE, DEF_ZOOM, NULL, NULL, MAPSERVICE, $jsPolygons);
662: $res =<<< EOT
663: {$jsmap}
664: <div id="{$mapid}" style="width:{$width}px; height:{$height}px; margin:20px 0px 20px 0px;"></div>
665:
666: EOT;
667: }
668: }
白地図を描画する JavaScriptコードを生成する関数/メソッドは「PHPで 都道府県別の最低賃金の分布を地図上に描く」で説明したので、ここでは割愛する。
参考サイト
- e-Stat 政府の統計窓口
- PHPで 都道府県別の最低賃金の分布を地図上に描く:ぱふぅ家のホームページ
- e-Stat 政府統計の総合窓口 - 各種クラウド連携サービス(WebAPI)の登録方法:ぱふぅ家のホームページ
