オープンソースカンファレンス2026東京春(OSC 2026 Tokyo/Spring)参加

2026年2月27,28日(金土)の 2日間にわたって駒沢大学で開催されたオープンソースカンファレンス2026東京春(OSC2026 Tokyo/Spring)に参加してきました。今回も日本MySQLユーザ会としてブース展示とセミナー1枠の開催をしてきました。
event.ospn.jp

定常運転

 1日目は11時から展示開始。11時の少し前に設営を完了し、全3部屋(オーディオ部屋入れると4部屋)ある各ブースの知り合いたちのところへご挨拶まわり。

まぁとにかく東京開催は規模が大きい。次に自分のブースに戻ってきたのは1時半近くでした。こんな感じのゆるいブース展示をやっていますので、MySQLユーザー会のブースのお手伝いをしてもいいなと思った方はぜひ一緒にやりましょう。
 少しブースで来場客のお相手などをしたらもうお昼の時間(といっても2時を大きく回っていますが)。同じくその時間に食べに行こうとしていた知人らとたまたま経路上で遭遇し、一緒にラーメン。戻ってからはさすがに真面目にブース対応しているうちに1日目終了。
 2日目は設営の時間もいらず、挨拶まわりも1日目にいなかった人を見つけてお話するぐらいだったので、サクッとブースに戻りブース対応。土曜日ということもあって、前の日と比べてとても多くの方が来場され、コロナ以降にようやく賑やかなOSCが戻ってきたなという印象を受けました。近隣ブースでのおしゃべり、自ブースでの対応などしつつ、いただいたセミナー枠でお話し、撤収、懇親会、を経て、熱い2日間が終わりました。

I/O 50周年

 とにかく今回印象的だったのは、工学社さんが出されていたブース。昔から「マイコン」を触っていた人たちにはお馴染み中のお馴染みの「月刊I/O誌」(いまもあるんですよ)が今年で創刊600号、50周年となるそうです。私もこどもの頃に読んでいたし、2003年ごろには記事を書いたこともあるので、特に思い入れが強いです。ひとつの雑誌が途切れることなく月刊刊行され続けてきたこと、本当にすごいと思います。1日目に感動したので、2日目には私の私物を3冊ほど(2023年が2冊と 1994年が1冊)展示用に提供させていただきました。同じ展示部屋だったので時々I/Oさんのブースの近くをうろうろしましたが、みなさん懐かしがっているようでした。良い。

 

「MySQLはいま」のセミナー

 2日目(土曜日)14時にセミナーをやらせていただきました。もともとは私が最近取り組んでいるMySQLのGIS機能についてお話するつもりだったのですが、この1ヶ月、更には特にこの2週間のうちにMySQLを取り巻く状況に様々なイベントが発生しました。そんなわけで(GISの話は「私が話したい話」として残しつつも)「いま」を紹介するセミナーといたしました。 多くの方にお越しいただきありがとうございます。
event.ospn.jp

「・MySQLのGIS機能を拡張する話
 ・MySQL界隈で最近起こっていることの話
 の2本だてです」
と紹介した上で、どちらを期待して今日は来てくれましたか、と最初に手を挙げてもらったのですが、0:100で後者でした。まぁそりゃそうよね。でもこのテーマにしたおかげでたくさん来てもらえたので、良かったです。

 多少センシティブな面がある話題でもあり、言葉での説明を前提として作成された資料の文言や少しふざけた言い回しが一人歩きするのも面倒なので、資料の公開予定はありませんが、ざっくりこんな話をしました。

