[Gvsig_desarrolladores] addLayer y queryByRect

Francisco José fpenarru en iver.es
Mie Ago 23 08:26:44 CEST 2006


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




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