Statistics
| Revision:

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

History | View | Annotate | Download (16.1 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.util.ArrayList;
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.driverManager.Driver;
18
import com.hardcode.driverManager.DriverLoadException;
19
import com.hardcode.gdbms.driver.exceptions.InitializeDriverException;
20
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
21
import com.hardcode.gdbms.engine.data.driver.DriverException;
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.exceptions.expansionfile.ExpansionFileReadException;
29
import com.iver.cit.gvsig.exceptions.layers.LegendLayerException;
30
import com.iver.cit.gvsig.exceptions.layers.StartEditionLayerException;
31
import com.iver.cit.gvsig.exceptions.visitors.VisitorException;
32
import com.iver.cit.gvsig.fmap.ViewPort;
33
import com.iver.cit.gvsig.fmap.core.IGeometry;
34
import com.iver.cit.gvsig.fmap.core.SymbologyFactory;
35
import com.iver.cit.gvsig.fmap.core.symbols.ISymbol;
36
import com.iver.cit.gvsig.fmap.core.symbols.ITextSymbol;
37
import com.iver.cit.gvsig.fmap.core.v02.FLabel;
38
import com.iver.cit.gvsig.fmap.core.v02.FSymbol;
39
import com.iver.cit.gvsig.fmap.crs.CRSFactory;
40
import com.iver.cit.gvsig.fmap.drivers.BoundedShapes;
41
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes;
42
import com.iver.cit.gvsig.fmap.drivers.VectorialDriver;
43
import com.iver.cit.gvsig.fmap.edition.AnnotationEditableAdapter;
44
import com.iver.cit.gvsig.fmap.operations.strategies.AnnotationStrategy;
45
import com.iver.cit.gvsig.fmap.operations.strategies.Strategy;
46
import com.iver.cit.gvsig.fmap.operations.strategies.StrategyManager;
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 (ReadDriverException 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
         *      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) {
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
                mapping = MappingAnnotation.createFromXML(xml.getChild(2));//getIntArrayProperty("mapping");
245
                setInPixels(xml.getBooleanProperty("isInPixels"));
246

    
247
                IProjection proj = null;
248

    
249
                if (xml.contains("proj")) {
250
                        proj = CRSFactory.getCRS(xml.getStringProperty("proj"));
251
                }
252

    
253
                VectorialFileAdapter adapter = new VectorialFileAdapter(new File(xml
254
                                .getStringProperty("file")));
255
                Driver d;
256

    
257
                try {
258
                        d = LayerFactory.getDM().getDriver(
259
                                        xml.getStringProperty("driverName"));
260
                } catch (DriverLoadException e1) {
261
                        throw new XMLException(e1);
262
                }
263

    
264
                adapter.setDriver((VectorialDriver) d);
265
                // TODO Meter esto dentro de la comprobaci?n de si hay memoria
266
                if (false) {
267
                } else {
268
                        setSource(adapter);
269
                        setProjection(proj);
270
                }
271

    
272
                // Le asignamos tambi?n una legenda por defecto acorde con
273
                // el tipo de shape que tenga. Tampoco s? si es aqu? el
274
                // sitio adecuado, pero en fin....
275
                /*
276
                 * if (d instanceof WithDefaultLegend) { WithDefaultLegend aux =
277
                 * (WithDefaultLegend) d; adapter.start(); setLegend((VectorialLegend)
278
                 * aux.getDefaultLegend()); adapter.stop(); } else {
279
                 * setLegend(LegendFactory.createSingleSymbolLegend(getShapeType())); }
280
                 */
281

    
282
                super.setXMLEntity(xml);
283
                try {
284
                        createLabels();
285
                } catch (ReadDriverException e) {
286
                        e.printStackTrace();
287
                }
288
        }
289

    
290
        /**
291
         * Esto tiene el fallo de que obligas a una etiqueta por entidad, para poder
292
         * evitar esto, una posible soluci?n ser?a que un FLabel pudiera ser una
293
         * colecci?n de FLabel (Patr?n Composite)
294
         *
295
         * @param lyrVect
296
         * @throws ReadDriverException
297
         * @throws DriverException
298
         */
299
        private void createLabels() throws ReadDriverException{
300
                SelectableDataSource ds = getRecordset();
301
                try {
302
                        ReadableVectorial adapter = getSource();
303
                        adapter.start();
304
                        ds.start();
305
                        int sc;
306
                        // El mapping[0] es el text
307
                        int fieldId = mapping.getColumnText();
308
                        // El mapping[1] es el ?ngulo
309
                        int idFieldRotationText = mapping.getColumnRotate();
310
                        // El mapping[2] es el color
311
                        int idFieldColorText = mapping.getColumnColor();
312
                        // El mapping[3] es el alto
313
                        int idFieldHeightText = mapping.getColumnHeight();
314
                        // El mapping[4] es el tipo de fuente
315
                        int idFieldTypeFontText = mapping.getColumnTypeFont();
316
                        // El mapping[5] es el estilo de fuente
317
                        int idFieldStyleFontText = mapping.getColumnStyleFont();
318

    
319
                        sc = (int) ds.getRowCount();
320
                        m_labels = new ArrayList(sc);
321
                        DriverAttributes attr = adapter.getDriverAttributes();
322
                        boolean bMustClone = false;
323
                        if (attr != null) {
324
                                if (attr.isLoadedInMemory()) {
325
                                        bMustClone = attr.isLoadedInMemory();
326
                                }
327
                        }
328
                        ICoordTrans ct = getCoordTrans();
329
                        FSymbol defaultSym = (FSymbol) getLegend().getDefaultSymbol();
330
                        for (int i = 0; i < sc; i++) {
331
                                IGeometry geom = adapter.getShape(i);
332

    
333
                                if (geom == null) {
334
                                        m_labels.add(null);
335
                                        continue;
336
                                }
337
                                if (ct != null) {
338
                                        if (bMustClone)
339
                                                geom = geom.cloneGeometry();
340
                                        geom.reProject(ct);
341
                                }
342

    
343
                                // TODO: El m?todo contenedor (createLabelLayer) debe recoger
344
                                // los par?metros de posicionamiento y de allowDuplicates
345
                                // if (i >= 328)
346
                                // System.out.println("i= " + i + " " + val.toString());
347
                                //ArrayList values=new ArrayList(4);
348
                                String t=new String();
349
                                Value val = ds.getFieldValue(i, fieldId);
350
                                t=val.toString();
351
                                //values.add(val);
352
                                if (idFieldColorText!=-1){
353
                                        Value valColor=ds.getFieldValue(i,idFieldColorText);
354
                                        t=t.concat(valColor.toString());
355
                                        //values.add(valColor);
356
                                }
357
                                if (idFieldTypeFontText!=-1){
358
                                        Value valTypeFont=ds.getFieldValue(i,idFieldTypeFontText);
359
                                        t=t.concat(valTypeFont.toString());
360
                                        //values.add(valTypeFont);
361
                                }
362

    
363
                                if (idFieldStyleFontText!=-1){
364
                                        Value valStyleFont=ds.getFieldValue(i,idFieldStyleFontText);
365
                                        t=t.concat(valStyleFont.toString());
366
                                        //values.add(valStyleFont);
367
                                }
368
                                //Value total=ValueFactory.createValue((Value[])values.toArray(new Value[0]));
369
                                Value total=ValueFactory.createValue(t);
370
                                if ((val instanceof NullValue) || (val == null)) {
371
                                        m_labels.add(null);
372
                                        continue;
373
                                }
374
                                FLabel[] lbls = geom.createLabels(0, true);
375
                                for (int j = 0; j < lbls.length; j++) {
376
                                        if (lbls[j] != null) {
377
                                                lbls[j].setString(val.toString());
378
                                                if (idFieldRotationText != -1) {
379
                                                        NumericValue rotation = (NumericValue) ds
380
                                                                        .getFieldValue(i, idFieldRotationText);
381
                                                        lbls[j].setRotation(rotation.doubleValue());
382
                                                } else {
383
                                                        lbls[j].setRotation(defaultSym.getRotation());
384
                                                }
385

    
386
                                                float height;
387
                                                if (idFieldHeightText != -1) {
388
                                                        NumericValue h = (NumericValue) ds
389
                                                                        .getFieldValue(i, idFieldHeightText);
390
                                                        height=h.floatValue();
391
                                                        lbls[j].setHeight(height);
392
                                                } else {
393
                                                        height=defaultSym.getFontSize();
394
                                                        lbls[j].setHeight(height);
395
                                                }
396

    
397

    
398

    
399
                                                if (vuvl.getSymbolByValue(total)==null){
400
                                                        Color color;
401
                                                        if (idFieldColorText != -1) {
402
                                                                NumericValue c = (NumericValue) ds.getFieldValue(
403
                                                                                i, idFieldColorText);
404
                                                                color=new Color(c.intValue());
405
                                                        } else {
406
                                                                color=defaultSym.getFontColor();
407
                                                        }
408
                                                        String typeFont;
409
                                                        if (idFieldTypeFontText != -1) {
410
                                                                StringValue tf = (StringValue) ds
411
                                                                                .getFieldValue(i, idFieldTypeFontText);
412
                                                                typeFont=tf.getValue();
413
                                                        } else {
414
                                                                typeFont=defaultSym.getFont().getFontName();
415
                                                        }
416
                                                        int style;
417
                                                        if (idFieldStyleFontText != -1) {
418
                                                                IntValue sf = (IntValue) ds
419
                                                                                .getFieldValue(i, idFieldStyleFontText);
420
                                                                style = sf.getValue();
421
                                                        } else {
422
                                                                style = defaultSym.getFont().getStyle();
423
                                                        }
424
                                                        //FSymbol symbol=new FSymbol(FConstant.SYMBOL_TYPE_TEXT);
425

    
426
                                                        ITextSymbol symbol;
427

    
428
                                                        symbol = SymbologyFactory.createDefaultTextSymbol();
429

    
430
                                                        // casca perque ara ?s un ITextSymbol
431
//                                                        symbol.setFontSizeInPixels(isInPixels());
432
                                                        symbol.setFont(new Font(typeFont, style, (int)height));
433
                                                        symbol.setDescription(lbls[j].getString());
434
                                                        //symbol.setFontColor(color);
435
                                                        symbol.setTextColor(color);
436
                                                        vuvl.addSymbol(total,symbol);
437
                                                }
438

    
439
                                        }
440
                                m_labels.add(lbls[j]);
441

    
442
                                }
443
                        }
444

    
445
                        ds.stop();
446
                        adapter.stop();
447
                } catch (ExpansionFileReadException e) {
448
                        throw new ReadDriverException(getName(),e);
449
                } catch (InitializeDriverException e) {
450
                        throw new ReadDriverException(getName(),e);
451
                }
452

    
453
        }
454

    
455
        public FLabel getLabel(int numReg) {
456
                if (m_labels == null || numReg == -1)
457
                        return null;
458
                if (getSource() instanceof AnnotationEditableAdapter){
459
                        AnnotationEditableAdapter aea=((AnnotationEditableAdapter)getSource());
460
                        return aea.getLabel(numReg,false);
461
                }
462
                return (FLabel)m_labels.get(numReg);
463
        }
464

    
465
        /*
466
         * (non-Javadoc)
467
         *
468
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.RandomVectorialData#createIndex()
469
         */
470
        public void createSpatialIndex() {
471
                // FJP: ESTO HABR? QUE CAMBIARLO. PARA LAS CAPAS SECUENCIALES, TENDREMOS
472
                // QUE ACCEDER CON UN WHILE NEXT. (O mejorar lo de los FeatureVisitor
473
                // para que acepten recorrer sin geometria, solo con rectangulos.
474

    
475
                //AZABALA: Como no tengo claro de donde se crean las capas de textos
476
                //el ?ndice espacial creado seguir? siendo el Quadtree en memoria
477
                //de JTS (QuadtreeJts es un adapter a nuestra api de indices)
478
                spatialIndex = new QuadtreeJts();
479
                ReadableVectorial va = getSource();
480
                ICoordTrans ct = getCoordTrans();
481
                BoundedShapes shapeBounds = (BoundedShapes) va.getDriver();
482
                try {
483
                        va.start();
484

    
485
                        for (int i = 0; i < va.getShapeCount(); i++) {
486
                                Rectangle2D r = null;
487
                                FLabel label=getLabel(i);
488
                                if (label != null) {
489
                                        r = label.getBoundBox();
490
                                } else {
491
                                        r = shapeBounds.getShapeBounds(i);
492
                                }
493
                                // TODO: MIRAR COMO SE TRAGAR?A ESTO LO DE LAS REPROYECCIONES
494
                                if (ct != null) {
495
                                        r = ct.convert(r);
496
                                }
497
                                if (r != null) {
498
//                                        Coordinate c1 = new Coordinate(r.getMinX(), r.getMinY());
499
//                                        Coordinate c2 = new Coordinate(r.getMaxX(), r.getMaxY());
500
//                                        Envelope env = new Envelope(c1, c2);
501
//                                        spatialIndex.insert(env, new Integer(i));
502
                                        spatialIndex.insert(r, i);
503
                                }
504
                        } // for
505
                        va.stop();
506
                } catch (ReadDriverException e) {
507
                        e.printStackTrace();
508
                } catch (ExpansionFileReadException e) {
509
                        e.printStackTrace();
510
                }
511
        }
512

    
513
        public void setSelectedEditing() throws ReadDriverException {
514
                FBitSet bitSet = getRecordset().getSelection();
515
                if (bitSet.cardinality() == 0)
516
                        return;
517
                indexEditing = bitSet.nextSetBit(0);
518
        }
519

    
520
        public void setInPixels(boolean b) {
521
                inPixels = b;
522
        }
523

    
524
        public boolean isInPixels() {
525
                return inPixels;
526
        }
527

    
528
        public void setInEdition(int i) {
529
                indexEditing = i;
530

    
531
        }
532

    
533
        public int getInEdition() {
534
                return indexEditing;
535
        }
536

    
537
        public ArrayList getLabels() {
538
                return m_labels;
539
        }
540

    
541

    
542
        public void setLegend() {
543
                try {
544
                        getSource().getRecordset().start();
545
                        vuvl.setFieldName(getSource().getRecordset().getFieldName(mapping.getColumnText()));
546

    
547
//                        vuvl.setDefaultSymbol(new FSymbol(FConstant.SYMBOL_TYPE_TEXT));
548
                        vuvl.setDefaultSymbol(SymbologyFactory.createDefaultTextSymbol());
549
                        setLegend(vuvl);
550
                        getSource().getRecordset().stop();
551
                } catch (LegendLayerException e) {
552
                        e.printStackTrace();
553
                } catch (ReadDriverException e) {
554
                        e.printStackTrace();
555
                }
556

    
557
        }
558

    
559
        public Strategy getStrategy() {
560
                return strategy;
561
        }
562
        public void setEditing(boolean b) throws StartEditionLayerException {
563
                super.setEditing(b);
564
                setISpatialIndex(null);
565
        }
566
}