・1月末に preFOSDEMで、Oracle内のMySQL担当トップが入れ替わることが発表された。コミュニティ回帰への宣言や3月3日にお披露目イベントをやることも
・コミュニティ回帰とは、ユーザからの報告にちゃんと対応するとか、Enterprise版だけだった機能をCommunity版に入れることにした、とか良い話
・新トップは、技術担当のジェイソンさんと、コミュニティ担当のヘザーさんという顔ぶれ
・この人達は今のJavaコミュニティを作り上げてきた人
・「今のJavaコミュニティを」という辺りで眉をひそめる人は多そう。だけどビジネスで安心して使えるJavaを育ててきたことには間違いないのではないか
・ところで、そういう感じなので、Oracleによる「更に独善的な」MySQLの支配が強まるのではとの不安の声もある
・2月17日に、そういった声を代表してペルコナ社が「(ざっくり言うと)OracleだけでやらないでみんなでMySQL育てようぜ」というオープンレターを発表 An Open Letter to Oracle: Let's Talk About MySQL's Future
・2月20日に急遽Oracleが「エキサイティングなお知らせだ。2月25日(日本時間だと24時=26日0時)にウェビナーをやるぜ!」と発表。案内はTwitterでのみ行われ、リンク先の申し込みページに行くと氏名とメアドを入れるフォームがあるだけ(開催後になってからイベントページが作成された)、申し込むとZoomの機能で受付メールが来て、「質問がある人はこちらへ!」と書かれたリンクはヘザーさんのメールアドレス(フォームですらない)という、「急いで企画したな」と分かるもの。なぜ、何に対して、こんなに急いだかはそれぞれのご想像で
・25日のイベント。1時間弱のものだったけど、新しいトップの方々を中心として、お話の仕方や表情などの空気感、しっかり説明していること(仕込みかどうか知らないけど質問から逃げずにちゃんとお話された印象)、などなど、個人的にはとても好印象だった

 基本的にみんな揉め事の話はワクワクするようなので、私のセミナーでも対立軸を明確にして少し面白おかしく仕立て上げようと思っていたのですが、25日のウェビナーの印象が想像以上に良かったので、何と言うかOracle社がこの「急ごしらえの」イベントを開催した意図が "火消し" であったとするならば、私個人としては、すっかり火を消された気分です。sakaik、チョロイ。 今後も一定の警戒心は持ちつつも好意的に注視していこうと思います。
 ただ、私は長年日本のコミュニティの盛り上げの一翼を担ってきた立場として、何かと複雑な思いはあるわけですが、多くの人にとっては「ただ、便利で高速で安定したMySQLというソフト」が欲しいだけだと思います。MySQLを提供する側の新しい人たち、新しい方針は、そういった多くのユーザにとって良いものになる予感はしています。

 みたいなことをお話させていただきました。思いのほか「Oracleさんヨイショ」みたいな話になってしまった気がして、終了後にちょっと反省しました(反省しなくていい)。とりあえず3月3日24時(JST)からオンラインイベントがあるので、あなた自身の目と耳で新たなMySQLのリーダーたちの声を聞いてみてもらいたいと思います(その結果、受けた印象が私とは正反対でも良いと思います。あなた自身で情報を得てみてほしい)。2人がメインで登場するのは最初の30分なので、眠かったらそこだけえも良いでしょう(私もそうなるかも)。
MySQL Global Forum – Built on 30 Years of Innovation

懇親会

 駒澤大学の同じ建物にある食堂をお借りしての大懇親会。たくさんの人と話せて、はじめての人ともお話し、時に私の知人同士(互いにはじめて)を引き合わせるきっかけになれたり、など、充実の空間です。料理もいっぱいあって(OSCの懇親会はハラペコで帰るイメージが私に染みついているので)意外性もあります(?)。 各地から参加されてる方のおみやげもありがとうございました。
 個人的なハイライトは、昨年からOSCに参加されている アイ・オー・データの方とI/O誌の方をお引き合わせできたこと。I/O and I-O。I/O誌は50周年ですが、I-O社も今年50周年だそうで、これは何か一緒にぶち上げて欲しいところです。おめでとうございます!
 どうでもいい話かもしれませんが、カレーがおいしかったです。駒澤大学の学食の銀座スエヒロさんによるものと思いますが(違ったらすいません)、懇親会にこんなカレーを出してくれる駒澤大学最高!

まとめ

 いつも見る顔が参加されていなかったりなど、ちょっとだけ勝手が違う部分もありましたが、それを補うパワフルな2日間でした。人の足が少し戻ってきたかなとの印象です。一方で、知識にも人にも触れることができるこんな場なのに、同僚や部下などを誘っても興味を示してくれないという悲しみの声も、会場内の雑談で複数聞きました。好みとか向上心とかそれぞれなので無理にお誘いするものでもないのですが、「知らないものに触れることができる」貴重な機会を活かせないのは勿体ないなぁとは思いますね。特定技術の狭い(深い)イベントも有意義ですが、OSCのような横断的な会でしか得られない養分もあります。 ようやく参加する意味が分かってきた頃には、もしかしたらこういうイベントはもうないかもしれませんよ(得てしてそういうものです)。 各地で開催されているOSC、あるいは他のITイベントに足を運ぶ技術者が増えたらいいのになぁと願います。

 で、2日間も歩き回り、立っている時間も長く、いつもより早起きして会場に行く、というのをしていたら、ぐったりしました。こんなに「眠すぎて起きていられないから寝る」ところまで疲れたのは久しぶりです。布団まで持っていったスマホを、充電ケーブル挿す時間さえ惜しんで眠りについてしまいました(笑)。楽しかったです!

