Estoy trabajando en un programa que determina la ubicación más cercana de un punto dado. La nube de puntos estoy de pruebas en contra, es muy grande (unos 800.000). Sin embargo, esto realmente no se explica por qué mi aplicación es tan lento. Este es mi planteamiento:
En primer lugar, he creado un índice espacial para la forma de la punta
pntshp.ExecuteSQL('CREATE SPATIAL INDEX ON %s' % table_name)
He definido una matriz de distancias de separación para limitar el radio de búsqueda. Que, por supuesto, también significa que tengo que crear un buffer para cada punto (lo cual puede ser costoso).
BUFFER_DISTANCES = ( 0.001, 0.005, 0.01, 0.02, 0.05 ) # 100m, 500m, 1km, 2km, 5km
A continuación, el tampón se utiliza como un filtro espacial
node_lyr.SetSpatialFilter(buff)
Si el filtro devuelve None
el búfer distancia será mayor.
for buffer_d in BUFFER_DISTANCES:
buffr = get_buffer(xy_street,buffer_d)
...
Entonces yo soy el cálculo de la distancia a los puntos devueltos por el filtro espacial
p=ogr.Geometry(ogr.wkbPoint)
p.AddPoint(xy[0],xy[1])
for feat in node_lyr:
geom = feat.GetGeometryRef()
d = p.Distance(geom)
dist.append(d)
Para obtener el punto más cercano:
def get_closest_pnt(dist, node, how_close):
mrg = zip(dist,node)
mrg.sort(key=lambda t: t[0])
try:
return mrg[how_close]
except IndexError, ierr:
print '%s \ndist/node tuple contain %s' % (ierr,mrg)
Funciona todo bien, pero es muy lento. La creación de un índice espacial no muestran ningún efecto, de verdad. Para calcular los 100 puntos esta implementaciones de toma ~6,7 segundos. El programa debe ser capaz de calcular la ubicación más cercana para más de 2000 puntos tan rápido como sea posible. Alguna idea sobre cómo mejorar mi enfoque?
EDITAR
He probado diferentes enfoques para ver a dónde me lleva. Me encontré con algo muy sorprendente quiero compartir aquí.
He implementado un sencillo algoritmo de búsqueda como se describe aquí, y una de las soluciones que donde se sugiere (el conjunto ordenado de aproximación).
El hecho sorprendente es que el rendimiento no sólo depende de la aplicación, pero más aún de la OSX. Mi original ogr/buffer algoritmo resulta ser rápida ardiente en mi OSX que es laborioso lento en Linux (por lo tanto, la pregunta aquí).
Aquí están mis resultados (100 va).
Method | OSX | Linux Ubuntu
ogr buffer | 0:00:01.434389 | 0:01:08.384309
sub string | 0:00:19.714432 | 0:00:10.048649
sorted set | 0:00:01.239999 | 0:00:00.600773
Specs Mac OSX
Processor 4x2.5 GHz
Memory 8 GB 1600 MHz
Specs Dell Linux Ubuntu
Processor 8x3.4GHz
Memory 7.8 GB
Si alguien puede explicar el por qué de estas diferencias se producen, no lo dudes.