Distância entre o centróide e o ponto mais distante do polígono

12

Eu tenho uma camada de polígono da vila que tem mais de 6,00,000 registros. Eu calculei o centróide de cada aldeia. Quero encontrar a distância entre o centróide e o nó mais distante de cada polígono. Verifique a imagem abaixo para referência. Linhas pretas são limites de polígono. insira a descrição da imagem aqui

insira a descrição da imagem aqui

insira a descrição da imagem aqui

Divya
fonte
interessante ... eu fiz esta sexta-feira com postgis para produzir um círculo em torno de um polígono. Preciso de alguns minutos para procurar o código que eu usei .. i.stack.imgur.com/EKnkg.png
kttii 27/06/16
1
Primeiro, precisamos saber quais programas você tem à sua disposição. Além disso, como você criou esses centróides e nós? (Mesmo se parece um pouco óbvio que os nós sobre os polígonos são os usados para definir os limites de suas formas, mas você adicionar ponto aditionnal no topo de thoses?)
Moreau Colin
A localização do centróide é importante? Como você os criou?
GISGe
Possível duplicada - gis.stackexchange.com/questions/133099/…
klewis
Se o centróide é verdadeiramente central, então é o raio do círculo menor centrado nesse ponto que se encaixa o polígono ( en.wikipedia.org/wiki/Smallest-circle_problem )
Mark Ireland

Respostas:

15

Usando o PostGIS, usei ST_ConvexHull para simplificar o polígono para obter um resultado mais rápido:

Obtenha o ponto mais distante:

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 você estiver interessado em criar um círculo a partir do centróide:

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;

insira a descrição da imagem aqui

kttii
fonte
Simples, rápido, eficiente. Obrigado por postar isso, porque isso também me ajudará no que estou trabalhando no momento.
Moreau Colin
@kttii Não sei como usar o PostGIS. Você pode fornecer uma solução mais simples, em arco ou mapinfo ou qgis
Divya
@kttii Então eu instalei o Postgresql. Copiei e colei esta consulta exata, mas deu um erro: a coluna "the_geom" não existe. O que eu faço?
Divya
the_geom deve ser substituído pelo nome do seu campo de geometria. Você teria que colocar seus dados no PostgreSQL também. O PostgreSQL é um banco de dados como o MSSQL. O PostGIS é uma extensão para conscientizar espacialmente o banco de dados e fornecer todas as funções ST_.
kttii
@kttii Atualizei o nome do campo de the_geom para "gid" no meu banco de dados. Depois de executar a consulta novamente, eu tenho esse erro: função ST_ConvexHull (inteiro) não existe
Divya
3

Usando o próximo código 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 este shapefile (com 11 recursos):

insira a descrição da imagem aqui

Consegui uma camada de memória em que as polilinhas eram a distância entre o centróide e o ponto mais distante de cada polígono (recurso); como pode ser observado na próxima imagem:

insira a descrição da imagem aqui

No console Python do QGIS, também foi impresso o índice do recurso, o índice do ponto no recurso em que a distância do centróide é uma distância máxima e, finalmente, máxima.

insira a descrição da imagem aqui

xunilk
fonte
Não sei como usar o PyQGIS. Você pode fornecer uma solução mais simples, em arco ou mapinfo ou qgis
Divya
1
Tente este link para obter ajuda sobre como começar com o PyQgis spatialgalaxy.net/2014/10/09/…
kttii
0

Como parece que você está usando o MapInfo, aqui está uma função MapBasic que escrevi há algum tempo para uma ferramenta interna em que estava trabalhando. Ele usa um nó de origem (seu ponto centróide) e um objeto de região (o polígono) como argumentos e retorna um objeto de ponto no nó mais distante do polígono a partir do ponto de origem.

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
T_Bacon
fonte