Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / layers / FLyrVect.java @ 2629

History | View | Annotate | Download (17.9 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package com.iver.cit.gvsig.fmap.layers;
42

    
43
import java.awt.Graphics2D;
44
import java.awt.geom.Point2D;
45
import java.awt.geom.Rectangle2D;
46
import java.awt.image.BufferedImage;
47
import java.util.ArrayList;
48
import java.util.BitSet;
49

    
50
import org.apache.log4j.Logger;
51
import org.cresques.cts.ICoordTrans;
52

    
53
import com.hardcode.driverManager.DriverLoadException;
54
import com.hardcode.gdbms.engine.data.DataSource;
55
import com.hardcode.gdbms.engine.data.NoSuchTableException;
56
import com.hardcode.gdbms.engine.instruction.FieldNotFoundException;
57
import com.hardcode.gdbms.engine.values.DoubleValue;
58
import com.hardcode.gdbms.engine.values.FloatValue;
59
import com.hardcode.gdbms.engine.values.NullValue;
60
import com.hardcode.gdbms.engine.values.Value;
61
import com.iver.cit.gvsig.fmap.DriverException;
62
import com.iver.cit.gvsig.fmap.ViewPort;
63
import com.iver.cit.gvsig.fmap.core.IGeometry;
64
import com.iver.cit.gvsig.fmap.core.v02.FLabel;
65
import com.iver.cit.gvsig.fmap.core.v02.FSymbol;
66
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes;
67
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
68
import com.iver.cit.gvsig.fmap.layers.layerOperations.AlphanumericData;
69
import com.iver.cit.gvsig.fmap.layers.layerOperations.ClassifiableVectorial;
70
import com.iver.cit.gvsig.fmap.layers.layerOperations.Labelable;
71
import com.iver.cit.gvsig.fmap.layers.layerOperations.RandomVectorialData;
72
import com.iver.cit.gvsig.fmap.layers.layerOperations.Selectable;
73
import com.iver.cit.gvsig.fmap.layers.layerOperations.SingleLayer;
74
import com.iver.cit.gvsig.fmap.layers.layerOperations.VectorialData;
75
import com.iver.cit.gvsig.fmap.operations.Cancellable;
76
import com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor;
77
import com.iver.cit.gvsig.fmap.operations.strategies.Strategy;
78
import com.iver.cit.gvsig.fmap.operations.strategies.StrategyManager;
79
import com.iver.cit.gvsig.fmap.operations.strategies.VisitException;
80
import com.iver.cit.gvsig.fmap.rendering.Legend;
81
import com.iver.cit.gvsig.fmap.rendering.LegendChangedEvent;
82
import com.iver.cit.gvsig.fmap.rendering.LegendFactory;
83
import com.iver.cit.gvsig.fmap.rendering.VectorialLegend;
84
import com.iver.utiles.XMLEntity;
85

    
86

    
87
/**
88
 * Capa b?sica Vectorial.
89
 *
90
 * @author Fernando Gonz?lez Cort?s
91
 */
92

    
93
//TODO Cuando no sea para pruebas debe no ser public
94
public class FLyrVect extends FLyrDefault implements Labelable, Selectable,
95
        AlphanumericData, ClassifiableVectorial, SingleLayer, VectorialData,
96
        RandomVectorialData {
97
        private static Logger logger = Logger.getLogger(FLyrVect.class.getName());
98

    
99
        /** Leyenda de la capa vectorial */
100
        private VectorialLegend legend;
101
        private int typeShape = -1;
102
        private SelectionSupport selectionSupport = new SelectionSupport();
103
        private LayerChangeSupport layerChangeSupport = new LayerChangeSupport();
104
        private VectorialAdapter source;
105
        private SelectableDataSource sds;
106

    
107
        /**
108
         * A?ade un SelectionListener a la lista de listeners.
109
         *
110
         * @param listener SelectionListener.
111
         */
112
        public void addSelectionListener(SelectionListener listener) {
113
                selectionSupport.addSelectionListener(listener);
114
        }
115

    
116
        /**
117
         * Borra un selectionListener de la lista de listeners.
118
         *
119
         * @param listener SelectionListener
120
         */
121
        public void removeSelectionListener(SelectionListener listener) {
122
                selectionSupport.removeSelectionListener(listener);
123
        }
124

    
125
        /**
126
         * Cuando ocurre un evento de cambio en la selecci?n, ?ste puede ser uno de
127
         * una gran cantidad de eventos. Con el fin de no propagar todos estos
128
         * eventos, se realiza la propagaci?n de manera manual al final de la
129
         * "r?faga" de eventos
130
         */
131
        public void fireSelectionEvents() {
132
                selectionSupport.fireSelectionEvents();
133
        }
134

    
135
        /**
136
         * Devuelve el VectorialAdapater de la capa.
137
         *
138
         * @return VectorialAdapter.
139
         */
140
        public VectorialAdapter getSource() {
141
                return source;
142
        }
143

    
144
        /**
145
         * Inserta el VectorialAdapter a la capa.
146
         *
147
         * @param va VectorialAdapter.
148
         */
149
        public void setSource(VectorialAdapter va) {
150
                source = va;
151
        }
152

    
153
        /**
154
         * @see com.iver.cit.gvsig.fmap.layers.LayerOperations#getFullExtent()
155
         */
156
        public Rectangle2D getFullExtent() throws DriverException {
157
                try {
158
                        Rectangle2D rAux;
159
                        logger.debug("source.start()");
160
                        source.start();
161
                        rAux = source.getFullExtent();
162
                        logger.debug("source.stop()");
163
                        source.stop();
164

    
165
                        // Si existe reproyecci?n, reproyectar el extent
166
                        ICoordTrans ct = getCoordTrans();
167

    
168
                        if (ct != null) {
169
                                Point2D pt1 = new Point2D.Double(rAux.getMinX(), rAux.getMinY());
170
                                Point2D pt2 = new Point2D.Double(rAux.getMaxX(), rAux.getMaxY());
171
                                pt1 = ct.convert(pt1, null);
172
                                pt2 = ct.convert(pt2, null);
173
                                rAux = new Rectangle2D.Double();
174
                                rAux.setFrameFromDiagonal(pt1, pt2);
175
                        }
176

    
177
                        return rAux;
178
                } catch (DriverIOException e) {
179
                        throw new DriverException(e);
180
                }
181
        }
182

    
183
        /**
184
         * @see com.iver.cit.gvsig.fmap.layers.LayerOperations#draw(java.awt.image.BufferedImage,
185
         *                 java.awt.Graphics2D, com.iver.cit.gvsig.fmap.ViewPort)
186
         */
187
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
188
                Cancellable cancel,double scale) throws DriverException {
189
            
190
                if (isWithinScale(scale)){        
191
            
192
                Strategy strategy = StrategyManager.getStrategy(this);
193

    
194
                strategy.draw(image, g, viewPort, cancel);
195

    
196
                if (getVirtualLayers() != null) {
197
                        getVirtualLayers().draw(image, g, viewPort, cancel,scale);
198
                }
199

    
200
                if (getLayerText() != null) {
201
                        getLayerText().draw(image, g, viewPort, cancel,scale);
202
                }
203
                }
204
        }
205

    
206
        /**
207
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#print(java.awt.Graphics2D,
208
         *                 com.iver.cit.gvsig.fmap.ViewPort,
209
         *                 com.iver.cit.gvsig.fmap.operations.Cancellable)
210
         */
211
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel,double scale)
212
                throws DriverException {
213
                if (isVisible() && isWithinScale(scale)){        
214
                Strategy strategy = StrategyManager.getStrategy(this);
215

    
216
                strategy.print(g, viewPort, cancel);
217

    
218
                if (getLayerText() != null) {
219
                        getLayerText().draw(null, g, viewPort, cancel,scale);
220
                }
221
                }
222
        }
