Distanza tra centroide e punto più lontano del poligono


12

Ho uno strato poligonale di villaggio che ha più di 6.000.000 di record. Ho calcolato il centroide di ogni villaggio. Voglio trovare la distanza tra il centroide e il nodo più lontano di ciascun poligono. Controlla l'immagine qui sotto per riferimento. Le linee nere sono contorni poligonali. inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine


interessante ... ho appena fatto questo venerdì con i postgis per produrre un cerchio attorno a un poligono. Ho bisogno di qualche minuto per cercare il codice che ho usato .. i.stack.imgur.com/EKnkg.png
kttii

1
Per prima cosa potremmo aver bisogno di sapere quali programmi hai a tua disposizione. Come hai creato questi centroidi e nodi? (Anche se sembra un po 'ovvio che i nodi sui poligoni sono quelli usati per stabilire i confini delle tue forme, ma hai aggiunto un punto aditionnal in cima a quelli?)
Moreau Colin,

La posizione del centroide è importante? Come li hai creati?
GISGe


Se il centroide è veramente centrale, allora è il raggio del cerchio più piccolo centrato su quel punto che si adatta al poligono ( en.wikipedia.org/wiki/Smallest-circle_problem )
Mark Ireland

Risposte:



15

Usando PostGIS, ho usato ST_ConvexHull per semplificare il poligono per un risultato più veloce:

Ottieni il punto più lontano:

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;

E se sei interessato a creare un cerchio dal centroide:

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;

inserisci qui la descrizione dell'immagine


Semplice, veloce, efficiente. Grazie per aver pubblicato questo perché questo mi aiuterà anche in quello su cui sto lavorando in questo momento.
Moreau Colin,

@kttii Non so come usare PostGIS. Puoi fornire una soluzione più semplice, in arco o mapinfo o qgis
Divya,

@kttii Così ho installato Postgresql. Ho copiato e incollato questa query esatta ma ha dato un ERRORE: la colonna "the_geom" non esiste. Cosa faccio?
Divya,

the_geom deve essere sostituito dal nome del campo della geometria. Dovresti inserire anche i tuoi dati in PostgreSQL. PostgreSQL è un database come MSSQL. PostGIS è un'estensione per rendere il database spazialmente consapevole e fornire tutte le funzioni ST_.
kttii,

@kttii Ho aggiornato il nome del campo da the_geom a "gid" nel mio database. Dopo aver eseguito nuovamente la query, ho ricevuto questo ERRORE: la funzione st_convexhull (intero) non esiste
Divya

4

Utilizzando il prossimo codice 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)

e questo shapefile (con 11 funzionalità):

inserisci qui la descrizione dell'immagine

Ho ottenuto uno strato di memoria in cui le polilinee erano la distanza tra il centroide e il punto più lontano di ciascun poligono (caratteristica); come si può vedere nella prossima immagine:

inserisci qui la descrizione dell'immagine

Alla Python Console di QGIS, è stato anche stampato l'indice della caratteristica, l'indice del punto nella caratteristica in cui la distanza dal centroide è una distanza massima e, infine, massima.

inserisci qui la descrizione dell'immagine


Non so come usare PyQGIS. Potete fornire una soluzione più semplice, in arco o mapinfo o qgis
Divya,

1
Prova questo link per ricevere assistenza su come iniziare con PyQgis spatialgalaxy.net/2014/10/09/…
kttii,

0

Sembra che tu stia usando MapInfo, ecco una funzione MapBasic che ho scritto qualche tempo fa per uno strumento interno su cui stavo lavorando. Prende un nodo sorgente (il punto centroide) e un oggetto regione (il poligono) come argomenti e restituisce un oggetto punto nel nodo più lontano nel poligono dal punto sorgente.

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.