Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extAnnotations / src / com / iver / cit / gvsig / fmap / layers / Annotation_Layer.java @ 28605

History | View | Annotate | Download (24.9 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

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

    
106

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
261
                                boolean bMustClone = false;
262

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

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

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

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

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

    
292

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

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

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

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

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

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

    
404
                return rAux;
405
        }
406

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
512

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

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

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

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

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

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

    
559
                return total;
560
        }
561

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

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

    
580
                try {
581
                        va.start();
582

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

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

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

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

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

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

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

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

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

    
639
        protected void setLegend() throws ReadDriverException, LegendLayerException {
640
                getSource().getRecordset().start();
641
                aLegend.setFieldName(getSource().getRecordset().getFieldName(mapping.getColumnText()));
642
                setLegend(aLegend);
643
                getSource().getRecordset().stop();
644
        }
645

    
646
        /**
647
         * DOCUMENT ME!
648
         *
649
         * @return DOCUMENT ME!
650
         */
651
        public Strategy getStrategy() {
652
                return strategy;
653
        }
654

    
655
        /**
656
         * DOCUMENT ME!
657
         *
658
         * @param b DOCUMENT ME!
659
         * @throws StartEditionLayerException
660
         *
661
         * @throws EditionException DOCUMENT ME!
662
         */
663
        public void setEditing(boolean b) throws StartEditionLayerException {
664
                super.setEditing(b);
665
                try {
666
                        if (b) {
667
                                Annotation_EditableAdapter aea = new Annotation_EditableAdapter(this);
668

    
669
                                aea.setOriginalVectorialAdapter(((VectorialEditableAdapter) super.getSource()).getOriginalAdapter());
670

    
671
                                ((VectorialEditableAdapter) super.getSource()).cancelEdition(EditionEvent.GRAPHIC);
672
                                aea.start();
673

    
674
                                aea.setCoordTrans(getCoordTrans());
675
                                // CHEMA
676
                                aea.startEdition(EditionEvent.GRAPHIC);
677
                                setSource(aea);
678
                                getRecordset().setSelectionSupport(aea.getOriginalAdapter()
679
                                                .getRecordset()
680
                                                .getSelectionSupport());
681
                                aea.addEditionListener(this);
682
                        } else {
683
                        }
684

    
685
                } catch (ReadDriverException e) {
686
                        throw new StartEditionLayerException(this.getName(),e);
687
                } catch (CancelEditingLayerException e) {
688
                        throw new StartEditionLayerException(this.getName(),e);
689
                } catch (StartWriterVisitorException e) {
690
                        throw new StartEditionLayerException(this.getName(),e);
691
                }
692
                deleteSpatialIndex();
693
        }
694

    
695
        /**
696
         * DOCUMENT ME!
697
         *
698
         * @param layer DOCUMENT ME!
699
         *
700
         * @return DOCUMENT ME!
701
         * @throws ReadDriverException
702
         *
703
         * @throws DriverException DOCUMENT ME!
704
         * @throws FieldNotFoundException DOCUMENT ME!
705
         */
706
        public static Annotation_Layer createLayerFromVect(FLyrVect layer) throws ReadDriverException {
707
                Annotation_Layer la = new Annotation_Layer();
708
                FLyrVect lv=(FLyrVect)LayerFactory.createLayer(layer.getName(),layer.getSource().getDriver(),layer.getProjection());
709
                la.setSource(lv.getSource());
710
                la.setRecordset(lv.getRecordset());
711
                la.setProjection(layer.getProjection());
712
                la.getRecordset().setSelection(layer.getRecordset().getSelection());
713

    
714
                return la;
715
        }
716

    
717
        /**
718
         * DOCUMENT ME!
719
         */
720
        public void removingThisLayer() {
721
//                super.removingThisLayer();
722
                spatialIndex = null;
723
                aLegend = null;
724
                strategy = null;
725
                System.gc();
726
        }
727

    
728
        public double getTextHeightInPixels(int unit, double height,ViewPort vp){
729
                if (unit!=-1) {
730
                        height = vp.fromMapDistance((int) (height)*MapContext.getDistanceTrans2Meter()[unit]);
731
                }
732
                return height;
733
        }
734
        public IGeometry getTextWrappingGeometryInPixels(int unit,double height, String description,
735
                        double rotation, String type, int style, int numReg,ViewPort vp, IGeometry geom) {
736

    
737
                Shape shapeP=geom.getInternalShape();
738
                FPoint2D p = null;
739
                if (!(shapeP instanceof FPoint2D)) {
740
                        Rectangle2D rP=shapeP.getBounds2D();
741
                        p=new FPoint2D(rP.getX(),rP.getY());
742
                }else {
743
                        p=(FPoint2D)shapeP;
744
                }
745

    
746
                height = getTextHeightInPixels(unit, height, vp);
747

    
748
                AffineTransform tx = null;
749
                /* Para tama?os de fuente de letras excesivamente grandes obtenemos
750
                 * shapes con todas las coordenadas a 0, por eso limitamos el tama?o
751
                 * a 1000 y despu?s reescalamos el bounds.
752
                 */
753
                double scale = 1;
754
                if (height > 1000){
755
                        scale = height/1000;
756
                        height = 1000;
757
                }
758
                Font font = new Font(type, style,
759
                                (int) (height));
760
                FontRenderContext frc = new FontRenderContext(tx,
761
                                false, true);
762

    
763
                GlyphVector gv = font.createGlyphVector(frc, description);
764
                Shape shape = gv.getOutline();
765

    
766
                Rectangle2D rGeom=shape.getBounds2D();
767

    
768
                IGeometry geomResult = ShapeFactory.createPolygon2D(new GeneralPathX(rGeom));
769

    
770
                tx = AffineTransform.getTranslateInstance(0, -rGeom.getY());
771

    
772
                if (rotation != 0) {
773
                        tx.preConcatenate(AffineTransform.getRotateInstance(Math.toRadians(rotation)));
774
                }
775

    
776
                if(scale != 1){
777
                        tx.preConcatenate(AffineTransform.getScaleInstance(scale, scale));
778
                }
779

    
780
                tx.preConcatenate(AffineTransform.getTranslateInstance(p.getX(), p.getY()));
781
                geomResult.transform(tx);
782

    
783
                return geomResult;
784
        }
785

    
786
public FLayer cloneLayer() throws Exception {
787
                Annotation_Layer clonedLayer = new Annotation_Layer();
788
                clonedLayer.setSource(getSource());
789
                clonedLayer.setVisible(isVisible());
790
                clonedLayer.setISpatialIndex(getISpatialIndex());
791
                clonedLayer.setName(getName());
792
                clonedLayer.setCoordTrans(getCoordTrans());
793
                clonedLayer.setLegend((IVectorLegend)getLegend());
794
                clonedLayer.mapping=mapping;
795
                clonedLayer.aLegend=aLegend;
796
                return clonedLayer;
797
        }
798
        private static void drawAnnotation(Graphics2D g2,int unit,Annotation_Layer layer,
799
                        Annotation_Legend legend,Point2D pAux, String text,ViewPort viewPort,PrintRequestAttributeSet properties) {
800
                SimpleTextSymbol textSymbol=(SimpleTextSymbol)legend.getDefaultSymbol();
801
                textSymbol.setText(text);
802
//                float x;
803
//                float y;
804
                // Las etiquetas que pongamos a nulo ser? porque no la queremos dibujar.
805
                // ?til para cuando queramos eliminar duplicados.
806
                if (text == null) {
807
                        return;
808
                }
809

    
810

    
811
//FIXME: No parece que haga falta todo esto.
812

    
813
//                int size=textSymbol.getFont().getSize();
814
//                double resolutionPrinting=0;
815
//                if (unit!=-1){
816
//                        size=viewPort.fromMapDistance(size*MapContext.getDistanceTrans2Meter()[unit]);
817
//                }
818

    
819
//                if (properties!=null){
820
//                        PrintQuality resolution=(PrintQuality)properties.get(PrintQuality.class);
821
//                        if (resolution.equals(PrintQuality.NORMAL)){
822
//                                resolutionPrinting=300/72;
823
//                        }else if (resolution.equals(PrintQuality.HIGH)){
824
//                                resolutionPrinting=600/72;
825
//                        }else if (resolution.equals(PrintQuality.DRAFT)){
826
//                                resolutionPrinting=72/72;
827
//                        }
828
//                        size=(int)(size*resolutionPrinting);
829
//                }
830

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

    
833
        }
834
}