i_s.ST_S_R_Sに見る様々な地球

RDBMS-GISアドヴェントカレンダー 7日目です。

本エントリのタイトルの正式名は「INFORMATION_SCHEMA.ST_SPATIAL_REFERENCE_SYSTEMS ビューに見る様々な地球」です。長いので省略しました。

 MySQLは 8.0 になって初めて「地球が丸い」という事を知りました。これはMySQL的にはどういうことかというと、内部に、地球の形(回転楕円体)のデータを持っているということです。

そもそも地球の形って?

 地球は地「球」というくらいだから球形なんでしょ?と言う人は、今の時代ほとんどいないと思いますが、じゃぁどういう形なの?と聞かれてちゃんと応えられる人もまた、それほど多くはないと思います。赤道方向にぷっくらとひしゃげている、というイメージくらいで捉えているのではないでしょうか。
 そもそも、地球はとってもデコボコです。そりゃ街の中を歩けば平らなところはないのだから、デコボコしてるのくらい知ってるよ、ですか? いえいえそういう話をしているのではありません。海抜ゼロメートルラインが、すでにでこぼこしているのです。それは地球上はそれぞれの場所ごとに重力が異なり(構成されている物質の違いなどにより密度が異なるから)、地球上における測量は常に「重力方向が、真下」というように重量そのものを拠り所としてきたからです。
 そこで、よりシンプルな形に「モデル化」する流れとなります。多くの場合、地球を回転楕円体として取り扱います。概ね赤道半径が6,400km で、 極方向の半径はそれよりもおよそ 298分の1だけ短い、そんなモデルです。
 歴史的経緯や、おそらく「決める人の立場」のために、様々な「地球のモデル」が作られてきました。本エントリでは、MySQLの定義における、これらの「いろいろな地球」を紹介していきたいと思います。

MySQLが知っている「地球」の形

 MySQLの知っている地球について、MySQLの脳内を覗いてみましょう。大丈夫。ソースコードじゃなくて、データとして定義されています。 INFROMATION_SCHEMA の ST_SPATIAL_REFERENCE_SYSTEMS ビューです。
 ここには、地理座標系と呼ばれる、地球を回転楕円体と見なした様々なモデルが 479種類、そのそれぞれに、平面の地図に変換して落として表現するためのモデル4628種類が登録されているのです。

mysql >use information_schema     
mysql> SELECT SUBSTR(definition, 1, 6) g, COUNT(*)  FROM ST_SPATIAL_REFERENCE_SYSTEMS GROUP BY g ORDER BY g;                     
+--------+----------+
| g      | COUNT(*) |
+--------+----------+
|        |        1 |
| GEOGCS |      479 |
| PROJCS |     4628 |
+--------+----------+
3 rows in set (0.02 sec)

 本エントリでは、地理座標系 GEOGCSに焦点を当てて見ていきます。

GEOGCS にはどのような事が記述されているのか

 ST_S_R_S から「様々な地球」の情報を読み解くために、まず、ここにはどのような事が記述されているのかを知っておくと良いでしょう。我々日本人がよく使うことになるであろう、"JGD2011"(6668) の定義を見てみます。definition列の値を整形すると、以下のようになります。

GEOGCS[
  "JGD2011",
  DATUM[
    "Japanese Geodetic Datum 2011",
    SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],
    AUTHORITY["EPSG","1128"]
  ],
  PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],
  UNIT["degree",0.017453292519943278, AUTHORITY["EPSG","9122"]],
  AXIS["Lat",NORTH], 
  AXIS["Lon",EAST], 
  AUTHORITY["EPSG","6668"]
]

最初に 座標系の名前が記述された後、DATUM, PRIMEM, UNIT, AXIS 等の順に続きます。
JGD2011では、赤道半径 6378137 km 、極半径はそれよりも 1/298.257222101 だけ短い、と定義されていることがわかります。単位(UNIT)は「度(degree)」であり、1度は 0.017453292519943278ラジアンであることも読み取れます。(1/360 * 2PI)
 AXISは、出てきた順に、第1軸、第2軸、となるようです。

様々な地球:半径と扁平率

それこそ伊能忠敬も知りたかった「地球の大きさ」。その定義が、ここです。1800年台前半頃から、さまざまな地球の大きさが見積もられてきました。また、楕円のつぶれ度合いにつちては、中には扁平率=0(真球)のものもあったりして、なかなか興味深いです。
 JGD2011は、この中で "GRS 1980" という楕円体モデルを採用しています。

