これは、RDBMS-GIS(MySQL,PostgreSQLなど) Advent Calendar 2020 の11日目のエントリだったはずのものです。実際には3日ほど遅れてしまいました。 MySQLで、空間情報を扱う動作の確認をしたいときに、ちょっとばかり多めのデータが欲しくなることがあります。 実際の世の中のデータを取り込む形で実現しても良いのですが、ある一定の範囲内に存在する点の分量を自由に増減できない点は不便です。 ということで、とってもザツに大量データを作成する機会があったので、本日記ではその方法を披露。 とりあえずテーブルを作る とりあえず ID めいたものと、POINT型のカラム…
緯度と経度それぞれが別々のカラムに格納されているデータに対して、生成列を使ってGEOMETRY型のカラムとして扱えるようにする方法を考えてみました。速度面で何かディスアドバンテージがあるのか否かは未知数ですが、こんな方法もあるのだというヒントになればと思い、書いてみました。
元データの用意
まず、緯度、経度それぞれが別々のカラムに格納されているテーブル spot1 を作成し、データを投入します。
DROP TABLE IF EXISTS spot1;
CREATE TABLE spot1 (
id integer auto_increment,
name varchar(256) ,
lat double ,
lng double ,
PRIMARY KEY (id)
);
INSERT INTO spot1 (name, lat, lng) VALUES ('サークルハッピー寺院', 35.16110304 ,136.87678426);
INSERT INTO spot1 (name, lat, lng) VALUES ('旋法学園螺旋', 35.16814112 ,136.88577498);
INSERT INTO spot1 …[さらに読む]
訳あって、MySQLで「GEOMETRY型のカラムに、いったん
SRID=0で登録したあと、一気に正しいSRIDに変換する」ということをやろうとしたところ、思惑通りにいかず随分悩んだので、整理しておきます。
やろうとしたこととエラー発生
ここではシンプルな例に置き換えた再現実験で紹介します。
まず、GEOMETRY型を入れられるテーブルを作りデータを1件登録します。
CREATE TABLE g1 (g GEOMETRY);
INSERT INTO g1 VALUES (ST_GeomFromText("POINT(35 135)"));
SRIDを指定していないので、SRID=0で登録されています。axis-orderは lat-long です(というか、そうなっていることを期待して登録しました)。登録された内容を確認してみます。
mysql> SELECT …[さらに読む]
数日前の日記の中で、「緯度1度あたりの長さは、緯度の高低に依らず一定と予想して、MySQLで計算してみたところ、差が出てびっくり」という実験結果を紹介しました。
http://sakaik.hateblo.jp/entry/20191202/mysql_gis_metre_per_degree
これは、地球が(そして今回計算に使用した JGD2011が)真球ではなく回転楕円体だからということに起因するものであると、すぐに想像できましたが、いやまて、よく見ると高緯度のほうが1度あたりの距離が長い。
mysql> SELECT id, ST_Distance(pos1, pos2) FROM g3 ORDER BY ID; +------+-------------------------+ | id | ST_Distance(pos1, pos2) | +------+-------------------------+ | 0 | …[さらに読む]
この日記は、RDBMS-GIS(MySQL,PostgreSQLなど) Advent Calendar 2019
の2日目の記事です。
( https://qiita.com/advent-calendar/2019/rdbms_gis )
経度一度ってどれくらい?
赤道付近の一周の長さが だいたい 40,000km だというのはみんな知っていますよね。実際はもう少し長いのですが、とりあえず感覚的なものでいいです。で、経度というのは、緯度が上がっていくごとに円が小さくなりますから、1度の長さもどんどん短くなるはずです。どんな感じなのかな、と …
[さらに読む]
GIS関係のデータを探していると、緯度経度を表す数値として、度で表されているものと、度分秒で表されているものがあります。MySQLで扱えるのは、度(「35.65810012度」のような数字)です。度分秒(「35度39分29.172秒」のような表現)で公開されているデータを度単位に直すのが意外と面倒くさいので、こんなストアドを試しに作ってみました。
delimiter //
CREATE FUNCTION dfb2deg(d float, f float, b float)
RETURNS float DETERMINISTIC
RETURN d+f/60+b/60/60
//
delimiter ;
こうやって使います。
mysql> SELECT dfb2deg(139, 44, 28.8869); +---------------------------+ | dfb2deg(139, 44, 28.8869) | +---------------------------+ | 139.74136352539062 | …[さらに読む]