Statistics
| Revision:

svn-gvsig-desktop / tags / v1_1_Build_1006 / libraries / libFMap / src / com / iver / cit / gvsig / fmap / layers / FLyrAnnotation.java @ 12458

History | View | Annotate | Download (16.8 KB)

1
package com.iver.cit.gvsig.fmap.layers;
2

    
3
import java.awt.Color;
4
import java.awt.Font;
5
import java.awt.Graphics2D;
6
import java.awt.geom.Point2D;
7
import java.awt.geom.Rectangle2D;
8
import java.awt.image.BufferedImage;
9
import java.io.File;
10
import java.io.IOException;
11
import java.util.ArrayList;
12
import java.util.Iterator;
13

    
14
import javax.print.attribute.PrintRequestAttributeSet;
15

    
16
import org.cresques.cts.ICoordTrans;
17
import org.cresques.cts.IProjection;
18

    
19
import com.hardcode.driverManager.Driver;
20
import com.hardcode.driverManager.DriverLoadException;
21
import com.hardcode.gdbms.engine.instruction.FieldNotFoundException;
22
import com.hardcode.gdbms.engine.values.IntValue;
23
import com.hardcode.gdbms.engine.values.NullValue;
24
import com.hardcode.gdbms.engine.values.NumericValue;
25
import com.hardcode.gdbms.engine.values.StringValue;
26
import com.hardcode.gdbms.engine.values.Value;
27
import com.hardcode.gdbms.engine.values.ValueFactory;
28
import com.iver.cit.gvsig.fmap.DriverException;
29
import com.iver.cit.gvsig.fmap.ViewPort;
30
import com.iver.cit.gvsig.fmap.core.IGeometry;
31
import com.iver.cit.gvsig.fmap.core.ISymbol;
32
import com.iver.cit.gvsig.fmap.core.v02.FConstant;
33
import com.iver.cit.gvsig.fmap.core.v02.FLabel;
34
import com.iver.cit.gvsig.fmap.core.v02.FSymbol;
35
import com.iver.cit.gvsig.fmap.crs.CRSFactory;
36
import com.iver.cit.gvsig.fmap.drivers.BoundedShapes;
37
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes;
38
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
39
import com.iver.cit.gvsig.fmap.drivers.VectorialDriver;
40
import com.iver.cit.gvsig.fmap.edition.AnnotationEditableAdapter;
41
import com.iver.cit.gvsig.fmap.edition.EditionException;
42
import com.iver.cit.gvsig.fmap.operations.strategies.AnnotationStrategy;
43
import com.iver.cit.gvsig.fmap.operations.strategies.Strategy;
44
import com.iver.cit.gvsig.fmap.operations.strategies.StrategyManager;
45
import com.iver.cit.gvsig.fmap.operations.strategies.VisitException;
46
import com.iver.cit.gvsig.fmap.rendering.VectorialLegend;
47
import com.iver.cit.gvsig.fmap.rendering.VectorialUniqueValueLegend;
48
import com.iver.cit.gvsig.fmap.spatialindex.QuadtreeJts;
49
import com.iver.utiles.XMLEntity;
50
import com.iver.utiles.swing.threads.Cancellable;
51

    
52
/**
53
 * DOCUMENT ME!
54
 *
55
 * @author Vicente Caballero Navarro
56
 */
