はじめに
MySQLが取り扱う地理情報データ「点」「線」「面」のうち、前回まで点と線のデータの取り扱いについて解説してきました。今回からは面について取り上げます。なお、面は少々複雑な部分があるため、今回と次回の2回にわたって解説していきます。
面のデータとは
しばしば「GISデータは点・線・面」と言われます。点と線はイメージが湧くけれども、面というのは今ひとつイメージがわからないという人もいるかもしれません。そういう人は「面とは物の形のことだ」と理解すると良いでしょう。
あなたが住む市区町村の形、建物や敷地の形、近くの湖の形…こういったもの全てを面のデータとして扱うことができます。線のデータが複数の点の並びであったのと同様に、面もまた複数の点をつないだ線によって囲まれた領域として表されます。
面のデータは「ポリゴンデータ」とも呼ばれます。
面のデータをMySQLに登録してみよう
面のデータを構成するポイントの例を以下に示します。
(36.10183713808493, 139.782216237473)
(35.84343682741019, 140.1687976399497)
(35.74429862752063, 140.8609362987691)
(35.52148422470504, 140.42934800651813)
(35.18322443142682, 140.3634300409093)
(34.922408730266085, 139.830593152238)
(34.973063074474155, 139.74544911332666)
(34.99781602776668, 139.84295277078968)
(35.34469057095044, 139.80587391513475)
(35.57399979402338, 140.08190539612167)
(35.65633519549527, 139.91230396321774)
(35.89198579167441, 139.88930133963848)
(36.10183713808493, 139.782216237473)
これは筆者が住んでいる千葉県の形を、たった12個の点でシンプルにデフォルメした面データを構成するポイントたちです。それぞれの点は緯度・経度の組み合わせで表されています。注目してもらいたいのは、1件目のデータと最後のデータが同じ座標を表しているということです。これらの点を順につなぐことで、線がひとまわりして元の場所に返ってくる、つまり、ぐるりと閉じた領域が表現されます。
それでは、実際にテーブルに登録してみましょう。まず、テーブルを作成します。これまでの連載で作ってきたものと同じ構造にしています。g列にSRID 6668(JGD2011)で、このポリゴンデータを登録します。
CREATE TABLE g3 (
id INTEGER,
name VARCHAR(30),
g GEOMETRY SRID 6668
);
面のデータすなわちポリゴンデータを登録する際にもWKTを使います。点は「POINT」、線は「LINESTRING」というキーワードを使うのでしたね。面の場合は「POLYGON」というキーワードを使います。
POLYGON((点1,点2,点3...点1))
POLYGONデータがPOINTやLINESTRINGと異なる部分としては、1つ目と最後に指定する点を同じものにする必要があること(上の例では「点1」)、点の並びを括弧2つで囲む必要があるということです。二重括弧にする理由については、次回で解説します。
構成する点の数が多くてWKTの文字列が長くなっていることで、データを登録するSQLが複雑に感じるかもしれませんが、基本的な構文はこれまでに紹介してきた点や線と同じです。「WKTをST_GeomFromText()関数に与えているだけだ」ということに着目すれば、点、線、面の登録のキモは「WKTを記述するようになれること」であると気づくでしょう。
INSERT INTO g3 VALUES (1, 'Chiba',
ST_GeomFromText(
'POLYGON((36.10183713808493 139.782216237473,
35.84343682741019 140.1687976399497,
35.74429862752063 140.8609362987691,
35.52148422470504 140.42934800651813,
35.18322443142682 140.3634300409093,
34.922408730266085 139.830593152238,
34.973063074474155 139.74544911332666,
34.99781602776668 139.84295277078968,
35.34469057095044 139.80587391513475,
35.57399979402338 140.08190539612167,
35.65633519549527 139.91230396321774,
35.89198579167441 139.88930133963848,
36.10183713808493 139.782216237473))',
6668));
登録された内容を確認してみましょう。点や線のときと同じように見慣れたバイナリーですが、ポリゴンの場合は一般に点や線よりもデータサイズは大きくなりがちな傾向があります。
mysql> SELECT * FROM g3\G
*************************** 1. row ***************************
id: 1
name: Chiba
g: 0x0C1A00000103000000010000000D00000018CB58EA07796140E8CBD4FF080D42403BE74ECA6685614000FCEABCF5EB4140E2E447CA8C9B614053D46B2D45DF414024D30738BD8D6140793EBDFEBFC24140DC820938A18B61403867EEE5739741409A241738947A6140D404417D117641403F5219B8DA776140E6E7B0548D7C4140A8D31678F97A61405D57836FB87F414081C617B8C979614061BC14D21EAC4140ACB610F89E826140DE9E43D378C9414001C11498317D6140D7EEABCA02D4414029411528757C61407FDE25972CF2414018CB58EA07796140E8CBD4FF080D4240
1 row in set (0.000 sec)
バイナリ部分(地理空間情報のMySQL内部表現)を眺めると、先頭から、
| バイト列 | 内容 | 値 |
|---|---|---|
| 0C1A 0000 | SRID | 0x1A0C=6668 |
| 01 | エンディアン | 1:リトルエンディアン |
| 0300 0000 | WKBタイプ | 3:POLYGONデータ |
というヘッダ情報に続いて、構成する各ポイントのデータらしきものが格納されていることが分かります。第8回で紹介したGUIツール「DBeaver」でこの値を地図上に表示してみたのが下図です。今回はたったの12点で構成されているので非常に荒いものですが、実際の地図データは数百または数千の点で構成されることも多く、よりきめ細かに形を表現しています。
地理情報法を扱う上で主役級と言っても良い数字が「緯度」と「経度」です。 この緯度と経度も、日本国内においては法律によりその基準となる場所(原点)が定められています。「測量法施行令」という政令です。
第二条 法第十一条第一項第四号に規定する日本経緯度原点の地点及び原点数値は、次のとおりとする。
一 地点 東京都港区麻布台二丁目十八番一地内日本経緯度原点金属標の十字の交点
二 原点数値 次に掲げる値
イ 経度 東経百三十九度四十四分二十八秒八八六九
ロ 緯度 北緯三十五度三十九分二十九秒一五七二
施行令で定められた東京都港区にある原点には、昔は東京天文台が置かれ、経度を測定するための「子午環」と呼ばれる観測機器が設置されていました。現在は天文台は移転してしまいましたが、その場所は公園(地目は「空き地」)になり、原点を示す金属標とモニュメントが設置されています。ロシア大使館の脇の道を入っていたところにあり、ビルの向こうには東京タワーが見えます。
筆者が愛用している簡易的なハンディGPSで計測したところ、得られた数字は
北緯:35度39.487分
東経:139度44.478分
でした。
度分秒表記に変換すると、
北緯:35度39分29.22秒
東経:139度44分28.68秒となり、施行令で定められた
北緯:35度39分29.1572秒
東経:139度44分28.8869秒とは若干の差があります。
また、ハンディGPSの画面では1千分の1分の桁まで表示されていることが分かると思いますが、これは0.06秒に相当します。施行令で定められた原点の値は1万分の1秒(0.0001秒)の単位までありますから、本格的な測量というものがいかに緻密に扱われているのかが、ここからも伺い知ることができます。