按百分比增长PostGIS几何


10

我正在寻找一种在PostGIS几何周围添加缓冲区的方法,但是缓冲区的大小应取决于几何的大小。也就是说,我希望每个几何图形都扩大5%。

我的想法是我正在寻找相交的几何,但是我想考虑的每个几何可能有多达5%的误差。

有人知道最好的方法吗?

该数据库的行数为一百万行,因此我希望它的运行速度相当快。


2
5%的什么?假设您使用的是多边形,它是最大宽度,最窄宽度,边界框,顶点到质心的距离的5%...?如果您在谈论点或线,那么意义就更小了!
MerseyViking,2012年

我猜想顶点-质心的距离-或可能将面积增加5%也可以。如果缩放几何以填充该边界框,则增加边界框就可以了。所有几何都是封闭的多边形(绝大多数是四边形)。
詹姆斯·贝克

Answers:


8

评论表明不需要高精度地达到5%。(如果这样做,将需要长时间来缓冲一百万个多边形!)因此,我们可以调用“ 比萨饼原理”将2D要素线性缩放比例为一个因子,其面积缩放 ^ 2。

推理方法如下:

  • 当形状不太复杂时(尤其是凸形时),缓冲产生的结果可与围绕中心点缩放比例相媲美。(但是,重要的是要理解,对于磁盘以外的任何形状,缓冲永远都不等同于重新缩放。对于某些凹形,通过重新缩放计算出的“缓冲区”实际上可能不包括原始形状本身的一部分!因此最终我们计算形状的真实缓冲区,但仅将这种近似等价作为启发式方法来估算缓冲的量。)

  • 如果缓冲区域要大5%,则重新缩放的大小应为sqrt(1 + 5/100),接近1.025:也就是说,我们应该在所有方向上将形状扩展2.5% 。

  • 同样,如果我们认为形状具有“直径”(等于典型的跨距),则其半径应增加2.5%。等于直径的2.5%/ 2 = 1.25%。

  • 我们可以从形状的边界框估算出典型直径。例如,使用盒子侧面长度的算术或几何平均值。

这建议以下工作流程:

  1. 获取形状的边界框。

  2. e为盒子的边长的平均值。

  3. e的1.25%缓冲形状;也就是说,乘以(5/100)/ 4 * e

因为步骤1和2需要很少的计算,所以它本身就是最快速的解决方案之一。作为准确性检查,您可以(当然)计算缓冲形状的面积并将它们与原始面积进行比较,以查看它们达到所需的5%增长的程度。有时,缓冲区的大小会大于5%,但很少有缓冲区会变小,并且不可能将缓冲区显着减小。

例子

作为检查和说明,让我们考虑一些简单的形状。

  1. 半径为r的磁盘具有一个边长为2 r的边界框。我们的公式计算出e =(5/100)/ 4 * 2 * r = r /40。缓冲的形状显然是半径r + r / 40 = 1.025 r的同心圆盘。旧区域为pi * r ^ 2,而新区域为pi *(1.025 r)^ 2 = pi * 1.0506 * r ^ 2,增加了5.06%。

  2. 边与长度为rs的坐标轴平行的矩形给出e =(r + s)/ 2。缓冲矩形产生的额外区域来自四个以边为边界的宽度(5/100)/ 4 e = e / 80 =(r + s)/ 160的矩形,以及在拐角处四个半径为e / 80的四分之一圆。忽略四分之一圆,该四分之一圆与其他区域相比要小,所以的总面积等于

    2(r + s)*(r + s)/ 160 =(r ^ 2 + s ^ 2 + 2 r * s)/ 80。

    rs差别不大时,我们可以得出r ^ 2 + s ^ 2约为2 r * s。这种近似将新的总面积简化为4 r * s / 80 = r * s原始面积的5%。


4

我想将ST_Scale(http://postgis.net/docs/ST_Scale.html)和ST_Translate(http://postgis.net/docs/ST_Translate.html)结合使用。我们在PostGIS in Action中有一个示例,在第8章中也有类似示例。如果您没有这本书,则可以在此处下载该章的代码:

http://www.postgis.us/chapter_08

书中的片段请看示例8.26:

    -- Listing 8.26 Combining Scale and Translation to maintain centroid
    SELECT xfactor, yfactor, 
       ST_Translate(ST_Scale(hex.the_geom, xfactor, yfactor), 
       ST_X(ST_Centroid(the_geom))*(1 - xfactor), 
       ST_Y(ST_Centroid(the_geom))*(1 - yfactor) ) As scaled_geometry
    FROM 
 ( SELECT ST_GeomFromText('POLYGON((0 0,64 64,64 128,0 192,-64 128,-64 64,0 0))') As the_geom)  As hex
    CROSS JOIN (SELECT x*0.5 As xfactor 
        FROM generate_series(1,4) As x) As xf
    CROSS JOIN (SELECT y*0.5 As yfactor
        FROM generate_series(1,4) As y) As yf;

作品。现在似乎也有,ST_Transscale但不知
为何

0

这次聚会很晚,但是我最近开发了一个自定义的PostGIS函数,可以执行此操作,并在必要时进行缩小:

ST_Dilate

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.