Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / layers / FLyrAnnotation.java @ 24160

History | View | Annotate | Download (16.9 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.util.ArrayList;
10
import java.util.Iterator;
11

    
12
import javax.print.attribute.PrintRequestAttributeSet;
13

    
14
import org.cresques.cts.ICoordTrans;
15
import org.cresques.cts.IProjection;
16

    
17
import com.hardcode.gdbms.driver.exceptions.InitializeDriverException;
18
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
19
import com.hardcode.gdbms.engine.data.driver.DriverException;
20
import com.hardcode.gdbms.engine.values.IntValue;
21
import com.hardcode.gdbms.engine.values.NullValue;
22
import com.hardcode.gdbms.engine.values.NumericValue;
23
import com.hardcode.gdbms.engine.values.StringValue;
24
import com.hardcode.gdbms.engine.values.Value;
25
import com.hardcode.gdbms.engine.values.ValueFactory;
26
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException;
27
import com.iver.cit.gvsig.exceptions.layers.LegendLayerException;
28
import com.iver.cit.gvsig.exceptions.layers.StartEditionLayerException;
29
import com.iver.cit.gvsig.exceptions.visitors.VisitorException;
30
import com.iver.cit.gvsig.fmap.ViewPort;
31
import com.iver.cit.gvsig.fmap.core.IGeometry;
32
import com.iver.cit.gvsig.fmap.core.SymbologyFactory;
33
import com.iver.cit.gvsig.fmap.core.symbols.ISymbol;
34
import com.iver.cit.gvsig.fmap.core.symbols.ITextSymbol;
35
import com.iver.cit.gvsig.fmap.core.v02.FLabel;
36
import com.iver.cit.gvsig.fmap.core.v02.FSymbol;
37
import com.iver.cit.gvsig.fmap.crs.CRSFactory;
38
import com.iver.cit.gvsig.fmap.drivers.BoundedShapes;
39
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes;
40
import com.iver.cit.gvsig.fmap.edition.AnnotationEditableAdapter;
41
import com.iver.cit.gvsig.fmap.operations.strategies.AnnotationStrategy;
42
import com.iver.cit.gvsig.fmap.operations.strategies.Strategy;
43
import com.iver.cit.gvsig.fmap.operations.strategies.StrategyManager;
44
import com.iver.cit.gvsig.fmap.rendering.IVectorLegend;
45
import com.iver.cit.gvsig.fmap.rendering.VectorialUniqueValueLegend;
46
import com.iver.cit.gvsig.fmap.spatialindex.QuadtreeJts;
47
import com.iver.utiles.XMLEntity;
48
import com.iver.utiles.swing.threads.Cancellable;
49

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

    
58
        private ArrayList m_labels;
59

    
60
        private int indexEditing = -1;
61

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

    
72
        /**
73
         * DOCUMENT ME!
74
         *
75
         * @param mapping
76
         *            DOCUMENT ME!
77
         */
78
        public void setMapping(MappingAnnotation mapping) {
79
                // TODO: comprobar si ha cambiado
80
                this.mapping = mapping;
81
                try {
82
                        setLegend();
83
                        createLabels();
84
                } catch (ReadDriverException e) {
85
                        e.printStackTrace();
86
                }
87
                this.updateDrawVersion();
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
         *      ISymbol)
102
         */
103
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
104
                        Cancellable cancel, double scale) throws ReadDriverException {
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 (ReadDriverException 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
         * @throws ReadDriverException
136
         * @throws ExpansionFileReadException
137
         * @see com.iver.cit.gvsig.fmap.layers.LayerOperations#getFullExtent()
138
         */
139
        public Rectangle2D getFullExtent() throws ReadDriverException, ExpansionFileReadException {
140
                Rectangle2D rAux;
141
                // logger.debug("source.start()");
142
                try {
143
                        getSource().start();
144
                } catch (InitializeDriverException e) {
145
                        throw new ReadDriverException(getName(),e);
146
                }
147
                rAux = getSource().getFullExtent();
148
                        // logger.debug("source.stop()");
149
                getSource().stop();
150
                        // Si existe reproyecci?n, reproyectar el extent
151
                ICoordTrans ct = getCoordTrans();
152
                if (ct != null) {
153
                        Point2D pt1 = new Point2D.Double(rAux.getMinX(), rAux.getMinY());
154
                        Point2D pt2 = new Point2D.Double(rAux.getMaxX(), rAux.getMaxY());
155
                        pt1 = ct.convert(pt1, null);
156
                        pt2 = ct.convert(pt2, null);
157
                        rAux = new Rectangle2D.Double();
158
                        rAux.setFrameFromDiagonal(pt1, pt2);
159
                }
160
                return rAux;
161
        }
162

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

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

    
184
                return s.queryByRect(rect);
185
        }
186

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

    
203
                return s.queryByPoint(p, tolerance);
204
        }
