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

サンプル・プログラムのダウンロード
eho.php | サンプル・プログラム本体 |
pahooGeoCode.php | 住所・緯度・経度に関わるクラス pahooGeoCode。 使い方は「PHPで住所・ランドマークから最寄り駅を求める」などを参照。include_path が通ったディレクトリに配置すること。 |
pahooCalendar.php | 暦計算クラス pahooCalendar。 暦計算クラスの使い方は「PHPで日出没・月出没・月齢・潮を計算」を参照。include_path が通ったディレクトリに配置すること。 |
恵方とは


もともとは、正月に各家庭で迎える歳神様がやって来る方角を意味していた。旧暦では立春が正月にあたるので、その前日の節分に、歳神様を迎える準備をする。
陰陽道が普及すると、恵方の方角に、その年の歳徳神(恵方神)がいて、祟り神が巡ってこない良い方角とされた。
恵方は 4種類しかなく、たとえば甲の年と己の年の恵方は同じである。
十干と恵方の対応を整理すると、下表のようになる。
十干 | 西暦の下1桁 | 恵方 | |
---|---|---|---|
甲 | 4 | 東北東微東 | 75度 |
乙 | 5 | 西南西微西 | 255度 |
丙 | 6 | 南南東微南 | 165度 |
丁 | 7 | 北北西微北 | 345度 |
戊 | 8 | 南南東微南 | 165度 |
己 | 9 | 東北東微東 | 75度 |
庚 | 0 | 西南西微西 | 255度 |
辛 | 1 | 南南東微南 | 165度 |
壬 | 2 | 北北西微北 | 345度 |
癸 | 3 | 南南東微南 | 165度 |
解説:pahooCalendarクラス
0076: //暦計算クラス:include_pathが通ったディレクトリに配置
0077: require_once('pahooCalendar.php');
0351: //pahooCalendarクラス
0352: $pcl = new pahooCalendar();
0353: $pcl->setLanguage('jp');
まず、クラスファイル "pahooCalendar.php" を require_once し、オブジェクトを生成する。
準備:pahooGeoCode クラス
0073: //住所・緯度・経度に関わるクラス:include_pathが通ったディレクトリに配置
0074: require_once('pahooGeoCode.php');
0349: //pahooGeoCodeクラス
0350: $pgc = new pahooGeoCode();
クラスについては「PHP でクラスを使ってテキストの読みやすさを調べる」を参照されたい。