57
public class FLyrAnnotation extends FLyrVect {
58
        private MappingAnnotation mapping = null;
59

    
60
        private ArrayList m_labels;
61

    
62
        private int indexEditing = -1;
63

    
64
        private boolean inPixels;
65
        private VectorialUniqueValueLegend vuvl=new VectorialUniqueValueLegend();
66
        private Strategy strategy=null;
67
        /**
68
         * Crea un nuevo FLyrAnnotation.
69
         */
70
        public FLyrAnnotation() {
71
                super();
72
        }
73

    
74
        /**
75
         * DOCUMENT ME!
76
         *
77
         * @param mapping
78
         *            DOCUMENT ME!
79
         */
80
        public void setMapping(MappingAnnotation mapping) {
81
                this.mapping = mapping;
82
                try {
83
                        setLegend();
84
                        createLabels();
85
                } catch (DriverException e) {
86
                        e.printStackTrace();
87
                }
88
        }
89

    
90
        /**
91
         * DOCUMENT ME!
92
         *
93
         * @return DOCUMENT ME!
94
         */
95
        public MappingAnnotation getMapping() {
96
                return mapping;
97
        }
98

    
99
        /**
100
         * @see com.iver.cit.gvsig.fmap.layers.LayerOperations#draw(java.awt.image.BufferedImage,
101
         *      java.awt.Graphics2D, ISymbol)
102
         */
103
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
104
                        Cancellable cancel, double scale) throws DriverException {
105
                if (isWithinScale(scale)) {
106
                        // Las que solo tienen etiquetado sin pintar el shape,
107
                        // no pasamos por ellas
108
                        boolean bDrawShapes = true;
109

    
110
                        if (bDrawShapes) {
111
                                if (strategy == null){
112
                                        strategy = (AnnotationStrategy) StrategyManager
113
                                                        .getStrategy(this);
114
                                }
115
                                try {
116
                                        g.setColor(Color.black);
117
                                        strategy.draw(image, g, viewPort, cancel);
118
                                        if (getISpatialIndex()==null && !isEditing()) {
119
                                                createSpatialIndex();
120
                                        }
121
                                } catch (DriverException e) {
122
                                        this.setVisible(false);
123
                                        this.setActive(false);
124
                                        throw e;
125
                                }
126
                        }
127

    
128
                        if (getVirtualLayers() != null) {
129
                                getVirtualLayers().draw(image, g, viewPort, cancel, scale);
130
                        }
131
                }
132
        }
133

    
134
        /**
135
         * @see com.iver.cit.gvsig.fmap.layers.LayerOperations#getFullExtent()
136
         */
137
        public Rectangle2D getFullExtent() throws DriverException {
138
                try {
139
                        Rectangle2D rAux;
140

    
141
                        // logger.debug("source.start()");
142
                        getSource().start();
143
                        rAux = getSource().getFullExtent();
144

    
145
                        // logger.debug("source.stop()");
146
                        getSource().stop();
147

    
148
                        // Si existe reproyecci?n, reproyectar el extent
149
                        ICoordTrans ct = getCoordTrans();
150

    
151
                        if (ct != null) {
152
                                Point2D pt1 = new Point2D.Double(rAux.getMinX(), rAux.getMinY());
153
                                Point2D pt2 = new Point2D.Double(rAux.getMaxX(), rAux.getMaxY());
154
                                pt1 = ct.convert(pt1, null);
155
                                pt2 = ct.convert(pt2, null);
156
                                rAux = new Rectangle2D.Double();
157
                                rAux.setFrameFromDiagonal(pt1, pt2);
158
                        }
159

    
160
                        return rAux;
161
                } catch (DriverIOException e) {
162
                        throw new DriverException(e);
163
                }
164
        }
165

    
166
        /**
167
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#print(java.awt.Graphics2D,
168
         *      com.iver.cit.gvsig.fmap.ViewPort,
169
         *      com.iver.utiles.swing.threads.Cancellable)
170
         */
171
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
172
                        double scale, PrintRequestAttributeSet properties) throws DriverException {
173
                if (isVisible() && isWithinScale(scale)) {
174
                        Strategy strategy = StrategyManager.getStrategy(this);
175
                        strategy.print(g, viewPort, cancel, properties);
176
                }
177
        }
178

    
179
        /*
180
         * (non-Javadoc)
181
         *
182
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.RandomVectorialData#queryByRect(java.awt.geom.Rectangle2D)
183
         */
184
        public FBitSet queryByRect(Rectangle2D rect) throws DriverException {
185
                Strategy s = StrategyManager.getStrategy(this);
186

    
187
                return s.queryByRect(rect);
188
        }
