Statistics
| Revision:

root / trunk / extensions / extAnnotations / src / com / iver / cit / gvsig / fmap / layers / Annotation_Layer.java @ 33261

History | View | Annotate | Download (25.7 KB)

1

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

    
43
package com.iver.cit.gvsig.fmap.layers;
44

    
45
import java.awt.Color;
46
import java.awt.Font;
47
import java.awt.Graphics2D;
48
import java.awt.Shape;
49
import java.awt.font.FontRenderContext;
50
import java.awt.font.GlyphVector;
51
import java.awt.geom.AffineTransform;
52
import java.awt.geom.Point2D;
53
import java.awt.geom.Rectangle2D;
54
import java.awt.image.BufferedImage;
55
import java.io.File;
56

    
57
import javax.print.attribute.PrintRequestAttributeSet;
58

    
59
import org.cresques.cts.ICoordTrans;
60
import org.cresques.cts.IProjection;
61
import org.gvsig.tools.file.PathGenerator;
62

    
63
import com.hardcode.driverManager.Driver;
64
import com.hardcode.driverManager.DriverLoadException;
65
import com.hardcode.gdbms.driver.exceptions.InitializeDriverException;
66
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
67
import com.hardcode.gdbms.engine.data.driver.DriverException;
68
import com.hardcode.gdbms.engine.instruction.FieldNotFoundException;
69
import com.hardcode.gdbms.engine.values.NullValue;
70
import com.hardcode.gdbms.engine.values.NumericValue;
71
import com.hardcode.gdbms.engine.values.StringValue;
72
import com.hardcode.gdbms.engine.values.Value;
73
import com.hardcode.gdbms.engine.values.ValueFactory;
74
import com.iver.andami.messages.NotificationManager;
75
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException;
76
import com.iver.cit.gvsig.exceptions.layers.CancelEditingLayerException;
77
import com.iver.cit.gvsig.exceptions.layers.LegendLayerException;
78
import com.iver.cit.gvsig.exceptions.layers.StartEditionLayerException;
79
import com.iver.cit.gvsig.exceptions.visitors.StartWriterVisitorException;
80
import com.iver.cit.gvsig.exceptions.visitors.VisitorException;
81
import com.iver.cit.gvsig.fmap.MapContext;
82
import com.iver.cit.gvsig.fmap.ViewPort;
83
import com.iver.cit.gvsig.fmap.core.FPoint2D;
84
import com.iver.cit.gvsig.fmap.core.GeneralPathX;
85
import com.iver.cit.gvsig.fmap.core.IGeometry;
86
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
87
import com.iver.cit.gvsig.fmap.core.SymbologyFactory;
88
import com.iver.cit.gvsig.fmap.core.symbols.IMarkerSymbol;
89
import com.iver.cit.gvsig.fmap.core.symbols.ISymbol;
90
import com.iver.cit.gvsig.fmap.core.symbols.ITextSymbol;
91
import com.iver.cit.gvsig.fmap.core.symbols.SimpleTextSymbol;
92
import com.iver.cit.gvsig.fmap.crs.CRSFactory;
93
import com.iver.cit.gvsig.fmap.drivers.BoundedShapes;
94
import com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver;
95
import com.iver.cit.gvsig.fmap.edition.Annotation_EditableAdapter;
96
import com.iver.cit.gvsig.fmap.edition.EditionEvent;
97
import com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter;
98
import com.iver.cit.gvsig.fmap.operation.strategies.Annotation_Strategy;
99
import com.iver.cit.gvsig.fmap.operations.strategies.Strategy;
100
import com.iver.cit.gvsig.fmap.operations.strategies.StrategyManager;
101
import com.iver.cit.gvsig.fmap.rendering.Annotation_Legend;
102
import com.iver.cit.gvsig.fmap.rendering.IVectorLegend;
103
import com.iver.cit.gvsig.fmap.spatialindex.QuadtreeJts;
104
import com.iver.utiles.XMLEntity;
105
import com.iver.utiles.swing.threads.Cancellable;
106

    
107

    
108
/**
109
 * Annotation's layer.
110
 *
111
 * @author Vicente Caballero Navarro
112
 */