205

    
206
        /**
207
         * DOCUMENT ME!
208
         *
209
         * @param g
210
         *            DOCUMENT ME!
211
         * @param relationship
212
         *            DOCUMENT ME!
213
         *
214
         * @return FBitset
215
         */
216
        public FBitSet queryByShape(IGeometry g, int relationship)
217
                        throws ReadDriverException, VisitorException {
218
                Strategy s = StrategyManager.getStrategy(this);
219

    
220
                return s.queryByShape(g, relationship);
221
        }
222

    
223
        /**
224
         * DOCUMENT ME!
225
         *
226
         * @return DOCUMENT ME!
227
         *
228
         * @throws XMLException
229
         *
230
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getProperties()
231
         */
232
        public XMLEntity getXMLEntity() throws XMLException {
233
                XMLEntity xml = super.getXMLEntity();
234
                xml.addChild(mapping.getXMLEntity());
235
                xml.putProperty("isInPixels", isInPixels());
236

    
237
                return xml;
238
        }
239

    
240
        /**
241
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setXMLEntity(com.iver.utiles.XMLEntity)
242
         */
243
        public void setXMLEntity(XMLEntity xml) throws XMLException {
244
                Iterator iter=xml.findChildren("className",MappingAnnotation.class.getName());
245
                if (iter.hasNext())
246
                        mapping = MappingAnnotation.createFromXML((XMLEntity)iter.next());
247
                else{
248
                        //Este else para versiones anteriores a la 1.0.2.(908)
249
                        if (xml.getChildrenCount()==3)
250
                                mapping = MappingAnnotation.createFromXML(xml.getChild(2));
251
                        else
252
                                mapping = MappingAnnotation.createFromXML(xml.getChild(3));
253
                }
254
                setInPixels(xml.getBooleanProperty("isInPixels"));
255

    
256
                IProjection proj = null;
257

    
258
                if (xml.contains("proj")) {
259
                        proj = CRSFactory.getCRS(xml.getStringProperty("proj"));
260
                }
261

    
262
//                VectorialAdapter adapter=null;
263
//                if (xml.contains("file")){
264
//                        adapter = new VectorialFileAdapter(new File(xml
265
//                                        .getStringProperty("file")));
266
//                }else if (xml.contains("db")){
267
//                        adapter = new VectorialDBAdapter();
268
//                }
269
//                Driver d;
270
//
271
//                try {
272
//                        d = LayerFactory.getDM().getDriver(
273
//                                        xml.getStringProperty("driverName"));
274
//                } catch (DriverLoadException e1) {
275
//                        throw new XMLException(e1);
276
//                }
277
//
278
//                adapter.setDriver((VectorialDriver) d);
279
//                // TODO Meter esto dentro de la comprobaci?n de si hay memoria
280
//                if (false) {
281
//                } else {
282
//                        setSource(adapter);
283
//                        setProjection(proj);
284
//                }
285

    
286
                // Le asignamos tambi?n una legenda por defecto acorde con
287
                // el tipo de shape que tenga. Tampoco s? si es aqu? el
288
                // sitio adecuado, pero en fin....
289
                /*
290
                 * if (d instanceof WithDefaultLegend) { WithDefaultLegend aux =
291
                 * (WithDefaultLegend) d; adapter.start(); setLegend((VectorialLegend)
292
                 * aux.getDefaultLegend()); adapter.stop(); } else {
293
                 * setLegend(LegendFactory.createSingleSymbolLegend(getShapeType())); }
294
                 */
295

    
296
                super.setXMLEntity(xml);
297
                try {
298
                        createLabels();
299
                } catch (ReadDriverException e) {
300
                        e.printStackTrace();
301
                }
302
        }