MySQL GIS拡張関数: STX_Project()

MySQLにSpatial(GIS)関数をいっぱい追加したくて、Pluginを作っています。
sakaik.hateblo.jp

テストを兼ねて一つ一つ関数を紹介しています。

STX_Project(point, dist, azimuth)

 与えられた点を、指定された方向に、指定された距離だけ移動した点を返す。地理座標系の場合は地球の丸さを考慮して計算する。
方向は、北をゼロとした時計回りにラジアンで指定する。
LINESTRING や POLYGONでは動作しない(NULL)。

動作紹介

  • 霞ヶ関付近から真北(0度)に1000m移動した点
mysql> SET @g=ST_GeomFromText('POINT(35.6762 139.7503)', 4326);
mysql> SELECT ST_AsText(@g) p1, ST_AsText(STX_Project(@g, 1000.0, 0.0)) p2;
+-------------------------+----------------------------------------------+
| p1                      | p2                                           |
+-------------------------+----------------------------------------------+
| POINT(35.6762 139.7503) | POINT(35.685212817707345 139.75030000000004) |
+-------------------------+----------------------------------------------+
1 row in set (0.000 sec)

青がProject前のp1、赤がProject後のp2です。

  • 北東(右上45度)に500m移動した例
mysql> SET @g=ST_GeomFromText('POINT(35.6762 139.7503)', 4326);
mysql> SELECT ST_AsText(@g) p1, ST_AsText(STX_Project(@g, 1000.0, PI()/4)) p2;
+-------------------------+---------------------------------------------+
| p1                      | p2                                          |
+-------------------------+---------------------------------------------+
| POINT(35.6762 139.7503) | POINT(35.68257277254631 139.75811129521304) |
+-------------------------+---------------------------------------------+
1 row in set (0.000 sec)

補足説明

 POINTしか使えないし、こんな関数どんな時に使うのだろうとAIさんと会話して教えてもらいました。

  • Wi-Fiの電波の届く範囲や、レーダーの照射範囲などをシミュレーションする場合など、中心点から角度を5度ずつ変化させながら対象となる点を得る

- 基地局から北東30度〜60度の範囲に広がるポリゴンを作るためのPOINT特定など

  • 移動体の位置推定

- 「今この座標にいて、時速5kmで北西に15分進んだらどこにいるか?」

  • 定義どおりに正確な「境界線」を作るとき

- 法律や規約で「海岸線から垂直に12海里離れた点」のように、基準点からの距離と方位で場所が定義されている場合に利用

いずれも、他の移動系関数(ST_Translateなど)と違い、地球の丸さを考慮した計算をしてくれるので、特に距離が長い場合に効果を発揮するそうです。


文字コードを確認できるAndroidアプリ"CodeMild"を公開しました

 超久々に、Androidアプリを公開しました。文字を入力すると UTF-8をはじめとして、Shift_JISやEUC-JPなどでの文字コードを表示してくれるだけの、簡単なツールです。たぶん Google Play ストアで "文字コード" で検索してもらえれば出てくると思います。出てこないときは "CodeMild" で。

文字コードを16進数で確認したいときに便利

 街なかを歩いているときにふと、「そういえばSJISで "表"という字の1バイト目ってなんだったっけ?」と気になることってありますよね。一旦気になり出すと「"ソ"はどうだったっけ」などと、どんどん気になる範囲が拡がってきて、眠れなくなります。道を歩いているときなんで眠らないほうがいいんですが。
 そんなときに便利なアプリです。ぜひお手元の一台にインストールしてご活用ください。


