Ⅰ. はじめに
タイトルの通り「C#でMySQLのジオメトリ記憶形式を読み取る方法」です。
本記事では便宜上「ジオメトリ記憶形式」という単語を利用しますが正しい単語ではありません。
英語では「Internal Geometry Storage Format」と書かれています。
Ⅱ. 手順
1. MySQLでWKTからバイナリを生成する
/* 東京駅 山手線 */ /* 緯度 35.6809591 */ /* 経度 139.7673068 */ select ST_GeomFromText('POINT(35.6809591 139.7673068)', 4326) /* 出力 */ /* E6 10 00 00 01 01 00 00 00 F3 7F FD C6 8D 78 61 40 F1 34 F4 AA 29 D7 41 40 */
2. C#を書く
var bytes = new byte[] { 0xE6, 0x10, 0x00, 0x00, // SRID (4326 = WGS84) 0x01, // Byte order (1 = Little endian) 0x01, 0x00, 0x00, 0x00, // Type (1 = Point) 0xF3, 0x7F, 0xFD, 0xC6, 0x8D, 0x78, 0x61, 0x40, // Longitude 0xF1, 0x34, 0xF4, 0xAA, 0x29, 0xD7, 0x41, 0x40, // Latitude }; var span = bytes.AsSpan(); var srid = BitConverter.ToInt32(span.Slice(0, 4)); var byteOrder = (int)span.Slice(4, 1)[0]; var type = BitConverter.ToInt32(span.Slice(5, 4)); var longitude = BitConverter.ToDouble(span.Slice(9, 8)); var latitude = BitConverter.ToDouble(span.Slice(17, 8)); Console.WriteLine($"SRID: {srid}"); Console.WriteLine($"Byte order: {byteOrder}"); Console.WriteLine($"Type: {type}"); Console.WriteLine($"Latitude(緯度): {latitude}"); Console.WriteLine($"Longitude(経度): {longitude}");
実行結果
SRID: 4326 Byte order: 1 Type: 1 Latitude(緯度): 35.6809591 Longitude(経度): 139.7673068
FAQ
Q. 手順1で生成したバイナリはWKBですか?
A. いいえ
/* MySQL系 ジオメトリ記憶形式 */ select ST_GeomFromText('POINT(35.6809591 139.7673068)', 4326) /* E6 10 00 00 01 01 00 00 00 F3 7F FD C6 8D 78 61 40 F1 34 F4 AA 29 D7 41 40 */ /* WKB */ select ST_AsWKB(ST_GeomFromText('POINT(35.6809591 139.7673068)', 4326)) /* 01 01 00 00 00 F1 34 F4 AA 29 D7 41 40 F3 7F FD C6 8D 78 61 40 */
Q. MariaDBでSRID 4326は対応していますか?
A. 対応していません
https://stackoverflow.com/a/73285842/4771485