223

    
224
        /**
225
         * @see com.iver.cit.gvsig.fmap.layers.VectorialOperations#createLabelLayer(int)
226
         */
227
        // public FLayer createLabelLayer(int fieldId) {
228
    public FLayer createLabelLayer(SelectableDataSource ds) {
229
                ArrayList labels = new ArrayList();
230

    
231
                try {
232
                        VectorialAdapter adapter = getSource();
233
                        logger.debug("adapter.start()");
234
                        adapter.start();
235
                        ds.start();
236

    
237
                        //VectorialDriver driver = (VectorialDriver) adapter.getDriver();
238
            long sc;
239

    
240
            sc = ds.getRowCount();
241
            
242
            int fieldId = ds.getFieldIndexByName(legend.getLabelField());
243

    
244
            DriverAttributes attr = adapter.getDriverAttributes();
245
            boolean bMustClone = false;
246
            if (attr != null)
247
            {
248
                if (attr.isLoadedInMemory())
249
                {
250
                    bMustClone = attr.isLoadedInMemory();               
251
                }
252
            }
253
            ICoordTrans ct = getCoordTrans();
254
            
255
                        VectorialLegend l = (VectorialLegend) getLegend();
256
                        int idFieldHeightText = -1;
257
                        int idFieldRotationText = -1;
258
                        
259

    
260
                        if (l.getLabelHeightField() != null) {
261
                                l.setBWithHeightText(true);
262
                                idFieldHeightText = ds.getFieldIndexByName(l.getLabelHeightField());
263
                        }else{
264
                                l.setBWithHeightText(false);
265
                        }
266

    
267
                        boolean bWithRotationText = false;
268

    
269
                        if (l.getLabelRotationField() != null) {
270
                                bWithRotationText = true;
271
                                idFieldRotationText = ds.getFieldIndexByName(l.getLabelRotationField());
272
                        }
273

    
274
                        for (int i = 0; i < sc; i++) {
275
                                Value val = ds.getFieldValue(i, fieldId);
276

    
277
                                if ((val instanceof NullValue) || (val == null)) {
278
                                        continue;
279
                                }
280

    
281
                                IGeometry geom = adapter.getShape(i);
282

    
283
                                if (geom == null) {
284
                                        continue;
285
                                }
286
                if (ct != null) {
287
                    if (bMustClone)
288
                        geom = geom.cloneGeometry();
289
                    geom.reProject(ct);
290
                }
291

    
292
                                FSymbol symbol = l.getSymbol(i);
293

    
294
                                // TODO: El m?todo contenedor (createLabelLayer) debe recoger
295
                                // los par?metros de posicionamiento y de allowDuplicates
296
                                // if (i >= 328)
297
                                //         System.out.println("i= " + i + " " + val.toString());
298
                                FLabel[] lbls = geom.createLabels(0, true);
299

    
300
                                for (int j = 0; j < lbls.length; j++) {
301
                                        if (lbls[j] != null) {
302
                                                lbls[j].setString(val.toString());
303

    
304
                                                if (l.isBWithHeightText()) {
305
                                                        FloatValue height = (FloatValue) ds.getFieldValue(i,
306
                                                                        idFieldHeightText);
307
                                                        lbls[j].setHeight(height.getValue());
308
                                                } else {
309
                                                        if (symbol!=null)
310
                                                        lbls[j].setHeight(symbol.getFontSize());
311
                                                }
312

    
313
                                                if (bWithRotationText) {
314
                                                        DoubleValue rotation = (DoubleValue) ds.getFieldValue(i,
315
                                                                        idFieldRotationText);
316
                                                        lbls[j].setRotation(rotation.getValue());
317
                                                }
318
                                                labels.add(lbls[j]);        
319
                                        }
320

    
321
                                        
322
                                }
323
                        }
324

    
325
                        //long t2 = System.currentTimeMillis();
326
                        logger.debug("adapter.stop()");
327
                        ds.stop();
328
                        adapter.stop();
329
                } catch (DriverIOException e) {
330
                        e.printStackTrace();
331
                } catch (DriverException e) {
332
                        e.printStackTrace();
333
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
334
                        // TODO Auto-generated catch block
335
                        e.printStackTrace();
336
                }
337

    
338
                FLyrText layerText = new FLyrText(labels);
339

    
340
                try {
341
                        layerText.setLegend((VectorialLegend) getLegend());
342
                } catch (FieldNotFoundException e1) {
343
                        // TODO Auto-generated catch block
344
                        e1.printStackTrace();
345
                } catch (DriverException e1) {
346
                        // TODO Auto-generated catch block
347
                        e1.printStackTrace();
348
                }
349

    
350
                setLayerText(layerText);
351

    
352
                return layerText;
353
        }
