[Gvsig_desarrolladores] addLayer y queryByRect

marcos boullón magán marcosboullon en gmail.com
Vie Ago 25 22:21:40 CEST 2006


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
>

-- 
-- marcos boullón magán



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