Yukon中椭圆弧对象的使用方法

作者:黄宁

摘要:参数化对象在规划行业中使用较为广泛,能够更精确地表达图形的面积、周长等。PostGIS提供了圆弧对象CIRCULARSTRING,可以参与线或面的构造,参见 PostGIS的geometry类型及使用方法。Yukon在PostGIS的矢量存储模型中扩展实现了椭圆弧对象,并提供了精确计算参数化对象/组合对象周长和面积的能力。本文对其使用方法进行说明。

椭圆弧对象构造

WKT 数据格式为 ELLIPTICALSTRING(xstart ystart,xend yend ,xcenter ycenter,minor,clockwise,rotation,axis,ratio);

  • xstart,ystart :起始点坐标
  • xend,yend: 终止点坐标
  • xcenter,ycenter: 中心点坐标
  • minor: 椭圆弧方向,只能是 0 或者 1,任何非 0 的数都会变为 1
  • clockwise 保留参数未使用
  • rotation :椭圆弧旋转角度
  • axis 长半轴长度
  • ratio 短轴与长轴之比

注意:椭圆的起始点和终止点必须要在椭圆上,否则会报错:

ERROR: the parameters of the ellipse must be valid

可以通过: select 'ELLIPTICALSTRING(-2 0,2 0,0 0,0,0,0,2,0.5)'::geometry; 来构造一个如下图所示的椭圆弧:

在这里插入图片描述

WKB 数据格式说明

select 'ELLIPTICALSTRING(-2 0,2 0,0 0,1,0,0,2,0.5)'::geometry;
01                     	-- 小端
12000000				-- 椭圆弧类型值 0x12(int)
03000000				-- 点的个数 0x03 (int)
00000000000000C0		-- xstart 	(double)	-2
0000000000000000		-- ystart 	(double)	0
0000000000000040		-- xend	  	(double)	2
0000000000000000		-- yend   	(double)	0
0000000000000000		-- xcenter	(double)	0
0000000000000000		-- ycenter	(double)	0
000000000000F03F		-- minor  	(double)	1
0000000000000000        -- clockwise(double)	0
0000000000000000		-- rotation	(double)	0
0000000000000040		-- axis	  	(double)   	2
000000000000E03F		-- ratio   	(double)   	0.5 

创建数据表

ELLIPTICALSTRING 支持 Z 和 M 属性。

create table ellipsetest(id serial,geom geometry(ELLIPTICALSTRING ,4326));
create table ellipsetest1(id serial,geom geometry(ELLIPTICALSTRINGZ ,4326));
create table ellipsetest2(id serial,geom geometry(ELLIPTICALSTRINGM ,4326));

插入数据

-- 插入不包含 Z M 属性的数据
insert into ellipsetest (geom) values ('ELLIPTICALSTRING(-2 0,2 0,0 0,0,0,0,2,0.5)');
-- 向不带有 Z 属性的表中插入带有 Z 属性的数据会报错:ERROR: Geometry has Z dimension but column does not
insert into ellipsetest (geom) values ('ELLIPTICALSTRINGZ(-2 0 0,2 0 0,0 0 0,0,0,0,2,0.5)');
-- 插入带有 Z 属性的数据
insert into ellipsetest1 (geom) values ('ELLIPTICALSTRINGZ(-2 0 0,2 0 0,0 0 0,0,0,0,2,0.5)');
-- 插入带有 M 属性的数据
insert into ellipsetest2 (geom) values ('ELLIPTICALSTRINGM(-2 0 0,2 0 0,0 0 0,0,0,0,2,0.5)');

查询数据

select geom from ellipsetest;
-- 结果
0112000020E61000000300000000000000000000C0000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000E03F
-- 使用 ST_AsText 查看 WKT 数据
select st_astext(geom) from ellipsetest;
-- 结果
ELLIPTICALSTRING(-2 0,2 0,0 0,0,0,0,2,0.5)
-- 带有 Z 属性
select st_astext(geom) from ellipsetest1;
-- 结果
ELLIPTICALSTRING Z (-2 0 0,2 0 0,0 0 0,0,0,0,2,0.5)
-- 带有 M 属性
select st_astext(geom) from ellipsetest2;
-- 结果
ELLIPTICALSTRING M (-2 0 0,2 0 0,0 0 0,0,0,0,2,0.5)

删除数据

delete from ellipsetest;

参与构造 COMPOUNDCURVE

select 'COMPOUNDCURVE((1 2,2 0),ELLIPTICALSTRING(2 0,-2 0,0 0,0,0,0,2,0.5))'::geometry;
-- 结果
010900000002000000010200000002000000000000000000F03F0000000000000040000000000000004000000000000000000112000000030000000000000000000040000000000000000000000000000000C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000E03F
select st_astext('COMPOUNDCURVE((1 2,2 0),ELLIPTICALSTRING(2 0,-2 0,0 0,0,0,0,2,0.5))'::geometry);
-- 结果
COMPOUNDCURVE((1 2,2 0),ELLIPTICALSTRING(2 0,-2 0,0 0,0,0,0,2,0.5))

