[Gvsig_desarrolladores] addLayer y queryByRect

Francisco José fpenarru en iver.es
Mar Ago 29 07:31:00 CEST 2006


Hola Marcos.

Yo probaría algo como lo que has hecho, pero con el paso 2:

1.- Quitar la capa de gvSIG.
2.- Cerrar la base de datos explícitamente. Puedes recuperar el objeto 
Connection que está usando la capa y cerrarlo, o, como a nosotros nos ha 
pasado en edición, hacer un rollback contra ese objeto connection. Con 
Rollback, los cursores que usa la capa se cierran, y la tabla queda 
libre para hacer lo que quieras (en tu caso, borrarla).
3.- Hacer el drop view.

Espero que te funcione, por aquí no hemos probado eso todavía.

Salu2.

PS: Lo del WHERE en mayusculas es porque en el cuadro de diálogo que 
hemos puesto donde se define la cláusula WHERE, ya convertimos a 
mayúsculas. Pero tienes razón, habría que comprobar las 2 cosas para 
evitar despistes y errores raros en el desarrollo de plugins. Tomamos nota.


marcos boullón magán escribió:
> Hola,
>
> Una pregunta sobre este código... y una pequeña corrección.
>
> Primero la corrección. Si tenemos X columnas de la tabla, una de ellas
> con la geometría, y queremos sus nombres... es correcto reservar
> "getColumnCount()-1" Strings porque sabemos que la columna de
> geometría no nos interesa; pero si no vamos a almacenar esa columna,
> el valor "fields.length" es menor que el número de columnas, y por
> tanto el bucle "for (int i=0; i<fields.length; i++) {}" nunca alcanza
> a examinar la última columna... estamos perdiendo un atributo (la
> última columna no tiene porqué ser la de geometría). Lo correcto es
> usar "fields.length+1" en el bucle (la comprobación del nombre de
> columna ya evita que se lea la columna geométrica):
>
> String[] fields = new String[rsmd.getColumnCount()-1];
> int j = 0;
> for (int i=0; i<fields.length+1; i++) {
>  if (!rsmd.getColumnName(i+1).equalsIgnoreCase(geomField)) {
>    fields[j++] = rsmd.getColumnName(i+1);
>  }
> }
>
>
> Y ahora mi pregunta. Utilizando este mismo código puedo hacer que mi
> extensión lea sin problemas una vista de mi base de datos PostGIS...
> pero como la vista fue creada sólo como cálculo intermedio, me
> gustaría que la extensión la borrara de la base de datos cuando se
> cierra. Es decir, ahora ejecuto la extensión, le pido que calcule, y
> genera en la base de datos una vista ("create view as ...") y la carga
> en la vista de gvSIG (este código). Ahora he terminado con la
> extensión, le doy al botón de salir, envía a la base de datos la
> instrucción "drop view..." con st.execute() y... se queda esperando
> para siempre a que termine esa instrucción. Es un conflicto de acceso
> concurrente: la extensión envía un "drop view", pero gvSIG está
> todavía conectado a la base de datos mostrando la vista. Todo se
> detiene.
>
> Sin embargo he intentado descargar primero la capa asociada a esa
> vista sql y consigo que desaparezca de la vista activa en gvSIG...
> pero sigue bloqueándose al enviar el "drop view":
> FLayers ls = vista.getMapControl().getMapContext().getLayers();
> ls.removeLayer(titulo_capa);
>
> ¿Qué me queda? ¿Qué tengo que hacer para liberar mi vista sql cautiva
> de gvSIG y poder borrarla de la base de datos? Agradezco cualquier
> consejo.
>
> M.
>
>
> PD: Sí, se hace un poco complicado el distinguir cuando hablo de vista
> SQL (create view...) y vista de gvSIG (com.iver.cit.gvsig.gui.View).
>
>
> 2006/8/23, Francisco José <fpenarru en iver.es>:
>> Hola Marcos.
>>
>> Este es un ejemplo en el que se carga una capa de PostGIS por código:
>>
>>         try {
>>             conn = DriverManager.getConnection(dbURL, user, pwd);
>>             conn.setAutoCommit(false);
>>
>>             String fidField = "gid"; // BE CAREFUL => MAY BE NOT!!!
>>             String geomField = "the_geom"; // BE CAREFUL => MAY BE
>> NOT!!! => You should read table GEOMETRY_COLUMNS.
>>                                             // See PostGIS help.
>>
>>             // To obtain the fields, make a connection and get them.
>>             Statement st = conn.createStatement();
>>             ResultSet rs = st.executeQuery("select * from " + tableName
>> + " LIMIT 1");
>>             ResultSetMetaData rsmd = rs.getMetaData();
>>             String[] fields = new String[rsmd.getColumnCount()-1]; // We
>> don't want to include the_geom field
>>             int j = 0;
>>             for (int i = 0; i < fields.length; i++) {
>>                 if 
>> (!rsmd.getColumnName(i+1).equalsIgnoreCase(geomField))
>>                 {
>>                     fields[j++] = rsmd.getColumnName(i+1);
>>
>>                 }
>>             }
>>             rs.close();
>>
>>             /* String[] fields = new String[1];
>>             fields[0] = "gid"; */
>>
>>             String whereClause = "";
>>
>>             VectorialJDBCDriver driver = (VectorialJDBCDriver)
>> LayerFactory.getDM()
>>                         .getDriver("PostGIS JDBC Driver");
>>
>>             // Here you can set the workingArea
>>             // 
>> driver.setWorkingArea(dbLayerDefinition.getWorkingArea());
>>
>>
>>             String strEPSG = mapCtrl.getViewPort()
>>                         .getProjection().getAbrev()
>>                         .substring(5);
>>             DBLayerDefinition lyrDef = new
>> DBLayerDefinition();
>>             lyrDef.setName(layerName);
>>             lyrDef.setTableName(tableName);
>>             lyrDef.setWhereClause(whereClause);
>>             lyrDef.setFieldNames(fields);
>>             lyrDef.setFieldGeometry(geomField);
>>             lyrDef.setFieldID(fidField);
>>             // if (dbLayerDefinition.getWorkingArea() != null)
>>             //
>> lyrDef.setWorkingArea(dbLayerDefinition.getWorkingArea());
>>
>>             lyrDef.setSRID_EPSG(strEPSG);
>>             if (driver instanceof ICanReproject)
>>             {
>>                 ((ICanReproject)driver).setDestProjection(strEPSG);
>>             }
>>             driver.setData(conn, lyrDef);
>>             IProjection proj = null;
>>             if (driver instanceof ICanReproject)
>>             {
>>                 proj = ProjectionPool.get("EPSG:" +
>> ((ICanReproject)driver).getSourceProjection());
>>             }
>>
>>             FLayer lyr = LayerFactory.createDBLayer(driver, layerName,
>> proj);
>>
>>             if (lyr != null) {
>>                 lyr.setVisible(true);
>>                 v.getMapControl().getMapContext().beginAtomicEvent();
>>                 // You shoud checkProjection to see if it is necesary to
>> reproject
>>                 checkProjection(lyr, v.getMapControl().getViewPort());
>>                 v.getMapControl().getMapContext().getLayers()
>>                        .addLayer(lyr);
>>                 v.getMapControl().getMapContext().endAtomicEvent();
>>
>>             }
>>         } catch (SQLException e) {
>>             // TODO Auto-generated catch block
>>             e.printStackTrace();
>>         }
>>
>> Me faltaría ver tu función getQueryLayer(), pero por correos anteriores,
>> me inclino a pensar que estás trabajando sin una proyección definida
>> (-1) en el SRID de tu tabla PostGIS.
>> Esta situación está muy poco probada en gvSIG (de hecho es uno de los
>> casos pendientes de revistar estos días). Quizás sea eso.
>>
>> De todas formas, un consejo. Por tu traza, da la sensación de que no
>> tienes configurado del todo el entorno de Eclipse para debuggear. Te
>> aconsejo que arranques la aplicación en modo debug y pongas un punto de
>> ruptura en la parte que te da problemas para ejecutar paso a paso e
>> inspeccionar variables. Te ahorrarás mucho tiempo.
>> El punto de ruptura yo lo pondría en la clase
>> com.iver.cit.gvsig.fmap.operations.DBStrategy, en la función queryByRect
>> (línea 276, o cerca).
>>
>> Saludos, y ya nos contarás.
>>
>> PS: Queremos que la parte PostGIS sea de las partes más robustas de
>> gvSIG. Nos viene bien todas estas pruebas, así que no te preocupes por
>> preguntar.
>>
>>
>> marcos boullón magán escribió:
>> > Hola,
>> >
>> > De verdad que lamento dar tanto la lata, pero es que a veces me
>> > bloqueo con tonterías terriblemente simples y no veo la diferencia
>> > entre mi código y el de las extensiones que sí funcionan.
>> >
>> > Mi pregunta es "¿Qué pasos necesito dar para que una capa que mi
>> > extensión carga desde una base de datos en la vista activa actual esté
>> > disponible para ser consultada con las otras herramients del GIS?".
>> >
>> > Porque ahora mismo he creado una extensión...
>> > "public class QueryEspazosExtension extends Extension {"
>> >
>> > ... que crea un panel gráfico donde se puede lanzar una consulta 
>> SQL...
>> > "public class QueryEspazosSelectionPanel extends JPanel implements
>> > View, ViewListener, SingletonView {
>> >  [...]
>> >  jButton0.addActionListener(new java.awt.event.ActionListener() {
>> >    public void actionPerformed(java.awt.event.ActionEvent e) {
>> >      lyr = (FLyrVect) getQueryLayer();
>> >      lyr.setVisible(true);
>> >      miMapControl.getMapContext().beginAtomicEvent();
>> >      miMapControl.getMapContext().getLayers().addLayer(lyr);
>> >      miMapControl.getMapContext().endAtomicEvent();
>> >    }
>> >  });"
>> >
>> > ... (en una tabla temporal) y la carga como capa...
>> > "public FLayer getQueryLayer() {
>> >  [...]
>> >  return (FLyrVect) LayerFactory.createDBLayer(driver, "resultado",
>> > proj);"
>> >
>> > Y puedo ver que la capa se introduce en la vista activa. Y puedo
>> > cerrar el panel gráfico e incluso terminar la extensión y la capa
>> > sigue en la vista activa... ¡¡Pero cada vez que intento seleccionar
>> > sus elementos o acceder a los datos o algo (antes o después de cerrar
>> > el panel) obtengo un java.lang.NullPointerException en
>> > com.iver.cit.gvsig.fmap.[...].queryByRect!!
>> >
>> > Es como si me faltara algún paso a la hora de introducir la nueva capa
>> > en la vista (permanentemente), de manera que la conexión quede
>> > registrada en alguna lista de conexiones de la vista y pueda ser
>> > reconsultada en cualquier momento. O como si uno de los objetos
>> > necesarios (¿tal vez un Connection o DBLayerDefinition o driver...?)
>> > hubiera terminado y sido liberado (sin embargo he puesto todas las
>> > variables importantes en la clase QueryEspazosExtension para no
>> > liberarlas por error antes de salir, y nada).
>> >
>> > ¿Se os ocurre qué puede ser? No veo nada distinto de otras
>> > extensiones. Por si ayuda, el trazado de errores cuando intento
>> > seleccionar por rectángulo algo de mi capa es...
>> >
>> > Layer resultado 208 milisecs.
>> > Tiempo de dibujado:562 mseg. Memoria libre:4962 KB
>> > DEBUG [AWT-EventQueue-1] (?:?) - Memoria total: 8053120
>> > DEBUG [AWT-EventQueue-1] (?:?) - View Vista : Sin título - 0 activated
>> > (callViewActivated)
>> > DEBUG [AWT-EventQueue-1] (?:?) - Memoria total: 8466288
>> > DEBUG [AWT-EventQueue-1] (?:?) - Ejecutando comando: SELRECT
>> > DEBUG [AWT-EventQueue-1] (?:?) - Comand : SELRECT
>> > DEBUG [AWT-EventQueue-1] (?:?) - Memoria total: 8914144
>> > DEBUG [AWT-EventQueue-1] (?:?) - Memoria total: 8963568
>> > INFO [Thread-8] (?:?) - datasource closed
>> > DEBUG [AWT-EventQueue-1] (?:?) - java.lang.NullPointerException
>> > java.lang.NullPointerException
>> >        at
>> > 
>> com.iver.cit.gvsig.fmap.operations.strategies.DBStrategy.queryByRect(Unknown 
>>
>> >
>> > Source)
>> >        at
>> > 
>> com.iver.cit.gvsig.fmap.operations.strategies.DefaultStrategy.queryByRect(Unknown 
>>
>> >
>> > Source)
>> >        at com.iver.cit.gvsig.fmap.layers.FLyrVect.queryByRect(Unknown
>> > Source)
>> >        at
>> > 
>> com.iver.cit.gvsig.fmap.tools.RectangleSelectionListener.rectangle(Unknown 
>>
>> >
>> > Source)
>> >        at
>> > 
>> com.iver.cit.gvsig.gui.toolListeners.RectangleSelectListener.rectangle(Unknown 
>>
>> >
>> > Source)
>> >        at
>> > 
>> com.iver.cit.gvsig.fmap.tools.Behavior.RectangleBehavior.mouseReleased(Unknown 
>>
>> >
>> > Source)
>> >        at
>> > com.iver.cit.gvsig.fmap.tools.CompoundBehavior.mouseReleased(Unknown
>> > Source)
>> >        at
>> > 
>> com.iver.cit.gvsig.fmap.MapControl$MapToolListener.mouseReleased(Unknown
>> > Source)
>> >        at java.awt.Component.processMouseEvent(Component.java:5100)
>> >        at java.awt.Component.processEvent(Component.java:4897)
>> >        at java.awt.Container.processEvent(Container.java:1569)
>> >        at java.awt.Component.dispatchEventImpl(Component.java:3615)
>> >        at java.awt.Container.dispatchEventImpl(Container.java:1627)
>> >        at java.awt.Component.dispatchEvent(Component.java:3477)
>> >        at
>> > java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:3483)
>> >        at
>> > java.awt.LightweightDispatcher.processMouseEvent(Container.java:3198)
>> >        at
>> > java.awt.LightweightDispatcher.dispatchEvent(Container.java:3128)
>> >        at java.awt.Container.dispatchEventImpl(Container.java:1613)
>> >        at java.awt.Window.dispatchEventImpl(Window.java:1606)
>> >        at java.awt.Component.dispatchEvent(Component.java:3477)
>> >        at java.awt.EventQueue.dispatchEvent(EventQueue.java:480)
>> >        at com.iver.andami.ui.AndamiEventQueue.dispatchEvent(Unknown
>> > Source)
>> >        at
>> > 
>> java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:201) 
>>
>> >
>> >        at
>> > 
>> java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151) 
>>
>> >
>> >        at
>> > java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:145)
>> >        at
>> > java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:137)
>> >        at 
>> java.awt.EventDispatchThread.run(EventDispatchThread.java:100)
>> >
>> > Gracias por adelantado,
>> >
>> > Marcos
>> >
>>
>>
>> -- 
>> Francisco José Peñarrubia
>> Equipo gvSIG
>>
>> IVER T.I. S.A.
>> c/Salamanca 50
>> 46005 Valencia
>> Spain
>>
>>
>> _______________________________________________
>> gvSIG_desarrolladores mailing list
>> gvSIG_desarrolladores en runas.cap.gva.es
>> http://runas.cap.gva.es/mailman/listinfo/gvsig_desarrolladores
>>
>


-- 
Francisco José Peñarrubia
Equipo gvSIG

IVER T.I. S.A.
c/Salamanca 50
46005 Valencia
Spain




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