354

    
355
        /**
356
         * @see com.iver.cit.gvsig.fmap.layers.VectorialOperations#removeLabels()
357
         */
358
        public void removeLabels() {
359
                setLayerText(null);
360
        }
361

    
362
        /**
363
         * @see com.iver.cit.gvsig.fmap.layers.VectorialOperations#createIndex()
364
         */
365
        public void createIndex() {
366
        }
367

    
368
        /**
369
         * @see com.iver.cit.gvsig.fmap.layers.VectorialOperations#process(com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor,
370
         *                 com.iver.cit.gvsig.fmap.operations.selection.VectorialSubSet)
371
         */
372
        public void process(FeatureVisitor visitor, BitSet subset)
373
                throws DriverException, VisitException {
374
                Strategy s = StrategyManager.getStrategy(this);
375
                s.process(visitor, subset);
376
        }
377

    
378
        /**
379
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.VectorialData#process(com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor)
380
         */
381
        public void process(FeatureVisitor visitor)
382
                throws DriverException, VisitException {
383
                Strategy s = StrategyManager.getStrategy(this);
384
                s.process(visitor);
385
        }
386

    
387
        /**
388
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#setSelection(com.iver.cit.gvsig.fmap.operations.selection.VectorialSubSet)
389
         */
390
        public void setSelection(FBitSet selection) {
391
                selectionSupport.setSelection(selection);
392
                fireSelectionEvents();
393
        }