無駄な設定項目

 そんな単機能なアプリですが、使い勝手を調整できるよう、無駄にしっかりと設定項目があります。16進数を表示する際に、バイト間に空白を入れたり、大文字小文字を設定したり。 個人的には「エンターキーで改行する」をオフにするモードがお気に入りです。もともと複数行を入力してコードを表示できる機能として考えていたのですが複数行対応なんて不要だという場合にこの設定をすると、Enterでコード表示が実行されて、サクサク操作できます。

今後

 今回の初回リリースで対応しているのは、UTF-8 Shift_JIS EUC-JP CP1252 の4つだけですが、アジア圏の文字を中心に、対応も自主を増やしていく予定です。そのほか、街の中で急に文字コード関連で調べたくなったときに便利な機能や、夜中にどうしても文字コードを調べたくなったときに役に立つ機能などがあれば充実を図りたいと考えています。

裏話、背景、

このツールって実は

 実はこのツール、西暦2000年台後半だったかな、Androidアプリを公開できるようになった最初期に、Javaでゴリゴリ書いて公開していたツールでした。その後、メンテもできなくなった(主に開発環境の再構築が面倒になってしまった)ことや、Googleさんの度重なる対応要請にも応答しなかった結果、公開停止となってしまっていました。
 とは言え、実は自分の手元にはアプリが残っている端末もあって、なにげに便利に使っていたので、改めて作ってみました。今回は Flutterを使っています。

公開作業は結構大変

 昔はアプリを作ったらぱっと公開できたような気がしているのですが(記憶曖昧)、いまは随分と複雑になっています。その手順も体験してみたかったのが今回の公開のきっかけのひとつでもあります。
 以前の開発アカウントが失効してしまったため、新たに開発アカウントを取得しました。新しめのアカウントだと大昔のアカウントよりも公開に厳しい制約があるようです。失効させなきゃよかった。。あの頃は「もうアプリ作る事なんてないしな」って思ってたんですよ、本当に。
 その公開手順。以外と手間暇掛かります。開発アカウントは取得済というところから始めても、

  • まず公開用のアプリを作って、テスト用公開の申請をする(Googleにアップロードする)
  • 12人以上の協力者を探す。12人にテストインストールをしてもらい、14日間経過する必要がある

- 起動回数が少ないとテストをしていないと判定されて審査に落ちるという話もあったので、ヒマなときになるべく起動して触ってもらうよう依頼
- 触ってもらえば何か意見をいただけるもので、何度か修正して最新版を限定公開。私は結局6バージョンリリースしました
- テスターさんにはなるべく最新版に追随してもらう

  • 14日間経過すると公開申請ができるようになるので申請
  • 数日待つと承認されるので、最後の一手間、「公開」用の手続きを行う

という結構長い期間をかけてようやく公開されます。中でも(検索するとまっさきにその情報がいっぱい出てきますが)「12人以上で14日間」という条件がかなりつらいですね。途中でこれを下回ってしまうと日数がクリアされるという話もあり、12人ギリギリではなくもう少し余裕を持ちたいところです。私は結局(あとから追加したのを含め)、15アカウントでテスト期間を乗り切りました。 自分や家族のほか、知人らにも多く協力していただきました。おかげで公開にたどり着きました。ありがとうございます!!
 なお、14日経過してからの公開審査の申請。7日くらいかかると書かれていましたが、今回は30時間ちょっとで承認されました。申請時に書く項目が各項目300文字まで書けるのですが、頑張ってすべて詳細な内容を200文字以上書いたことも良かったのかなと(真実はわかりませんが)思っています。

 せっかく開発環境を作ったことだし、アプリひとつよりは沢山のアプリを公開したほうが環境維持のモチベーションも高くなるので、いろいろ公開するぞ~!と思っていたのですが、なんだか今回公開のプロセスを体験してみて、もうおなかいっぱいになっちゃった気がしないでもないです。

Novicyl Labs ってなに

 今回(から)アプリを公開するにあたって、チーム名というか屋号というか、そういうのをつけることにしました。Novice(初心者)+Cycle(繰り返し)ということで、常に初心を忘れずに繰り返し、しょうもない低技術力なアプリを公開していこうというネーミングです。最初は実は Novel(新しい)だったんですが、たぶんNoviceのほうがイメージにピッタリ。
 改善点のたくさんある、ノビシロのあるアプリを目指しています。

