重心とポリゴンの最も遠い点の間の距離


12

6,00,000を超えるレコードを持つ村のポリゴンレイヤーがあります。各村の重心を計算しました。重心と各ポリゴンの最も遠いノードの間の距離を見つけたいです。参考のために下の画像を確認してください。黒い線はポリゴンの境界です。 ここに画像の説明を入力してください

ここに画像の説明を入力してください

ここに画像の説明を入力してください


おもしろい...今週金曜日にpostgisでポリゴンの周りに円を作成しました。使用したコードを探すのに数分かかります 。i.stack.imgur.com/EKnkg.png
kttii

1
まず、自由に使えるプログラムを知る必要があるかもしれません。また、それらのセントロイドとノードをどのように作成しましたか?(これは、ポリゴン上のノードは、あなたの図形の境界を設定するために使用されるものですが、あなたはthosesの上にaditionnalポイントを追加しなかったことが少し明らかに思える場合でも?)
モローコリン・

重心の位置は重要ですか?それらをどのように作成しましたか?
GISGe


重心が本当に中心である場合、それは最小の円の半径は、ポリゴン(収まる点を中心だen.wikipedia.org/wiki/Smallest-circle_problem
マークアイルランド

回答:



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;

ここに画像の説明を入力してください


シンプル、高速、効率的。これを投稿していただきありがとうございます。これは、私が今取り組んでいることでも私を助けてくれるからです。
モローコリン

@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(整数)が存在しません
Divya

3

次の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)

このシェイプファイル(11の機能):

ここに画像の説明を入力してください

ポリラインが重心と各ポリゴンの最も遠いポイントとの間の距離であるメモリレイヤーを取得しました(フィーチャ)。次の画像で確認できるように:

ここに画像の説明を入力してください

QGISのPythonコンソールでは、フィーチャーのインデックス、重心からの距離が最大で、最後に最大距離であるフィーチャーのポイントのインデックスも印刷されました。

ここに画像の説明を入力してください


PyQGISの使用方法がわかりません。arcまたはmapinfoまたはqgisでよりシンプルなソリューションを提供できますか?
Divya

1
PyQgisを使い始めると、ヘルプのために、このリンクをお試しください spatialgalaxy.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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.