113
public class Annotation_Layer extends FLyrVect {
114
        private Annotation_Mapping mapping = null;
115
        private int indexEditing = -1;
116
        private Annotation_Legend aLegend;
117
        private Strategy strategy = null;
118
        private IMarkerSymbol symbolPoint = SymbologyFactory.createDefaultMarkerSymbol();
119
        private final static AffineTransform ati=new AffineTransform();
120
        /**
121
         * Crea un nuevo FLyrAnnotation.
122
         */
123
        public Annotation_Layer() {
124
                super();
125
        }
126

    
127
        /**
128
         * DOCUMENT ME!
129
         *
130
         * @param mapping DOCUMENT ME!
131
         * @throws ReadDriverException
132
         * @throws LegendLayerException
133
         * @throws DriverException
134
         * @throws FieldNotFoundException
135
         */
136
        public void setMapping(Annotation_Mapping mapping) throws LegendLayerException, ReadDriverException {
137
                this.mapping = mapping;
138
                aLegend = new Annotation_Legend();
139
                setLegend();
140
        }
141

    
142
        /**
143
         * DOCUMENT ME!
144
         *
145
         * @return DOCUMENT ME!
146
         */
147
        public Annotation_Mapping getAnnotatonMapping() {
148
                return mapping;
149
        }
150

    
151
        /**
152
         * @throws ReadDriverException
153
         * @throws InitializeDriverException
154
         * @see com.iver.cit.gvsig.fmap.layers.LayerOperations#draw(java.awt.image.BufferedImage,
155
         *      java.awt.Graphics2D, ISymbol)
156
         */
157
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
158
                        Cancellable cancel, double scale) throws InitializeDriverException, ReadDriverException {
159
                if (isWithinScale(scale)) {
160
                        // Las que solo tienen etiquetado sin pintar el shape,
161
                        // no pasamos por ellas
162
                        boolean bDrawShapes = true;
163

    
164
                        if (bDrawShapes) {
165
                                if (strategy == null) {
166
                                        strategy = new Annotation_Strategy(this);
167
                                }
168
                                g.setColor(Color.black);
169
                                ReadableVectorial adapter = getSource();
170
                                adapter.start();
171
                                drawAnnotations(image,g,viewPort,cancel,null);
172
                                adapter.stop();
173
                        }
174

    
175
                        if (getVirtualLayers() != null) {
176
                                getVirtualLayers().draw(image, g, viewPort, cancel, scale);
177
                        }
178
                }
179
        }