そんなわけで

 そんなわけで、毒にも薬にもならないアプリなので(改めての事実上の)初回公開のご祝儀としてとりあえずインストールしちゃっていただけると喜びます。高評価や機能提案なども歓迎です。低評価は喜びませんがそれが利用者の実感なら仕方ない、受け入れます(笑)。

MySQL GIS拡張関数: STX_dms2deg, STX_deg2dms_*

MySQL Spatial Functions Plugin、関数を動作確認して紹介するシリーズ。度分秒を変換する関数が欲しかったので追加しました。

STX_dms2deg(d, m, s)

 度、分、秒の数字を与えて、小数点の度の数値へ変換する機能です。GISツールどこにもそんな機能はない(と思う)のですが、私が頻繁に使うので、関数として追加することにしました。

STX_deg2dms_deg/_min/_sec (d)

 小数点表示の「度」の数値を度分秒に変換する関数です。3つの値を同時に返すことはできないので、それぞれの値を返す3つの関数にしました。度、分は整数、秒は(必要であれば)小数付きで返ります。

動作紹介

  • 度分秒を与える(分と秒がゼロのときは度の値が返ってくることの確認)
mysql> SELECT STX_dms2deg(135,0,0);
+----------------------+
| STX_dms2deg(135,0,0) |
+----------------------+
|                  135 |
+----------------------+
1 row in set (0.001 sec)
  • 度分秒を与える(秒がゼロのとき。30分なので0.5度と正しい値が加わっている)
mysql> SELECT STX_dms2deg(135,30,0);
+-----------------------+
| STX_dms2deg(135,30,0) |
+-----------------------+
|                 135.5 |
+-----------------------+
1 row in set (0.000 sec)
  • 度分秒を与える(すべての値)
mysql> SELECT STX_dms2deg(135,30,30);
+------------------------+
| STX_dms2deg(135,30,30) |
+------------------------+
|     135.50833333333333 |
+------------------------+
1 row in set (0.000 sec)
  • 度分秒を与える(秒に小数点があってもOK)
mysql> SELECT STX_dms2deg(135,30,10.1234);
+-----------------------------+
| STX_dms2deg(135,30,10.1234) |
+-----------------------------+
|          135.50281205555555 |
+-----------------------------+
  • 度分を与える(もともと度分で持っている値(Garmin eTexのような)は度分だけを与えて実行もできる)
mysql> SELECT STX_dms2deg(135,30.1234);
+--------------------------+
| STX_dms2deg(135,30.1234) |
+--------------------------+
|       135.50205666666668 |
+--------------------------+
1 row in set (0.000 sec)
  • 上の例は秒にゼロを与えても構わない(引数自体を省略しても構わない)。値が同じであることの確認。
mysql> SELECT STX_dms2deg(135,30.1234,0);
+----------------------------+
| STX_dms2deg(135,30.1234,0) |
+----------------------------+
|         135.50205666666668 |
+----------------------------+
1 row in set (0.000 sec)
  • 単なる計算なので、分や秒が60未満である必要はまったくない。120分=2度 として正しく計算される
mysql> SELECT STX_dms2deg(135,120,0);
+------------------------+
| STX_dms2deg(135,120,0) |
+------------------------+
|                    137 |
+------------------------+
1 row in set (0.000 sec)
  • 逆の変換。135.5度が 135度30分になることを確認
mysql> SELECT STX_deg2dms_deg(135.5), STX_deg2dms_min(135.5), STX_deg2dms_sec(135.5);
+------------------------+------------------------+------------------------+
| STX_deg2dms_deg(135.5) | STX_deg2dms_min(135.5) | STX_deg2dms_sec(135.5) |
+------------------------+------------------------+------------------------+
|                    135 |                     30 |                      0 |
+------------------------+------------------------+------------------------+
1 row in set (0.000 sec)
  • 上のほうで実施したものの逆変換。135度30分10.1234秒だが計算誤差が発生している
mysql> SET @d=135.50281205555555;
mysql> SELECT STX_deg2dms_deg(@d), STX_deg2dms_min(@d), STX_deg2dms_sec(@d);
+---------------------+---------------------+---------------------+
| STX_deg2dms_deg(@d) | STX_deg2dms_min(@d) | STX_deg2dms_sec(@d) |
+---------------------+---------------------+---------------------+
|                 135 |                  30 |  10.123399999986304 |
+---------------------+---------------------+---------------------+
1 row in set (0.000 sec)


