重心与多边形最远点之间的距离


12

我有一个乡村多边形图层,其中有600万条记录。我已经计算出每个村庄的质心。我想找到质心和每个多边形的最远节点之间的距离。检查下面的图像以供参考。黑线是多边形边界。 在此处输入图片说明

在此处输入图片说明

在此处输入图片说明


有趣的是...我只是在星期五用postgis在多边形周围产生一个圆。我需要几分钟来查找我使用的代码 。i.stack.imgur.com/EKnkg.png
kttii

1
首先,我们可能需要了解可供您使用的程序。您还如何创建这些质心和节点?(即使似乎很明显多边形上的节点是用于设置形状边界的节点,但您是否还在这些节点上添加了附加点?)
Moreau Colin

质心的位置重要吗?您是如何创建它们的?
GISGe


如果重心确实是中心,那么它是最小的圆的半径集中在这一点上,适合多边形(en.wikipedia.org/wiki/Smallest-circle_problem
马克爱尔兰

Answers:



15

使用PostGIS,我使用ST_ConvexHull简化了多边形以获得更快的结果:

获得最远的积分:

SELECT Villages_v4_Trial_region.geom as FarPoint from (
SELECT ST_PointN(ST_ExteriorRing(ST_ConvexHull(Villages_v4_Trial_region.geom)),
generate_series(1, ST_NPoints(ST_ExteriorRing(ST_ConvexHull(Villages_v4_Trial_region.geom))))) as points, 
geom
FROM Villages_v4_Trial_region
ORDER BY ST_MaxDistance(points,ST_Centroid(Villages_v4_Trial_region.geom)) DESC
LIMIT 1;

如果您有兴趣从质心创建一个圆,请执行以下操作:

SELECT ST_Buffer(Center,ST_Distance(Center,FarPoint)) as Circle
FROM (
SELECT Villages_v4_Trial_region.geom as FarPoint, Center from (
    SELECT ST_PointN(ST_ExteriorRing(ST_ConvexHull(Villages_v4_Trial_region.geom)),
    generate_series(1, ST_NPoints(ST_ExteriorRing(ST_ConvexHull(Villages_v4_Trial_region.geom))))) as points,
    ST_Centroid(Villages_v4_Trial_region.geom) as Center, 
    geom
    FROM Villages_v4_Trial_region
    ) as Villages_v4_Trial_region
    ORDER BY ST_MaxDistance(points,Center) DESC
    LIMIT 1) as foo;

在此处输入图片说明


简单,快速,高效。感谢您发布此信息,因为这也会对我目前正在研究的内容有所帮助。
Moreau Colin

@kttii我不知道如何使用PostGIS。您能否在arc或mapinfo或qgis中提供更简单的解决方案
Divya,

@kttii所以我安装了Postgresql。我复制粘贴了这个确切的查询,但它给出了一个错误:列“ the_geom”不存在。我该怎么办?
Divya

the_geom应该替换为您的几何字段名称。您还必须将数据放入PostgreSQL。PostgreSQL是MSSQL之类的数据库。PostGIS是对数据库进行空间感知并提供所有ST_功能的扩展。
kttii

@kttii我将数据库中的字段名称从the_geom更新为“ gid”。再次运行查询后,出现此错误:函数st_convexhull(integer)不存在
Divya

4

使用下一个PyQGIS代码:

from math import sqrt

layer = iface.activeLayer()

feats = [ feat for feat in layer.getFeatures() ]

n = len(feats)

centroids = [ feat.geometry().centroid().asPoint() for feat in feats ]
polygons = [ feat.geometry().asPolygon()[0] for feat in feats ]

lengths = []

for i, pol in enumerate(polygons):
    max_dist = 0
    idx_j = 0
    for j, point in enumerate(pol):
        dist = sqrt(centroids[i].sqrDist(point))
        if dist > max_dist:
            max_dist = dist
            idx_j = j
    print i, idx_j, max_dist
    lengths.append([centroids[i], pol[idx_j]])

crs = layer.crs()
epsg = crs.postgisSrid()

uri = "LineString?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"

mem_layer = QgsVectorLayer(uri,
                           'max_distance',
                           'memory')

prov = mem_layer.dataProvider()

feats = [ QgsFeature() for i in range(n) ]

for i, feat in enumerate(feats):
    feat.setAttributes([i])
    feat.setGeometry(QgsGeometry.fromPolyline(lengths[i]))

prov.addFeatures(feats)

QgsMapLayerRegistry.instance().addMapLayer(mem_layer)

和这个shapefile(具有11个功能):

在此处输入图片说明

我得到了一个存储层,折线是质心和每个多边形(特征)的最远点之间的距离;在下一张图片中可以看到:

在此处输入图片说明

在QGIS的Python控制台上,它还打印了要素索引,要素中距质心的距离为最大,最后是最大距离的点的索引。

在此处输入图片说明


我不知道如何使用PyQGIS。您能否在arc或mapinfo或qgis中提供更简单的解决方案
Divya,

1
尝试使用此链接获取有关PyQgisspacegalaxy.net/2014/10/09/… 入门的
kttii

0

看起来您正在使用MapInfo,这是我不久前为正在使用的内部工具编写的MapBasic函数。它以源节点(质心点)和区域对象(多边形)为参数,并从源点返回多边形中最远节点处的点对象。

Function GetFurthest(ByVal oNode1 as Object, ByVal oObj as Object) as Object

Dim sourceE,sourceN,East,North,Longest,Dist as Float,
    nNodes,nPolys,i,j as SmallInt,
    oNode2 as Object

    sourceE = CentroidX(oNode1)
    sourceN = CentroidY(oNode1)
    Longest = 0

    nPolys = ObjectInfo(oObj,OBJ_INFO_NPOLYGONS)
    For i = 1 to nPolys
        nNodes = ObjectInfo(oObj,OBJ_INFO_NPOLYGONS+nPolys)
        For j = 1 to nNodes
            East = ObjectNodeX(oObj,i,j)
            North = ObjectNodeY(oObj,i,j)
            Dist = Distance(sourceE,sourceN,East,North,"m")
            If Dist > Longest then
                Longest = Dist
                oNode2 = CreatePoint(East,North)
            End if
        Next
    Next

    GetFurthest = oNode2

End Function
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.