180
        private void drawAnnotations(BufferedImage image, Graphics2D g, ViewPort viewPort,
181
                        Cancellable cancel,PrintRequestAttributeSet properties) {
182
                BufferedImage bi=new BufferedImage(viewPort.getImageWidth(),viewPort.getImageHeight(),BufferedImage.TYPE_INT_ARGB);
183
                Graphics2D gBi=(Graphics2D)bi.getGraphics();
184
                Point2D offset=viewPort.getOffset();
185
                gBi.translate(-offset.getX(),-offset.getY());
186
                Annotation_Legend l = (Annotation_Legend) getLegend();
187
                ITextSymbol sym = (ITextSymbol) l.getDefaultSymbol();
188

    
189
                try {
190
                        ReadableVectorial source = getSource();
191
                        // limit the labeling to the visible extent
192
                        FBitSet bs = queryByRect(viewPort.getAdjustedExtent());
193

    
194
                        SelectableDataSource recordSet = source.getRecordset();
195
                        recordSet.start();
196
                        FBitSet bitSet = recordSet.getSelection();
197
                        Annotation_Mapping mapping = getAnnotatonMapping();
198
                        int idHeightField = mapping.getColumnHeight();
199
                        int idFontName = mapping.getColumnTypeFont();
200
                        int idFontStyle = mapping.getColumnStyleFont();
201
                        int idRotationField = mapping.getColumnRotate();
202
                        int idFontColor = mapping.getColumnColor();
203
                        int idTextField = mapping.getColumnText();
204

    
205
                        double rotation = 0D;
206
                        float size = sym.getFont().getSize();
207

    
208
                        String fontName = "Dialog";
209
                        int fontStyle = sym.getFont().getStyle();
210
                        int fontColor = sym.getTextColor().getRGB();
211
                        long t1 = System.currentTimeMillis();
212

    
213
                        for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1)) {
214
                                if (cancel.isCanceled()) {
215
                                        break;
216
                                }
217

    
218
                                Value[] vv = recordSet.getRow(i);
219

    
220
                                if (idHeightField != -1) {
221
                                        // text size is defined in the table
222
                                        try {
223
                                                size = (float)(((NumericValue) vv[idHeightField]).doubleValue());
224
                                        } catch (ClassCastException ccEx) {
225
                                                if (!NullValue.class.equals(
226
                                                                vv[idHeightField].getClass())) {
227
                                                }
228
                                                continue;
229
                                        }
230
                                }
231

    
232
                                if (idFontName != -1) {
233
                                        fontName = ((StringValue) vv[idFontName]).toString();
234
                                }
235

    
236
                                if (idFontStyle != -1) {
237
                                        fontStyle = ((NumericValue) vv[idFontStyle]).intValue();
238
                                }
239

    
240
                                if (idRotationField != -1) {
241
                                        // text rotation is defined in the table
242
                                        rotation = ((NumericValue) vv[idRotationField]).doubleValue();
243
                                        ((SimpleTextSymbol)sym).setRotation(Math.toRadians(rotation));
244
                                }
245

    
246
                                if (idFontColor != -1) {
247
                                        // text rotation is defined in the table
248
                                        fontColor = ((NumericValue) vv[idFontColor]).intValue();
249
                                        sym.setTextColor(new Color(fontColor));
250
                                }
251

    
252
                                if (bitSet.get(i)) {
253
                                        sym = (ITextSymbol) sym.getSymbolForSelection();
254
                                }
255

    
256
                                sym.setFont(new Font(fontName, fontStyle, (int) size));
257
                                source.start();
258
                                IGeometry geom = source.getShape(i);
259
                                source.stop();
260
                                ICoordTrans ct = getCoordTrans();
261

    
262
                                boolean bMustClone = false;
263

    
264
                                if (geom == null) {
265
                                        return;
266
                                }
267

    
268
                                if (ct != null) {
269
                                        if (bMustClone) {
270
                                                geom = geom.cloneGeometry();
271
                                        }
272

    
273
                                        geom.reProject(ct);
274
                                }
275
                                geom.transform(viewPort.getAffineTransform());
276
                                Shape shape=geom.getInternalShape();
277
                                FPoint2D fpPixels=null;
278
                                if (!(shape instanceof FPoint2D)) {
279
                                        Rectangle2D rP=shape.getBounds2D();
280
                                        fpPixels=new FPoint2D(rP.getX(),rP.getY());
281
                                }else {
282
                                        fpPixels=(FPoint2D)shape;
283
                                }
284
                                int unit=-1;
285

    
286
                                unit=l.getUnits();
287
                                boolean draw=false;
288
                                Rectangle2D r=getTextWrappingGeometryInPixels(unit,size,vv[idTextField].toString(),rotation,fontName, fontStyle,i,viewPort,geom).getBounds2D();
289
                                Rectangle2D rPixels=new Rectangle2D.Double(r.getMinX(),r.getMinY(),r.getWidth(),r.getHeight());
290

    
291
                                Point2D p=new Point2D.Double(fpPixels.getX(),fpPixels.getY());
292

    
293

    
294
                                if (!isEditing() && l.isAvoidOverLapping()){
295
                                        p=getPoint(bi,rPixels,l.isDelOverLapping(), offset);
296
                                        if (p!=null){
297
                                                draw=true;
298
                                        }
299
                                }else{
300
                                        if (!isEditing() && l.isDelOverLapping()){
301
                                                if (isOverlapping(bi,rPixels, offset)){
302
                                                        draw=true;
303
                                                }
304
                                        }else{
305
                                                draw=true;
306
                                        }
307
                                }
308
                                if (l.isPointVisible()) {
309
                                        symbolPoint.draw(gBi,
310
                                                        ati,
311
                                                        fpPixels, cancel);
312
                                }
313

    
314
                                if (draw){
315
                                        //Si el tama?o de la fuente est? en unidades de mapa.
316
                                        if (unit!=-1) {
317
                                                ((SimpleTextSymbol)l.getDefaultSymbol()).setFontSize(getTextHeightInPixels(unit, size, viewPort));
318
                                        }
319
                                        //Como ya hemos cambiado el tama?o a la fuente adapt?ndolo a p?xels pasamos units = -1 ?
320
                                        drawAnnotation(gBi,-1,this,l, p, vv[idTextField].toString(),viewPort,properties);
321
                                }
322
                        }
323
                        gBi.translate(offset.getX(),offset.getY());
324
                        g.drawImage(bi,(int)offset.getX(),(int)offset.getY(),null);
325
                        System.err.println(System.currentTimeMillis()-t1+"millis");
326
                        recordSet.stop();