303

    
304
        /**
305
         * Esto tiene el fallo de que obligas a una etiqueta por entidad, para poder
306
         * evitar esto, una posible soluci?n ser?a que un FLabel pudiera ser una
307
         * colecci?n de FLabel (Patr?n Composite)
308
         *
309
         * @param lyrVect
310
         * @throws ReadDriverException
311
         * @throws DriverException
312
         */
313
        private void createLabels() throws ReadDriverException{
314
                SelectableDataSource ds = getRecordset();
315
                try {
316
                        ReadableVectorial adapter = getSource();
317
                        adapter.start();
318
                        ds.start();
319
                        int sc;
320
                        // El mapping[0] es el text
321
                        int fieldId = mapping.getColumnText();
322
                        // El mapping[1] es el ?ngulo
323
                        int idFieldRotationText = mapping.getColumnRotate();
324
                        // El mapping[2] es el color
325
                        int idFieldColorText = mapping.getColumnColor();
326
                        // El mapping[3] es el alto
327
                        int idFieldHeightText = mapping.getColumnHeight();
328
                        // El mapping[4] es el tipo de fuente
329
                        int idFieldTypeFontText = mapping.getColumnTypeFont();
330
                        // El mapping[5] es el estilo de fuente
331
                        int idFieldStyleFontText = mapping.getColumnStyleFont();
332

    
333
                        sc = (int) ds.getRowCount();
334
                        m_labels = new ArrayList(sc);
335
                        DriverAttributes attr = adapter.getDriverAttributes();
336
                        boolean bMustClone = false;
337
                        if (attr != null) {
338
                                if (attr.isLoadedInMemory()) {
339
                                        bMustClone = attr.isLoadedInMemory();
340
                                }
341
                        }
342
                        ICoordTrans ct = getCoordTrans();
343
                        FSymbol defaultSym = (FSymbol) getLegend().getDefaultSymbol();
344
                        for (int i = 0; i < sc; i++) {
345
                                IGeometry geom = adapter.getShape(i);
346

    
347
                                if (geom == null) {
348
                                        m_labels.add(null);
349
                                        continue;
350
                                }
351
                                if (ct != null) {
352
                                        if (bMustClone)
353
                                                geom = geom.cloneGeometry();
354
                                        geom.reProject(ct);
355
                                }
356

    
357
                                // TODO: El m?todo contenedor (createLabelLayer) debe recoger
358
                                // los par?metros de posicionamiento y de allowDuplicates
359
                                // if (i >= 328)
360
                                // System.out.println("i= " + i + " " + val.toString());
361
                                //ArrayList values=new ArrayList(4);
362
                                String t=new String();
363
                                Value val = ds.getFieldValue(i, fieldId);
364
                                t=val.toString();
365
                                //values.add(val);
366
                                if (idFieldColorText!=-1){
367
                                        Value valColor=ds.getFieldValue(i,idFieldColorText);
368
                                        t=t.concat(valColor.toString());
369
                                        //values.add(valColor);
370
                                }
371
                                if (idFieldTypeFontText!=-1){
372
                                        Value valTypeFont=ds.getFieldValue(i,idFieldTypeFontText);
373
                                        t=t.concat(valTypeFont.toString());
374
                                        //values.add(valTypeFont);
375
                                }
376

    
377
                                if (idFieldStyleFontText!=-1){
378
                                        Value valStyleFont=ds.getFieldValue(i,idFieldStyleFontText);
379
                                        t=t.concat(valStyleFont.toString());
380
                                        //values.add(valStyleFont);
381
                                }
382
                                //Value total=ValueFactory.createValue((Value[])values.toArray(new Value[0]));
383
                                Value total=ValueFactory.createValue(t);
384
                                if ((val instanceof NullValue) || (val == null)) {
385
                                        m_labels.add(null);
386
                                        continue;
387
                                }
388
                                FLabel[] lbls = geom.createLabels(0, true);
389
                                for (int j = 0; j < lbls.length; j++) {
390
                                        if (lbls[j] != null) {
391
                                                lbls[j].setString(val.toString());
392
                                                if (idFieldRotationText != -1) {
393
                                                        NumericValue rotation = (NumericValue) ds
394
                                                                        .getFieldValue(i, idFieldRotationText);
395
                                                        lbls[j].setRotation(rotation.doubleValue());
396
                                                } else {
397
                                                        lbls[j].setRotation(defaultSym.getRotation());
398
                                                }
399

    
400
                                                float height;
401
                                                if (idFieldHeightText != -1) {
402
                                                        NumericValue h = (NumericValue) ds
403
                                                                        .getFieldValue(i, idFieldHeightText);
404
                                                        height=h.floatValue();
405
                                                        lbls[j].setHeight(height);
406
                                                } else {
407
                                                        height=defaultSym.getFontSize();
408
                                                        lbls[j].setHeight(height);
409
                                                }
410

    
411

    
412

    
413
                                                if (vuvl.getSymbolByValue(total)==null){
414
                                                        Color color;
415
                                                        if (idFieldColorText != -1) {
416
                                                                NumericValue c = (NumericValue) ds.getFieldValue(
417
                                                                                i, idFieldColorText);
418
                                                                color=new Color(c.intValue());
419
                                                        } else {
420
                                                                color=defaultSym.getFontColor();
421
                                                        }
422
                                                        String typeFont;
423
                                                        if (idFieldTypeFontText != -1) {
424
                                                                StringValue tf = (StringValue) ds
425
                                                                                .getFieldValue(i, idFieldTypeFontText);
426
                                                                typeFont=tf.getValue();
427
                                                        } else {
428
                                                                typeFont=defaultSym.getFont().getFontName();
429
                                                        }
430
                                                        int style;
431
                                                        if (idFieldStyleFontText != -1) {
432
                                                                IntValue sf = (IntValue) ds
433
                                                                                .getFieldValue(i, idFieldStyleFontText);
434
                                                                style = sf.getValue();
435
                                                        } else {
436
                                                                style = defaultSym.getFont().getStyle();
437
                                                        }
438
                                                        //FSymbol symbol=new FSymbol(FConstant.SYMBOL_TYPE_TEXT);
439

    
440
                                                        ITextSymbol symbol;
441

    
442
                                                        symbol = SymbologyFactory.createDefaultTextSymbol();
443

    
444
                                                        // casca perque ara ?s un ITextSymbol
445
//                                                        symbol.setFontSizeInPixels(isInPixels());
446
                                                        symbol.setFont(new Font(typeFont, style, (int)height));
447
                                                        symbol.setDescription(lbls[j].getString());
448
                                                        //symbol.setFontColor(color);
449
                                                        symbol.setTextColor(color);
450
                                                        vuvl.addSymbol(total,symbol);
451
                                                }
452

    
453
                                        }
454
                                m_labels.add(lbls[j]);
455

    
456
                                }
457
                        }
458

    
459
                        ds.stop();
460
                        adapter.stop();
461
                } catch (ExpansionFileReadException e) {
462
                        throw new ReadDriverException(getName(),e);
463
                } catch (InitializeDriverException e) {
464
                        throw new ReadDriverException(getName(),e);
465
                }
466

    
467
        }