189

    
190
        /**
191
         * DOCUMENT ME!
192
         *
193
         * @param p
194
         *            DOCUMENT ME!
195
         * @param tolerance
196
         *            DOCUMENT ME!
197
         *
198
         * @return DOCUMENT ME!
199
         *
200
         * @throws DriverException
201
         *             DOCUMENT ME!
202
         */
203
        public FBitSet queryByPoint(Point2D p, double tolerance)
204
                        throws DriverException {
205
                Strategy s = StrategyManager.getStrategy(this);
206

    
207
                return s.queryByPoint(p, tolerance);
208
        }
209

    
210
        /**
211
         * DOCUMENT ME!
212
         *
213
         * @param g
214
         *            DOCUMENT ME!
215
         * @param relationship
216
         *            DOCUMENT ME!
217
         *
218
         * @return DOCUMENT ME!
219
         *
220
         * @throws DriverException
221
         *             DOCUMENT ME!
222
         * @throws VisitException
223
         *             DOCUMENT ME!
224
         */
225
        public FBitSet queryByShape(IGeometry g, int relationship)
226
                        throws DriverException, VisitException {
227
                Strategy s = StrategyManager.getStrategy(this);
228

    
229
                return s.queryByShape(g, relationship);
230
        }
231

    
232
        /**
233
         * DOCUMENT ME!
234
         *
235
         * @return DOCUMENT ME!
236
         *
237
         * @throws XMLException
238
         *
239
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getProperties()
240
         */
241
        public XMLEntity getXMLEntity() throws XMLException {
242
                XMLEntity xml = super.getXMLEntity();
243
                xml.addChild(mapping.getXMLEntity());
244
                xml.putProperty("isInPixels", isInPixels());
245

    
246
                return xml;
247
        }
248

    
249
        /**
250
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setXMLEntity(com.iver.utiles.XMLEntity)
251
         */
252
        public void setXMLEntity(XMLEntity xml) throws XMLException {
253
                Iterator iter=xml.findChildren("className",MappingAnnotation.class.getName());
254
                if (iter.hasNext())
255
                        mapping = MappingAnnotation.createFromXML((XMLEntity)iter.next());
256
                else{
257
                        //Este else para versiones anteriores a la 1.0.2.(908)
258
                        if (xml.getChildrenCount()==3)
259
                                mapping = MappingAnnotation.createFromXML(xml.getChild(2));
260
                        else
261
                                mapping = MappingAnnotation.createFromXML(xml.getChild(3));
262
                }
263
                setInPixels(xml.getBooleanProperty("isInPixels"));
264

    
265
                IProjection proj = null;
266

    
267
                if (xml.contains("proj")) {
268
                        proj = CRSFactory.getCRS(xml.getStringProperty("proj"));
269
                }
270

    
271
//                VectorialAdapter adapter=null;
272
//                if (xml.contains("file")){
273
//                        adapter = new VectorialFileAdapter(new File(xml
274
//                                        .getStringProperty("file")));
275
//                }else if (xml.contains("db")){
276
//                        adapter = new VectorialDBAdapter();
277
//                }
278
//                Driver d;
279
//
280
//                try {
281
//                        d = LayerFactory.getDM().getDriver(
282
//                                        xml.getStringProperty("driverName"));
283
//                } catch (DriverLoadException e1) {
284
//                        throw new XMLException(e1);
285
//                }
286
//
287
//                adapter.setDriver((VectorialDriver) d);
288
//                // TODO Meter esto dentro de la comprobaci?n de si hay memoria
289
//                if (false) {
290
//                } else {
291
//                        setSource(adapter);
292
//                        setProjection(proj);
293
//                }
294

    
295
                // Le asignamos tambi?n una legenda por defecto acorde con
296
                // el tipo de shape que tenga. Tampoco s? si es aqu? el
297
                // sitio adecuado, pero en fin....
298
                /*
299
                 * if (d instanceof WithDefaultLegend) { WithDefaultLegend aux =
300
                 * (WithDefaultLegend) d; adapter.start(); setLegend((VectorialLegend)
301
                 * aux.getDefaultLegend()); adapter.stop(); } else {
302
                 * setLegend(LegendFactory.createSingleSymbolLegend(getShapeType())); }
303
                 */
304

    
305
                super.setXMLEntity(xml);
306
                try {
307
                        createLabels();
308
                } catch (DriverException e) {
309
                        // TODO Auto-generated catch block
310
                        e.printStackTrace();
311
                }
312
        }