327
                } catch (Exception e) {
328
                        NotificationManager.addError(e); // TODO esto no puede estar aqu?, pertenece a una capa de abtracci?n superior
329
                }
330
        }
331
        private Point2D getPoint(BufferedImage bi, Rectangle2D rec, boolean b, Point2D offset) {
332
                Rectangle2D r=new Rectangle2D.Double(rec.getMinX(),rec.getMaxY(),rec.getWidth(),rec.getHeight());
333
                if (isOverlapping(bi,r, offset)){
334
                        return new Point2D.Double(r.getX(),r.getY());
335
                }
336
                r.setFrame(rec.getMinX(),rec.getMinY(),rec.getWidth(),rec.getHeight());
337
                if (isOverlapping(bi,r, offset)){
338
                        return new Point2D.Double(r.getX(),r.getY());
339
                }
340
                r.setFrame(rec.getMinX()-rec.getWidth(),rec.getMaxY(),rec.getWidth(),rec.getHeight());
341
                if (isOverlapping(bi,r, offset)){
342
                        return new Point2D.Double(r.getX(),r.getY());
343
                }
344
                r.setFrame(rec.getMinX()-rec.getWidth(),rec.getMinY(),rec.getWidth(),rec.getHeight());
345
                if (isOverlapping(bi,r, offset)){
346
                        return new Point2D.Double(r.getX(),r.getY());
347
                }
348
                r.setFrame(rec.getMinX()-rec.getWidth()/2,rec.getMaxY(),rec.getWidth(),rec.getHeight());
349
                if (isOverlapping(bi,r, offset)){
350
                        return new Point2D.Double(r.getX(),r.getY());
351
                }
352
                r.setFrame(rec.getMinX()-rec.getWidth()/2,rec.getMinY(),rec.getWidth(),rec.getHeight());
353
                if (isOverlapping(bi,r, offset)){
354
                        return new Point2D.Double(r.getX(),r.getY());
355
                }
356
                r.setFrame(rec.getMinX(),(rec.getMaxY()+rec.getMinY())/2,rec.getWidth(),rec.getHeight());
357
                if (isOverlapping(bi,r, offset)){
358
                        return new Point2D.Double(r.getX(),r.getY());
359
                }
360
                if (!b){
361
                        return new Point2D.Double(rec.getMinX(),rec.getMaxY());
362
                } else {
363
                        return null;
364
                }
365
        }
366

    
367
        private boolean isOverlapping(BufferedImage bi, Rectangle2D rPixels, Point2D offset) {
368
                for (int i=(int)(rPixels.getMinX()-offset.getX());i<rPixels.getMaxX()-offset.getX();i++){
369
                        for (int j=(int)(rPixels.getMinY()-offset.getY());j<rPixels.getMaxY()-offset.getY();j++){
370
                                if (i<0 || j<0 || bi.getWidth()<i+1 || bi.getHeight()<j+1)
371
                                        continue;
372
                                if (bi.getRGB(i,j)!=0){
373
                                        return false;
374
                                }
375
                        }
376
                }
377
                return true;
378
        }
379

    
380
        /**
381
         * @throws ReadDriverException
382
         * @throws InitializeDriverException
383
         * @throws ExpansionFileReadException
384
         * @see com.iver.cit.gvsig.fmap.layers.LayerOperations#getFullExtent()
385
         */
386
        public Rectangle2D getFullExtent() throws InitializeDriverException,
387
        ReadDriverException, ExpansionFileReadException {
388
                Rectangle2D rAux;
389
                getSource().start();
390
                rAux = getSource().getFullExtent();
391
                getSource().stop();
392

    
393
                // Si existe reproyecci?n, reproyectar el extent
394
                ICoordTrans ct = getCoordTrans();
395

    
396
                if (ct != null) {
397
                        Point2D pt1 = new Point2D.Double(rAux.getMinX(), rAux.getMinY());
398
                        Point2D pt2 = new Point2D.Double(rAux.getMaxX(), rAux.getMaxY());
399
                        pt1 = ct.convert(pt1, null);
400
                        pt2 = ct.convert(pt2, null);
401
                        rAux = new Rectangle2D.Double();
402
                        rAux.setFrameFromDiagonal(pt1, pt2);
403
                }
404

    
405
                return rAux;
406
        }
