use*_*696 6 sql postgresql postgis
样本数据:
CREATE TABLE poly_and_multipoly (
"id" SERIAL NOT NULL PRIMARY KEY,
"name" char(1) NOT NULL,
"the_geom" geometry NOT NULL
);
-- add data, A is a polygon, B is a multipolygon
INSERT INTO poly_and_multipoly (name, the_geom) VALUES (
'A', 'POLYGON((7.7 3.8,7.7 5.8,9.0 5.8,7.7 3.8))'::geometry
), (
'B',
'MULTIPOLYGON(((0 0,4 0,4 4,0 4,0 0),(1 1,2 1,2 2,1 2,1 1)), ((-1 -1,-1 -2,-2 -2,-2 -1,-1 -1)))'::geometry
);
Run Code Online (Sandbox Code Playgroud)
我有一个多边形和多边形的表格,我正在尝试使用ST_Azimuth计算表格中外环的内角(即没有内环......).有没有办法修改附加的查询以在线串的sp和ep上使用ST_Azimuth?
SELECT id, name, ST_AsText( ST_MakeLine(sp,ep) )
FROM
-- extract the endpoints for every 2-point line segment for each linestring
(SELECT id, name,
ST_PointN(geom, generate_series(1, ST_NPoints(geom)-1)) as sp,
ST_PointN(geom, generate_series(2, ST_NPoints(geom) )) as ep
FROM
-- extract the individual linestrings
(SELECT id, name, (ST_Dump(ST_Boundary(the_geom))).geom
FROM poly_and_multipoly
) AS linestrings
) AS segments;
1;"A";"LINESTRING(7.7 3.8,7.7 5.8)"
1;"A";"LINESTRING(7.7 5.8,9 5.8)"
1;"A";"LINESTRING(9 5.8,7.7 3.8)"
2;"B";"LINESTRING(0 0,4 0)"
Run Code Online (Sandbox Code Playgroud)
小智 3
在 aengus 示例中使用 ST_Azimuth 函数会出现错误,因为您不能使用两个generate_series作为单个函数的参数。如果您在另一个子查询中使用 ep / sp 值,那么您不会遇到任何麻烦。
这是我的解决方案:
-- 3.- Create segments from points and calculate azimuth for each line.
-- two calls of generate_series for a single function wont work (azimuth).
select id,
name,
polygon_num,
point_order as vertex,
--
case when point_order = 1
then last_value(ST_Astext(ST_Makeline(sp,ep))) over (partition by id, polygon_num)
else lag(ST_Astext(ST_Makeline(sp,ep)),1) over (partition by id, polygon_num order by point_order)
end ||' - '||ST_Astext(ST_Makeline(sp,ep)) as lines,
--
abs(abs(
case when point_order = 1
then last_value(degrees(ST_Azimuth(sp,ep))) over (partition by id, polygon_num)
else lag(degrees(ST_Azimuth(sp,ep)),1) over (partition by id, polygon_num order by point_order)
end - degrees(ST_Azimuth(sp,ep))) -180 ) as ang
from (-- 2.- extract the endpoints for every 2-point line segment for each linestring
-- Group polygons from multipolygon
select id,
name,
coalesce(path[1],0) as polygon_num,
generate_series(1, ST_Npoints(geom)-1) as point_order,
ST_Pointn(geom, generate_series(1, ST_Npoints(geom)-1)) as sp,
ST_Pointn(geom, generate_series(2, ST_Npoints(geom) )) as ep
from ( -- 1.- Extract the individual linestrings and the Polygon number for later identification
select id,
name,
(ST_Dump(ST_Boundary(the_geom))).geom as geom,
(ST_Dump(ST_Boundary(the_geom))).path as path -- To identify the polygon
from poly_and_multipoly ) as pointlist ) as segments;
Run Code Online (Sandbox Code Playgroud)
我添加了一些复杂性,因为我想识别每个多边形以避免混合线进行角度计算。
由于 sqlfiddle 不支持 PostGIS,我已将这个示例和一些补充代码上传到 github这里