以下のクエリをベースに結果を加工(SELECT SUBSTRING(definition, locate("SPHERO", definition)) sp FROM ST_SPATIAL_REFERENCE_SYSTEMS WHERE definition LIKE 'GEOGCS%' ORDER BY sp)
| SPHEROID["Airy 1830",                6377563.396, 299.3249646, AUTHORITY["EPSG","7001"]],
| SPHEROID["Airy Modified 1849",       6377340.189, 299.3249646, AUTHORITY["EPSG","7002"]],
| SPHEROID["Australian National Spheroid",6378160, 298.25, AUTHORITY["EPSG","7003"]],
| SPHEROID["Average Terrestrial System 1977",6378135, 298.257, AUTHORITY["EPSG","7041"]],
| SPHEROID["Bessel 1841",              6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]],
| SPHEROID["Bessel Modified",          6377492.018, 299.1528128, AUTHORITY["EPSG","7005"]],
| SPHEROID["Bessel Namibia (GLM)",     6377483.865280419, 299.1528128, AUTHORITY["EPSG","7046"]],
| SPHEROID["CGCS2000",                 6378137, 298.257222101, AUTHORITY["EPSG","1024"]],
| SPHEROID["Clarke 1858",              6378293.645208759, 294.26067636926103, AUTHORITY["EPSG","7007"]],
| SPHEROID["Clarke 1866 Authalic Sphere",6370997, 0, AUTHORITY["EPSG","7052"]],
| SPHEROID["Clarke 1866",              6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]],
| SPHEROID["Clarke 1880 (Arc)",        6378249.145, 293.4663077, AUTHORITY["EPSG","7013"]],
| SPHEROID["Clarke 1880 (Benoit)",     6378300.789, 293.4663155389811, AUTHORITY["EPSG","7010"]],
| SPHEROID["Clarke 1880 (IGN)",        6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]],
| SPHEROID["Clarke 1880 (RGS)",        6378249.145, 293.465, AUTHORITY["EPSG","7012"]],
| SPHEROID["Clarke 1880 (SGA 1922)",   6378249.2, 293.46598, AUTHORITY["EPSG","7014"]],
| SPHEROID["Clarke 1880 (international foot)",6378306.3696, 293.46630765562986, AUTHORITY["EPSG","7055"]],
| SPHEROID["Clarke 1880",              6378249.144808011, 293.46630765562986, AUTHORITY["EPSG","7034"]],
| SPHEROID["Danish 1876",              6377019.27, 300, AUTHORITY["EPSG","7051"]],
| SPHEROID["Everest (1830 Definition)",6377299.36559538, 300.80172554336184, AUTHORITY["EPSG","7042"]],
| SPHEROID["Everest 1830 (1937 Adjustment)",6377276. 345,300.8017, AUTHORITY["EPSG","7015"]],
| SPHEROID["Everest 1830 (1962 Definition)",6377301. 243,300.8017255, AUTHORITY["EPSG","7044"]],
| SPHEROID["Everest 1830 (1967 Definition)",6377298. 556,300.8017, AUTHORITY["EPSG","7016"]],
| SPHEROID["Everest 1830 (1975 Definition)",6377299. 151,300.8017255, AUTHORITY["EPSG","7045"]],
| SPHEROID["Everest 1830 (RSO 1969)", 6377295.664, 300.8017, AUTHORITY["EPSG","7056"]],
| SPHEROID["Everest 1830 Modified",   6377304.063, 300.8017, AUTHORITY["EPSG","7018"]],
| SPHEROID["GEM 10C",                 6378137, 298.257223563, AUTHORITY["EPSG","7031"]],
| SPHEROID["GRS 1967 Modified",       6378160, 298.25, AUTHORITY["EPSG","7050"]],
| SPHEROID["GRS 1967",                6378160, 298.247167427, AUTHORITY["EPSG","7036"]],
| SPHEROID["GRS 1980 Authalic Sphere",6371007,0, AUTHORITY["EPSG","7048"]],
| SPHEROID["GRS 1980",                6378137, 298.257222101, AUTHORITY["EPSG","7019"]],
| SPHEROID["GSK-2011",                6378136.5, 298.2564151, AUTHORITY["EPSG","1025"]],
| SPHEROID["Helmert 1906",            6378200, 298.3, AUTHORITY["EPSG","7020"]],
| SPHEROID["Hough 1960",              6378270, 297, AUTHORITY["EPSG","7053"]],
| SPHEROID["Hughes 1980",             6378273, 298.279411123064, AUTHORITY["EPSG","7058"]],
| SPHEROID["IAG 1975",                6378140, 298.257, AUTHORITY["EPSG","7049"]],
| SPHEROID["Indonesian National Spheroid",6378160, 298.247, AUTHORITY["EPSG","7021"]],
| SPHEROID["International 1924 Authalic Sphere",6371228, 0, AUTHORITY["EPSG","7057"]],
| SPHEROID["International 1924",      6378388, 297, AUTHORITY["EPSG","7022"]],
| SPHEROID["Krassowsky 1940",         6378245, 298.3, AUTHORITY["EPSG","7024"]],
| SPHEROID["NWL 9D",                  6378145, 298.25, AUTHORITY["EPSG","7025"]],
| SPHEROID["OSU86F",                  6378136. 2,298.257223563, AUTHORITY["EPSG","7032"]],
| SPHEROID["OSU91A",                  6378136. 3,298.257223563, AUTHORITY["EPSG","7033"]],
| SPHEROID["PZ-90",                   6378136, 298.257839303, AUTHORITY["EPSG","7054"]],
| SPHEROID["Plessis 1817",            6376523, 308.64, AUTHORITY["EPSG","7027"]],
| SPHEROID["Struve 1860",             6378298. 3,294.73, AUTHORITY["EPSG","7028"]],
| SPHEROID["WGS 72",                  6378135, 298.26, AUTHORITY["EPSG","7043"]],
| SPHEROID["WGS 84",                  6378137, 298.257223563, AUTHORITY["EPSG","7030"]],
| SPHEROID["War Office",              6378300, 296, AUTHORITY["EPSG","7029"]],
| SPHEROID["Zach 1812",               6376045, 310, AUTHORITY["EPSG","1026"]],
+-----------------------------------------------------------------------+

