基本的なデータ挿入

こんな感じでデータ入れます。非GISな人でも、例をみれば緯度経度指定方法の雰囲気はわかるかと。SRIDって何?っていう人はとりあえず4326を入れておけばおk。

-- geographyでもgeometryでもコンストラクタはSTGeomFromTextである。
insert into tbl1 (pkey, name, geog, geom) values (100, 'Gym Ghingnham',
  geography::STGeomFromText('POINT(135.0 35.0)', 4326),
  geometry::STGeomFromText('POINT(135.0 35.0)', 4326))

ただしこれはエラー*1になります。

VPCMCE(sa): Msg 6522, Level 16, State 1, Line 1
A .NET Framework error occurred during execution of user defined routine or aggregate 'geography': 
System.FormatException: 24201: Latitude values must be between -90 and 90 degrees.
*** 略 ***
The statement has been terminated.

なぜならSQL ServerではWKTの座標指定順をLON, LAT ではなくLAT, LON*2として解釈するからです。PostGIS等との互換注意。
上記サンプルSQLだと緯度の範囲外エラーになりますので、緯度、経度の順で指定してみます。

-- SRIDによる範囲チェックがかかるのだ。
 insert into tbl1 (pkey, name, geog, geom) values (100, 'Harry Ord',
  geography::STGeomFromText('POINT(35.0 135.0)', 4326),
  geometry::STGeomFromText('POINT(35.0 135.0)', 4326))

これは成功。

行によって同一列に複数SRIDが混在するのはかまいません。

 insert into tbl1 (pkey, name, geog, geom) values (101, 'Kihel Heim',
  geography::STGeomFromText('POINT(35.0 135.0)', 4301),
  geometry::STGeomFromText('POINT(35.0 135.0)', 4301))

これは成功。

野良SRIDを未定義のまま使うと怒られます。

 insert into tbl1 (pkey, name, geog, geom) values (101, 'Kihel Heim',
  geography::STGeomFromText('POINT(35.0 135.0)', 123456),
  geometry::STGeomFromText('POINT(35.0 135.0)', 123456))
VPCMCE(sa): Msg 6522, Level 16, State 1, Line 2
A .NET Framework error occurred during execution of user defined routine or aggregate 'geography': 
System.ArgumentException: 24204: The spatial reference identifier (SRID) is not valid. The specified SRID must match one of 

the supported SRIDs displayed in the sys.spatial_reference_systems catalog view.
*** 略 ***
The statement has been terminated.

geographyとgeometryには自動変換などはかからない。ごっちゃにしてもよしなにはしてくれない。

 insert into tbl1 (pkey, name, geog, geom) values (102, 'Diana Soriel',
  geometry::STGeomFromText('POINT(35.0 135.0)', 4326),
  geography::STGeomFromText('POINT(35.0 135.0)', 4326))

これはCLR UDTのエラーじゃないよね。

VPCMCE(sa): Msg 206, Level 16, State 2, Line 2
Operand type clash: sys.geometry is incompatible with sys.geography

別の行の同一列にポリゴンとポイント混在して入れても大丈夫

 insert into tbl1 (pkey, name, geog, geom) values (103, 'Liry Borjarno',
  geography::STGeomFromText('POLYGON((35 135, 35 136, 36 136, 36 135, 35 135))', 4326),
  geometry::STGeomFromText('POLYGON((35 135, 35 136, 36 136, 36 135, 35 135))', 4326))

これは成功。

ポリゴンが右巻きか左巻きかは重要(Geographyだと右巻きInsertはエラーになる)。

 insert into tbl1 (pkey, name, geog, geom) values (104, 'Sochie Heim',
  geography::STGeomFromText('POLYGON((35 135, 36 135, 36 136, 35 136, 35 135))', 4326),
  geometry::STGeomFromText('POINT(35.135)', 4326))
VPCMCE(sa): Msg 6522, Level 16, State 1, Line 2
A .NET Framework error occurred during execution of user defined routine or aggregate 'geography': 
Microsoft.SqlServer.Types.GLArgumentException: 24205: The specified input does not represent a valid geography instance 

because it exceeds a single hemisphere. Each geography instance must fit inside a single hemisphere. A common reason for this 

error is that a polygon has the wrong ring orientation.
*** 略 ***
The statement has been terminated.

ポリゴンが右巻きか左巻きかは重要(Geometryだと右巻きInsert可)*3

 insert into tbl1 (pkey, name, geog, geom) values (104, 'Sochie Heim',
  geography::STGeomFromText('POINT(35 135)', 4326),
  geometry::STGeomFromText('POLYGON((35 135, 36 135, 36 136, 35 136, 35 135))', 4326))

これは成功。

つづく....

*1:.Netの例外が上がってることに注意

*2:で、いいのかについての議論は長くなるのでこちらを参照

*3:内外判定も普通の人の直感とあってます。次回以降で