407

    
408
        /**
409
         * @throws ReadDriverException
410
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#print(java.awt.Graphics2D,
411
         *      com.iver.cit.gvsig.fmap.ViewPort,
412
         *      com.iver.utiles.swing.threads.Cancellable)
413
         */
414
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
415
                        double scale, PrintRequestAttributeSet properties) throws ReadDriverException{
416
                if (isVisible() && isWithinScale(scale)) {
417
                        drawAnnotations(null,g, viewPort, cancel, properties);
418
                }
419
        }
420

    
421
        /*
422
         * (non-Javadoc)
423
         *
424
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.RandomVectorialData#queryByRect(java.awt.geom.Rectangle2D)
425
         */
426
        public FBitSet queryByRect(Rectangle2D rect) throws ReadDriverException, VisitorException {
427
                Strategy s = StrategyManager.getStrategy(this);
428

    
429
                return s.queryByRect(rect);
430
        }
431

    
432
        /**
433
         * DOCUMENT ME!
434
         *
435
         * @param p DOCUMENT ME!
436
         * @param tolerance DOCUMENT ME!
437
         *
438
         * @return DOCUMENT ME!
439
         * @throws VisitorException
440
         * @throws ReadDriverException
441
         *
442
         * @throws DriverException DOCUMENT ME!
443
         */
444
        public FBitSet queryByPoint(Point2D p, double tolerance) throws ReadDriverException, VisitorException {
445
                Strategy s = StrategyManager.getStrategy(this);
446

    
447
                return s.queryByPoint(p, tolerance);
448
        }
449

    
450
        /**
451
         * DOCUMENT ME!
452
         *
453
         * @param g DOCUMENT ME!
454
         * @param relationship DOCUMENT ME!
455
         *
456
         * @return DOCUMENT ME!
457
         * @throws VisitorException
458
         * @throws ReadDriverException
459
         *
460
         * @throws DriverException DOCUMENT ME!
461
         * @throws VisitException DOCUMENT ME!
462
         */
463
        public FBitSet queryByShape(IGeometry g, int relationship) throws ReadDriverException, VisitorException {
464
                Strategy s = StrategyManager.getStrategy(this);
465

    
466
                return s.queryByShape(g, relationship);
467
        }
468

    
469
        /**
470
         * DOCUMENT ME!
471
         *
472
         * @return DOCUMENT ME!
473
         *
474
         * @throws XMLException
475
         *
476
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getProperties()
477
         */
478
        public XMLEntity getXMLEntity() throws XMLException {
479
                XMLEntity xml = super.getXMLEntity();
480
                return xml;
481
        }
482

    
483
        /**
484
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setXMLEntity(com.iver.utiles.XMLEntity)
485
         */
486
        public void setXMLEntity(XMLEntity xml) throws XMLException {
487
                IProjection proj = null;
488

    
489
                if (xml.contains("proj")) {
490
                        proj = CRSFactory.getCRS(xml.getStringProperty("proj"));
491
                }
492

    
493
                if (xml.contains("file")) {
494
                        Driver d;
495

    
496
                        try {
497
                                d = LayerFactory.getDM().getDriver(xml.getStringProperty(
498
                                                "driverName"));
499
                        } catch (DriverLoadException e1) {
500
                                throw new XMLException(e1);
501
                        }
502

    
503
                        FLyrVect lv = (FLyrVect) LayerFactory.createLayer(xml.getName(),
504
                                        (VectorialFileDriver) d,
505
                                        new File(PathGenerator.getInstance().getAbsolutePath(xml.getStringProperty("file"))), proj);
506

    
507
                        try {
508
                                this.setSource(lv.getSource());
509
                                this.setRecordset(lv.getRecordset());
510
                                this.setProjection(lv.getProjection());
511
                                this.setLegend((IVectorLegend) lv.getLegend());
512

    
513

    
514
                                Annotation_Mapping.addAnnotationMapping(this);
515
                        } catch (ReadDriverException e) {
516
                                throw new XMLException(e);
517
                        } catch (LegendLayerException e) {
518
                                throw new XMLException(e);
519
                        }
520
                }
521
                super.setXMLEntity(xml);
522
//                if (this.getLabelingStrategy()==null){
523
//                        boolean isInPixel=((Annotation_Legend)this.getLegend()).isFontSizeInPixels();
524
//                        if (isInPixel){
525
//                                AttrInTableLabelingStrategy labeling = new AttrInTableLabelingStrategy();
526
//                                labeling.setUnit(-1);
527
//                                setLabelingStrategy(labeling);
528
//                        }else{
529
//                                AttrInTableLabelingStrategy labeling = new AttrInTableLabelingStrategy();
530
//                                labeling.setUnit(1);
531
//                                setLabelingStrategy(labeling);
532
//                        }
533
//                }
534
        }