地球の形:「経度ゼロ度」

 日本は東経135度をまたぐ形で存在しているのは、皆さんも学校で習ったことと思います。この東経の基準となる点は、イギリスのグリニッチ天文台付近を通る経線(子午線)であることも、きっと知っていることでしょう。このゼロ度の子午線を「本初子午線」と言います。
 「じゃぁ~、なんで~、グリニッチのところがゼロ度になったの?」(チコちゃん風に)


 まぁ国際会議委で決めたからなんですが、それまでは、パリ子午線、ブリュッセル子午線(ベルギー子午線)など、いろんな子午線が各地で使われていたらしいんですよ。その痕跡を ST_S_R_S の definition の中にある PRIMEM[] に見ることができます。
 本初子午線、こんなにたくさん!まぁ、「本初子午線」というのは人間が便宜的に決めるもの(地球をぐるりと回るのに、スタート地点もフィニッシュ地点もない)なので、こういうものです。

PRIMEM["Athens"     , 23.716337499999998  ,AUTHORITY["EPSG","8912"]]
PRIMEM["Bern"       ,  7.439583333333334  , AUTHORITY["EPSG","8907"]]
PRIMEM["Bogota"     ,-74.08091666666667   ,AUTHORITY["EPSG","8904"]]
PRIMEM["Brussels"   ,  4.3679749999999995 ,AUTHORITY["EPSG","8910"]]
PRIMEM["Ferro"      ,-17.677777777777774  ,AUTHORITY["EPSG","8909"]]
PRIMEM["Greenwich"  ,  0                  ,AUTHORITY["EPSG","8901"]]
PRIMEM["Jakarta"    ,106.80771944444443   ,AUTHORITY["EPSG","8908"]]
PRIMEM["Lisbon"     , -9.131906111111112  ,AUTHORITY["EPSG","8902"]]
PRIMEM["Madrid"     , -3.6879388888888895 ,AUTHORITY["EPSG","8905"]]
PRIMEM["Oslo"       , 10.722916666666666  ,AUTHORITY["EPSG","8913"]]
PRIMEM["Paris RGS"  ,  2.596898148148148  ,AUTHORITY["EPSG","8914"]]
PRIMEM["Paris"      ,  2.5969213          ,AUTHORITY["EPSG","8903"]]
PRIMEM["Rome"       , 12.452333333333332  ,AUTHORITY["EPSG","8906"]]
PRIMEM["Stockholm"  , 18.058277777777775  ,AUTHORITY["EPSG","8911"]]

地球の形:一周は、何度?

 まぁ普通は、一周は360度ですよね。ところが一周を360度としない世界があるのですよ。

-------------------------------------+
UNIT["degree",0.017453292519943278,AUTHORITY["EPSG","9122"]]
UNIT["grad",0.01570796326794895,AUTHORITY["EPSG","9105"]]
-------------------------------------+

 グラードといって、一周が400度です。フランスで主に使われていたようです。100の位の数字を変えるだけで方角が90度変えられるというのが便利らしいですが、どう便利なのかいまいちわかりません。90度変えた方角を得たいことというのが日常にないし。

 興味を持った方は、以下のSQLで definition などを見てみてください。