394

    
395
        /**
396
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#isSelected(int)
397
         */
398
        public boolean isSelected(int index) {
399
                return selectionSupport.isSelected(index);
400
        }
401

    
402
        /**
403
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#getSelection()
404
         */
405
        public FBitSet getSelection() {
406
                return selectionSupport.getSelection();
407
        }
408

    
409
        /**
410
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#clearSelection()
411
         */
412
        public void clearSelection() {
413
                selectionSupport.clearSelection();
414
        }
415

    
416
        /**
417
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#queryByRect(java.awt.geom.Rectangle2D)
418
         */
419
        public BitSet queryByRect(Rectangle2D rect) throws DriverException {
420
                Strategy s = StrategyManager.getStrategy(this);
421

    
422
                return s.queryByRect(rect);
423
        }
424

    
425
        /**
426
         * @throws DriverException
427
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#getRecordset()
428
         */
429
        public SelectableDataSource getRecordset() throws DriverException {
430
                if (sds == null){
431
                        try {
432
                                DataSource ds = source.getRecordset();
433

    
434
                                if (ds == null) {
435
                                        return null;
436
                                }
437

    
438
                                sds = new SelectableDataSource(ds);
439
                                sds.setSelectionSupport(selectionSupport);
440
                                
441
                                return sds;
442
                        } catch (DriverLoadException e) {
443
                                throw new DriverException(e);
444
                        } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
445
                                throw new DriverException(e);
446
            }
447
                }
448
                return sds;
449
        }
450
    
451
    /**
452
     * Para cuando haces una uni?n, sustituyes el recorset por el nuevo.
453
     * De esta forma, podr?s poner leyendas basadas en el nuevo
454
     * recordset
455
     * @param newSds
456
     */
457
    public void setRecordset(SelectableDataSource newSds)
458
    {
459
        sds = newSds;
460
        sds.setSelectionSupport(selectionSupport);
461
    }
462

    
463
        /**
464
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#setLegend(int,
465
         *                 com.iver.cit.gvsig.fmap.rendering.Legend)
466
         */
467
        public void setLegend(VectorialLegend r)
468
                throws DriverException, FieldNotFoundException {
469
                VectorialLegend oldLegend = legend;
470
                legend = r;
471

    
472
                try {
473
                        legend.setDataSource(getRecordset());
474

    
475
                        if (legend.getLabelField() != null) {
476
                            // sds.start();
477
                                // int idLabelField = getRecordset().getFieldIndexByName(legend.getLabelField());
478
                                createLabelLayer(sds);
479
                                // sds.stop();
480
                        }
481
                        else
482
                            removeLabels();
483
                } catch (DriverException e) {
484
                        throw new DriverException(e);
485
                } catch (FieldNotFoundException e) {
486
                        // TODO Auto-generated catch block
487
                        e.printStackTrace();
488
        }
489

    
490
                LegendChangedEvent e = LegendChangedEvent.createLegendChangedEvent(oldLegend, legend);
491
                callLegendChanged(e);
492
        }
493

    
494
        /**
495
         * Devuelve la Leyenda de la capa.
496
         *
497
         * @return Leyenda.
498
         */
499
        public Legend getLegend() {
500
                return legend;
501
        }
502

    
503
        /**
504
         * Devuelve el tipo de shape que contiene la capa.
505
         *
506
         * @return tipo de shape.
507
         *
508
         * @throws DriverException
509
         */
510
        public int getShapeType() throws DriverException {
511
                if (typeShape == -1) {
512
                        try {
513
                                logger.debug("source.start()");
514
                                source.start();
515
                                typeShape = source.getShapeType();
516
                                logger.debug("source.stop()");
517
                                source.stop();
518
                        } catch (DriverIOException e) {
519
                                throw new DriverException(e);
520
                        }
521
                }
522

    
523
                return typeShape;
524
        }