.

MySQL GIS拡張関数: STX_LineFromEncodedPolyline(),STX_AsEncodedPolyline()

 自作の MySQL Spatial Functions Plugin の関数をひとつひとつ検証しています。今回は Googleの Encoded Polyline 形式に変換したり、逆にEncoded PolylineからLINESTRINGに変換したりするエンコード、デコード関数を。

STX_AsEncodedPolyline(geom [, prec])、STX_LineFromEnccodedPolyline(text [, srid [, prec]])

 LINESTRINGをGoogle の Encoded Polyline 形式にエンコード/デコードする関数です。

Encoded Polylineについては、こちらを:
developers.google.com

動作紹介

以下の青い線を表すLINESTRINGを用意します

LINESTRING(35.870196 139.975133, 35.868136 139.977429, 35.861102 139.983394, 35.856148 139.979398)


  • LINESTRINGを EncodedPolylineとして出力。意味不明の文字列が返ってくる。これがEncodedPolylineってやつ。
mysql> SELECT STX_AsEncodedPolyline(ST_GeomFromText(
    ->              'LINESTRING(35.870196 139.975133, 
    '>                          35.868136 139.977429, 
    '>                          35.861102 139.983394, 
    '>                          35.856148 139.979398)',6668)) en;
+--------------------------+
| en                       |
+--------------------------+
| w{|yEq{iuYzKkM~j@gd@|]|W |
+--------------------------+
1 row in set (0.000 sec)
  • この不思議な文字列(EncodedPolyline)からLINESTRINGに変換。表示用にAsText化している。
mysql> SELECT ST_AsText(STX_LineFromEncodedPolyline('w{|yEq{~j@gd@|]|W',6668)) ls;
+---------------------------------------------------------------+
| ls                                                            |
+---------------------------------------------------------------+
| LINESTRING(35.8702 7.20841,35.87616 7.20346,35.87217 7.20346) |
+---------------------------------------------------------------+
1 row in set (0.000 sec)

DBeaverで表示させてみると、ただしく元の線が再現されていることがわかる。ちなみにEncodedPolyline文字列には測地系の情報は含まれていない(Googleさんなのでもうデフォルトで4326だろうという発想(?))ので、6668で扱いたいなら第2引数にSRIDを指定する必要がある。


mysql> SELECT ST_AsText(STX_LineFromEncodedPolyline('_p~iF~ps|U_ulLnnqC_mqNvxq`@')) ls;
+------------------------------------------------------+
| ls                                                   |
+------------------------------------------------------+
| LINESTRING(38.5 -120.2,40.7 -120.95,43.252 -126.453) |
+------------------------------------------------------+
1 row in set (0.000 sec)


余談

 この Googleの Encoded Polyline という記述法。今回PostGISマニュアルを眺めるまで全然知りませんでした。色々な表現方法があるんですね。
この記法で出し入れできて何が嬉しいのか正直分かっていないので(このコードで公開されているデータとかがあるのかな?逆にこのコードをGoogleに渡すことでイイコトがあったりするのかな)、ご存じの方はぜひ教えてください。

MySQL GIS拡張関数: STX_Angle()

MySQLにSpatial(GIS)関数を追加しています(プラグインとして)。ひとつひとつの関数を動作確認しつつ紹介するシリーズ。ひとつ前に続いて、角度関係です。

STX_Angle(p1, p2, p3)

 3つのPOINTを与えてそれが為す角(p1-p2-p3)の角度を求めます。戻り値はラジアン。PostGISに倣い、本関数は与えられた座標を平面として扱います。また、PostGISに実装されている「4つのPOINTを与える機能」「2つのLINESTRINGを与える機能」は実装されていません(要望があったら考えます)。
 角度はp1からp2を経由してp3に向かう p2における角度を、「反時計回りで」の角度として返します。

動作紹介

  • 3時の方向から来て真上に抜けていく3点:反時計回りに90度
mysql> SELECT STX_Angle( ST_GeomFromText('POINT(10 10)'), 
    ->                   ST_GeomFromText('POINT( 5 10)'),
    ->                   ST_GeomFromText('POINT( 5 15)')) / PI()*180 agl; 
+------+
| agl  |
+------+
|   90 |
+------+
1 row in set (0.000 sec)
  • 上から来て8時のほうに抜けていく線(左回りに90度をちょっと超えたくらい)
mysql> SELECT STX_Angle( ST_GeomFromText('POINT(15 15)'), 
    ->                   ST_GeomFromText('POINT(15 10)'),
    ->                   ST_GeomFromText('POINT( 5 5)')) / PI()*180 agl; 
+--------------------+
| agl                |
+--------------------+
| 116.56505117707799 |
+--------------------+
1 row in set (0.000 sec)


  • 1時のほうから来て真上に抜ける角は38度くらい。STX_Azimuthと異なり、地球の丸さを考慮していない点に注意
mysql> SELECT STX_Angle( ST_GeomFromText('POINT(36.103056 140.088611)', 4326),
    ->                   ST_GeomFromText('POINT(35.658099 139.741357)', 6668),
    ->                   ST_GeomFromText('POINT(37        139.741357)', 6668))/ PI()*180 agl;
+-------------------+
| agl               |
+-------------------+
| 37.96924208395343 |
+-------------------+
1 row in set (0.000 sec)
  • 参考:地球の丸さを考慮したSTX_Azimuthの結果。32.3度くらいになる。距離が長い(数十キロ)こともあり随分とSTX_Angleの結果とは異なります
mysql> SELECT STX_AZimuth(ST_GeomFromText('POINT(35.658099 139.741357)', 6668),
    ->                    ST_GeomFromText('POINT(36.103056 140.088611)', 4326))/ PI()*180 agl;
+-------------------+
| agl               |
+-------------------+
| 32.31909836897371 |
+-------------------+
1 row in set (0.000 sec)

補足説明

 冒頭でも解説した通り、この関数は地球の丸さを考慮しません。これはPostGISの実装に倣ったものです。この関数自体はOGCなどで定義されているものではなく、PostGIS独自開発のため、明確な共通仕様がないことから、MySQLでも同じ動作となるようにしました。とは言え、引数については今のところ 3つのPOINTを与えるのみ(PostGISは2つのLINESTRINGなどを受け取る仕様もある)なので、追加実装の必要が生じたら実装しようかなと思います。
 STX_Azimuthが北方向からターゲットPOINT方向への「時計回りの」角度を返すのに対して、本関数は p1からp3に向けての「反時計回りの」角度を返すことにも注意が必要です。

 また、STX_Azimuthとの差を見ると分かるとおり、地球規模の地点間の角度を見るのには向いていません。町の中など、ごく近い範囲の角度を得るために(平面での近似のため)高速な処理が得られるものとして割り切って使う関数かなと思います。

(このへんの仕様の違いを把握したり、それで良いのか作り替えるべきなのかを検討したりで、地味な関数ながら、ここまで書いてきた関数紹介の中で一番時間がかかった・・・・(日曜の午前が溶けた...))

 余談ですが、地理座標系での動作テストのSQLと結果をAIさんに渡したら、「この東京から筑波への方位角は」と しれっと言っていて、たまげました。なんかもう、「察する能力が高い」と評価せざるを得ません。そう、日本経緯度原点からつくばVLBI(跡)への原点方位角なのです。











MySQL GIS拡張関数: STX_Azimuth()

MySQL にSpatial(GIS)関数を大量に追加する(ひとり)プロジェクト、MySQL Spatial Functions Plugin。実装した関数を、ひとつひとつ動作確認しながら紹介していきます。今回は方位角。

STX_Azimuth(p1, p2)

 点1から点2への方位角をラジアンで返します。方位角は、上(または北)を 0 とし、右回りに数えます。
ラジアンなので、真右が Pi/2(=90度)、真下がPi(=180度)、真左が 3* Pi/2 (=270度) です。2つの点が同じ時は 0 を返します(PostGISではnullとなるそうですが)。

動作紹介

  • 原点と、そこから右にひとつ移動した点との方位角は90度。真右なのだからそうなりますね(度に変換するために 180/Pi を乗じています)
mysql> SELECT STX_Azimuth( ST_GeomFromText('POINT(0 0)'), ST_GeomFromText('POINT(1 0)')) / PI()*180 az; 
+------+
| az   |
+------+
|   90 |
+------+
1 row in set (0.000 sec)
  • (5 5)から(10 10)は斜め右上、45度となります
mysql> SELECT STX_Azimuth( ST_GeomFromText('POINT(5 5)'), ST_GeomFromText('POINT(10 10)')) / PI()*180 az; 
+------+
| az   |
+------+
|   45 |
+------+
1 row in set (0.000 sec)
  • ぐるりと半分(180度)を少し回った例。(10 10)から左・下の位置となる(5 -5)への方位角
mysql> SELECT STX_Azimuth( ST_GeomFromText('POINT(10 10)'), ST_GeomFromText('POINT(5 -5)')) / PI()*180 az; 
+--------------------+
| az                 |
+--------------------+
| 198.43494882292202 |
+--------------------+
1 row in set (0.000 sec)
  • (150 100)の点から、わずか左(149,)、結構上(,200)の点へは、ほぼ一周まわった359.4度
mysql> SELECT STX_Azimuth( ST_GeomFromText('POINT(150 100)'), ST_GeomFromText('POINT(149 200)')) / PI()*180 az; 
+--------------------+
| az                 |
+--------------------+
| 359.42706130231653 |
+--------------------+
1 row in set (0.000 sec)
  • 2つの点が同じ場合は(NULLではなく) 0 を返します。
mysql> SELECT STX_Azimuth( ST_GeomFromText('POINT(10 10)'), ST_GeomFromText('POINT(10 10)')) / PI()*180 az; 
+------+
| az   |
+------+
|    0 |
+------+
1 row in set (0.000 sec)
  • 平面座標だけでなく勿論地理座標にも対応しています。同緯度で少し東に移動した点への方位角。90度でないのは「追加情報」で解説します
mysql> SELECT STX_Azimuth( ST_GeomFromText('POINT(35 139)', 4326), ST_GeomFromText('POINT(35 140)', 4326)) / PI()*180 az;  
+-------------------+
| az                |
+-------------------+
| 89.71320687467116 |
+-------------------+
1 row in set (0.000 sec)

追加情報

 SRID=4326を指定した際に真東(と思われる点)への方位角が90度よりも少し小さくなりました。これは直感に反する人も多いでしょう(私もそうです。だって真東なんだから90度じゃん!と)。
 これ、「緯線」というものがいかにクセモノかを表しています。経線というのは北極と南極を結ぶものです。この形に切ろうと思うと球体をくるくる回しながら切ることになり、その結果の例としてはミカンの房ひとつひとつになるようなイメージです。すべての房が球の中心を通ります。一方の緯線は謂わばタマネギの輪切り。タマネギをまな板の上に置いたまま回転させずに包丁を平行移動しながらザクザク切っていく、これが緯線です。中心を通っていないので「球との関係」という観点で見ると若干我が道を行っているような切り方です(中心を通らないという観点で)。
 この違いは、おそらく昔からみんな見聞きしている「ニューヨークに行くのに、わざわざ高緯度のほうを遠回りして行ってる」という形で現れます。実際にその「遠回り」は、地球の中心を通る面で切った経路なので最短距離になるのですが、緯線という線があるせいで感覚的に錯覚を起こしてしまうのです。この話は以前、包含関係を調査しているときにもこの日記で紹介しました。

sakaik.hateblo.jp


 今回のAzimuthでも、この話と同じ事が起きています。ある地点から「真東にある(と思った)点」への最短経路(方向)は、北半球の場合すこし真東よりも北側を向きます。日本からニューヨークまでならばスタートの方角はかなり北に向くでしょうし、もっと近くであればそれよりは緩くなるでしょう。STX_Azimuth関数を使って確認してみましょう。先ほどは 東経139度から140度への方位角として、89.7132度を得ていました。もっと近くの、139度から139.001度への例を示します。

mysql> SELECT STX_Azimuth( ST_GeomFromText('POINT(35 139)', 4326), ST_GeomFromText('POINT(35 139.001)', 4326)) / PI()*180 az; 
+-------------------+
| az                |
+-------------------+
| 89.99971321166849 |
+-------------------+
1 row in set (0.000 sec)

 89.9997度になりました。かなり90度に近くなりますね。このように「同じ緯度」であっても距離によって方位角が変化する。地球って面白いですね。