SELECT definition sp FROM ST_SPATIAL_REFERENCE_SYSTEMS WHERE definition LIKE 'GEOGCS%' AND definition LIKE '%grad%' ORDER BY sp

緯度経度の表記順?

 MySQLでは、JGD2011や WGS84などを使用した際の位置の表記方法として (緯度 経度) の順で表します。この順序は、ST_S_R_S の definition の中身に出てくる AXIS の順に従うようです。では、MySQLでは他の測地系もみんな (緯度 経度)の順になっているのか、という点について確認してみました。

 なお、順序そのものについての議論は、boiledorange73さんの以下の記事を起点としていろいろお読みいただくと、いろいろわかると思います。
https://qiita.com/boiledorange73/items/eea0c7fd21e40140b491


 やはり NORTH-EAST ではなく、 EAST-NORTH の順で定義されているものもあるようですね。 しかし、そもそも座標系の名称に (lon-lat)と明記されている点で、なんか色々な都合で無理矢理作った感があります(全部を詳細に見ていませんが、ぱっと見、この(lon-lat)がつくものとつかないもののセットで存在しているようです)。
なので、我々も "JGD2011(lon-lat)" という座標系をひとつ作ってしまえば、いままでの postGIS の膨大なサンプルをそのまま使用できる、、、かも?(軽口)

| GEOGCS["RGAF09 (lon-lat)",DATUM["Reseau Geodesique des Antilles Francaises 2009",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],AUTHORITY["EPSG","1073"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.017453292519943278,AUTHORITY["EPSG","9122"]],AXIS["Lon",EAST],AXIS["Lat",NORTH],AUTHORITY["EPSG","7086"]]                           |
| GEOGCS["RGF93 (lon-lat)",DATUM["Reseau Geodesique Francais 1993",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],AUTHORITY["EPSG","6171"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.017453292519943278,AUTHORITY["EPSG","9122"]],AXIS["Lon",EAST],AXIS["Lat",NORTH],AUTHORITY["EPSG","7084"]]                                           |
| GEOGCS["RGFG95 (lon-lat)",DATUM["Reseau Geodesique Francais Guyane 1995",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],AUTHORITY["EPSG","6624"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.017453292519943278,AUTHORITY["EPSG","9122"]],AXIS["Lon",EAST],AXIS["Lat",NORTH],AUTHORITY["EPSG","7041"]]                                   |
| GEOGCS["RGM04 (lon-lat)",DATUM["Reseau Geodesique de Mayotte 2004",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],AUTHORITY["EPSG","1036"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.017453292519943278,AUTHORITY["EPSG","9122"]],AXIS["Lon",EAST],AXIS["Lat",NORTH],AUTHORITY["EPSG","7039"]]                                         |
| GEOGCS["RGR92 (lon-lat)",DATUM["Reseau Geodesique de la Reunion 1992",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],AUTHORITY["EPSG","6627"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.017453292519943278,AUTHORITY["EPSG","9122"]],AXIS["Lon",EAST],AXIS["Lat",NORTH],AUTHORITY["EPSG","7037"]]                                      |
| GEOGCS["RGSPM06 (lon-lat)",DATUM["Reseau Geodesique de Saint Pierre et Miquelon 2006",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],AUTHORITY["EPSG","1038"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.017453292519943278,AUTHORITY["EPSG","9122"]],AXIS["Lon",EAST],AXIS["Lat",NORTH],AUTHORITY["EPSG","7035"]]                      |
| GEOGCS["RGTAAF07 (lon-lat)",DATUM["Reseau Geodesique des Terres Australes et Antarctiques Francaises 2007",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],AUTHORITY["EPSG","1113"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.017453292519943278,AUTHORITY["EPSG","9122"]],AXIS["Lon",EAST],AXIS["Lat",NORTH],AUTHORITY["EPSG","7133"]] |

最後に

 以上、ST_SPATIAL_INFORMATION_SYSTEMS ビューにおける定義から、様々な地球について見てきました。MySQL 8.0.13では、とりあえずこれらの 地理座標系で表された位置どうしを変換する関数(ST_Transform())も実装されたようですし、別の座標系で表された資料から自分が使いたい座標系へと変換しての使用などができるようになれば、過去の(おそらく)大量の資料が生かしやすすくなるのでしょうね。

f:id:sakaik:20181111105648j:plain
※写真は本文とは関係ありません