Yahoo! JAPAN Web サービスを利用するには Yahoo! JAPAN Web サービス アプリケーション IDが必要で、その入手方法は「Yahoo!JAPAN デベロッパーネットワーク - WebAPI の登録方法」を参照されたい。
また、地図として Google マップを利用するのであれば、Google Cloud Platform API キー が必要で、その入手方法は「Google Cloud Platform - WebAPI の登録方法」を参照されたい。また、Google マップで経路探索を行う場合は、DirectionsService APIを有効にする必要がある。課金率が高いので留意されたい。
準備:地図サービス(WebAPI)の選択
0034: //地図サービス(WebAPI)の選択
0035: // 0:Google
0036: // 2:地理院地図・OSM
0037: define('MAPSERVICE', 2);
あらかじめ、定数 MAPSERVICE に値を設定すること。
準備:住所検索サービス(WebAPI)の選択
0039: //住所検索サービスの選択
0040: // 0:Google
0041: // 1:Yahoo!JAPAN
0042: // 11:HeartRails Geo API
0043: // 12:OSM Nominatim Search API
0044: define('GEOSERVICE', 0);
あらかじめ、定数 GEOSERVICE に値を設定すること。
準備:各種パラメータ
0053: //マップの表示サイズ(単位:ピクセル)
0054: define('MAP_WIDTH', 600);
0055: define('MAP_HEIGHT', 400);
0056: //マップID
0057: define('MAPID', 'map_id');
0058:
0059: //初期値
0060: define('DEF_LONGITUDE', 139.766667); //地図中心(経度)
0061: define('DEF_LATITUDE', 35.681111); // (緯度)
0062: define('DEF_QUERY', '東京駅'); //検索クエリ
0063: define('DEF_TYPE', 'roadmap'); //マップタイプ
0064: define('DEF_ZOOM', 12); //ズーム
0065: define('DEF_CAT', 'address'); //カテゴリ(Yahoo!)
0066: define('LINE_COLOR', '#FF0000'); //恵方の色
0067: define('LINE_OPACITY', 0.6); //恵方の透明度
0068: define('LINE_WEIGHT', 5); //恵方の太さ
0069: define('LINE_LENGTH', 5000); //恵方の全長(メートル)
0070: define('ARROW_ANGLE', 20); //恵方:矢印の角度
0071: define('ARROW_LENGTH', 0.1); //恵方:矢の長さ(全長に対する比率)
解説:恵方の方位角を求める
0740: /**
0741: * 恵方の方位角を求める
0742: * @param int $year 西暦年
0743: * @return float 恵方の方位角(北を0度として時計回り)
0744: */
0745: function eho($year) {
0746: static $table = array(
0747: 255, //庚年(西南西微西)
0748: 165, //辛年(南南東微南)
0749: 345, //壬年(北北西微北)
0750: 165, //癸年(南南東微南)
0751: 75, //甲年(東北東微東)
0752: 255, //乙年(西南西微西)
0753: 165, //丙年(南南東微南)
0754: 345, //丁年(北北西微北)
0755: 165 //戊年(南南東微南)
0756: );
0757: $i = $year % 10;
0758:
0759: return $table[$i];
0760: }
解説:地図上に矢印を描く
0202: /**
0203: * 地図上に矢印を描くスクリプトを生成
0204: * @param object $pgc pahooGeoCodeクラス
0205: * @param float $lat, $lng 開始点の緯度・経度
0206: * @param float $angle 方位角(北を0度として時計回り)
0207: * @param int $api 0:Google Maps JavaScript(省略時)
0208: * 11:地理院地図・OSM(Leaflet使用)
0209: * @return string JavaScript
0210: */
0211: function jsArrow($pgc, $latitude, $longitude, $angle, $api=0) {
0212: //本線
0213: list($lat1, $lng1) = $pgc->getPointAngle($longitude, $latitude, $angle, LINE_LENGTH);
0214: $points[0]['latitude'] = $latitude;
0215: $points[0]['longitude'] = $longitude;
0216: $points[1]['latitude'] = $lat1;
0217: $points[1]['longitude'] = $lng1;
0218: $js = $pgc->jsLine($points, LINE_COLOR, LINE_OPACITY, LINE_WEIGHT, MAPSERVICE);
0219:
0220: //矢印
0221: $a = $angle - 180 - ARROW_ANGLE;
0222: if ($a < 0) $a += 360;
0223: list($lat2, $lng2) = $pgc->getPointAngle($lng1, $lat1, $a, LINE_LENGTH * ARROW_LENGTH);
0224: $points[0]['latitude'] = $lat1;
0225: $points[0]['longitude'] = $lng1;
0226: $points[1]['latitude'] = $lat2;
0227: $points[1]['longitude'] = $lng2;
0228: $js .= $pgc->jsLine($points, LINE_COLOR, LINE_OPACITY, LINE_WEIGHT, MAPSERVICE);
0229:
0230: $a = $angle - 180 + ARROW_ANGLE;
0231: if ($a < 0) $a += 360;
0232: list($lat3, $lng3) = $pgc->getPointAngle($lng1, $lat1, $a, LINE_LENGTH * ARROW_LENGTH);
0233: $points[1]['latitude'] = $lat3;
0234: $points[1]['longitude'] = $lng3;
0235: $js .= $pgc->jsLine($points, LINE_COLOR, LINE_OPACITY, LINE_WEIGHT, MAPSERVICE);
0236:
0237: return $js;
0238: }
矢印を 3 本の直線に分解して描くことを考える。方位角を示す本線と、その終点にぶら下がる矢印(2 本の短い線分)である。

本線は、eho 関数で得られた方位角へ向かって直線を描けばいい。始点と終点は緯度・経度で指定する必要があるので、始点から、方位角と距離を指定して終点を算出するユーザー関数 getPointAngle を用意した(後述)。