313

    
314
        /**
315
         * Esto tiene el fallo de que obligas a una etiqueta por entidad, para poder
316
         * evitar esto, una posible soluci?n ser?a que un FLabel pudiera ser una
317
         * colecci?n de FLabel (Patr?n Composite)
318
         *
319
         * @param lyrVect
320
         * @throws DriverException
321
         */
322
        private void createLabels() throws DriverException {
323
                SelectableDataSource ds = getRecordset();
324
                FSymbol symbol;
325
                try {
326
                        ReadableVectorial adapter = getSource();
327
                        adapter.start();
328
                        if (isJoined()){
329
                                ds.start();
330
                        }
331
                        int sc;
332
                        // El mapping[0] es el text
333
                        int fieldId = mapping.getColumnText();
334
                        // El mapping[1] es el ?ngulo
335
                        int idFieldRotationText = mapping.getColumnRotate();
336
                        // El mapping[2] es el color
337
                        int idFieldColorText = mapping.getColumnColor();
338
                        // El mapping[3] es el alto
339
                        int idFieldHeightText = mapping.getColumnHeight();
340
                        // El mapping[4] es el tipo de fuente
341
                        int idFieldTypeFontText = mapping.getColumnTypeFont();
342
                        // El mapping[5] es el estilo de fuente
343
                        int idFieldStyleFontText = mapping.getColumnStyleFont();
344

    
345
                        sc = (int) ds.getRowCount();
346
                        m_labels = new ArrayList(sc);
347
                        DriverAttributes attr = adapter.getDriverAttributes();
348
                        boolean bMustClone = false;
349
                        if (attr != null) {
350
                                if (attr.isLoadedInMemory()) {
351
                                        bMustClone = attr.isLoadedInMemory();
352
                                }
353
                        }
354
                        ICoordTrans ct = getCoordTrans();
355
                        FSymbol defaultSym = (FSymbol) getLegend().getDefaultSymbol();
356
                        for (int i = 0; i < sc; i++) {
357
                                IGeometry geom = adapter.getShape(i);
358

    
359
                                if (geom == null) {
360
                                        m_labels.add(null);
361
                                        continue;
362
                                }
363
                                if (ct != null) {
364
                                        if (bMustClone)
365
                                                geom = geom.cloneGeometry();
366
                                        geom.reProject(ct);
367
                                }
368

    
369
                                // TODO: El m?todo contenedor (createLabelLayer) debe recoger
370
                                // los par?metros de posicionamiento y de allowDuplicates
371
                                // if (i >= 328)
372
                                // System.out.println("i= " + i + " " + val.toString());
373
                                //ArrayList values=new ArrayList(4);
374
                                String t=new String();
375
                                Value val = ds.getFieldValue(i, fieldId);
376
                                t=val.toString();
377
                                //values.add(val);
378
                                if (idFieldColorText!=-1){
379
                                        Value valColor=ds.getFieldValue(i,idFieldColorText);
380
                                        t=t.concat(valColor.toString());
381
                                        //values.add(valColor);
382
                                }
383
                                if (idFieldTypeFontText!=-1){
384
                                        Value valTypeFont=ds.getFieldValue(i,idFieldTypeFontText);
385
                                        t=t.concat(valTypeFont.toString());
386
                                        //values.add(valTypeFont);
387
                                }
388

    
389
                                if (idFieldStyleFontText!=-1){
390
                                        Value valStyleFont=ds.getFieldValue(i,idFieldStyleFontText);
391
                                        t=t.concat(valStyleFont.toString());
392
                                        //values.add(valStyleFont);
393
                                }
394
                                //Value total=ValueFactory.createValue((Value[])values.toArray(new Value[0]));
395
                                Value total=ValueFactory.createValue(t);
396
                                if ((val instanceof NullValue) || (val == null)) {
397
                                        m_labels.add(null);
398
                                        continue;
399
                                }
400
                                FLabel[] lbls = geom.createLabels(0, true);
401
                                for (int j = 0; j < lbls.length; j++) {
402
                                        if (lbls[j] != null) {
403
                                                lbls[j].setString(val.toString());
404
                                                if (idFieldRotationText != -1) {
405
                                                        NumericValue rotation = (NumericValue) ds
406
                                                                        .getFieldValue(i, idFieldRotationText);
407
                                                        lbls[j].setRotation(rotation.doubleValue());
408
                                                } else {
409
                                                        lbls[j].setRotation(defaultSym.getRotation());
410
                                                }
411

    
412
                                                float height;
413
                                                if (idFieldHeightText != -1) {
414
                                                        NumericValue h = (NumericValue) ds
415
                                                                        .getFieldValue(i, idFieldHeightText);
416
                                                        height=h.floatValue();
417
                                                        lbls[j].setHeight(height);
418
                                                } else {
419
                                                        height=defaultSym.getFontSize();
420
                                                        lbls[j].setHeight(height);
421
                                                }
422

    
423

    
424

    
425
                                                if (vuvl.getSymbolByValue(total)==null){
426
                                                        Color color;
427
                                                        if (idFieldColorText != -1) {
428
                                                                NumericValue c = (NumericValue) ds.getFieldValue(
429
                                                                                i, idFieldColorText);
430
                                                                color=new Color(c.intValue());
431
                                                        } else {
432
                                                                color=defaultSym.getFontColor();
433
                                                        }
434
                                                        String typeFont;
435
                                                        if (idFieldTypeFontText != -1) {
436
                                                                StringValue tf = (StringValue) ds
437
                                                                                .getFieldValue(i, idFieldTypeFontText);
438
                                                                typeFont=tf.getValue();
439
                                                        } else {
440
                                                                typeFont=defaultSym.getFont().getFontName();
441
                                                        }
442
                                                        int style;
443
                                                        if (idFieldStyleFontText != -1) {
444
                                                                IntValue sf = (IntValue) ds
445
                                                                                .getFieldValue(i, idFieldStyleFontText);
446
                                                                style=sf.getValue();
447
                                                        } else {
448
                                                                style=defaultSym.getFont().getStyle();
449
                                                        }
450
                                                        symbol=new FSymbol(FConstant.SYMBOL_TYPE_TEXT);
451
                                                        symbol.setFontSizeInPixels(isInPixels());
452
                                                        symbol.setFont(new Font(typeFont,style,(int)height));
453
                                                        symbol.setDescription(lbls[j].getString());
454
                                                        symbol.setFontColor(color);
455
                                                        vuvl.addSymbol(total,symbol);
456
                                                }
457

    
458
                                        }
459
                                m_labels.add(lbls[j]);
460

    
461
                                }
462
                        }
463

    
464
                        if (this.isJoined()){
465
                                ds.stop();
466
                        }
467
                        adapter.stop();
468
                } catch (DriverIOException e) {
469
                        e.printStackTrace();
470
                        throw new DriverException(e);
471
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
472
                        e.printStackTrace();
473
                        throw new DriverException(e);
474
                }
475

    
476
        }
