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


目次
サンプル・プログラムのダウンロード
tide.php | サンプル・プログラム本体。 |
pahooCalendar.php | 暦・潮位計算クラス pahooCalendar。 暦・潮位計算クラスの使い方は「PHPで二十四節気・七十二候一覧を作成」「PHPで月齢を計算」「PHPで日出没・月出没・月齢・潮を計算」「PHPで潮位を計算する」などを参照。include_path が通ったディレクトリに配置すること。 |
pahooInputData.php | データ入力に関わる関数群。 使い方は「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。 |
tideData.zip | 計算パラメータ。pahooTideが解凍せずに参照する圧縮ファイル。 |
pahooGeoCode.php | 住所・緯度・経度に関わるクラス pahooGeoCode。 使い方は「PHPで住所・ランドマークから最寄り駅を求める」「PHPで住所・ランドマークから緯度・経度を求める」などを参照。include_path が通ったディレクトリに配置すること。 |
moon/moon_00.png~moon_30.png | 月齢画像。 |
makeTideDataFiles.php | tideData.zip を自動生成する。 サンプル・プログラム実行時には不要。 |
table_C1C2.xlsx | 表-C.1, C.2の元データ。 サンプル・プログラム実行時には不要。 |
dispC1C2table.php | 表-C.1, C.2をTABLE表示する。 サンプル・プログラム実行時には不要。 |
バージョン | 更新日 | 内容 |
---|---|---|
3.4.0 | 2025/08/24 | .pahooEnv導入 |
3.3.0 | 2022/07/09 | 数値入力にpahooInputData導入 |
3.21 | 2022/07/09 | bug-fix |
3.2 | 2022/06/04 | PHP8対応,リファラ・チェック改良,計算パラメータ更新 |
3.11 | 2019/06/24 | 逆ジオコーディングサービスの選択肢を増やした |
バージョン | 更新日 | 内容 |
---|---|---|
4.5.1 | 2025/05/31 | deg2ddmm(), deg2hhmm() 不具合修正 |
4.5.0 | 2024/03/17 | ヒジュラ暦メソッドを追加 |
4.4.1 | 2024/03/17 | getCabinetOfficeHolidayTable() -- bug-fix |
4.4.0 | 2024/02/25 | 内閣府の祝日表を参照できるようにした |
4.3.2 | 2023/02/11 | getSolarTerm72() 表記改訂:水澤腹堅→水沢腹堅 |
バージョン | 更新日 | 内容 |
---|---|---|
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.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の変更に対応 |
準備:PHP の https対応


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

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