次に矢印部分であるが、これは、終点から見て、角度 +ARROW_ANGLE 方向、-ARROW_ANGLE 方向へ短い線分を描けばいい。線分の長さは、本線との比率 ARROW_LENGTH で計算している。
解説:方位角と距離を指定した地点の緯度・経度を求める
0647: /**
0648: * ある地点から方位角と距離を指定した地点の緯度・経度を求める
0649: * @param float $longitude 経度(世界測地系)
0650: * @param float $latitude 緯度(世界測地系)
0651: * @param float $angle 方位角(度)
0652: * @param float $distance 距離(メートル)
0653: * @return float array(緯度,経度)
0654: */
0655: function getPointAngle($longitude, $latitude, $angle, $distance) {
0656: $rad = 6378137.0; //地球の半径(メートル)
0657: $e2 = 6.69437999019758E-03;
0658:
0659: $wt = sqrt(1.0 - $e2 * pow(sin($latitude * pi() / 180.0), 2));
0660: $mt = $rad * (1.0 - $e2) / pow($wt, 3);
0661: $dit = $distance * cos($angle * pi() / 180.0) / $mt;
0662: $i = $latitude * pi() / 180.0 + $dit / 2;
0663: $w = sqrt(1.0 - $e2 * pow(sin($i), 2));
0664:
0665: //緯度
0666: $m = $rad * (1 - $e2) / pow($w, 3);
0667: $di = $distance * cos($angle * pi() / 180) / $m;
0668: $lat = $latitude + $di * 180 / pi();
0669:
0670: //経度
0671: $n = $rad / $w;
0672: $dk = $distance * sin($angle * pi() / 180) / ($n * cos($i));
0673: $lng = $longitude + $dk * 180 / pi();
0674:
0675: return array($lat, $lng);
0676: }
解説:Google JavaScriptマップ用スクリプト生成(直線描画)
0984: /**
0985: * 直線描画スクリプト:Googleマップ用
0986: * @param array $points 直線の座標配列
0987: * [$n]['longitude'] 経度(世界測地系)
0988: * [$n]['latitude'] 緯度(世界測地系)
0989: * @param string $color 描画色(省略時=#FF0000)
0990: * @param float $opacity 透明度(省略時=1)
0991: * @param int $weight 線の太さ(省略時=1)
0992: * @return string JavaScript
0993: */
0994: function jsLine_Gmap($points, $color='#FF0000', $opacity=1.0, $weight=1) {
0995: $ss = '';
0996: $cnt = 0;
0997: foreach ($points as $pt) {
0998: if ($cnt > 0) $ss .= ",\n";
0999: $ss .= "\t\tnew google.maps.LatLng({$pt['latitude']}, {$pt['longitude']})";
1000: $cnt++;
1001: }
1002:
1003: $js =<<< EOT
1004: var pt = [
1005: {$ss}
1006: ];
1007: var lines = new google.maps.Polyline({
1008: map: map,
1009: path: pt,
1010: strokeColor: '{$color}',
1011: strokeOpacity: {$opacity},
1012: strokeWeight: {$weight}
1013: });
1014: lines.setMap(map);
1015:
1016: EOT;
1017: return $js;
1018: }
解説:Leaflet用スクリプト生成(直線描画)
1849: /**
1850: * 直線描画スクリプト:Leaflet用
1851: * @param array $points 直線の座標配列
1852: * [$n]['longitude'] 経度(世界測地系)
1853: * [$n]['latitude'] 緯度(世界測地系)
1854: * @param string $color 描画色(省略時=#FF0000)
1855: * @param float $opacity 透明度(省略時=1)
1856: * @param int $weight 線の太さ(省略時=1)
1857: * @return string JavaScript
1858: */
1859: function jsLine_Leaflet($points, $color='#FF0000', $opacity='1.0', $weight=1) {
1860: $ss = '';
1861: $cnt = 0;
1862: foreach ($points as $pt) {
1863: if ($cnt > 0) $ss .= ', ';
1864: $ss .= "[{$pt['latitude']}, {$pt['longitude']}]";
1865: $cnt++;
1866: }
1867:
1868: $js =<<< EOT
1869: L.polyline(
1870: [{$ss}], {
1871: 'color': '{$color}',
1872: 'opacity': {$opacity},
1873: 'weight': {$weight}
1874: }).addTo(map);
1875:
1876: EOT;
1877: return $js;
1878: }
解説:マップ上に直線を描くスクリプト生成
2203: /**
2204: * マップ上に直線を描くスクリプト生成
2205: * @param array $points 直線の座標配列
2206: * [$n]['longitude'] 経度(世界測地系)
2207: * [$n]['latitude'] 緯度(世界測地系)
2208: * @param string $color 描画色(省略時=#FF0000)
2209: * @param float $opacity 透明度(省略時=1)
2210: * @param int $weight 線の太さ(省略時=1)
2211: * @param int $api 0:Google Maps JavaScript(省略時)
2212: * 11:地理院地図・OSM(Leaflet使用)
2213: * @return string JavaScript
2214: */
2215: function jsLine($points, $color='#FF0000', $opacity='1.0', $weight=1, $api=0) {
2216: switch ($api) {
2217: //Google Maps JavaScript
2218: case 0;
2219: $js = $this->jsLine_Gmap($points, $color, $opacity, $weight, $api);
2220: break;
2221: //地理院地図・OSM(Leaflet使用)
2222: case 2:
2223: $js = $this->jsLine_Leaflet($points, $color, $opacity, $weight, $api);
2224: break;
2225: }
2226:
2227: return $js;
2228: }
#jsLine_Leaflet:title=jsLine_Leaflet] で生成したスクリプトは、drawJSmap メソッドの引数 $call に渡してやる。
参考サイト
- 各種WebAPI の登録方法:ぱふぅ家のホームページ
- PHP で二十四節気・七十二候一覧を作成
- PHP で大圏航路を描く:ぱふぅ家のホームページ