[Gvsig_desarrolladores] Optimización de consultas geográficas - Email found in subject

Juan Lucas Dominguez Rubio jldominguez en prodevelop.es
Jue Mar 4 18:52:57 CET 2010


Hola, la primera idea que me viene a la cabeza es:
 
- calcula el bounding box de G, llamémosle B
- haz la misma llamada que se haría en gvSIG si tuviera que pintarse una capa basada en esa tabla de Oracle para una vista cuya extensión fuese B.
- Acumula las geometrías obtenidas en un array y comprueba para cada una si efectivamente contiene a G o no (es decir, refina el resultado)
 
Si has instanciado un capa basada en Oracle Spatial y le pides una geometría concreta, efectivamente, se hará una petición a la BD por cada llamada.
 
Saludos, 
 
Juan Lucas Domínguez Rubio
---
Prodevelop SL, Valencia (España)
Tlf.: 96.351.06.12 -- Fax: 96.351.09.68
http://www.prodevelop.es <http://www.prodevelop.es/> 
---

________________________________

De: gvsig_desarrolladores-bounces en listserv.gva.es en nombre de Antonio Grassi
Enviado el: jue 28/01/2010 15:12
Para: gvsig_desarrolladores en listserv.gva.es
Asunto: [Gvsig_desarrolladores] Optimización de consultas geográficas - Email found in subject


Buenos días miembros de la lista! 

Estoy teniendo problemas con la rapidez de ciertas consultas geográficas. Supongo que tiene que haber formas más eficientes de realizarlas. El escenario es el siguiente:

Estoy desarrollando sobre la versión 1.9 estable. Tengo una capa POLIGONOS en una base de datos Oracle. Me interesa, para una geometría G, saber dentro de que polígonos se encuentra dicha geometría. El código que utilizo para esto es el siguiente:

FLyrVect poligonos = ...
IGeometry g = ...

FBitSet resultado = poligonos.queryByShape(g, QueryByGeometryVisitor.WITHIN);

for (int i = resultado.nextSetBit(0); i >= 0; i = resultado.nextSetBit(i + 1))
{
    IFeature p = poligonos.getSource().getFeature(i);
}

El código produce el resultado esperado, pero demora cantidades enormes de tiempo en ejecutarse para capas muy pequeñas. La capa POLIGONOS está adecuadamente definida en la base, y cuenta con índice geométrico.

Estuve investigando un poco el tema. Esperaba que la invocación a queryByShape terminara implementándose mediante una consulta SQL sobre la tabla POLIGONOS utilizando como filtro un predicado geométrico que relacionase la columna GEOM con la geometría dada como parámetro, mediante la condición WITHIN, algo como lo siguiente (no recuerdo la especificación de las funciones SDO, es solo a modo de ejemplo):

select * from POLIGONOS where SDO_WITHIN(SDO_GEOMETRY(...), GEOM);

Depurando un poco el código, creo que en realidad se recorre la capa mediante un patrón VISITOR en donde se van obteniendo todos los features y realizando la relación geométrica en el cliente.

Por otro lado, la obtención de un feature de la capa (por ej., mediante poligonos.getSource().getFeature(i)) toma bastante tiempo, por lo que supongo que se realiza una consulta a la base por cada invocación.

Mis preguntas son entonces:

1) Es correcto el código que utilizo para realizar la consulta geográfica?
2) Existe alguna manera de hacer una consulta geográfica sobre la capa utilizando las funcionalidades geométricas de la base (como describía más arriba, y sin realizar una consulta SQL escrita a mano sobre la conexión JDBC, obviamente)?
3) Con respecto al método getFeature(), es correcta mi suposición de que se hace una consulta a la base por cada invocación? Existe alguna manera de optimizar esta operación?

Desde ya muchísimas gracias,
Antonio Grassi
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: http://listserv.gva.es/pipermail/gvsig_desarrolladores/attachments/20100304/3c9b83b8/attachment.htm 


Más información sobre la lista de distribución gvSIG_desarrolladores