477

    
478
        public FLabel getLabel(int numReg) {
479
                if (m_labels == null || numReg == -1)
480
                        return null;
481
                if (getSource() instanceof AnnotationEditableAdapter){
482
                        AnnotationEditableAdapter aea=((AnnotationEditableAdapter)getSource());
483
                        return aea.getLabel(numReg,false);
484
                }
485
                return (FLabel)m_labels.get(numReg);
486
        }
487

    
488
        /*
489
         * (non-Javadoc)
490
         *
491
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.RandomVectorialData#createIndex()
492
         */
493
        public void createSpatialIndex() {
494
                // FJP: ESTO HABR? QUE CAMBIARLO. PARA LAS CAPAS SECUENCIALES, TENDREMOS
495
                // QUE ACCEDER CON UN WHILE NEXT. (O mejorar lo de los FeatureVisitor
496
                // para que acepten recorrer sin geometria, solo con rectangulos.
497

    
498
                //AZABALA: Como no tengo claro de donde se crean las capas de textos
499
                //el ?ndice espacial creado seguir? siendo el Quadtree en memoria
500
                //de JTS (QuadtreeJts es un adapter a nuestra api de indices)
501
                spatialIndex = new QuadtreeJts();
502
                ReadableVectorial va = getSource();
503
                ICoordTrans ct = getCoordTrans();
504
                BoundedShapes shapeBounds = (BoundedShapes) va.getDriver();
505
                try {
506
                        va.start();
507

    
508
                        for (int i = 0; i < va.getShapeCount(); i++) {
509
                                Rectangle2D r = null;
510
                                FLabel label=getLabel(i);
511
                                if (label != null) {
512
                                        r = label.getBoundBox();
513
                                } else {
514
                                        r = shapeBounds.getShapeBounds(i);
515
                                }
516
                                // TODO: MIRAR COMO SE TRAGAR?A ESTO LO DE LAS REPROYECCIONES
517
                                if (ct != null) {
518
                                        r = ct.convert(r);
519
                                }
520
                                if (r != null) {
521
//                                        Coordinate c1 = new Coordinate(r.getMinX(), r.getMinY());
522
//                                        Coordinate c2 = new Coordinate(r.getMaxX(), r.getMaxY());
523
//                                        Envelope env = new Envelope(c1, c2);
524
//                                        spatialIndex.insert(env, new Integer(i));
525
                                        spatialIndex.insert(r, i);
526
                                }
527
                        } // for
528
                        va.stop();
529
                } catch (DriverIOException e) {
530
                        e.printStackTrace();
531
                } catch (IOException e) {
532
                        e.printStackTrace();
533
                }
534
        }