535

    
536
        public Value getSymbolKey(int i) throws ReadDriverException {
537
                SelectableDataSource ds = getRecordset();
538
                String t = new String();
539
                Value val = ds.getFieldValue(i, mapping.getColumnText());
540
                t = val.toString();
541

    
542
                if (mapping.getColumnColor() != -1) {
543
                        Value valColor = ds.getFieldValue(i, mapping.getColumnColor());
544
                        t = t.concat(valColor.toString());
545
                }
546

    
547
                if (mapping.getColumnTypeFont() != -1) {
548
                        Value valTypeFont = ds.getFieldValue(i, mapping.getColumnTypeFont());
549
                        t = t.concat(valTypeFont.toString());
550
                }
551

    
552
                if (mapping.getColumnStyleFont() != -1) {
553
                        Value valStyleFont = ds.getFieldValue(i,
554
                                        mapping.getColumnStyleFont());
555
                        t = t.concat(valStyleFont.toString());
556
                }
557

    
558
                Value total = ValueFactory.createValue(t);
559

    
560
                return total;
561
        }
562

    
563
        /*
564
         * (non-Javadoc)
565
         *
566
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.RandomVectorialData#createIndex()
567
         */
568
        public void createSpatialIndex()  {
569
                // FJP: ESTO HABR? QUE CAMBIARLO. PARA LAS CAPAS SECUENCIALES, TENDREMOS
570
                // QUE ACCEDER CON UN WHILE NEXT. (O mejorar lo de los FeatureVisitor
571
                // para que acepten recorrer sin geometria, solo con rectangulos.
572
                // AZABALA: Como no tengo claro de donde se crean las capas de textos
573
                // el ?ndice espacial creado seguir? siendo el Quadtree en memoria
574
                // de JTS (QuadtreeJts es un adapter a nuestra api de indices)
575
                spatialIndex = new QuadtreeJts();
576

    
577
                ReadableVectorial va = getSource();
578
                ICoordTrans ct = getCoordTrans();
579
                BoundedShapes shapeBounds = (BoundedShapes) va.getDriver();
580

    
581
                try {
582
                        va.start();
583

    
584
                        for (int i = 0; i < va.getShapeCount(); i++) {
585
                                Rectangle2D r = null;
586
                                IGeometry geom = va.getShape(i);
587
                                if (geom != null) {
588
                                        r = geom.getBounds2D();
589
                                } else {
590
                                        r = shapeBounds.getShapeBounds(i);
591
                                }
592

    
593
                                // TODO: MIRAR COMO SE TRAGAR?A ESTO LO DE LAS REPROYECCIONES
594
                                if (ct != null) {
595
                                        r = ct.convert(r);
596
                                }
597

    
598
                                if (r != null) {
599
                                        spatialIndex.insert(r, i);
600
                                }
601
                        } // for
602

    
603
                        va.stop();
604
                } catch (ExpansionFileReadException e) {
605
                        NotificationManager.addError(this.getName(),e);
606
                } catch (ReadDriverException e) {
607
                        NotificationManager.addError(this.getName(),e);
608
                }
609
        }
610

    
611
        /**
612
         * DOCUMENT ME!
613
         * @throws ReadDriverException
614
         *
615
         * @throws DriverException DOCUMENT ME!
616
         */
617
        public void setSelectedEditing() throws ReadDriverException {
618
                FBitSet bitSet = getRecordset().getSelection();
619

    
620
                if (bitSet.cardinality() == 0) {
621
                        return;
622
                }
623

    
624
                indexEditing = bitSet.nextSetBit(0);
625
        }
626

    
627
        public void setInEdition(int i) {
628
                indexEditing = i;
629
        }
630

    
631
        /**
632
         * DOCUMENT ME!
633
         *
634
         * @return DOCUMENT ME!
635
         */
636
        public int getInEdition() {
637
                return indexEditing;
638
        }