468

    
469
        public FLabel getLabel(int numReg) {
470
                if (m_labels == null || numReg == -1)
471
                        return null;
472
                if (getSource() instanceof AnnotationEditableAdapter){
473
                        AnnotationEditableAdapter aea=((AnnotationEditableAdapter)getSource());
474
                        return aea.getLabel(numReg,false);
475
                }
476
                return (FLabel)m_labels.get(numReg);
477
        }
478

    
479
        /*
480
         * (non-Javadoc)
481
         *
482
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.RandomVectorialData#createIndex()
483
         */
484
        public void createSpatialIndex() {
485
                // FJP: ESTO HABR? QUE CAMBIARLO. PARA LAS CAPAS SECUENCIALES, TENDREMOS
486
                // QUE ACCEDER CON UN WHILE NEXT. (O mejorar lo de los FeatureVisitor
487
                // para que acepten recorrer sin geometria, solo con rectangulos.
488

    
489
                //AZABALA: Como no tengo claro de donde se crean las capas de textos
490
                //el ?ndice espacial creado seguir? siendo el Quadtree en memoria
491
                //de JTS (QuadtreeJts es un adapter a nuestra api de indices)
492
                spatialIndex = new QuadtreeJts();
493
                ReadableVectorial va = getSource();
494
                ICoordTrans ct = getCoordTrans();
495
                BoundedShapes shapeBounds = (BoundedShapes) va.getDriver();
496
                try {
497
                        va.start();
498

    
499
                        for (int i = 0; i < va.getShapeCount(); i++) {
500
                                Rectangle2D r = null;
501
                                FLabel label=getLabel(i);
502
                                if (label != null) {
503
                                        r = label.getBoundBox();
504
                                } else {
505
                                        r = shapeBounds.getShapeBounds(i);
506
                                }
507
                                // TODO: MIRAR COMO SE TRAGAR?A ESTO LO DE LAS REPROYECCIONES
508
                                if (ct != null) {
509
                                        r = ct.convert(r);
510
                                }
511
                                if (r != null) {
512
//                                        Coordinate c1 = new Coordinate(r.getMinX(), r.getMinY());
513
//                                        Coordinate c2 = new Coordinate(r.getMaxX(), r.getMaxY());
514
//                                        Envelope env = new Envelope(c1, c2);
515
//                                        spatialIndex.insert(env, new Integer(i));
516
                                        spatialIndex.insert(r, i);
517
                                }
518
                        } // for
519
                        va.stop();
520
                } catch (ReadDriverException e) {
521
                        e.printStackTrace();
522
                } 
523
        }
