Abstand zwischen Schwerpunkt und weitestem Punkt des Polygons


12

Ich habe einen Dorfpolygon-Layer mit mehr als 6,00.000 Datensätzen. Ich habe den Schwerpunkt jedes Dorfes berechnet. Ich möchte den Abstand zwischen dem Schwerpunkt und dem entferntesten Knoten jedes Polygons finden. Überprüfen Sie das Bild unten als Referenz. Schwarze Linien sind Polygongrenzen. Bildbeschreibung hier eingeben

Bildbeschreibung hier eingeben

Bildbeschreibung hier eingeben


interessant ... ich habe diesen freitag gerade mit postgis gemacht, um einen kreis um ein polygon zu erzeugen. Ich brauche ein paar Minuten, um nach dem verwendeten Code zu suchen. I.stack.imgur.com/EKnkg.png
kttii

1
Zuerst müssen wir möglicherweise wissen, welche Programme Ihnen zur Verfügung stehen. Wie haben Sie diese Schwerpunkte und Knoten erstellt? (Auch wenn es ein bisschen offensichtlich erscheint, dass die Knoten auf den Polygonen die Grenzen Ihrer Formen festlegen, haben Sie darüber einen zusätzlichen Punkt hinzugefügt?)
Moreau Colin,

Ist die Position des Schwerpunkts wichtig? Wie hast du sie geschaffen?
GISGe


Wenn der Schwerpunkt wirklich zentral ist, ist es der Radius des kleinsten Kreises, der auf diesem Punkt zentriert ist und zum Polygon passt ( de.wikipedia.org/wiki/Kleinstes_Kreis-Problem )
Markieren Sie Irland am

Antworten:



15

Mit PostGIS habe ich ST_ConvexHull verwendet, um das Polygon für ein schnelleres Ergebnis zu vereinfachen:

Holen Sie sich den weitesten Punkt:

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;

Und wenn Sie daran interessiert sind, einen Kreis aus dem Schwerpunkt zu erstellen:

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;

Bildbeschreibung hier eingeben


Einfach, schnell und effizient. Vielen Dank, dass Sie dies gepostet haben, denn dies wird mir auch bei dem helfen, woran ich gerade arbeite.
Moreau Colin

@kttii Ich weiß nicht, wie man PostGIS benutzt. Können Sie eine einfachere Lösung bieten, in arc oder mapinfo oder qgis
Divya

@kttii Also habe ich Postgresql installiert. Ich habe genau diese Abfrage kopiert, aber sie hat einen FEHLER ergeben: Spalte "the_geom" existiert nicht. Was mache ich?
Divya

the_geom sollte durch den Namen Ihres Geometriefelds ersetzt werden. Sie müssten Ihre Daten auch in PostgreSQL ablegen. PostgreSQL ist eine Datenbank wie MSSQL. PostGIS ist eine Erweiterung, um die Datenbank räumlich wahrzunehmen und alle ST_-Funktionen bereitzustellen.
kttii

@kttii Ich habe den Feldnamen in meiner Datenbank von the_geom auf "gid" aktualisiert. Nachdem ich die Abfrage erneut ausgeführt habe, habe ich diesen FEHLER erhalten: Funktion st_convexhull (Ganzzahl) existiert nicht
Divya

3

Verwenden des nächsten PyQGIS- Codes:

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)

und dieses Shapefile (mit 11 Features):

Bildbeschreibung hier eingeben

Ich habe eine Memory-Ebene erhalten, in der die Polylinien den Abstand zwischen dem Schwerpunkt und dem entferntesten Punkt jedes Polygons (Feature) darstellen. wie es auf dem nächsten Bild zu sehen ist:

Bildbeschreibung hier eingeben

In der Python-Konsole von QGIS wurde auch der Merkmalsindex gedruckt, der Index des Merkmalspunkts, bei dem der Abstand zum Schwerpunkt ein Maximum und schließlich der maximale Abstand ist.

Bildbeschreibung hier eingeben


Ich weiß nicht, wie man PyQGIS benutzt. Können Sie eine einfachere Lösung bieten, in arc oder mapinfo oder qgis
Divya

1
Versuchen Sie diesen Link, um Hilfe bei den ersten Schritten
kttii

0

Anscheinend verwenden Sie MapInfo. Hier ist eine MapBasic-Funktion, die ich vor einiger Zeit für ein internes Tool geschrieben habe, an dem ich gearbeitet habe. Es verwendet einen Quellknoten (Ihren Schwerpunkt) und ein Bereichsobjekt (das Polygon) als Argumente und gibt ein Punktobjekt am entferntesten Knoten des Polygons vom Quellpunkt zurück.

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.