525

    
526
        /**
527
         * @throws XMLException
528
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getProperties()
529
         */
530
        public XMLEntity getXMLEntity() throws XMLException {
531
                XMLEntity xml = super.getXMLEntity();
532
                xml.addChild(legend.getXMLEntity());
533
                xml.addChild(selectionSupport.getXMLEntity());
534

    
535
                if (source instanceof VectorialFileAdapter) {
536
                        xml.putProperty("type", "vectorial");
537
                        xml.putProperty("file", ((VectorialFileAdapter) source).getFile());
538
                        try {
539
                                xml.putProperty("recordset-name", getRecordset().getName());
540
                        } catch (DriverException e) {
541
                                throw new XMLException(e);
542
                        }
543
                } else if (source instanceof VectorialDBAdapter) {
544
                } else if (source instanceof WFSAdapter) {
545
                }
546

    
547
                xml.putProperty("driverName", getSource().getDriver().getName());
548

    
549
                return xml;
550
        }
551

    
552
        /**
553
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setXMLEntity(com.iver.utiles.XMLEntity)
554
         */
555
        public void setXMLEntity03(XMLEntity xml)
556
                throws XMLException {
557
                
558
                super.setXMLEntity(xml);
559
                legend = LegendFactory.createFromXML03(xml.getChild(0));
560

    
561
                try {
562
                        // legend.setDataSource(getRecordset());
563
                        setLegend(legend);
564
                } catch (FieldNotFoundException e) {
565
                        throw new XMLException(e);
566
                } catch (DriverException e) {
567
                        throw new XMLException(e);
568
                }        
569

    
570
                selectionSupport.setXMLEntity03(xml.getChild(1));
571
        }
572

    
573
        /**
574
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setXMLEntity(com.iver.utiles.XMLEntity)
575
         */
576
        public void setXMLEntity(XMLEntity xml)
577
                throws XMLException {
578
                
579
                super.setXMLEntity(xml);
580
                legend = LegendFactory.createFromXML(xml.getChild(0));
581

    
582
                try {
583
                        // legend.setDataSource(getRecordset());
584
                        setLegend(legend);
585
                } catch (FieldNotFoundException e) {
586
                        throw new XMLException(e);
587
                } catch (DriverException e) {
588
                        throw new XMLException(e);
589
                }        
590
                
591
                selectionSupport.setXMLEntity(xml.getChild(1));
592

    
593
                String recordsetName = xml.getStringProperty("recordset-name");
594
                try {
595
                        LayerFactory.getDataSourceFactory().changeDataSourceName(
596
                    getRecordset().getName(), recordsetName
597
                                        );
598
            //Para que vuelva a leer el DataSource y tenga el nombre coherente con la factoria
599
                        sds = null;
600
                } catch (NoSuchTableException e1) {
601
                        throw new XMLException(e1);
602
                } catch (DriverException e1) {
603
                        throw new XMLException(e1);
604
                }
605
        }
606

    
607
        /**
608
         * A?ade un LegendListener a la lista de Listeners.
609
         *
610
         * @param listener LegendListener.
611
         */
612
        public void addLegendListener(LegendListener listener) {
613
                layerChangeSupport.addLayerListener(listener);
614
        }
615

    
616
        /**
617
         * Llamada al m?todo callLegendChanged de los listener.
618
         *
619
         * @param e Evento.
620
         */
621
        private void callLegendChanged(LegendChangedEvent e) {
622
                layerChangeSupport.callLegendChanged(e);
623
        }
624

    
625
        /**
626
         * Borra un LegendListener de la lista de Listeners
627
         *
628
         * @param listener LegendListener.
629
         */
630
        public void removeLegendListener(LegendListener listener) {
631
                layerChangeSupport.removeLayerListener(listener);
632
        }
633

    
634
        /**
635
         * Sobreimplementaci?n del m?todo toString para que las bases de datos
636
         * identifiquen la capa.
637
         *
638
         * @return DOCUMENT ME!
639
         */
640
        public String toString() {
641
                /*
642
                 * Se usa internamente para que la parte de datos
643
                 * identifique de forma un?voca las tablas
644
                 */
645
                String ret = super.toString();
646

    
647
                return "layer" + ret.substring(ret.indexOf('@') + 1);
648
        }
649
}