524

    
525
        public void setSelectedEditing() throws ReadDriverException {
526
                FBitSet bitSet = getRecordset().getSelection();
527
                if (bitSet.cardinality() == 0)
528
                        return;
529
                indexEditing = bitSet.nextSetBit(0);
530
        }
531

    
532
        public void setInPixels(boolean b) {
533
                inPixels = b;
534
        }
535

    
536
        public boolean isInPixels() {
537
                return inPixels;
538
        }
539

    
540
        public void setInEdition(int i) {
541
                indexEditing = i;
542

    
543
        }
544

    
545
        public int getInEdition() {
546
                return indexEditing;
547
        }
548

    
549
        public ArrayList getLabels() {
550
                return m_labels;
551
        }
552

    
553

    
554
        public void setLegend() {
555
                try {
556
                        getSource().getRecordset().start();
557
                        vuvl.setClassifyingFieldNames(
558
                                        new String[] {
559
                                                        getSource().getRecordset().getFieldName(mapping.getColumnText())
560
                                        }
561
                        );
562

    
563
//                        vuvl.setDefaultSymbol(new FSymbol(FConstant.SYMBOL_TYPE_TEXT));
564
                        vuvl.setDefaultSymbol(SymbologyFactory.createDefaultTextSymbol());
565
                        setLegend((IVectorLegend) vuvl);
566
                        getSource().getRecordset().stop();
567
                } catch (LegendLayerException e) {
568
                        e.printStackTrace();
569
                } catch (ReadDriverException e) {
570
                        e.printStackTrace();
571
                }
572

    
573
        }
574

    
575
        public Strategy getStrategy() {
576
                return strategy;
577
        }
578
        public void setEditing(boolean b) throws StartEditionLayerException {
579
                super.setEditing(b);
580
                deleteSpatialIndex();
581
        }
582

    
583
        public static FLayer createLayerFromVect(FLyrVect layer) throws ReadDriverException, LegendLayerException{
584
                FLyrAnnotation la=new FLyrAnnotation();
585
                la.setSource(layer.getSource());
586
                la.setRecordset(layer.getRecordset());
587
                la.setProjection(layer.getProjection());
588
                la.setLegend((IVectorLegend)layer.getLegend());
589
                return la;
590
        }
591
}