注意 COMPOUNDCURVE 中上一个对象与新添加的对象必须是连接在一起的。

同时支持 st_curvetoline 函数,转换为 LINESTRING 后可以在 QGIS 中显示如下:

select ST_AsText(st_curvetoline('COMPOUNDCURVE((1 0,2 0),ELLIPTICALSTRING(2 0 ,4 0, 3 0 ,1,0,0,1,0.5))'));

在这里插入图片描述

将两个椭圆连在一起,转换为线后在 QGIS 中的显示

select ST_AsText(st_curvetoline('COMPOUNDCURVE(ELLIPTICALSTRING(-2 0,1.1602773 0.8145177,0 0,0,0,0,2,0.5),ELLIPTICALSTRING(1.1602773 0.8145177,4.3205547 0,2.3205547 0,0,0,0,2,0.5))'));

在这里插入图片描述

参与构造 CURVEPOLYGON

select st_curvetoline(st_astext('CURVEPOLYGON(ELLIPTICALSTRING(2 0,2 0,0 0,0,0,0,2,0.5),CIRCULARSTRING(-0.5 0,0.5 0,-0.5 0))'));

注意 CURVEPOLYGON 中的各个子对象必须是闭合的,例如其中的 ELLIPTICALSTRING 对象,起始点和终止点必须是一样的。

绘制图形如果所示:

在这里插入图片描述

面积计算

--- COMPOUNDCURVE 中包含椭圆时,面积的计算
select st_area('COMPOUNDCURVE(ELLIPTICALSTRING(-1 0, -1 0, 0 0,1,0,0,1,0.5))');

-- 结果
1.5707963267948966

--- CURVEPOLYGON 中包含椭圆时,面积的计算
select st_area('CURVEPOLYGON(ELLIPTICALSTRING(-1 0, -1 0, 0 0,1,0,0,1,0.5))');

-- 结果
1.5688033694578472

由于 PostGIS 3.1.2 中计算面积使用的是拟合的方式,因此我们增加了 ST_AreaParam 方法来计算精确的面积

-- 完整圆
select st_areaparam('CURVEPOLYGON(CIRCULARSTRING(-1 5, 1 5 ,-1 5))');
-- 结果
--3.141592653589793

-- 圆弧和线组合
select st_areaparam('CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(10 11,12 11,11 10),LINESTRING(11 10,11 11,10 11)))');
-- 结果
--2.356194490192344


-- 椭圆弧和线组合
select st_areaparam('CURVEPOLYGON(COMPOUNDCURVE(ELLIPTICALSTRING(-2 0,0 -1,0 0,1,0,0,2,0.5),(0 -1,0 0 ,-2 0)))');
-- 结果
--1.5707963267948974

周长计算

-- 完整的椭圆
select st_length('ELLIPTICALSTRING(0 0,0 0,2 0,0,1,0,2,0.5)'); -- 1 ellipse
-- 结果
9.685374273494212

-- 1/2 椭圆
select st_length('ELLIPTICALSTRING(0 0,4 0,2 0,0,1,0,2,0.5)'); -- 1/2 ellipse
-- 结果
4.843839839458154

-- 1/4 椭圆
select st_length('ELLIPTICALSTRING(2 2,4 1,2 1,0,0,0,2,0.5)'); -- 1/4 ellipse
-- 结果
2.4220640204276096

-- 3/4 椭圆
select st_length('ELLIPTICALSTRING(2 2,4 1,2 1,1,0,0,2,0.5)'); -- 3/4 ellipse
-- 结果
7.266192061282826

-- 线和椭圆组合
select st_length('COMPOUNDCURVE(LINESTRING(-4 0, -2 0),ELLIPTICALSTRING(-2 0,2 0,0 0,0,1,0,2,0.5))');  
-- 结果
6.843839839458153

-- 线和椭圆组合
select st_length('COMPOUNDCURVE((-4 0, -2 0),ELLIPTICALSTRING(-2 0,2 0,0 0,0,1,0,2,0.5))');  
-- 结果
6.843839839458153

-- 圆弧和椭圆组合
select st_length('COMPOUNDCURVE(CIRCULARSTRING(1 -1,0.2929 -0.7071,0 0),ELLIPTICALSTRING(0 0,4 0,2 0,0,1,0,2,0.5))'); 
-- 结果
6.414626229293022

-- 圆弧,椭圆和线组合
select st_length('COMPOUNDCURVE(CIRCULARSTRING(1 -1,0.2929 -0.7071,0 0),ELLIPTICALSTRING(0 0,4 0,2 0,0,1,0,2,0.5),LINESTRING(4 0,4 8))'); 
-- 结果
14.414626229293022

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值