Statistics
| Revision:

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

History | View | Annotate | Download (17.5 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
                ArrayList labels = new ArrayList();
229

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

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

    
240
                        sc = adapter.getShapeCount();
241

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

    
258
                        if (l.getLabelHeightField() != null) {
259
                                bWithHeightText = true;
260
                                idFieldHeightText = ds.getFieldIndexByName(l.getLabelHeightField());
261
                        }
262

    
263
                        boolean bWithRotationText = false;
264

    
265
                        if (l.getLabelRotationField() != null) {
266
                                bWithRotationText = true;
267
                                idFieldRotationText = ds.getFieldIndexByName(l.getLabelRotationField());
268
                        }
269

    
270
                        for (int i = 0; i < sc; i++) {
271
                                Value val = ds.getFieldValue(i, fieldId);
272

    
273
                                if ((val instanceof NullValue) || (val == null)) {
274
                                        continue;
275
                                }
276

    
277
                                IGeometry geom = adapter.getShape(i);
278

    
279
                                if (geom == null) {
280
                                        continue;
281
                                }
282
                if (ct != null) {
283
                    if (bMustClone)
284
                        geom = geom.cloneGeometry();
285
                    geom.reProject(ct);
286
                }
287

    
288
                                FSymbol symbol = l.getSymbol(i);
289

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

    
296
                                for (int j = 0; j < lbls.length; j++) {
297
                                        if (lbls[j] != null) {
298
                                                lbls[j].setString(val.toString());
299

    
300
                                                if (bWithHeightText) {
301
                                                        FloatValue height = (FloatValue) ds.getFieldValue(i,
302
                                                                        idFieldHeightText);
303
                                                        lbls[j].setHeight(height.getValue());
304
                                                } else {
305
                                                        if (symbol!=null)
306
                                                        lbls[j].setHeight(symbol.getFontSize());
307
                                                }
308

    
309
                                                if (bWithRotationText) {
310
                                                        DoubleValue rotation = (DoubleValue) ds.getFieldValue(i,
311
                                                                        idFieldRotationText);
312
                                                        lbls[j].setRotation(rotation.getValue());
313
                                                }
314
                                                labels.add(lbls[j]);        
315
                                        }
316

    
317
                                        
318
                                }
319
                        }
320

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

    
334
                FLyrText layerText = new FLyrText(labels);
335

    
336
                try {
337
                        layerText.setLegend((VectorialLegend) getLegend());
338
                } catch (FieldNotFoundException e1) {
339
                        // TODO Auto-generated catch block
340
                        e1.printStackTrace();
341
                } catch (DriverException e1) {
342
                        // TODO Auto-generated catch block
343
                        e1.printStackTrace();
344
                }
345

    
346
                setLayerText(layerText);
347

    
348
                return layerText;
349
        }
350

    
351
        /**
352
         * @see com.iver.cit.gvsig.fmap.layers.VectorialOperations#removeLabels()
353
         */
354
        public void removeLabels() {
355
                setLayerText(null);
356
        }
357

    
358
        /**
359
         * @see com.iver.cit.gvsig.fmap.layers.VectorialOperations#createIndex()
360
         */
361
        public void createIndex() {
362
        }
363

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

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

    
383
        /**
384
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#setSelection(com.iver.cit.gvsig.fmap.operations.selection.VectorialSubSet)
385
         */
386
        public void setSelection(FBitSet selection) {
387
                selectionSupport.setSelection(selection);
388
                fireSelectionEvents();
389
        }
390

    
391
        /**
392
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#isSelected(int)
393
         */
394
        public boolean isSelected(int index) {
395
                return selectionSupport.isSelected(index);
396
        }
397

    
398
        /**
399
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#getSelection()
400
         */
401
        public FBitSet getSelection() {
402
                return selectionSupport.getSelection();
403
        }
404

    
405
        /**
406
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#clearSelection()
407
         */
408
        public void clearSelection() {
409
                selectionSupport.clearSelection();
410
        }
411

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

    
418
                return s.queryByRect(rect);
419
        }
420

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

    
430
                                if (ds == null) {
431
                                        return null;
432
                                }
433

    
434
                                sds = new SelectableDataSource(ds);
435
                                sds.setSelectionSupport(selectionSupport);
436
                                
437
                                return sds;
438
                        } catch (DriverLoadException e) {
439
                                throw new DriverException(e);
440
                        } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
441
                                throw new DriverException(e);
442
            }
443
                }
444
                return sds;
445
        }
446

    
447
        /**
448
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#setLegend(int,
449
         *                 com.iver.cit.gvsig.fmap.rendering.Legend)
450
         */
451
        public void setLegend(VectorialLegend r)
452
                throws DriverException, FieldNotFoundException {
453
                VectorialLegend oldLegend = legend;
454
                legend = r;
455

    
456
                try {
457
                        legend.setDataSource(getRecordset());
458

    
459
                        if (legend.getLabelField() != null) {
460
                            sds.start();
461
                                int idLabelField = getRecordset().getFieldIndexByName(legend.getLabelField());
462
                                createLabelLayer(idLabelField);
463
                                sds.stop();
464
                        }
465
                        else
466
                            removeLabels();
467
                } catch (DriverException e) {
468
                        throw new DriverException(e);
469
                } catch (FieldNotFoundException e) {
470
                        // TODO Auto-generated catch block
471
                        e.printStackTrace();
472
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
473
                        throw new DriverException(e);
474
        }
475

    
476
                LegendChangedEvent e = LegendChangedEvent.createLegendChangedEvent(oldLegend, legend);
477
                callLegendChanged(e);
478
        }
