我有一个postgis表
buildings
,其中包含位于德国的房屋周长,srid
3857,我想计算每栋房屋的面积。
我的假设是
select st_area(st_transform(geom, utmzone(st_centroid(geom)))) as area from buildings
返回最精确的结果,但我希望得到您的确认。
跑步
select utmzone(st_centroid(geom)), count(*) from buildings group by utmzone(st_centroid(geom));
给我:
在以下查询中,我采用了更多方法来计算面积:
select
rel_err(st_area(geom), area) a,
rel_err(st_area(st_transform(geom, 4326)), area) b,
rel_err(st_area(st_transform(geom, 4326)::geography), area) c,
rel_err(st_area(st_transform(geom, 25832)), area) d,
rel_err(st_area(st_transform(geom, 25833)), area) e,
rel_err(st_area(st_transform(geom, 31467)), area) f,
rel_err(st_area(st_transform(geom, 32631)), area) g,
rel_err(st_area(st_transform(geom, 32632)), area) h
from
(select st_area(st_transform(geom, utmzone(st_centroid(geom)))) as area, geom from buildings) q;
结果输出如下所示:
(其中
rel_err(x, a) := (x-a)/a
)
所以这是我的问题:计算值
area
真的是房屋周长面积的最佳近似值,还是c
到h
其中一列的值更精确?或者还有其他更精确的计算方法吗?
答案是
c
,球体上基于地理的距离。
SRID
3857
在距离和区域越北的地方就相当糟糕。它认为两极是与赤道一样长的线。 当您询问距北极以东 200 米的位置时,看看会发生什么情况:
with the_north_pole as (select st_point(0,90,4326) geom)
select ST_Distance( st_transform(geom,3857)
,ST_Translate(st_transform(geom,3857),200,0))--moving 200m East
from the_north_pole ;
st_距离 |
---|
200 |
实际上,距北极东 200 米仍然是北极 - 你只是在原地旋转,围绕该点旋转。如果你使用正确的
geography
,它知道如果你向东180度,你没有移动:
select ST_Distance( st_point(0 ,90,4326)::geography
,st_point(180,90,4326)::geography
,use_spheroid=>true );
st_距离 |
---|
0 |
您感兴趣的区域并不那么极端,但这种效果仍然适用:您所有的平面投影都将物体进一步向北延伸,这就是为什么当您将它们deproject到
geography(polygon,4326)
时,您会看到它们的表面积缩小。您使用的区域越大,通常一切都会变得越扭曲,所以
3857
是你最扭曲的结果,2583x
,3263x
31467
作为局部投影取得了良好的平衡此外,实际上,所有大型“平坦”表面实际上都是弯曲的,以匹配地球的曲率,并且基于
geography
的计算解释了这一点,而投影 geometries
认为它完全是平坦的。