535

    
536
        public void setSelectedEditing() throws DriverException {
537
                FBitSet bitSet = getRecordset().getSelection();
538
                if (bitSet.cardinality() == 0)
539
                        return;
540
                indexEditing = bitSet.nextSetBit(0);
541
        }
542

    
543
        public void setInPixels(boolean b) {
544
                inPixels = b;
545
        }
546

    
547
        public boolean isInPixels() {
548
                return inPixels;
549
        }
550

    
551
        public void setInEdition(int i) {
552
                indexEditing = i;
553

    
554
        }
555

    
556
        public int getInEdition() {
557
                return indexEditing;
558
        }
559

    
560
        public ArrayList getLabels() {
561
                return m_labels;
562
        }
563

    
564

    
565
        public void setLegend() {
566
                try {
567
                        getSource().getRecordset().start();
568
                        vuvl.setFieldName(getSource().getRecordset().getFieldName(mapping.getColumnText()));
569
                        vuvl.setDefaultSymbol(new FSymbol(FConstant.SYMBOL_TYPE_TEXT));
570
                        setLegend(vuvl);
571
                        getSource().getRecordset().stop();
572
                } catch (FieldNotFoundException e) {
573
                        e.printStackTrace();
574
                } catch (DriverException e) {
575
                        e.printStackTrace();
576
                } catch (DriverLoadException e) {
577
                        e.printStackTrace();
578
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
579
                        e.printStackTrace();
580
                }
581

    
582
        }
583

    
584
        public Strategy getStrategy() {
585
                return strategy;
586
        }
587

    
588
        public void setEditing(boolean b) throws EditionException {
589
                super.setEditing(b);
590
                deleteSpatialIndex();
591
        }
592

    
593
        public static FLayer createLayerFromVect(FLyrVect layer) throws DriverException, FieldNotFoundException {
594
                FLyrAnnotation la=new FLyrAnnotation();
595
                la.setSource(layer.getSource());
596
                la.setRecordset(layer.getRecordset());
597
                la.setProjection(layer.getProjection());
598
                la.setLegend((VectorialLegend)layer.getLegend());
599
                return la;
600
        }
601
}