また、各種クラウドサービスに登録したときに取得するアカウント情報、アプリケーションパスワードなどを登録した .pahooEnv ファイルから読み込む関数 pahooLoadEnv を備えている。こちらについては、「各種クラウド連携サービス(WebAPI)の登録方法」をご覧いただきたい。
準備:pahooCalendar クラス
pahooCalendar.php
11: class pahooCalendar {
12: var $CONVERGE = 0.00005; //逐次近似計算収束判定値
13: var $ASTRO_REFRACT = 0.585556; //大気差
14: var $TDIFF = +9.0; //世界時との時差
15: var $error, $errmsg; //エラーフラグ,エラーメッセージ
16: var $year, $month, $day; //西暦年月日
17: var $tblmoon; //グレゴリオ暦=旧暦テーブル
18: var $language; //表示言語(jp:日本語, en:英語, en3:英語略記)
19: var $resolve2033; //旧暦2033年問題解決案 0:解決しない,1:案1,2:案2,3:対応案3 → https://www.pahoo.org/e-soul/webtech/php02/php02-45-01.shtm#php_resolveLunarCalendar2033
20: var $pcc; //pahooCacheインスタンス
21: var $CabinetOfficeHolidayTables; //内閣府が公開している祝日表
22: const CABINETOFFICE_HOLIDAY_FILE = 'https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv'; //内閣府が公開している祝日表URL
23:
24: /**
25: * コンストラクタ
26: * @param string $language 表示言語;省略時 jp
27: * @param float $tdiff 世界時との時差(省略時 +9.0;日本標準時)
28: * @param object $pcc pahooCacheインスタンス;省略時 NULL
29: * インターネット経由で内閣府の国民の祝日を参照するときに指定
30: * @return bool オブジェクト/FALSE:$tdiffが不正
31: */
32: function __construct($language='jp', $tdiff=+9.0, $pcc=NULL) {
33: $this->error = FALSE;
34: $this->errmsg = '';
35: $this->year = date('Y');
36: $this->month = date('n');
37: $this->day = date('j');
38: $this->resolve2033 = 0;
39: $this->pcc = $pcc;
40: $this->CabinetOfficeHolidayTables = array();
41:
42: $this->setLanguage($language);
43: if ($this->setTimeDifference($tdiff) == FALSE) {
44: $this->error = TRUE;
45: $this->errmsg = 'illegal tdiff';
46: }
47: }
準備: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 = '';

地図や住所検索として 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でクラスを使ってテキストの読みやすさを調べる」を参照されたい。
準備:各種定数など
tide.php
56: // 各種定数(START) ===========================================================
57:
58: // jqPlotのあるフォルダ
59: define('JQPLOT', '../../../../common/jqplot/');
60:
61: // 月の満ち欠け画像ファイルの場所
62: // 画像作成方法→https://www.pahoo.org/e-soul/webtech/phpgd/phpgd-17-01.shtm
63: define('MOONAGE', './moon/');
64:
65: // 潮位表:計算期間(日)の初期値
66: define('INTERVAL_DEF', 7);
67:
68: // 潮位グラフ:計算期間(日)の初期値
69: define('INTERVAL_GRAPH_DEF', 5);
70:
71: // 潮位グラフのプロット間隔(日)
72: define('INTERVAL_GRAPH', 0.02);
73:
74: // 潮位グラフの名前
75: define('GRAPH_TIDE', 'jqPlot_tide');
76:
77: // 地図描画サービスの選択
78: // 0:Google
79: // 2:地理院地図・OSM
80: define('MAPSERVICE', 2);
81:
82: // 住所検索サービスの選択
83: // 0:Google
84: // 1:Yahoo!JAPAN
85: // 11:HeartRails Geo API
86: define('GEOSERVICE', 1);
87:
88: // 逆ジオコーディングサービスの選択
89: // 0:Google
90: // 1:Yahoo!JAPAN
91: // 11:HeartRails Geo API
92: // 21:簡易ジオコーディングサービス
93: define('REVGEOSERVICE', 1);
94:
95: // 指定できる西暦年の範囲
96: define('MIN_YEAR', 1901);
97: define('MAX_YEAR', 2099);
98:
99: // 表示言語(jp:日本語, en:英語, en3:英語略記)
100: define('LANGUAGE', 'jp');
101:
102: // 世界時からの時差(日本標準時)
103: define('UTCDIFF', +9.0);
104:
105: // 観測点のデフォルト値(東京駅)
106: define('DEF_LOCATION', 'TK'); // 東京
107: define('DEF_LATITUDE', 35.681111);
108: define('DEF_LONGITUDE', 139.766667);
109: define('DEF_HEIGHT', 4.0);
110:
111: // 月齢計算時刻
112: define('MOONAGE_HOUR', 21);
113:
114: // マップID
115: define('MAPID', 'map_id');
116: // 初期値
117: define('MAP_WIDTH', 800); // 表示幅
118: define('MAP_HEIGHT', 300); // 表示高
119: define('DEF_TYPE', 'roadmap'); // デフォルトのマップタイプ
120: define('DEF_ZOOM', 8); // デフォルトの拡大率
121: define('DEF_CAT', 'address'); // カテゴリ
122:
123: // 各種定数(END) ===============================================================
ユーザークラス "pahooTide" が参照するデータファイル "tideData.zip" はクラスファイルと同じディレクトリに配置すること。
準備:地図サービス(WebAPI)の選択
住所検索サービスは、Google、Yahoo!JAPAN、HeartRails Geo API、OSM Nominatim Search API から選べる。あらかじめ、定数 GEOSERVICE に値を設定すること。
逆ジオコーディングサービスは、Google、Yahoo!JAPAN、HeartRails Geo API、簡易ジオコーディングサービスから選べる。あらかじめ、定数 REVGEOSERVICE に値を設定すること。
全体の流れ

潮汐は複数の分潮の合成であり、下記の式で求めることができる。
$$ \displaystyle \eta\ =\ Z_0\ +\ \sum_{i=1}^{k}\ f_i\ H_i\ cos(V_i\ +\ u_i\ -\ k_i) \tag{C.1} $$
η | 潮位 |
Z0 | 観測値の平均水面 |
fi | 分潮iの振幅に対する補正係数 |
Hi | 観測地において計算された振幅 |
Vi | 時間とともに変化する分潮引数 |
ui | 時間とともに変化する位相の補正係数 |
ti | 観測地において計算された位相遅れ |
pahooCalendar.php
2803: // 潮位計算 ===============================================================
2804: // @参考URL https://www.pahoo.org/e-soul/webtech/php02/php02-51-01.shtm
2805: class pahooTide {
2806: const FILE_ZIPNAME = 'tideData.zip'; //計算用パラメータ格納ZIPファイル
2807: const FILE_C1 = '_C1.txt'; //表-C.1
2808: const FILE_C2 = '_C2.txt'; //表-C.2
2809: const FILE_INDEX = '_index.txt'; //地点一覧
2810: const FILE_EXT = '.txt'; //拡張子
2811: const JST = -9; //日本時の時差
2812: const COMMENT = '#'; //コメント文字
2813: var $error, $errmsg; //エラーフラグ,エラーメッセージ
2814: var $_s, $_h, $_p, $_N; //天文引数
2815:
2816: var $c1, $c2; //表-C.1, C.2
2817: var $index; //地点一覧
2818: var $port; //ある地点の分潮一覧表
2819:
2820: //分潮記号
2821: var $keys = array('Sa', 'Ssa', 'Mm', 'MSf', 'Mf', '2Q1', 'σ1', 'Q1', 'ρ1', 'O1', 'MP1', 'M1', 'χ1', 'π1', 'P1', 'S1', 'K1', 'ψ1', 'φ1', 'θ1', 'J1', 'SO1', 'OO1', 'OQ2', 'MNS2', '2N2', 'μ2', 'N2', 'ν2', 'OP2', 'M2', 'MKS2', 'λ2', 'L2', 'T2', 'S2', 'R2', 'K2', 'MSN2', 'KJ2', '2SM2', 'MO3', 'M3', 'SO3', 'MK3', 'SK3', 'MN4', 'M4', 'SN4', 'MS4', 'MK4', 'S4', 'SK4', '2MN6', 'M6', 'MSN6', '2MS6', '2MK6', '2SM6', 'MSK6');
潮汐と分潮
1つ1つの周期を分潮と呼び、60種類が定義されている。このうち影響の大きい下記の4つを、主要4分潮を呼ぶ。
M2 | 月の引力によるもので、周期は約12時間25分。 |
S2 | 太陽の引力によるもので、周期は約12時間。 |
O1 | 月の引力によるもので、周期は約25時間49分。 |
K1 | 観月と太陽の合成引力によるもので、周期は約23時間56分。 |
天文引数の計算
Y | 西暦 |
D | その年の1月1日からの経過日数 |
L | 西暦2000年からその年の年初までの閏日の数 |
pahooCalendar.php
2906: /**
2907: * 指定した年月日から天文引数を求める.
2908: * @param int $year, $month, $day グレゴリオ暦による年月日
2909: * @return なし
2910: */
2911: function sun_moon($year, $month, $day) {
2912: $y = (float)$year - 2000.0;
2913: $L = (float)floor(($year + 3.0) / 4.0) - 500.0;
2914: $d = (float)date('z', mktime(0, 0, 0, $month, $day, $year)) + $L;
2915:
2916: $this->_s = (float)211.728 + 129.38471 * $y + 13.176396 * $d;
2917: $this->_h = (float)279.974 - 0.23871 * $y + 0.985647 * $d;
2918: $this->_p = (float) 83.298 + 40.66229 * $y + 0.111404 * $d;
2919: $this->_N = (float)125.071 - 19.32812 * $y - 0.052954 * $d;
2920:
2921: $this->_s = $this->_stdegree($this->_s);
2922: $this->_h = $this->_stdegree($this->_h);
2923: $this->_p = $this->_stdegree($this->_p);
2924: $this->_N = $this->_stdegree($this->_N);
2925: }
分潮引数 Vi の計算
$$ \displaystyle V_i\ +\ u_i\ =\ V_{0i}\ +\ u_i\ +\ nLat\ +\ \sigma _i(t_l\ +\ t_s) \tag{C.9} $$
V0i | 世界時0時における分潮引数 $ V_i $ |
σi | 分潮iの角速度で、後述する表-C.2から取得する。 |
n | 1日周期は1、半日周期は2、1/4周期は4‥‥となる定数で、後述する表-C.2から取得する。 |
tl | ローカル時間(時)。 |
ts | 世界時との時差(時)。日本標準時の場合は -9。 |
Lat | 観測地点の経度。東経はプラス、西経はマイナス。 |
基準となる $ V_{0i} $ は次のようにして計算できる。
$$ V_{0i}\ =\ a_ss\ +\ a_hh\ +\ a_pp\ +\ c \tag{C.10} $$
$ a_s $、 $ a_h $、 $ a_p $、 $ c $ は、後述する表-C.2から取得できる。
補正係数 fi、ui の計算

1)L2、M1分潮 $$ \displaystyle \begin{align} (f\ cos\ u)(L_2) &= 1 - 0.2505\ cos\ 2p - 0.1102\ cos(2p-N) - 0.0156\ cos(2p-2N)-0.0370\ cosN \tag{C.17} \\ (f sin\ u)(L_2) &= - 0.2505\ sin\ 2p - 0.1102\ sin(2p-N) - 0.0156\ sin(2p-2N)-0.0370\ sinN \tag{C.18} \\ (f\ cos\ u)(M_1) &= 2\ cos\ p + 0.4\ cos(p-N) \tag{C.19} \\ (f\ sin\ u)(M_1) &= sin\ p + 0.2\ cos(p-N) \tag{C.20} \\ f_i &= \sqrt{(f cos\ u)_{2}^{i} + (f\ sin\ u)_{2}^{i}} \tag{C.21} \\ u_i &= tan^{-1}\frac{(f\ sin\ u)_i}{(f\ cos\ u)_i} \tag{C.22} \end{align} $$
pahooCalendar.php
2927: /**
2928: * L2, M1分潮のfi, uiを求める.
2929: * @param string $i 分潮記号 'L2' または 'M1'
2930: * @param string $fn 'fi' または 'ui'
2931: * @return float 計算結果
2932: */
2933: function fiui_L2M1($i, $fn) {
2934: //L2
2935: if ($i == 'L2') {
2936: $fcosu = (float)1 - 0.2505 * cos(deg2rad(2 * $this->_p))
2937: - 0.1102 * cos(deg2rad(2 * $this->_p - $this->_N))
2938: - 0.0156 * cos(deg2rad(2 * $this->_p - 2 * $this->_N))
2939: - 0.0370 * cos(deg2rad($this->_N));
2940: $fsinu = (float)-0.2505 * sin(deg2rad(2 * $this->_p))
2941: - 0.1102 * sin(deg2rad(2 * $this->_p - $this->_N))
2942: - 0.0156 * sin(deg2rad(2 * $this->_p - 2 * $this->_N))
2943: - 0.0370 * sin(deg2rad($this->_N));
2944: //M1
2945: } else {
2946: $fcosu = (float)2 * cos(deg2rad($this->_p))
2947: + 0.4 * cos(deg2rad($this->_p - $this->_N));
2948: $fsinu = (float)sin(deg2rad($this->_p))
2949: + 0.2 * sin(deg2rad($this->_p - $this->_N));
2950: }
2951:
2952: //fi
2953: if ($fn == 'fi') {
2954: $res = (float)sqrt($fcosu * $fcosu + $fsinu * $fsinu);
2955: //ui
2956: } else {
2957: $res = (float)atan($fcosu / $fsinu);
2958: }
2959:
2960: return $res;
2961: }
表-C.2の列に記載した計算式によって求める。
pahooCalendar.php
2963: /**
2964: * fi, uiを求める.
2965: * @param string $i 分潮記号
2966: * @param string $fn 'fi' または 'ui'
2967: * @return float 計算結果
2968: */
2969: function fiui($i, $fn) {
2970: //L2 or M1
2971: if (($i == 'L2') || ($i == 'M1')) {
2972: $res = (float)$this->fiui_L2M1($i, $fn);
2973:
2974: //fi
2975: } else if ($fn == 'fi') {
2976: //表-C.1による計算
2977: if (isset($this->c1[$i])) {
2978: $res = (float)$this->c1[$i][0]
2979: + (float)$this->c1[$i][1] * cos(deg2rad($this->_N))
2980: + (float)$this->c1[$i][2] * cos(2 * deg2rad($this->_N))
2981: + (float)$this->c1[$i][3] * cos(3 * deg2rad($this->_N));
2982: //表-C.2の参照
2983: } else {
2984: $res = $this->c2[$i][5];
2985: if (! is_numeric($res)) $res = (float)$this->fiui($res, $fn);
2986: }
2987: //ui
2988: } else {
2989: //表-C.1による計算
2990: if (isset($this->c1[$i])) {
2991: $res = (float)$this->c1[$i][4] * sin(deg2rad($this->_N))
2992: + (float)$this->c1[$i][5] * sin(2 * deg2rad($this->_N))
2993: + (float)$this->c1[$i][6] * sin(3 * deg2rad($this->_N));
2994: //表-C.2の参照
2995: } else {
2996: $res = (float)$this->c2[$i][6];
2997: if (! is_numeric($res)) $res = (float)$this->fiui($res, $fn);
2998: }
2999: }
3000: return $res;
3001: }
表-C.1、表-C.2
pahooCalendar.php
2872: /**
2873: * 表から配列へパラメータを格納する.
2874: * @param string $str パラメータ表
2875: * @param array $arr パラメータを格納する配列
2876: * @return なし
2877: */
2878: function str2array($str, &$arr) {
2879: $tok = strtok($str, "\n");
2880: while ($tok != FALSE) {
2881: $ss = trim($tok);
2882: if ($ss == "") continue;
2883: $cols = preg_split("/\t/iu", $ss);
2884: $key = trim($cols[0]);
2885: if (mb_substr($key, 0, 1) != self::COMMENT) {
2886: for ($i = 1; $i < count($cols); $i++) {
2887: if (mb_substr($cols[$i], 0, 1) == self::COMMENT) break; //コメントから行末まで無視
2888: $arr[$key][$i - 1] = trim($cols[$i]);
2889: }
2890: }
2891: $tok = strtok("\n");
2892: }
2893: }
分潮記号 | fi | ui | |||||
---|---|---|---|---|---|---|---|
1 | cos N | cos 2N | cos 3N | sin N | sin 2N | sin 3N | |
Mm | 1.0000 | -0.1300 | 0.0013 | 0.0000 | 0.00 | 0.00 | 0.00 |
Mf | 1.0429 | 0.4135 | -0.0040 | 0.0000 | -23.74 | 2.68 | -0.38 |
O1 | 1.0089 | 0.1871 | -0.0147 | 0.0014 | 10.80 | -1.34 | 0.19 |
K1 | 1.0060 | 0.1150 | -0.0088 | 0.0006 | -8.86 | 0.68 | -0.07 |
J1 | 1.0129 | 0.1676 | -0.0170 | 0.0016 | -12.94 | 1.34 | -0.19 |
OO1 | 1.1027 | 0.6504 | 0.0317 | -0.0014 | -36.68 | 4.02 | -0.57 |
M2 | 1.0004 | -0.0373 | 0.0002 | 0.0000 | -2.14 | 0.00 | 0.00 |
K2 | 1.0241 | 0.2863 | 0.0083 | -0.0015 | -17.74 | 0.68 | -0.04 |
分潮記号 | s | h | p | c | n | fi | ui | σ (deg/hour) | period (hour) |
---|---|---|---|---|---|---|---|---|---|
Sa | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0.0410686 | 8765.8211 |
Ssa | 0 | 2 | 0 | 0 | 0 | 1 | 0 | 0.0821373 | 4382.9052 |
Mm | 1 | 0 | -1 | 0 | 0 | Mm | Mm | 0.5443747 | 661.3092 |
MSf | 2 | -2 | 0 | 0 | 0 | M2 | -M2 | 1.0158958 | 354.3671 |
Mf | 2 | 0 | 0 | 0 | 0 | Mf | Mf | 1.0980331 | 327.8590 |
2Q1 | -4 | 1 | 2 | 270 | 1 | O1 | O1 | 12.8542862 | 28.0062 |
σ1 | -4 | 3 | 0 | 270 | 1 | O1 | O1 | 12.9271398 | 27.8484 |
Q1 | -3 | 1 | 1 | 270 | 1 | O1 | O1 | 12.3986609 | 26.8684 |
ρ1 | -3 | 3 | -1 | 270 | 1 | O1 | O1 | 13.4715145 | 26.7231 |
O1 | -2 | 1 | 0 | 270 | 1 | O1 | O1 | 13.9430356 | 25.8193 |
MP1 | -2 | 3 | 0 | 90 | 1 | M2 | M2 | 14.0251729 | 25.6681 |
M1 | -1 | 1 | 0 | 90 | 1 | M1 | M1 | 14.4920521 | 24.8412 |
χ1 | -1 | 3 | -1 | 90 | 1 | J1 | J1 | 14.5695476 | 24.7091 |
π1 | 0 | -2 | 0 | 193 | 1 | 1 | 0 | 14.9178647 | 24.1321 |
P1 | 0 | -1 | 0 | 270 | 1 | 1 | 0 | 14.9589314 | 24.0659 |
S1 | 0 | 0 | 0 | 180 | 1 | 1 | 0 | 15.0000000 | 24.0000 |
K1 | 0 | 1 | 0 | 90 | 1 | K1 | K1 | 15.0410686 | 23.9345 |
ψ1 | 0 | 2 | 0 | 167 | 1 | 1 | 0 | 15.0821353 | 23.8693 |
φ1 | 0 | 3 | 0 | 90 | 1 | 1 | 0 | 15.1232059 | 23.8045 |
θ1 | 1 | -1 | 1 | 90 | 1 | J1 | J1 | 15.5125897 | 23.2070 |
J1 | 1 | 1 | -1 | 90 | 1 | J1 | J1 | 15.5854433 | 23.0985 |
SO1 | 2 | -1 | 0 | 90 | 1 | J1 | J1 | 16.0569644 | 22.4202 |
OO1 | 2 | 1 | 0 | 90 | 1 | OO1 | OO1 | 16.1391017 | 22.3061 |
OQ2 | -5 | 2 | 1 | 180 | 2 | O1*Q1 | O1+Q1 | 27.3416964 | 13.1667 |
MNS2 | -5 | 4 | 1 | 0 | 2 | M2^2 | 2*M2 | 27.4238337 | 13.1273 |
2N2 | -4 | 2 | 2 | 0 | 2 | M2 | M2 | 27.8953548 | 12.9054 |
μ2 | -4 | 4 | 0 | 0 | 2 | M2 | M2 | 27.9682084 | 12.8718 |
N2 | -3 | 2 | 1 | 0 | 2 | M2 | M2 | 28.4397295 | 12.6583 |
ν2 | -3 | 4 | -1 | 0 | 2 | M2 | M2 | 28.5125831 | 12.6260 |
OP2 | -2 | 0 | 0 | 180 | 2 | O1*P1 | O1+P1 | 28.9019669 | 12.4559 |
M2 | -2 | 2 | 0 | 0 | 2 | M2 | M2 | 28.9841042 | 12.4206 |
MKS2 | -2 | 4 | 0 | 0 | 2 | M2*K2 | M2+K2 | 29.0662415 | 12.3855 |
λ2 | -1 | 0 | 1 | 180 | 2 | M2 | M2 | 29.4556253 | 12.2218 |
L2 | -1 | 2 | -1 | 180 | 2 | L2 | L2 | 29.5284789 | 12.1916 |
T2 | 0 | -1 | 0 | 283 | 2 | 1 | 0 | 29.9589333 | 12.0164 |
S2 | 0 | 0 | 0 | 0 | 2 | 1 | 0 | 30.0000000 | 12.0000 |
R2 | 0 | 1 | 0 | 257 | 2 | 1 | 0 | 30.0410667 | 11.9836 |
K2 | 0 | 2 | 0 | 0 | 2 | K2 | K2 | 30.0821373 | 11.9672 |
MSN2 | 1 | 0 | -1 | 0 | 2 | M2^2 | 2*M2 | 30.5443747 | 11.7861 |
KJ2 | 1 | 2 | -1 | 180 | 2 | K1*J1 | K1+J1 | 30.6265120 | 11.7545 |
2SM2 | 2 | -2 | 0 | 0 | 2 | M2 | -M2 | 31.0158958 | 11.6070 |
MO3 | -4 | 3 | 0 | 270 | 3 | M2*O1 | M2+O1 | 42.9271398 | 8.3863 |
M3 | -3 | 3 | 0 | 180 | 3 | M2^1.5 | 1.5*M2 | 43.4761563 | 8.2804 |
SO3 | -2 | 1 | 0 | 270 | 3 | O1 | O1 | 43.9430356 | 8.1924 |
MK3 | -2 | 3 | 0 | 90 | 3 | M2*K1 | M2+K1 | 44.0251729 | 8.1771 |
SK3 | 0 | 1 | 0 | 90 | 3 | K1 | K1 | 45.0410686 | 7.9927 |
MN4 | -5 | 4 | 1 | 0 | 4 | M2^2 | 2*M2 | 57.4238337 | 6.2692 |
M4 | -4 | 4 | 0 | 0 | 4 | M2^2 | 2*M2 | 57.9682084 | 6.2103 |
SN4 | -3 | 2 | 1 | 0 | 4 | M2 | M2 | 58.4397295 | 6.1602 |
MS4 | -2 | 2 | 0 | 0 | 4 | M2 | M2 | 58.9841042 | 6.1033 |
MK4 | -2 | 4 | 0 | 0 | 4 | M2*K2 | M2+K2 | 59.0662415 | 6.0949 |
S4 | 0 | 0 | 0 | 0 | 4 | 1 | 0 | 60.0000000 | 6.0000 |
SK4 | 0 | 2 | 0 | 0 | 4 | K2 | K2 | 60.0821373 | 5.9918 |
2MN6 | -7 | 6 | 1 | 0 | 6 | M2^3 | 3*M2 | 86.4079380 | 4.1663 |
M6 | -6 | 6 | 0 | 0 | 6 | M2^3 | 3*M2 | 86.9523127 | 4.1402 |
MSN6 | -5 | 4 | 1 | 0 | 6 | M2^2 | 2*M2 | 87.4238337 | 4.1179 |
2MS6 | -4 | 4 | 0 | 0 | 6 | M2^2 | 2*M2 | 87.9682084 | 4.0924 |
2MK6 | -4 | 6 | 0 | 0 | 6 | M2^2*K2 | 2*M2+K2 | 88.0503457 | 4.0886 |
2SM6 | -2 | 2 | 0 | 0 | 6 | M2 | M2 | 88.9841042 | 4.0457 |
MSK6 | -2 | 4 | 0 | 0 | 6 | M2*K2 | M2+K2 | 89.0662415 | 4.0419 |
Zi、Hi、ui の入手
これらの値は、気象庁の潮位表掲載地点一覧表から取得することができる。対象は、一覧表のうち、分潮一覧表の列のリンク先にコンテンツがあるもののみである。

これらのコンテンツを自動的に読み込んでゆき、各地点の分潮一覧表をZIP圧縮ファイルに格納していくプログラムが "makeTideDataFiles.php" である。
ある日の干潮、満潮時刻と潮位を求める
干潮、満潮は、1日に各々最大4回起きる。1分ごとに潮位を計算し、上昇から下降へ転じる点が満潮時刻、その逆が干潮時刻である。だが、1分ごとに計算すると、1日で 60×24=1440回も計算しなければならない。
計算回数を減らすために、まず15分ごとに計算することで変化点を検出し、そこから±15分間を1分ごとに計算することで正確な時刻を求める。計算回数は、1日で4×24+15×8=216回に減らすことができる。
pahooCalendar.php
3120: /**
3121: * 指定地点のある日の干潮,満潮時刻と潮位を求める.
3122: * @param string $code 地点記号
3123: * @param int $year, $month, $day グレゴリオ暦による年月日
3124: * @param array $items 結果を格納する配列
3125: * array('high'=>array('hh:mm',潮位), 'low'=>array('hh:mm',潮位))
3126: * @return TRUE/FALSE
3127: */
3128: function tide_day($code, $year, $month, $day, &$items) {
3129: $this->setLocation($code);
3130: if ($this->error) return FALSE;
3131:
3132: $this->sun_moon($year, $month, $day);
3133:
3134: $interval = 15.0; //第1段階刻み(分)
3135: $td0 = $this->tide_level($year, $month, $day, self::JST, -$interval);
3136: $flag = 0;
3137: $cnt_high = 0;
3138: $cnt_low = 0;
3139: for ($i = 0; $i <= 24 * 60; $i += $interval) {
3140: //第1段階刻み
3141: $hh = floor($i / 60.0);
3142: $mm = $i - $hh * 60.0;
3143: $td1 = $this->tide_level($year, $month, $day, $hh + self::JST, $mm);
3144: if ($flag == 0) {
3145: if ($td1 > $td0) $flag = +1; //上昇
3146: else $flag = -1; //下降
3147: } else if ($flag < 0) {
3148: if ($td1 > $td0) { //上昇へ転じた
3149: //第2段階刻み
3150: $td0 = $this->tide_level($year, $month, $day, $hh + self::JST, $mm - $interval - 1);
3151: for ($j = -$interval; $j < $interval; $j++) {
3152: $hh = floor(($i + $j) / 60.0);
3153: $mm = ($i + $j) - $hh * 60.0;
3154: $td1 = $this->tide_level($year, $month, $day, $hh + self::JST, $mm);
3155: if ($td1 > $td0) { //上昇へ転じた
3156: $items['low'][$cnt_low]['hhmm'] = sprintf("%02d:%02d", $hh, $mm);
3157: $items['low'][$cnt_low]['lev'] = (int)$td0;
3158: $cnt_low++;
3159: $flag = +1;
3160: break;
3161: }
3162: $td0 = $td1;
3163: }
3164: }
3165: } else {
3166: if ($td1 < $td0) { //下降へ転じた
3167: //第2段階刻み
3168: $td0 = $this->tide_level($year, $month, $day, self::JST, $mm - $interval - 1);
3169: for ($j = -$interval; $j < $interval; $j++) {
3170: $hh = floor(($i + $j) / 60.0);
3171: $mm = ($i + $j) - $hh * 60.0;
3172: $td1 = $this->tide_level($year, $month, $day, $hh + self::JST, $mm);
3173: if ($td1 < $td0) { //下降へ転じた
3174: $items['high'][$cnt_high]['hhmm'] = sprintf("%02d:%02d", $hh, $mm);
3175: $items['high'][$cnt_high]['lev'] = (int)$td0;
3176: $cnt_high++;
3177: $flag = -1;
3178: break;
3179: }
3180: $td0 = $td1;
3181: }
3182: }
3183: }
3184: $td0 = $td1;
3185: }
3186: return TRUE;
3187: }
解説:各種定数
tide.php
58: // jqPlotのあるフォルダ
59: define('JQPLOT', '../../../../common/jqplot/');
60:
61: // 月の満ち欠け画像ファイルの場所
62: // 画像作成方法→https://www.pahoo.org/e-soul/webtech/phpgd/phpgd-17-01.shtm
63: define('MOONAGE', './moon/');
64:
65: // 潮位表:計算期間(日)の初期値
66: define('INTERVAL_DEF', 7);
67:
68: // 潮位グラフ:計算期間(日)の初期値
69: define('INTERVAL_GRAPH_DEF', 5);
70:
71: // 潮位グラフのプロット間隔(日)
72: define('INTERVAL_GRAPH', 0.02);
73:
74: // 潮位グラフの名前
75: define('GRAPH_TIDE', 'jqPlot_tide');
ただし、冒頭に述べたとおり計算量が大きいので、INTERVAL_DEF や INTERVAL_GRAPH_DEF は、あまり大きな値にしない方がいいだろう。

潮位グラフを描くために、jQueryプラグイン「jqPlot」を利用する。使い方については、「PHPでNHK政治意識月例調査をグラフ表示」を参照のこと。定数 JQPLOT の示すディレクトリに配置する。
また、月齢を示す月の画像は、定数 MOONAGE の示すディレクトリに配置する。圧縮ファイルに含まれている画像は、「PHPで月の満ち欠けを描画」で作成したモノだ。
解説:地点セレクタ
tide.php
360: /**
361: * 地点セレクタを作成する.
362: * @param pahooTide $pt 潮位計算クラス
363: * @param string $code 地点記号
364: * @param string $errmsg エラーメッセージ格納用;エラーなければ空文字
365: * @return string HTML/FALSE:失敗
366: */
367: function makeJSlocation($pt, $code) {
368: static $prefs = array(
369: '--選択--','北海道', '青森県', '岩手県', '宮城県', '秋田県', '山形県', '福島県',
370: '茨城県', '栃木県', '群馬県', '埼玉県', '千葉県', '東京都', '神奈川県',
371: '新潟県', '富山県', '石川県', '福井県', '山梨県', '長野県', '岐阜県', '静岡県',
372: '愛知県', '三重県', '滋賀県', '京都府', '大阪府', '兵庫県', '奈良県',
373: '和歌山県', '鳥取県', '島根県', '岡山県', '広島県', '山口県', '徳島県',
374: '香川県', '愛媛県', '高知県', '福岡県', '佐賀県', '長崎県', '熊本県', '大分県',
375: '宮崎県', '鹿児島県', '沖縄県');
376:
377: if ($code == '') {
378: $pp = '';
379: } else if (! isset($pt->index[$code])) {
380: $errmsg = "not exist location '{$code}'";
381: return FALSE;
382: } else {
383: $pp = $pt->index[$code][4];
384: }
385:
386: // 都道府県
387: $js = "var pref = [\n";
388: foreach ($prefs as $key=>$val) {
389: $selected = ($val == $pp) ? 'selected' : '';
390: $js .= "{'type':{$key}, 'text':'{$val}', 'value':'{$val}', 'selected':'{$selected}'},\n";
391: }
392: // 地点
393: $js .= "];\nvar loc = [\n";
394: foreach ($prefs as $key=>$val) {
395: $js .= "{'type':{$key}, 'text':'--選択--', 'value':''},\n";
396: foreach ($pt->index as $cd=>$arr) {
397: if ($arr[4] == $val) {
398: $selected = ($cd == $code) ? 'selected' : '';
399: $js .= "{'type':{$key}, 'text':'{$arr[0]}', 'value':'{$cd}', 'selected':'{$selected}'},\n";
400: }
401: }
402: }
403:
404: // スクリプト
405: $js .=<<< EOT
406: ];
407:
408: $(function() {
409: var html = '';
410: for (var i in pref) {
411: html += '<option value="'+ pref[i].value + '" ' + pref[i].selected + '>'+ pref[i].text +'</option>';
412: }
413: $('#pref').append(html);
414:
415: var html = '';
416: var index = $('#pref option:selected').index();
417: for (var i in loc) {
418: if (loc[i].type == index) {
419: html += '<option value="'+ loc[i].value + '" ' + loc[i].selected + '>' + loc[i].text +'</option>';
420: }
421: }
422: $('#code').append(html);
423:
424: // 都道府県を選択した時の挙動
425: $('#pref').change(function() {
426: var html = '';
427: var index = $('#pref option:selected').index();
428: // 地点の内容を削除
429: $('#code').empty();
430: // 対応する地点の内容を表示
431: for (var i in loc) {
432: if (loc[i].type == index) {
433: html += '<option value="'+ loc[i].value +'">'+ loc[i].text +'</option>';
434: }
435: }
436: $('#code').append(html);
437: });
438: });
439:
440: EOT;
441: return $js;
442: }
観測地点セレクタを都道府県セレクタに連動させるために、jQuery を利用した。
解説:潮位表の計算と作成
tide.php
445: /**
446: * 潮位表:潮位・月齢を計算し,配列へ格納する.
447: * @param pahooTide $pt 潮位計算クラス
448: * @param pahooCalendar $pc 暦計算クラス
449: * @param array $inputs 計算用パラメータ
450: * @param array $items 計算結果格納用配列
451: * @param array $locs 地点情報格納用配列
452: * @param string $errmsg エラーメッセージ格納用;エラーなければ空文字
453: * @return bool TRUE:計算成功/FALSE:失敗
454: */
455: function calcTideTable($pt, $pc, $params, &$items, &$locs, &$errmsg) {
456: // 地点を設定
457: $pt->setLocation($params['code']);
458: if ($pt->iserror()) return FALSE;
459:
460: // 地点を取得
461: $pt->getLocation($params['code'], $locs);
462: if ($pt->iserror()) return FALSE;
463:
464: // 月齢・潮位を計算
465: $res = TRUE;
466: $jd = $pc->Gregorian2JD($params['year'], $params['month'], $params['day'], 0, 0, 0);
467: for ($i = 0; $i < $params['interval']; $i++) {
468: $arr = array();
469: list($year, $month, $day, $hour, $min, $sec) = $pc->JD2Gregorian($jd);
470: $yb = $pc->getWeekString($year, $month, $day);
471: $items[$i]['dt'] = sprintf("%04d-%02d-%02d(%s)", $year, $month, $day, $yb);
472: $items[$i]['moonage'] = $pc->moon_age($year, $month, $day, MOONAGE_HOUR, 0, 0);
473: $moonmeridian = $pc->moon_time(2, $params['longitude'], $params['latitude'], $params['height'], $year, $month, $day);
474: $moonmeridian = ($moonmeridian == FALSE) ? '---' : $pc->day2hhmm($moonmeridian);
475: $items[$i]['tide'] = (preg_match('/([0-9]+)\:([0-9]+)/', $moonmeridian, $arr) > 0) ? $pc->tide($year, $month, $day, $arr[1], $arr[2], 0) : '';
476: unset($arr);
477:
478: $arr = array();
479: $pt->tide_day($params['code'], $year, $month, $day, $arr);
480: // 満潮
481: for ($j = 0; $j < 4; $j++) {
482: if (isset($arr['high'][$j])) {
483: $items[$i]['high'][$j]['hhmm'] = $arr['high'][$j]['hhmm'];
484: $items[$i]['high'][$j]['lev'] = sprintf("%d", $arr['high'][$j]['lev']);
485: $items[$i]['high'][$j]['align'] = 'text-align:right;';
486: } else {
487: $items[$i]['high'][$j]['hhmm'] = '*';
488: $items[$i]['high'][$j]['lev'] = '*';
489: $items[$i]['high'][$j]['align'] = 'text-align:center;';
490: }
491: }
492: // 干潮
493: for ($j = 0; $j < 4; $j++) {
494: if (isset($arr['low'][$j])) {
495: $items[$i]['low'][$j]['hhmm'] = $arr['low'][$j]['hhmm'];
496: $items[$i]['low'][$j]['lev'] = sprintf("%d", $arr['low'][$j]['lev']);
497: $items[$i]['low'][$j]['align'] = 'text-align:right;';
498: } else {
499: $items[$i]['low'][$j]['hhmm'] = '*';
500: $items[$i]['low'][$j]['lev'] = '*';
501: $items[$i]['low'][$j]['align'] = 'text-align:center;';
502: }
503: }
504: $jd++;
505: }
506:
507: return $res;
508: }
月齢・潮の計算は、「PHPで日出没・月出没・月齢・潮を計算」で紹介したとおりである。
tide.php
510: /**
511: * 潮位表:表示用HTMLを作成する.
512: * @param pahooTide $pt 潮位計算クラス
513: * @param pahooCalendar $pc 暦計算クラス
514: * @param array $params 計算用パラメータ
515: * @param string $js スクリプト格納用
516: * @param string $html HTML格納用
517: * @param string $errmsg エラーメッセージ格納用
518: * @return bool TRUE:成功/FALSE:失敗
519: * @return 表示用HTML
520: */
521: function makeTable($pt, $pc, $params, &$js, &$html, &$errmsg) {
522: $js = $html = '';
523: $items = array();
524: $locs = array();
525: if (calcTideTable($pt, $pc, $params, $items, $locs, $errmsg) == FALSE) return FALSE;
526:
527: $hour = MOONAGE_HOUR;
528: $html =<<< EOT
529: <table class="tide">
530: <caption>{$locs['title']}({$locs['prefecture']}{$locs['address']})</caption>
531: <tr><th rowspan="2">年月日</th><th rowspan="2">月齢<br /><span style="font-size:small; font-weight:normal;">{$hour}時</span></th><th rowspan="2">潮</th><th colspan="8">満潮</th><th colspan="8">干潮</th></tr>
532:
533: EOT;
534: $html .= "<tr>";
535: for ($j = 0; $j < 8; $j++) {
536: $html .= "<th class=\"index\">時刻</th><th class=\"index\">潮位<br />(cm)</th>";
537: }
538: $html .= "</tr>\n";
539: foreach ($items as $item) {
540: $html .= sprintf("<tr><td>%s</td><td>%.1f</td><td>%s</td>", $item['dt'], $item['moonage'], $item['tide']);
541: for ($j = 0; $j < 4; $j++) {
542: $html .= sprintf("<td>%s</td><td style=\"%s\">%s</td>", $item['high'][$j]['hhmm'], $item['high'][$j]['align'], $item['high'][$j]['lev']);
543: }
544: for ($j = 0; $j < 4; $j++) {
545: $html .= sprintf("<td>%s</td><td style=\"%s\">%s</td>", $item['low'][$j]['hhmm'], $item['low'][$j]['align'], $item['low'][$j]['lev']);
546: }
547: $html .= "</tr>\n";
548: }
549: $html .= "</table>\n";
550:
551: return TRUE;
552: }
解説:潮位グラフの計算と作成
tide.php
554: /**
555: * 潮位グラフ:潮位・月齢を計算し,配列に格納する.
556: * @param pahooTide $pt 潮位計算クラス
557: * @param pahooCalendar $pc 暦計算クラス
558: * @param array $params 計算用パラメータ
559: * @param array $items 潮位計算結果格納用配列
560: * @param array $moons 月齢計算結果格納用配列
561: * @param array $locs 地点情報格納用配列
562: * @param string $errmsg エラーメッセージ格納用;エラーなければ空文字
563: * @return bool TRUE:計算成功/FALSE:失敗
564: */
565: function calcTideGraph($pt, $pc, $params, &$items, &$moons, &$locs, &$errmsg) {
566: // 地点を設定
567: $pt->setLocation($params['code']);
568: if ($pt->iserror()) return FALSE;
569:
570: // 地点を取得
571: $pt->getLocation($params['code'], $locs);
572: if ($pt->iserror()) return FALSE;
573:
574: $res = TRUE;
575:
576: // 潮位を計算
577: $jd = $pc->Gregorian2JD($params['year'], $params['month'], $params['day'], 0, 0);
578: $n = $params['interval'] / INTERVAL_GRAPH;
579: for ($i = 0; $i < $n; $i++) {
580: list($year, $month, $day, $hour, $min, $sec) = $pc->JD2Gregorian($jd);
581: $items[$i]['dt'] = sprintf("%04d/%02d/%02d %02d:%02d", $year, $month, $day, $hour, $min);
582: list($year, $month, $day, $hour, $min, $sec) = $pc->JD2Gregorian($jd);
583: $pt->sun_moon($year, $month, $day);
584: $items[$i]['tlevel'] = $pt->tide_level($year, $month, $day, $hour, $min);
585: $jd += INTERVAL_GRAPH;
586: }
587:
588: // 月齢を計算
589: $height = 0; // 標高0メートルを仮定
590: $n = $params['interval'];
591: $jd = $pc->Gregorian2JD($params['year'], $params['month'], $params['day'], 0, 0, 0);
592: $i = $d = 0;
593: while ($i < $n) {
594: // 月の南中時刻
595: list($year, $month, $day, $hour, $min, $sec) = $pc->JD2Gregorian($jd);
596: $moonmeridian = $pc->moon_time(2, $params['longitude'], $params['latitude'], $height, $year, $month, $day);
597: if ($moonmeridian != FALSE) {
598: $x = (double)$i + $moonmeridian;
599: $moons[$i]['t'] = $d + $moonmeridian;
600: $moons[$i]['age'] = $pc->moon_age($year, $month, $day, $moonmeridian * 24, 0, 0);
601: $i++;
602: }
603: $jd++;
604: $d++;
605: }
606:
607: return $res;
608: }