639

    
640
        protected void setLegend() throws ReadDriverException, LegendLayerException {
641
                getSource().getRecordset().start();
642
                if (mapping.getColumnText()!=-1) {
643
                        try {
644
                                aLegend.setFieldName(getSource().getRecordset().getFieldName(mapping.getColumnText()));
645
                                setLegend(aLegend);
646
                                getSource().getRecordset().stop();
647
                                return;
648
                        }
649
                        catch (IndexOutOfBoundsException ex) {
650
                                // if mapping is -1, don't apply the legend
651
                        }
652
                }
653
                throw new ReadDriverException(getSource().getDriver().getName(), new RuntimeException("This does not seem an annotation layer"));
654
        }
655

    
656
        /**
657
         * DOCUMENT ME!
658
         *
659
         * @return DOCUMENT ME!
660
         */
661
        public Strategy getStrategy() {
662
                return strategy;
663
        }
664

    
665
        /**
666
         * DOCUMENT ME!
667
         *
668
         * @param b DOCUMENT ME!
669
         * @throws StartEditionLayerException
670
         *
671
         * @throws EditionException DOCUMENT ME!
672
         */
673
        public void setEditing(boolean b) throws StartEditionLayerException {
674
                super.setEditing(b);
675
                try {
676
                        if (b) {
677
                                Annotation_EditableAdapter aea = new Annotation_EditableAdapter(this);
678

    
679
                                aea.setOriginalVectorialAdapter(((VectorialEditableAdapter) super.getSource()).getOriginalAdapter());
680

    
681
                                ((VectorialEditableAdapter) super.getSource()).cancelEdition(EditionEvent.GRAPHIC);
682
                                aea.start();
683

    
684
                                aea.setCoordTrans(getCoordTrans());
685
                                // CHEMA
686
                                aea.startEdition(EditionEvent.GRAPHIC);
687
                                setSource(aea);
688
                                getRecordset().setSelectionSupport(aea.getOriginalAdapter()
689
                                                .getRecordset()
690
                                                .getSelectionSupport());
691
                                aea.addEditionListener(this);
692
                        } else {
693
                        }
694

    
695
                } catch (ReadDriverException e) {
696
                        throw new StartEditionLayerException(this.getName(),e);
697
                } catch (CancelEditingLayerException e) {
698
                        throw new StartEditionLayerException(this.getName(),e);
699
                } catch (StartWriterVisitorException e) {
700
                        throw new StartEditionLayerException(this.getName(),e);
701
                }
702
                deleteSpatialIndex();
703
        }
704

    
705
        /**
706
         * DOCUMENT ME!
707
         *
708
         * @param layer DOCUMENT ME!
709
         *
710
         * @return DOCUMENT ME!
711
         * @throws ReadDriverException
712
         *
713
         * @throws DriverException DOCUMENT ME!
714
         * @throws FieldNotFoundException DOCUMENT ME!
715
         */
716
        public static Annotation_Layer createLayerFromVect(FLyrVect layer) throws ReadDriverException {
717
                Annotation_Layer la = new Annotation_Layer();
718
                FLyrVect lv=(FLyrVect)LayerFactory.createLayer(layer.getName(),layer.getSource().getDriver(),layer.getProjection());
719
                la.setSource(lv.getSource());
720
                la.setRecordset(lv.getRecordset());
721
                la.setProjection(layer.getProjection());
722
                la.getRecordset().setSelection(layer.getRecordset().getSelection());
723

    
724
                return la;
725
        }
726

    
727
        /**
728
         * DOCUMENT ME!
729
         */
730
        public void removingThisLayer() {
731
//                super.removingThisLayer();
732
                spatialIndex = null;
733
                aLegend = null;
734
                strategy = null;
735
                System.gc();
736
        }
737

    
738
        public double getTextHeightInPixels(int unit, double height,ViewPort vp){
739
                if (unit!=-1) {
740
                        double[] distanceTrans2Meter = MapContext.getDistanceTrans2Meter();
741
                        height = vp.fromMapDistance((int) (height)*distanceTrans2Meter[unit]/
742
                                        distanceTrans2Meter[vp.getMapUnits()]);
743
                }
744
                return height;
745
        }