479

    
480
        /**
481
         * Devuelve la Leyenda de la capa.
482
         *
483
         * @return Leyenda.
484
         */
485
        public Legend getLegend() {
486
                return legend;
487
        }
488

    
489
        /**
490
         * Devuelve el tipo de shape que contiene la capa.
491
         *
492
         * @return tipo de shape.
493
         *
494
         * @throws DriverException
495
         */
496
        public int getShapeType() throws DriverException {
497
                if (typeShape == -1) {
498
                        try {
499
                                logger.debug("source.start()");
500
                                source.start();
501
                                typeShape = source.getShapeType();
502
                                logger.debug("source.stop()");
503
                                source.stop();
504
                        } catch (DriverIOException e) {
505
                                throw new DriverException(e);
506
                        }
507
                }
508

    
509
                return typeShape;
510
        }
511

    
512
        /**
513
         * @throws XMLException
514
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getProperties()
515
         */
516
        public XMLEntity getXMLEntity() throws XMLException {
517
                XMLEntity xml = super.getXMLEntity();
518
                xml.addChild(legend.getXMLEntity());
519
                xml.addChild(selectionSupport.getXMLEntity());
520

    
521
                if (source instanceof VectorialFileAdapter) {
522
                        xml.putProperty("type", "vectorial");
523
                        xml.putProperty("file", ((VectorialFileAdapter) source).getFile());
524
                        try {
525
                                xml.putProperty("recordset-name", getRecordset().getName());
526
                        } catch (DriverException e) {
527
                                throw new XMLException(e);
528
                        }
529
                } else if (source instanceof VectorialDBAdapter) {
530
                } else if (source instanceof WFSAdapter) {
531
                }
532

    
533
                xml.putProperty("driverName", getSource().getDriver().getName());
534

    
535
                return xml;
536
        }
537

    
538
        /**
539
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setXMLEntity(com.iver.utiles.XMLEntity)
540
         */
541
        public void setXMLEntity03(XMLEntity xml)
542
                throws XMLException {
543
                
544
                super.setXMLEntity(xml);
545
                legend = LegendFactory.createFromXML03(xml.getChild(0));
546

    
547
                try {
548
                        // legend.setDataSource(getRecordset());
549
                        setLegend(legend);
550
                } catch (FieldNotFoundException e) {
551
                        throw new XMLException(e);
552
                } catch (DriverException e) {
553
                        throw new XMLException(e);
554
                }        
555

    
556
                selectionSupport.setXMLEntity03(xml.getChild(1));
557
        }
558

    
559
        /**
560
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setXMLEntity(com.iver.utiles.XMLEntity)
561
         */
562
        public void setXMLEntity(XMLEntity xml)
563
                throws XMLException {
564
                
565
                super.setXMLEntity(xml);
566
                legend = LegendFactory.createFromXML(xml.getChild(0));
567

    
568
                try {
569
                        // legend.setDataSource(getRecordset());
570
                        setLegend(legend);
571
                } catch (FieldNotFoundException e) {
572
                        throw new XMLException(e);
573
                } catch (DriverException e) {
574
                        throw new XMLException(e);
575
                }        
576
                
577
                selectionSupport.setXMLEntity(xml.getChild(1));
578

    
579
                String recordsetName = xml.getStringProperty("recordset-name");
580
                try {
581
                        LayerFactory.getDataSourceFactory().changeDataSourceName(
582
                    getRecordset().getName(), recordsetName
583
                                        );
584
            //Para que vuelva a leer el DataSource y tenga el nombre coherente con la factoria
585
                        sds = null;
586
                } catch (NoSuchTableException e1) {
587
                        throw new XMLException(e1);
588
                } catch (DriverException e1) {
589
                        throw new XMLException(e1);
590
                }
591
        }
592

    
593
        /**
594
         * A?ade un LegendListener a la lista de Listeners.
595
         *
596
         * @param listener LegendListener.
597
         */
598
        public void addLegendListener(LegendListener listener) {
599
                layerChangeSupport.addLayerListener(listener);
600
        }
601

    
602
        /**
603
         * Llamada al m?todo callLegendChanged de los listener.
604
         *
605
         * @param e Evento.
606
         */
607
        private void callLegendChanged(LegendChangedEvent e) {
608
                layerChangeSupport.callLegendChanged(e);
609
        }
610

    
611
        /**
612
         * Borra un LegendListener de la lista de Listeners
613
         *
614
         * @param listener LegendListener.
615
         */
616
        public void removeLegendListener(LegendListener listener) {
617
                layerChangeSupport.removeLayerListener(listener);
618
        }
619

    
620
        /**
621
         * Sobreimplementaci?n del m?todo toString para que las bases de datos
622
         * identifiquen la capa.
623
         *
624
         * @return DOCUMENT ME!
625
         */
626
        public String toString() {
627
                /*
628
                 * Se usa internamente para que la parte de datos
629
                 * identifique de forma un?voca las tablas
630
                 */
631
                String ret = super.toString();
632

    
633
                return "layer" + ret.substring(ret.indexOf('@') + 1);
634
        }
635
}