PostGISで円を描画する
ST_Buffer関数を用いると、点、線、面の形状を指定した長さの面を取得する事が出来ます。点オブジェクトを入力すると、円形のポリゴンを得ることが出来ます。
GEOMETRY型の世界測地系(WGS84:SRID4326)で円を作成
大体100mの円形状
SELECT
ST_Buffer(
--第1引数: 点オブジェクト ( 東経139.76719度 北緯 35.6811 の世界測地系の点 )
ST_SetSRID( ST_POINT( 139.76719 , 35.6811 ) , 4326 )
--第2引数: 半径
, 0.00001 --度単位
)
大体100mの円描画
© OpenStreetMap contributors
ちょっと縦長の楕円のように見えます。
ST_Buffer処理で半径を度単位で処理をした為に歪んでいると思われます。
GEOGRAPHY型で円を作成
球座標系であるGEOGRAPHY型ではメートル単位で空間情報処理が可能です。
平面座標系のGEOMETRY型の世界測地系から球座標系のGEOGRAPHY型は直接キャストが可能です。(::geography
)
100mの円形状
SELECT
ST_Buffer(
--第1引数: 点オブジェクト ( 東経139.76719度 北緯 35.6811 の世界測地系の点 )
ST_SetSRID( ST_POINT( 139.76719 , 35.6811 ) , 4326 )::geography
--第2引数: 半径
, 100 --メートル単位
)
GEOGRAPHY型(球座標)による円描画(水色)
© OpenStreetMap contributors
水色の線は、かなり真円に近い形に見えます。
おまけ:ST_Bufferの円は32角形?
半径を段階的に大きくし、ST_Bufferのポイント数の変化を観察してみました。
半径別円ポリゴンのポイント数カウント
--5段階の半径を予め準備
with t_level(id, label, r )as (
values (1, '1m', 1),
(2, '10m', 10),
(3, '100m', 100),
(4, '1km', 1000),
(5, '10km', 10000)
)
--各半径毎にポイント数をカウント
SELECT
id , label , r , MAX(path) AS point_num
FROM
(
SELECT
id, label, r ,
((ST_dumppoints( ST_ExteriorRing( ST_Buffer( ST_POINT(139.76719 , 35.6811 )::geography , r )::geometry ) ) ).path)[1]
FROM t_level
) AS t1
GROUP BY 1,2,3
ORDER BY 1
結果
id | 半径 | 半径(m) | ポイント数 |
---|---|---|---|
1 | 1m | 1 | 33 |
2 | 10m | 10 | 33 |
3 | 100m | 100 | 33 |
4 | 1km | 1000 | 33 |
5 | 10km | 10000 | 33 |
どの半径でもポイント数は33個であるという結果が得られました。
円形状のポリゴンデータから点を抽出したので、実は始点と終点が同じ座標です。
よって、点の数は33個であり、角の数は32個であるという事になります。