miércoles, 8 de marzo de 2017

Determinación del rasgo central (feature) con base en la suma de distancias en PyQGIS

En el post anterior se consideró un algoritmo que permite reducir el tiempo de cómputo de la suma de distancias porque las realiza sólo en la porción triangular superior de la matriz de distancias. En este post el referido algoritmo se incluye en un codigo que permite determinar el feature central para la capa activa. Se ha escogido una capa de puntos con 700 rasgos; tal como se observa a continuación:




El código completo es el siguiente:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import itertools
from datetime import datetime
import numpy as np  

layer = iface.activeLayer()

feats = [ feat for feat in layer.getFeatures() ]

n = len(feats)

start_time = datetime.now()

s = [ [] for i in range(n-1) ] #because there are n-1 distances for each feature

#for calculating only upper triangular distance matrix
for i, j in itertools.combinations(range(n), 2):
    d = feats[i].geometry().distance(feats[j].geometry())
    s[i].append(d)

#for calculating factors to add in distance matrix
index = [ [] for i in range(len(s)) ]
values = [ [] for i in range(len(s)) ]

sums1 = [0]

for i in range(len(s)):
    k = i
    for j in range(i+1):
        index[i].append([j, k])
        k -= 1

    for item in index[i]:
        values[i].append(s[item[0]][item[1]])

    sums1.append(np.sum(values[i]))

sums2 = [ np.sum(item) for item in s ]

sums2.append(0)

#because there are n distances for ALL features
sum_distances = [ sums1[i] + sums2[i] for i in range(len(feats)) ]

print "time: ", datetime.now() - start_time

id = np.argmin(sum_distances)

print id

layer = iface.activeLayer()

layer.select(id)

Después de ejecutado en la Python Console de QGIS, se escoge automáticamente el rasgo con id = 282 (como se esperaba) en apenas 2.762649 segundos. Esto se aprecia en la imagen siguiente:


Pruebas independientes con la misma capa, pero empleando la matriz de distancias completa, pueden llevar un tiempo de ejecución mayor a los 9 segundos.


No hay comentarios: