2017-01-05 7 views
0

私は単純なテーブルがあります。PostgreSQLでポリゴンの具体的なポイントをどのように取得できますか?

create table boxes2(id serial, rect polygon); 
insert into boxes2(rect) values(polygon'((0,0),(10,0),(10,10),(0,10))'); 

をそして、私はこの多角形の具体的なポイントを取得したい、私はこの

select rect[0] from boxes2 where id = 1; 

を作ったが、エラーがあります:「タイプポリゴンが配列でない、不可能任命インデックスは、要素の "

どうすればいいですか?

版 - "はPostgreSQL 9.5.4、ビルドのVisual C++でコンパイル1800、32ビットの" 幾何学的なオブジェクトから点を抽出するためのPostGISの拡張子で機能ST_DumpPoints(geometry geom)があり

答えて

1

これは、PostgreSQLが頂点を入力したのと同じ順序で保持し、ポリゴンをテキストに変換した後、正規表現を使用してテキストを解析すると仮定して、ポリゴンの 'n番目'あなたが興味を持っている部分を取り出して、ポイントタイプにキャストし直します。それはかなり複雑です:

WITH boxes2(id, rect) AS 
(
VALUES 
    (1, polygon'((0,0),(10,0),(10,10),(0,10))') 
) 
SELECT 
    p 
FROM 
    (
    SELECT 
     row_number() over() AS rn, p 
    FROM 
     (
     SELECT 
      (
      (regexp_matches(rect::text, 
       '\([^()]+\)', 'g') 
      )[1] 
      )::point AS p 
     FROM 
      boxes2 
     WHERE 
      id = 1 
     ) AS pol_to_table_of_points 
    ) AS numbered_table_of_points 
WHERE 
    rn = 2 /* This is if you want to get then 2nd point */ ; 

私は私の知る限り、これはかなりひどい見え認めるが、しなければならないが、多角形(もパス)の「n番目」のポイントを得るために何の公表方法はありません。私はあなたがPostGISを使ってそれを行うことができると確信していますが、それなしでそれを行う方法を見つけていません。

ポイント数(npoints(polygon '((1,1),(0,0))'))を取得する機能はありますが、特定のポイントは取得できません。ポリゴンを点の配列に変換すると(キャストa_polygon :: point [])、どちらも機能しません。ビューの幾何学的な点から

、A、B、C及びDは、点(頂点又は隅部)である場合、(A、B、C、D)に記載次いでpolygons


警告(D、C、B、C)と同じ(順序付けられた)四重項であるが、(C、D、A、B) ...絶対に同等です。

したがって、ポリゴンの「2番目の」頂点は実際には言えません。この時点で、いくつかのサンプルをチェックしたところで、となり、PostgreSQLはポリゴンを頂点の順序付きリストとして表し、元の順序を維持しています。しかし、実際にはになります。この新しい表現が何らかの形で役立ちます。

はたとえば、次のクエリですべてのポリゴンは同等です:

WITH some_polygons (p1, p2, p3, p4, p5, p6, p7, p8) AS 
(
VALUES 
    ('(0,0), (1,0), (2,2), (0,3)' :: polygon, 
    '(1,0), (2,2), (0,3), (0,0)' :: polygon, 
    '(2,2), (0,3), (0,0), (1,0)' :: polygon, 
    '(0,3), (0,0), (1,0), (2,2)' :: polygon, 

    '(0,3), (2,2), (1,0), (0,0)' :: polygon, 
    '(0,0), (0,3), (2,2), (1,0)' :: polygon, 
    '(1,0), (0,0), (0,3), (2,2)' :: polygon, 
    '(2,2), (1,0), (0,0), (0,3)' :: polygon 
    ) 
) 
SELECT 
    p1 ~= p2 AS eq2, -- ~= stands for "same as" 
    p1 ~= p3 AS eq3, 
    p1 ~= p4 AS eq4, 
    p1 ~= p5 AS eq5, 
    p1 ~= p6 AS eq6, 
    p1 ~= p7 AS eq7, 
    p1 ~= p8 AS eq8 
FROM 
    some_polygons ; 

私は、これは、PostgreSQLを使用すると、多角形の"nth" vertexてみましょうしないことに決めた理由だと思う:それは理論的に定義されていないものです。

したがって、安全な側を維持し、後で実装の変更によってコードが破損するおそれがない場合は、代わりに点の配列(point[])を格納できます。配列は、が保証されたで、値は供給されたのと同じ順序で保持されます。ポリゴンと元の頂点リストの両方が必要な場合は、2つのデータがあると思います(正規化されていないフォームでも)。長方形だけで作業する場合は、タイプboxを使用します。それはあなたのニーズをよりよく表します。

+0

興味深い決定。 PostGISの問題を解決できない場合、私の最後の希望です。私はそれを試してみる – Log

+0

PostgreSQLの人たちが 'ポリゴン'(または 'path')から' n番目のポイントを取得する '機能を追加しなかったと思ったら、幾何学的な(機能的な)ポイントあなたが定義できるものではありません。その場合、現在の表現と私がやったことは本当に安全ではないと思います。 Pls。私の答えに追加した_caveat_を読んでください。配列の配列が必要な場合は 'point []'を使い、常に四角形を表現したい場合は@klinのように 'box'を使います。 – joanolo

+0

はい、私はすでにポリゴンの代わりに点の配列を考えましたが、私はこの変形が好きです。 – Log

2

rect値は単なる箱であれば、あなたはボックスにポリゴンに変換することができます:

この場合
select (box(rect))[0] right_top, (box(rect))[1] left_bottom 
from boxes2 
where id = 1; 

right_top | left_bottom 
-----------+------------- 
(10,10) | (0,0) 
(1 row) 

しかし、あなたは、単にタイプboxとして値を格納することができます。

+0

ありがとう、この機能の拡張機能もインストールする必要があります。 – Log

関連する問題