月齢は、月の画像をグラフ上にオーバーライトすることを目指す。プロットする場所は、月の南中時刻とすべく、メソッド pahooCalendar::moon_time によって南中時刻を求める。
tide.php
610: /**
611: * 潮位グラフ:表示用スクリプトおよびHTMLを求める.
612: * @param pahooTide $pt 潮位計算クラス
613: * @param pahooCalendar $pc 暦計算クラス
614: * @param array $params 計算用パラメータ
615: * @param string $js スクリプト格納用
616: * @param string $html HTML格納用
617: * @param string $errmsg エラーメッセージ格納用
618: * @return bool TRUE:成功/FALSE:失敗
619: */
620: function makeGraph($pt, $pc, $params, &$js, &$html, &$errmsg) {
621: $js = $html = '';
622: $items = array();
623: $moons = array();
624: $locs = array();
625: if (calcTideGraph($pt, $pc, $params, $items, $moons, $locs, $errmsg) == FALSE) return FALSE;
626:
627: $title = "{$locs['title']}({$locs['prefecture']}{$locs['address']})";
628: $name = GRAPH_TIDE;
629: $width = MAP_WIDTH;
630: $height = MAP_HEIGHT;
631:
632: // 潮位プロット・データ作成
633: $data = '';
634: foreach ($items as $item) {
635: $data .= sprintf("['%s', %f], ", $item['dt'], $item['tlevel']);
636: }
637:
638: // 月齢データ作成
639: $moon = '';
640: $path = MOONAGE;
641: foreach ($moons as $val) {
642: $x = round(30 + (MAP_WIDTH - 70) / $params['interval'] * $val['t']);
643: $fname = sprintf("{$path}moon_%02d.png", round($val['age']));
644: $moon .=<<< EOT
645: <img style="position:absolute; top:35px; left:{$x}px; width:40px; height:40px; z-index:999;" src="{$fname}" />
646:
647: EOT;
648: }
649:
650: $js =<<< EOT
651: $(function() {
652: jQuery.jqplot('{$name}',
653: [
654: [ {$data} ]
655: ],
656: {
657: // タイトル
658: title: {
659: text: '{$title}',
660: show: true,
661: fontSize: '16px',
662: textAlign: 'center',
663: textColor: 'black'
664: },
665: // 背景
666: grid: {
667: background: '#EEFFFF'
668: },
669: // グラフ
670: seriesDefaults: {
671: showLine: true,
672: rendererOptions: { smooth: false },
673: markerOptions: { size: 0 },
674: color: 'blue',
675: },
676: // 軸ラベル
677: axes: {
678: xaxis: {
679: renderer: $.jqplot.DateAxisRenderer,
680: tickOptions: { formatString: '%m/%d' },
681: tickInterval: '1 days'
682: },
683: yaxis: {
684: label: '潮位(cm)'
685: }
686: }
687: }
688: );
689: });
690:
691: EOT;
692: $html =<<< EOT
693: <div id="{$name}" style="width:{$width}px; height:{$height}px;">
694: {$moon}
695: </div>
696: </body>
697:
698: EOT;
699:
700: return TRUE;
701: }
jqPlot に渡すスクリプトと、表示するHTMLは別々に生成する。jqPlot で画像を扱えないため、無理をしてHTML側でグラフ上にオーバーライトしている。
解説:メインプログラム
Googleマップの表示や住所検索については「PHPでGoogle等を利用して住所から緯度・経度を求める」を、UI:Datepicker を利用した日付入力については「PHPで日付入力:カレンダーから選択」を参照してほしい。
参考サイト
- 各種WebAPIの登録方法:ぱふぅ家のホームページ
- PHPで日出没・月出没・月齢・潮を計算:ぱふぅ家のホームページ
- PHPでNHK政治意識月例調査をグラフ表示:ぱふぅ家のホームページ
- PHPで月の満ち欠けを描画:ぱふぅ家のホームページ
- 潮位表掲載地点一覧表:気象庁
さて、「PHPで日出没・月出没・月齢・潮を計算」では潮の計算を行うプログラムを紹介したが、潮位を計算するには、はるかに複雑な計算を行う必要がある。幸い、コンピュータの計算能力が飛躍的に向上したおかげで、潮位の計算もストレスなく行えるようになった。
そこで、これまで作ってきた "pahooCalendar.php" に、あらた潮位計算クラス "pahooTide" を追加し、Googleマップに表示されている地点の近くの海岸において、指定日から1週間の毎日の満潮・干潮の時刻と潮位を一覧およびグラフ表示するサンプル・プログラムを作ってみることにする。
(2025年8月24日).pahooEnv 導入
(2025年6月14日)GoogleMaps JavaScript APIの変更に対応した.