LoginSignup
2
0

More than 5 years have passed since last update.

PostGISで三角形を描画する

Last updated at Posted at 2016-03-27

PostGISで3角形を描画する

忙しい人用:自作関数による3角描画(経度、緯度、外接円の半径)

第1引数の経度、第2引数の緯度で指定された中心点を持つ、第3引数rで指定した半径の円の中にある正三角形を出力します。

create_function_st_triangle.sql
/**
 * Create triangle geometry.
 * @param lon double precision center point WGS84 SRID:4326
 * @param lat double precision WGS84 SRID:4326
 * @param r double precision circumradius by the meter
 * @return geometry
 **/
CREATE OR REPLACE FUNCTION st_triangle( lon double precision, lat double precision , r double precision )
RETURNS geometry
AS 'with t_plist(id,n)as (
    values (1, 25 ) , (2, 4 ) , (3, 14 ) ,(4, 25 ) )
SELECT
 ST_SetSRID( ST_MakePolygon(ST_MakeLine( array( SELECT geom 
FROM
(
    SELECT
      id, geom
    FROM
     ST_dumppoints( ST_ExteriorRing( ST_Buffer( ST_POINT( $1 , $2)::geography , $3)::geometry  ) )  AS c
     , t_plist
    WHERE 
     t_plist.n = path[1]
    ORDER BY t_plist.id
) AS a ) ) ) , 4326 );'
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;

デモ:東京駅を中心とした、三角形の描画

test_st_triangle.sql
SELECT ST_AsText( st_triangle( 139.76719 , 35.6811 ,50) ) 
UNION
SELECT ST_AsText( st_triangle( 139.76719 , 35.6811 ,100) ) 
UNION
SELECT ST_AsText( st_triangle( 139.76719 , 35.6811 ,150) )  
UNION
SELECT ST_AsText( st_triangle( 139.76719 , 35.6811 ,200) )  

3.3.png

PostGISで三角形を作画するには

任意の大きさの作図を実現するST_Bufferの利用

以前の投稿PostGISのST_Bufferで円を描画するで、ST_Bufferで作成した円は、半径に関わらず32角である事が分かりました。そこで、32角の特定の角をピックアップすれば、三角形が作成出来ると考えました。

ST_Bufferの補間点の出力の観察

補間点をQGISで表示して観察してみると、最も東の点から時計回りで出力されいます。
3.2.png

真北に頂点を持つ正三角形を作成するには、「25→4→14→25」の順番で点を結ぶとポリゴンが作成できます。

18.09.29.png

  • 32角から、25と4と14と25を列挙する
with t_plist(id,n)as (
    values (1, 25 ) , (2, 4 ) , (3, 14 ) ,(4, 25 ) )
  • 円から補間点を抽出し、t_plistのn列で指定した番号のポイントを抽出
    SELECT
      id, geom
    FROM
     ST_dumppoints( ST_ExteriorRing( ST_Buffer( ST_POINT( $1 , $2)::geography , $3)::geometry  ) )  AS c
     , t_plist
    WHERE 
     t_plist.n = path[1]

PostGISの関数の簡単な解説
ST_POINT : 緯度経度からポイント型の地物を作成する
ST_Buffer : 地物の周りに面を付与する
ST_ExteriorRing : ポリゴン形状の外枠を線オブジェクトとして出力する
ST_dumppoints : 地物の補間点を列挙する

関数化

SQLによるストアドファンクション(自作関数)を作成してみます。
PostgreSQLの場合、関数名が同じでも引数と戻り値が異なると、同一名称でも複数個の登録が可能です。

CREATE OR REPLACE FUNCTION 関数名( 引数名  )
RETURNS 戻り値の型
AS 'ここにSQLを記述する。 引数は$1で呼び出し可能'
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;

折角なので、3タイプ程関数を作ってみます。
同じ名称ですが、1つのデータベースに同居可能です。

関数1:緯度、経度、外接円の半径を指定する関数

create_function_st_triangle_1.sql
/**
 * Create triangle geometry.
 * @param lon double precision center point WGS84 SRID:4326
 * @param lat double precision WGS84 SRID:4326
 * @param r double precision circumradius by the meter
 * @return geometry
 **/
CREATE OR REPLACE FUNCTION st_triangle( lon double precision, lat double precision , r double precision )
RETURNS geometry
AS 'with t_plist(id,n)as (
    values (1, 25 ) , (2, 4 ) , (3, 14 ) ,(4, 25 ) )
SELECT
 ST_SetSRID( ST_MakePolygon(ST_MakeLine( array( SELECT geom 
FROM
(
    SELECT
      id, geom
    FROM
     ST_dumppoints( ST_ExteriorRing( ST_Buffer( ST_POINT( $1 , $2)::geography , $3)::geometry  ) )  AS c
     , t_plist
    WHERE 
     t_plist.n = path[1]
    ORDER BY t_plist.id
) AS a ) ) ) , 4326 );'
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;

関数2 :GEOMETRY型と外接円の半径を指定するタイプ

create_function_st_triangle_2.sql
/**
 * Create triangle geometry.
 * @param center_point geometry 
 * @param r double precision circumradius by the meter
 * @return geometry
 **/
CREATE OR REPLACE FUNCTION st_triangle( center_point geometry , r double precision )
RETURNS geometry
AS 'with t_plist(id,n)as (
    values (1, 25 ) , (2, 4 ) , (3, 14 ) ,(4, 25 ) )
SELECT
 ST_SetSRID( ST_MakePolygon(ST_MakeLine( array( SELECT geom 
FROM
(
    SELECT
      id, geom
    FROM
     ST_dumppoints( ST_ExteriorRing( ST_Buffer( ST_Transform( $1 , 4326)::geography , $2 )::geometry  ) )  AS c
     , t_plist
    WHERE 
     t_plist.n = path[1]
    ORDER BY t_plist.id
) AS a ) ) ) , 4326 );'
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;

関数3 :GEOGRAPHY型と外接円の半径を指定するタイプ

create_function_st_triangle_3.sql
/**
 * Create triangle geometry.
 * @param center_point geography 
 * @param r double precision circumradius by the meter
 * @return geography
 **/
CREATE OR REPLACE FUNCTION st_triangle( center_point geography , r double precision )
RETURNS geography
AS 'with t_plist(id,n)as (
    values (1, 25 ) , (2, 4 ) , (3, 14 ) ,(4, 25 ) )
SELECT
 ST_SetSRID( ST_MakePolygon(ST_MakeLine( array( SELECT geom 
FROM
(
    SELECT
      id, geom
    FROM
     ST_dumppoints( ST_ExteriorRing( ST_Buffer($1 , $2 )::geometry  ) )  AS c
     , t_plist
    WHERE 
     t_plist.n = path[1]
    ORDER BY t_plist.id
) AS a ) ) ) , 4326 )::geography ;'
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0