我有简单的表格:
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 ++ build 1800,32位编译”
答案 0 :(得分:2)
PostGIS扩展中有一个函数ST_DumpPoints(geometry geom),用于从几何对象中提取点。
如果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
类型。
答案 1 :(得分:1)
这是一种相当复杂的方式来获得第一个'多边形的点,基于假设PostgreSQL以与输入相同的顺序保持顶点,将多边形转换为文本,然后使用正则表达式解析文本,取出您感兴趣的部分,并将其重新投射回来到点类型。它相当复杂:
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 */ ;
我必须承认这看起来很糟糕,但是,AFAIK,没有公开的方式来获得第一个'多边形的点(也不是路径)。我很确定你可以使用PostGIS做到这一点,但没有它就找不到办法。
有一个函数可以获得点数(npoints(polygon '((1,1),(0,0))')
),但不是特定点。将多边形转换为点数组(cast a_polygon :: point [])也不起作用。
警告:
从几何角度来看,如果A,B,C和D是点(顶点或角点),那么(A,B,C,D)所描述的polygons,(B,C, D,A),(C,D,A,B),(D,A,B,C)和相同的(有序的)四联体但反转:(D,C,B,A),...绝对等效。
所以,你不能真正说出第二个"第二个"多边形的顶点。此时,只是检查了几个点数非常少的样本,似乎表明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[]
)。数组保证以保持值与提供的顺序相同。如果你需要一个多边形和原始的顶点列表,我想我会得到两个数据(即使这是一个非规范化的形式)。如果您只使用矩形,我会使用box
类型;它更能代表您的需求。