746
        public IGeometry getTextWrappingGeometryInPixels(int unit,double height, String description,
747
                        double rotation, String type, int style, int numReg,ViewPort vp, IGeometry geom) {
748

    
749
                Shape shapeP=geom.getInternalShape();
750
                FPoint2D p = null;
751
                if (!(shapeP instanceof FPoint2D)) {
752
                        Rectangle2D rP=shapeP.getBounds2D();
753
                        p=new FPoint2D(rP.getX(),rP.getY());
754
                }else {
755
                        p=(FPoint2D)shapeP;
756
                }
757

    
758
                height = getTextHeightInPixels(unit, height, vp);
759

    
760
                AffineTransform tx = null;
761
                /* Para tama?os de fuente de letras excesivamente grandes obtenemos
762
                 * shapes con todas las coordenadas a 0, por eso limitamos el tama?o
763
                 * a 1000 y despu?s reescalamos el bounds.
764
                 */
765
                double scale = 1;
766
                if (height > 1000){
767
                        scale = height/1000;
768
                        height = 1000;
769
                }
770
                Font font = new Font(type, style,
771
                                (int) (height));
772
                FontRenderContext frc = new FontRenderContext(tx,
773
                                false, true);
774
                
775

    
776
                GlyphVector gv = font.createGlyphVector(frc, description);
777
                Shape shape = gv.getOutline();
778

    
779
                Rectangle2D rGeom=shape.getBounds2D();
780

    
781
                IGeometry geomResult = ShapeFactory.createPolygon2D(new GeneralPathX(rGeom));
782

    
783
                tx = AffineTransform.getTranslateInstance(0, -rGeom.getY());
784

    
785
                if (rotation != 0) {
786
                        tx.preConcatenate(AffineTransform.getRotateInstance(Math.toRadians(rotation)));
787
                }
788

    
789
                if(scale != 1){
790
                        tx.preConcatenate(AffineTransform.getScaleInstance(scale, scale));
791
                }
792
                
793
                /*
794
                 * Parche para arreglar la diferencia entre la altura de la letra y
795
                 * la altura del bounds que contiene la letra impresa.
796
                 */
797
                double boundsHeight = rGeom.getHeight();
798
                double fontScale = height/boundsHeight;
799
                tx.preConcatenate(AffineTransform.getScaleInstance(1, fontScale));
800
                //Fin del parche.
801
                
802
                tx.preConcatenate(AffineTransform.getTranslateInstance(p.getX(), p.getY()));
803
                geomResult.transform(tx);
804

    
805
                return geomResult;
806
        }
807

    
808
public FLayer cloneLayer() throws Exception {
809
                Annotation_Layer clonedLayer = new Annotation_Layer();
810
                clonedLayer.setSource(getSource());
811
                clonedLayer.setVisible(isVisible());
812
                clonedLayer.setISpatialIndex(getISpatialIndex());
813
                clonedLayer.setName(getName());
814
                clonedLayer.setCoordTrans(getCoordTrans());
815
                clonedLayer.setLegend((IVectorLegend)getLegend());
816
                clonedLayer.mapping=mapping;
817
                clonedLayer.aLegend=aLegend;
818
                return clonedLayer;
819
        }
820
        private static void drawAnnotation(Graphics2D g2,int unit,Annotation_Layer layer,
821
                        Annotation_Legend legend,Point2D pAux, String text,ViewPort viewPort,PrintRequestAttributeSet properties) {
822
                SimpleTextSymbol textSymbol=(SimpleTextSymbol)legend.getDefaultSymbol();
823
                textSymbol.setText(text);
824
//                float x;
825
//                float y;
826
                // Las etiquetas que pongamos a nulo ser? porque no la queremos dibujar.
827
                // ?til para cuando queramos eliminar duplicados.
828
                if (text == null) {
829
                        return;
830
                }
831

    
832

    
833
//FIXME: No parece que haga falta todo esto.
834

    
835
//                int size=textSymbol.getFont().getSize();
836
//                double resolutionPrinting=0;
837
//                if (unit!=-1){
838
//                        size=viewPort.fromMapDistance(size*MapContext.getDistanceTrans2Meter()[unit]);
839
//                }
840

    
841
//                if (properties!=null){
842
//                        PrintQuality resolution=(PrintQuality)properties.get(PrintQuality.class);
843
//                        if (resolution.equals(PrintQuality.NORMAL)){
844
//                                resolutionPrinting=300/72;
845
//                        }else if (resolution.equals(PrintQuality.HIGH)){
846
//                                resolutionPrinting=600/72;
847
//                        }else if (resolution.equals(PrintQuality.DRAFT)){
848
//                                resolutionPrinting=72/72;
849
//                        }
850
//                        size=(int)(size*resolutionPrinting);
851
//                }
852

    
853
                textSymbol.draw(g2,viewPort.getAffineTransform(),new FPoint2D(pAux.getX(),pAux.getY()), null);
854

    
855
        }
856
}