Polígonos vecinos de 1ro, 2do y orden superior mediante PyQGIS

En el post anterior señalé el interés en digitalizar al ráster al cual allí se hacía referencia. La razón era porque quería desarrollar una aplicación para encontrar el orden de vecindad de polígonos donde la tabla de contingencia era parcialmente conocida.

El código finalmente desarrollado es el siguiente:

from math import sqrt
import itertools

def  neighborsInBetween(idx1, idx2):
    if idx1 > idx2:

        tmp = idx1
        idx1 = idx2
        idx2 = tmp

    ver = 0
    nib = 0  #neighbors in between

    while(ver == 0):

        distances = []

        for item in table:
            if item[0] == idx1 and item[1] == idx2:

                if item[3] == False:
                   nib += 1
                else:
                   ver = 1

        new_idx = []

        for item in table:
            if item[0] == idx1 and item[3] == True:
                new_idx.append(item[1])

        for item in table:
            for value in new_idx:
                if value > idx2:

                    tmp = value
                    value = idx2
                    idx2 = tmp
                if item[0] == value and item[1] == idx2:

                    distances.append(item[2])

        try:
            min_d = min ( distances )

        except ValueError:
            min_d = 0

        for item in table:
            if (min_d in item) is True:
                a = item

        idx1 = a[0]

    print nib #neighbors in between

#code starts here

layer = iface.activeLayer()

features = [feature for feature in layer.getFeatures() ]

centroids = [ feature.geometry().centroid().asPoint() for feature in features ]

n = len(centroids)

list = range(n)

table = [ [i, j, sqrt(centroids[i].sqrDist(centroids[j])), features[i].geometry().touches(features[j].geometry())] 
        for i,j in itertools.combinations(list, 2) ]

print "polygon 1   polygon2  neighborsInBetween"

for i, j in itertools.combinations(list, 2):
    print ' {:>3} {:>12}             '.format(i, j),
    neighborsInBetween(i,j)

El algoritmo se basa en determinar la vecindad para pares no repetidos. Si no resultan vecinos se explora más allá según la distancia mínima de los centroides de los vecinos del polígono de origen al centroide del polígono destino. El proceso se repite hasta encontrar el par vecino con la distancia mínima. Un contador se encarga de registrar el número de poligonos que se encuentran entre el polígono de origen y el destino.

El shapefile utilizado se visualiza en la imagen siguiente:

neighbors1

Después de ejecutar el código anterior en la Python Console se obtuvo lo siguiente:

polygon 1   polygon2  neighborsInBetween
   0            1              0
   0            2              1
   0            3              1
   0            4              0
   0            5              0
   0            6              1
   0            7              1
   0            8              2
   0            9              3
   0           10              2
   1            2              0
   1            3              1
   1            4              0
   1            5              1
   1            6              2
   1            7              1
   1            8              2
   1            9              3
   1           10              2
   2            3              0
   2            4              0
   2            5              1
   2            6              2
   2            7              1
   2            8              1
   2            9              2
   2           10              2
   3            4              0
   3            5              1
   3            6              1
   3            7              0
   3            8              0
   3            9              1
   3           10              1
   4            5              0
   4            6              1
   4            7              0
   4            8              1
   4            9              2
   4           10              1
   5            6              0
   5            7              0
   5            8              1
   5            9              2
   5           10              1
   6            7              0
   6            8              1
   6            9              1
   6           10              0
   7            8              0
   7            9              1
   7           10              0
   8            9              0
   8           10              0
   9           10              0

que concuerda con lo esperado.

Esta entrada fue publicada en PyQGIS, QGIS, SIG, Software Libre. Guarda el enlace permanente.

Responder

Por favor, inicia sesión con uno de estos métodos para publicar tu comentario:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s