Statistics
| Revision:

svn-gvsig-desktop / branches / v10 / extensions / extAnnotations / src / com / iver / cit / gvsig / fmap / operation / strategies / Annotation_Strategy.java @ 17609

History | View | Annotate | Download (27.4 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.operation.strategies;
44

    
45
import java.awt.Color;
46
import java.awt.Dimension;
47
import java.awt.Font;
48
import java.awt.Graphics2D;
49
import java.awt.Shape;
50
import java.awt.geom.AffineTransform;
51
import java.awt.geom.NoninvertibleTransformException;
52
import java.awt.geom.Point2D;
53
import java.awt.geom.Rectangle2D;
54
import java.awt.image.BufferedImage;
55
import java.util.List;
56

    
57
import javax.print.attribute.PrintRequestAttributeSet;
58
import javax.print.attribute.standard.PrintQuality;
59

    
60
import org.cresques.cts.ICoordTrans;
61

    
62
import com.hardcode.driverManager.DriverLoadException;
63
import com.hardcode.gdbms.engine.values.NullValue;
64
import com.hardcode.gdbms.engine.values.NumericValue;
65
import com.hardcode.gdbms.engine.values.StringValue;
66
import com.hardcode.gdbms.engine.values.Value;
67
import com.iver.andami.messages.NotificationManager;
68
import com.iver.cit.gvsig.fmap.DriverException;
69
import com.iver.cit.gvsig.fmap.ViewPort;
70
import com.iver.cit.gvsig.fmap.core.FPoint2D;
71
import com.iver.cit.gvsig.fmap.core.FShape;
72
import com.iver.cit.gvsig.fmap.core.IGeometry;
73
import com.iver.cit.gvsig.fmap.core.v02.FConstant;
74
import com.iver.cit.gvsig.fmap.core.v02.FSymbol;
75
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes;
76
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
77
import com.iver.cit.gvsig.fmap.layers.Annotation_Layer;
78
import com.iver.cit.gvsig.fmap.layers.Annotation_Mapping;
79
import com.iver.cit.gvsig.fmap.layers.FBitSet;
80
import com.iver.cit.gvsig.fmap.layers.FLayer;
81
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
82
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial;
83
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
84
import com.iver.cit.gvsig.fmap.operations.strategies.DefaultStrategy;
85
import com.iver.cit.gvsig.fmap.operations.strategies.VisitException;
86
import com.iver.cit.gvsig.fmap.rendering.Annotation_Legend;
87
import com.iver.utiles.swing.threads.Cancellable;
88
import com.vividsolutions.jts.geom.Geometry;
89
import com.vividsolutions.jts.geom.IntersectionMatrix;
90

    
91

    
92
/**
93
 * Esta clase se encargar? de dibujar de la forma m?s eficiente los temas de
94
 * anotaciones.
95
 *
96
 * @author Vicente Caballero Navarro
97
 */
98
public class Annotation_Strategy extends DefaultStrategy {
99
    private FSymbol symbolPoint = new FSymbol(FShape.POINT, Color.black);
100
    private Annotation_Layer capa;
101
    private static AffineTransform ati=new AffineTransform();
102
    /**
103
     * Crea un nuevo AnotationStrategy.
104
     *
105
     * @param layer
106
     */
107
    public Annotation_Strategy(FLayer layer) {
108
        super(layer);
109
        capa = (Annotation_Layer) getCapa();
110
        symbolPoint.setSize(5);
111
    }
112

    
113
      public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
114
        Cancellable cancel) {
115
              drawAnnotations(image,g,viewPort,cancel,null);
116
    }
117

    
118
      private void drawAllAnnotations(Graphics2D g,
119
                          ViewPort viewPort, Cancellable cancel,
120
                          PrintRequestAttributeSet properties) {
121
//                  Point2D offset = viewPort.getOffset();
122
//                  g.translate(-offset.getX(), -offset.getY());
123
                  Annotation_Legend l = (Annotation_Legend) capa.getLegend();
124
                  FSymbol sym = (FSymbol) l.getDefaultSymbol();
125

    
126
                  try {
127
                          ReadableVectorial source = capa.getSource();
128
                          // limit the labeling to the visible extent
129
                          FBitSet bs = capa.queryByRect(viewPort.getAdjustedExtent());
130

    
131
                          SelectableDataSource recordSet = source.getRecordset();
132
                          recordSet.start();
133
                          FBitSet bitSet = recordSet.getSelection();
134
                          Annotation_Mapping mapping = ((Annotation_Layer) capa)
135
                                          .getAnnotatonMapping();
136
                          int idHeightField = mapping.getColumnHeight();
137
                          int idFontName = mapping.getColumnTypeFont();
138
                          int idFontStyle = mapping.getColumnStyleFont();
139
                          int idRotationField = mapping.getColumnRotate();
140
                          int idFontColor = mapping.getColumnColor();
141
                          int idTextField = mapping.getColumnText();
142

    
143
                          double rotation = 0D;
144
                          float size = sym.getFont().getSize()
145
                                          * (float) FConstant.FONT_HEIGHT_SCALE_FACTOR;
146

    
147
                          String fontName = "Dialog";
148
                          int fontStyle = sym.getFont().getStyle();
149
                          int fontColor = sym.getFontColor().getRGB();
150
                          long t1 = System.currentTimeMillis();
151

    
152
                          for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1)) {
153
                                  if (cancel.isCanceled()) {
154
                                          break;
155
                                  }
156

    
157
                                  Value[] vv = recordSet.getRow(i);
158

    
159
                                  if (idHeightField != -1) {
160
                                          // text size is defined in the table
161
                                          try {
162
                                                  size = (float) (((NumericValue) vv[idHeightField])
163
                                                                  .doubleValue() * FConstant.FONT_HEIGHT_SCALE_FACTOR);
164
                                          } catch (ClassCastException ccEx) {
165
                                                  if (!NullValue.class.equals(vv[idHeightField]
166
                                                                  .getClass())) {
167
                                                  }
168
                                                  continue;
169
                                          }
170
                                  }
171

    
172
                                  if (idFontName != -1) {
173
                                          fontName = ((StringValue) vv[idFontName]).toString();
174
                                  }
175

    
176
                                  if (idFontStyle != -1) {
177
                                          fontStyle = ((NumericValue) vv[idFontStyle]).intValue();
178
                                  }
179

    
180
                                  if (idRotationField != -1) {
181
                                          // text rotation is defined in the table
182
                                          rotation = ((NumericValue) vv[idRotationField])
183
                                                          .doubleValue();
184
                                          sym.setRotation((int) rotation);
185
                                  }
186

    
187
                                  if (idFontColor != -1) {
188
                                          // text rotation is defined in the table
189
                                          fontColor = ((NumericValue) vv[idFontColor]).intValue();
190
                                          sym.setFontColor(new Color(fontColor));
191
                                  }
192

    
193
                                  if (bitSet.get(i)) {
194
                                          sym = (FSymbol) sym.getSymbolForSelection();
195
                                  }
196

    
197
                                  sym.setFont(new Font(fontName, fontStyle, (int) size));
198
                                  source.start();
199
                                  IGeometry geom = source.getShape(i);
200
                                  source.stop();
201
                                  ICoordTrans ct = capa.getCoordTrans();
202

    
203
                                  boolean bMustClone = false;
204

    
205
                                  if (geom == null) {
206
                                          return;
207
                                  }
208

    
209
                                  if (ct != null) {
210
                                          if (bMustClone) {
211
                                                  geom = geom.cloneGeometry();
212
                                          }
213

    
214
                                          geom.reProject(ct);
215
                                  }
216
                                  geom.transform(viewPort.getAffineTransform());
217
                                  Shape shape = geom.getInternalShape();
218
                                  FPoint2D fpPixels = null;
219
                                  if (!(shape instanceof FPoint2D)) {
220
                                          Rectangle2D rP = shape.getBounds2D();
221
                                          fpPixels = new FPoint2D(rP.getX(), rP.getMaxY());
222
                                  } else {
223
                                          fpPixels = (FPoint2D) shape;
224
                                  }
225
                                  // Si el tama?o de la fuente est? en unidades de mapa.
226
                                  if (!sym.isFontSizeInPixels()) {
227
                                          Rectangle2D r = capa.getTextWrappingGeometryInPixels(size,
228
                                                          vv[idTextField].toString(), rotation, fontName,
229
                                                          fontStyle, i, viewPort, geom).getBounds2D();
230
                                          Rectangle2D rPixels = new Rectangle2D.Double(r.getX(), r
231
                                                          .getY()
232
                                                          + r.getHeight(), r.getWidth(), r.getHeight());
233

    
234
                                          Point2D p = new Point2D.Double(fpPixels.getX(), fpPixels
235
                                                          .getY());
236

    
237
                                          if (!capa.isEditing() && l.isAvoidOverLapping()) {
238
                                                  p = new Point2D.Double(rPixels.getX(),rPixels.getY());
239
                                                  if (sym.isShapeVisible()) {
240
                                                          symbolPoint.draw(g, ati, fpPixels);
241
                                                  }
242
                                                  DrawAnnotation(g, sym, p, vv[idTextField].toString(),
243
                                                                  viewPort, properties);
244
                                          }
245
                                  } else {
246

    
247
                                          // Si el tama?o de la fuente est? en pixels.
248
                                          Point2D pSearch = new Point2D.Double(fpPixels.getX(),
249
                                                          fpPixels.getY());
250

    
251
                                          if (!capa.isEditing()) {
252
                                                  if (sym.isShapeVisible()) {
253
                                                          symbolPoint.draw(g, ati, fpPixels);
254
                                                  }
255
                                                  DrawAnnotation(g, sym, pSearch, vv[idTextField]
256
                                                                  .toString(), viewPort, properties);
257
                                          }
258
                                  }
259
                          }
260
//                          g.translate(offset.getX(), offset.getY());
261
                          System.err.println(System.currentTimeMillis() - t1 + "millis");
262
                          recordSet.stop();
263
                  } catch (Exception e) {
264
                          NotificationManager.addError(e);
265
                  }
266
          }
267
      private void drawAnnotations(BufferedImage image, Graphics2D g,
268
                        ViewPort viewPort, Cancellable cancel,
269
                        PrintRequestAttributeSet properties) {
270
                Dimension dimension = viewPort.getImageSize();
271
                BufferedImage bi = new BufferedImage((int) dimension.getWidth(),
272
                                (int) dimension.getHeight(), BufferedImage.TYPE_INT_ARGB);
273
                Graphics2D gBi = (Graphics2D) bi.getGraphics();
274
                gBi.setTransform(g.getTransform());
275
                Point2D offset = viewPort.getOffset();
276
//                gBi.translate(-offset.getX(), -offset.getY());
277
                Annotation_Legend l = (Annotation_Legend) capa.getLegend();
278
                FSymbol sym = (FSymbol) l.getDefaultSymbol();
279

    
280
                try {
281
                        ReadableVectorial source = capa.getSource();
282
                        // limit the labeling to the visible extent
283
                        FBitSet bs = capa.queryByRect(viewPort.getAdjustedExtent());
284

    
285
                        SelectableDataSource recordSet = source.getRecordset();
286
                        recordSet.start();
287
                        FBitSet bitSet = recordSet.getSelection();
288
                        Annotation_Mapping mapping = ((Annotation_Layer) capa)
289
                                        .getAnnotatonMapping();
290
                        int idHeightField = mapping.getColumnHeight();
291
                        int idFontName = mapping.getColumnTypeFont();
292
                        int idFontStyle = mapping.getColumnStyleFont();
293
                        int idRotationField = mapping.getColumnRotate();
294
                        int idFontColor = mapping.getColumnColor();
295
                        int idTextField = mapping.getColumnText();
296

    
297
                        double rotation = 0D;
298
                        float size = sym.getFont().getSize()
299
                                        * (float) FConstant.FONT_HEIGHT_SCALE_FACTOR;
300

    
301
                        String fontName = "Dialog";
302
                        int fontStyle = sym.getFont().getStyle();
303
                        int fontColor = sym.getFontColor().getRGB();
304
                        long t1 = System.currentTimeMillis();
305

    
306
                        for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1)) {
307
                                if (cancel.isCanceled()) {
308
                                        break;
309
                                }
310

    
311
                                Value[] vv = recordSet.getRow(i);
312

    
313
                                if (idHeightField != -1) {
314
                                        // text size is defined in the table
315
                                        try {
316
                                                size = (float) (((NumericValue) vv[idHeightField])
317
                                                                .doubleValue() * FConstant.FONT_HEIGHT_SCALE_FACTOR);
318
                                        } catch (ClassCastException ccEx) {
319
                                                if (!NullValue.class.equals(vv[idHeightField]
320
                                                                .getClass())) {
321
                                                }
322
                                                continue;
323
                                        }
324
                                }
325

    
326
                                if (idFontName != -1) {
327
                                        fontName = ((StringValue) vv[idFontName]).toString();
328
                                }
329

    
330
                                if (idFontStyle != -1) {
331
                                        fontStyle = ((NumericValue) vv[idFontStyle]).intValue();
332
                                }
333

    
334
                                if (idRotationField != -1) {
335
                                        // text rotation is defined in the table
336
                                        rotation = ((NumericValue) vv[idRotationField])
337
                                                        .doubleValue();
338
                                        sym.setRotation((int) rotation);
339
                                }
340

    
341
                                if (idFontColor != -1) {
342
                                        // text rotation is defined in the table
343
                                        fontColor = ((NumericValue) vv[idFontColor]).intValue();
344
                                        sym.setFontColor(new Color(fontColor));
345
                                }
346

    
347
                                if (bitSet.get(i)) {
348
                                        sym = (FSymbol) sym.getSymbolForSelection();
349
                                }
350

    
351
                                sym.setFont(new Font(fontName, fontStyle, (int) size));
352
                                source.start();
353
                                IGeometry geom = source.getShape(i);
354
                                source.stop();
355
                                ICoordTrans ct = capa.getCoordTrans();
356

    
357
                                boolean bMustClone = false;
358

    
359
                                if (geom == null) {
360
                                        return;
361
                                }
362

    
363
                                if (ct != null) {
364
                                        if (bMustClone) {
365
                                                geom = geom.cloneGeometry();
366
                                        }
367

    
368
                                        geom.reProject(ct);
369
                                }
370
                                geom.transform(viewPort.getAffineTransform());
371
                                Shape shape = geom.getInternalShape();
372
                                FPoint2D fpPixels = null;
373
                                if (!(shape instanceof FPoint2D)) {
374
                                        Rectangle2D rP = shape.getBounds2D();
375
                                        fpPixels = new FPoint2D(rP.getX(), rP.getMaxY());
376
                                } else {
377
                                        fpPixels = (FPoint2D) shape;
378
                                }
379
//                                Point2D pOffset=viewPort.getOffset();
380
//                                fpPixels=new FPoint2D(fpPixels.getX()+pOffset.getX(),fpPixels.getY()+pOffset.getY());
381
                                // Si el tama?o de la fuente est? en unidades de mapa.
382
                                if (!sym.isFontSizeInPixels()) {
383
                                        boolean draw = false;
384
                                        Rectangle2D r = capa.getTextWrappingGeometryInPixels(size,
385
                                                        vv[idTextField].toString(), rotation, fontName,
386
                                                        fontStyle, i, viewPort, geom).getBounds2D();
387
                                        Rectangle2D rPixels = new Rectangle2D.Double(r.getX(), r
388
                                                        .getY()
389
                                                        + r.getHeight(), r.getWidth(), r.getHeight());
390

    
391
                                        Point2D p = new Point2D.Double(fpPixels.getX(), fpPixels
392
                                                        .getY());
393

    
394
                                        if (!capa.isEditing() && l.isAvoidOverLapping()) {
395
                                                p = getPoint(bi, rPixels, l.isDelOverLapping());
396
                                                if (p != null)
397
                                                        draw = true;
398
                                        } else {
399
                                                if (!capa.isEditing() && l.isDelOverLapping()) {
400
                                                        if (isOverlapping(bi, rPixels)) {
401
                                                                draw = true;
402
                                                        }
403
                                                } else {
404
                                                        draw = true;
405
                                                }
406
                                        }
407
                                        if (draw) {
408
                                                if (sym.isShapeVisible()) {
409
                                                        symbolPoint.draw(gBi, ati, fpPixels);
410
                                                }
411
                                                // g.drawRect((int)rPixels.getX(),(int)rPixels.getY(),(int)rPixels.getWidth(),(int)rPixels.getHeight());
412
                                                // FGraphicUtilities.DrawAnnotation(gBi,
413
                                                // ati, sym, aux[0], metrics, false);
414
                                                DrawAnnotation(gBi, sym, p, vv[idTextField].toString(),
415
                                                                viewPort, properties);
416
                                        }
417
                                } else {
418

    
419
                                        // Si el tama?o de la fuente est? en pixels.
420
                                        boolean draw = false;
421

    
422
                                        Rectangle2D r = capa.getTextWrappingGeometryInPixels(size,
423
                                                        vv[idTextField].toString(), rotation, fontName,
424
                                                        fontStyle, i, viewPort, geom).getBounds2D();
425
                                        // g.draw(capa.getTextWrappingGeometryInPixels(size,vv[idTextField].toString(),rotation,fontName,fontStyle,i,viewPort,geom));
426
                                        Rectangle2D rPixels = new Rectangle2D.Double(r.getX(), r
427
                                                        .getY()
428
                                                        + r.getHeight(), r.getWidth(), r.getHeight());
429

    
430
                                        Point2D pSearch = new Point2D.Double(fpPixels.getX(),
431
                                                        fpPixels.getY());
432

    
433
                                        if (!capa.isEditing() && l.isAvoidOverLapping()) {
434
                                                pSearch = getPoint(bi, rPixels, l.isDelOverLapping());
435
                                                if (pSearch != null) {
436
                                                        draw = true;
437
                                                }
438
                                        } else {
439
                                                if (!capa.isEditing() && l.isDelOverLapping()) {
440
                                                        if (isOverlapping(bi, rPixels)) {
441
                                                                draw = true;
442
                                                        }
443
                                                } else {
444
                                                        draw = true;
445
                                                }
446
                                        }
447
                                        if (draw) {
448
                                                if (sym.isShapeVisible()) {
449
                                                        symbolPoint.draw(gBi, ati, fpPixels);
450
                                                }
451
                                                // g.drawRect((int)pSearch.getX(),(int)(pSearch.getY()-rPixels.getHeight()),(int)rPixels.getWidth(),(int)rPixels.getHeight());
452
                                                // FGraphicUtilities.DrawAnnotation(gBi,
453
                                                // ati, sym, aux[0], metrics, false);
454
                                                DrawAnnotation(gBi, sym, pSearch, vv[idTextField]
455
                                                                .toString(), viewPort, properties);
456
                                        }
457
                                }
458
                                // Al dibujar esta imagen sobre el graphics la trasparencia no
459
                                // puede existir.
460
                                if (i % 1000 == 0) {
461
                                        g.drawImage(bi,  (int) offset.getX(), (int) offset.getY(), null);
462
                                }
463
                        }
464
//                        gBi.translate(offset.getX(), offset.getY());
465
                        g.drawImage(bi, (int)  offset.getX(), (int) offset.getY(), null);
466
                        System.err.println(System.currentTimeMillis() - t1 + "millis");
467
                        recordSet.stop();
468
                } catch (Exception e) {
469
                        NotificationManager.addError(e);
470
                }
471
        }
472
    private Point2D getPoint(BufferedImage bi, Rectangle2D rec, boolean b) {
473
                Rectangle2D r=new Rectangle2D.Double(rec.getX(),rec.getY()-rec.getHeight(),rec.getWidth(),rec.getHeight());
474
                if (isOverlapping(bi,r))
475
                        return new Point2D.Double(r.getX(),r.getY()+rec.getHeight());
476

    
477
                r.setFrame(rec.getX(),rec.getY(),rec.getWidth(),rec.getHeight());
478
                if (isOverlapping(bi,r))
479
                        return new Point2D.Double(r.getX(),r.getY()+rec.getHeight());
480

    
481
                r.setFrame(rec.getX()-rec.getWidth(),rec.getY()-rec.getHeight(),rec.getWidth(),rec.getHeight());
482
                if (isOverlapping(bi,r))
483
                        return new Point2D.Double(r.getX(),r.getY()+rec.getHeight());
484

    
485
                r.setFrame(rec.getX()-rec.getWidth(),rec.getY(),rec.getWidth(),rec.getHeight());
486
                if (isOverlapping(bi,r))
487
                        return new Point2D.Double(r.getX(),r.getY()+rec.getHeight());
488

    
489
                r.setFrame(rec.getX()-rec.getWidth()/2,rec.getY(),rec.getWidth(),rec.getHeight());
490
                if (isOverlapping(bi,r))
491
                        return new Point2D.Double(r.getX(),r.getY()+rec.getHeight());
492

    
493
                r.setFrame(rec.getX()-rec.getWidth()/2,rec.getY()-rec.getHeight(),rec.getWidth(),rec.getHeight());
494
                if (isOverlapping(bi,r))
495
                        return new Point2D.Double(r.getX(),r.getY()+rec.getHeight());
496

    
497
                r.setFrame(rec.getX(),rec.getY()+rec.getHeight()/2,rec.getWidth(),rec.getHeight());
498
                if (isOverlapping(bi,r))
499
                        return new Point2D.Double(r.getX(),r.getY()+rec.getHeight());
500

    
501
                if (!b)
502
                        return new Point2D.Double(rec.getX(),rec.getY());
503
                else
504
                        return null;
505
        }
506

    
507
        private boolean isOverlapping(BufferedImage bi, Rectangle2D rPixels) {
508
        for (int i=(int)rPixels.getX();i<rPixels.getMaxX();i++){
509
            for (int j=(int)rPixels.getY();j<rPixels.getMaxY();j++){
510
                if (i<0 || j<0 || bi.getWidth()<i+1 || bi.getHeight()<j+1)
511
                    continue;
512
                if (bi.getRGB(i,j)!=0){
513
                    return false;
514
                }
515
            }
516
        }
517
        return true;
518
    }
519

    
520
    /*
521
         * (non-Javadoc)
522
         *
523
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#queryByShape(com.iver.cit.gvsig.fmap.core.IGeometry,
524
         *      int)
525
         */
526
    public FBitSet queryByShape(IGeometry g, int relationship)
527
        throws DriverException, VisitException {
528
        // Si hay un ?ndice espacial, lo usamos para hacer el query.
529
        FLyrVect lyr = (FLyrVect) capa;
530

    
531
        // if (lyr.getSpatialIndex() == null)
532
        if (lyr.getISpatialIndex() == null) {
533
            return super.queryByShape(g, relationship);
534
        }
535

    
536
        long t1 = System.currentTimeMillis();
537
        ReadableVectorial va = lyr.getSource();
538
        ICoordTrans ct = lyr.getCoordTrans();
539
        Rectangle2D bounds = g.getBounds2D();
540

    
541
        // Coordinate c1 = new Coordinate(bounds.getMinX(), bounds.getMinY());
542
        // Coordinate c2 = new Coordinate(bounds.getMaxX(), bounds.getMaxY());
543
        // Envelope env = new Envelope(c1, c2);
544
        // List lstRecs = lyr.getSpatialIndex().query(env);
545
        List lstRecs = lyr.getISpatialIndex().query(bounds);
546
        Integer idRec;
547
        FBitSet bitset = new FBitSet();
548
        Geometry jtsShape = g.toJTSGeometry();
549
        IntersectionMatrix m;
550
        int index;
551

    
552
        try {
553
            va.start();
554

    
555
            // Annotation_Legend aLegend=(Annotation_Legend)capa.getLegend();
556
            for (int i = 0; i < lstRecs.size(); i++) {
557
                idRec = (Integer) lstRecs.get(i);
558
                index = idRec.intValue();
559

    
560
                IGeometry geom = va.getShape(index);
561

    
562
                // FSymbol symbol=(FSymbol)aLegend.getSymbol(index);
563
                // IGeometry geom=aLegend.getTextWrappingGeometry(symbol,index);
564
                // IGeometry
565
                // geom=getGeometry(((Annotation_Layer)capa).getLabel(index).getBoundBox());
566
                if (ct != null) {
567
                    geom.reProject(ct);
568
                }
569

    
570
                Geometry jtsGeom = geom.toJTSGeometry();
571

    
572
                switch (relationship) {
573
                case CONTAINS:
574
                    m = jtsShape.relate(jtsGeom);
575

    
576
                    if (m.isContains()) {
577
                        bitset.set(index, true);
578
                    }
579

    
580
                    break;
581

    
582
                case CROSSES:
583
                    m = jtsShape.relate(jtsGeom);
584

    
585
                    if (m.isCrosses(jtsGeom.getDimension(),
586
                                jtsShape.getDimension())) {
587
                        bitset.set(index, true);
588
                    }
589

    
590
                    break;
591

    
592
                case DISJOINT:
593

    
594
                    // TODO: CREO QUE EL DISJOINT NO SE PUEDE METER AQUI
595
                    m = jtsShape.relate(jtsGeom);
596

    
597
                    if (m.isDisjoint()) {
598
                        bitset.set(index, true);
599
                    }
600

    
601
                    break;
602

    
603
                case EQUALS:
604
                    m = jtsShape.relate(jtsGeom);
605

    
606
                    if (m.isEquals(jtsGeom.getDimension(),
607
                                jtsShape.getDimension())) {
608
                        bitset.set(index, true);
609
                    }
610

    
611
                    break;
612

    
613
                case INTERSECTS:
614
                    m = jtsShape.relate(jtsGeom);
615

    
616
                    if (m.isIntersects()) {
617
                        bitset.set(index, true);
618
                    }
619

    
620
                    break;
621

    
622
                case OVERLAPS:
623
                    m = jtsShape.relate(jtsGeom);
624

    
625
                    if (m.isOverlaps(jtsGeom.getDimension(),
626
                                jtsShape.getDimension())) {
627
                        bitset.set(index, true);
628
                    }
629

    
630
                    break;
631

    
632
                case TOUCHES:
633
                    m = jtsShape.relate(jtsGeom);
634

    
635
                    if (m.isTouches(jtsGeom.getDimension(),
636
                                jtsShape.getDimension())) {
637
                        bitset.set(index, true);
638
                    }
639

    
640
                    break;
641

    
642
                case WITHIN:
643
                    m = jtsShape.relate(jtsGeom);
644

    
645
                    if (m.isWithin()) {
646
                        bitset.set(index, true);
647
                    }
648

    
649
                    break;
650
                }
651
            }
652

    
653
            va.stop();
654
        } catch (DriverIOException e) {
655
                throw new DriverException(e);
656
        }
657

    
658
        long t2 = System.currentTimeMillis();
659

    
660
        // logger.debug("queryByShape optimizado sobre la capa " + lyr.getName()
661
        // + ". " + (t2-t1) + " mseg.");
662
        return bitset;
663
    }
664

    
665
    /**
666
     * DOCUMENT ME!
667
     *
668
     * @param rect DOCUMENT ME!
669
     *
670
     * @return DOCUMENT ME!
671
     *
672
     * @throws DriverException DOCUMENT ME!
673
     */
674
    public FBitSet queryByRect(Rectangle2D rect) throws DriverException {
675
        // Si hay un ?ndice espacial, lo usamos para hacer el query.
676
        Annotation_Layer lyr = (Annotation_Layer) capa;
677
        ReadableVectorial va = lyr.getSource();
678
        ICoordTrans ct = lyr.getCoordTrans();
679
        Rectangle2D bounds = rect;
680
        // if (lyr.getSpatialIndex() == null)
681
        if (lyr.getISpatialIndex() == null) {
682
            return super.queryByRect(rect);
683
        }
684
        // Coordinate c1 = new Coordinate(bounds.getMinX(), bounds.getMinY());
685
        // Coordinate c2 = new Coordinate(bounds.getMaxX(), bounds.getMaxY());
686
        // Envelope env = new Envelope(c1, c2);
687
        //
688
        // List lstRecs = lyr.getSpatialIndex().query(env);
689
        // azabala
690
        List lstRecs = lyr.getISpatialIndex().query(bounds);
691
        Integer idRec;
692
        FBitSet bitset = new FBitSet();
693
        int index;
694

    
695
        try {
696
            va.start();
697

    
698
            DriverAttributes attr = va.getDriverAttributes();
699
            boolean bMustClone = false;
700

    
701
            if (attr != null) {
702
                if (attr.isLoadedInMemory()) {
703
                    bMustClone = attr.isLoadedInMemory();
704
                }
705
            }
706
            ViewPort vp=getCapa().getMapContext().getViewPort();
707
            SelectableDataSource sds=va.getRecordset();
708
            // Annotation_Legend aLegend=(Annotation_Legend)capa.getLegend();
709
            for (int i = 0; i < lstRecs.size(); i++) {
710
                idRec = (Integer) lstRecs.get(i);
711
                index = idRec.intValue();
712

    
713
                Annotation_Mapping mapping = ((Annotation_Layer) capa).getAnnotatonMapping();
714
                NumericValue vRotation = (NumericValue) sds.getFieldValue(index,
715
                        mapping.getColumnRotate());
716
                NumericValue vHeight = (NumericValue) sds.getFieldValue(index,
717
                        mapping.getColumnHeight());
718
                NumericValue vStyle = (NumericValue) sds.getFieldValue(index,mapping.getColumnStyleFont());
719
                StringValue vType = (StringValue) sds.getFieldValue(index,mapping.getColumnTypeFont());
720
                Value vText = sds.getFieldValue(index,
721
                        mapping.getColumnText());
722
                va.start();
723
                IGeometry geom = va.getShape(i);
724
                va.stop();
725

    
726
                if (ct != null) {
727
                    if (bMustClone) {
728
                        geom = geom.cloneGeometry();
729
                    }
730

    
731
                    geom.reProject(ct);
732
                }
733
                geom.transform(vp.getAffineTransform());
734
                IGeometry geom1 = ((Annotation_Layer) capa).getTextWrappingGeometryInPixels(vHeight.floatValue(),
735
                        vText.toString(), vRotation.doubleValue(),vType.getValue(),vStyle.intValue(), index, vp,geom);
736
                geom1.transform(vp.getAffineTransform().createInverse());
737
                if (geom1.intersects(rect)) {
738
                    bitset.set(index, true);
739
                }
740
            }
741

    
742
            va.stop();
743
        } catch (DriverIOException e) {
744
            throw new DriverException(e);
745
        } catch (DriverLoadException e) {
746
                throw new DriverException(e);
747
        } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
748
                throw new DriverException(e);
749
        } catch (NoninvertibleTransformException e) {
750
                throw new DriverException(e);
751
                }
752

    
753
        return bitset;
754
    }
755

    
756
    /*
757
     * (non-Javadoc)
758
     *
759
     * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#queryByPoint(java.awt.geom.Point2D,
760
     *      double)
761
     */
762
    public FBitSet queryByPoint(Point2D p, double tolerance)
763
        throws DriverException {
764
        // TODO: OJO!!!!. Est? implementado como un rectangulo.
765
        // Lo correcto deber?a ser calculando las distancias reales
766
        // es decir, con un c?rculo.
767
        Rectangle2D recPoint = new Rectangle2D.Double(p.getX() -
768
                (tolerance / 2), p.getY() - (tolerance / 2), tolerance,
769
                tolerance);
770

    
771
        return queryByRect(recPoint);
772
    }
773

    
774
    public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
775
        PrintRequestAttributeSet properties) throws DriverException {
776
        capa.beforePrinting(properties);
777
        drawAllAnnotations(g, viewPort, cancel, properties);
778
        capa.afterPrinting();
779
    }
780
    private static void DrawAnnotation(Graphics2D g2,
781
                    FSymbol theSymbol,Point2D pAux, String text,ViewPort viewPort,PrintRequestAttributeSet properties) {
782
                    float x;
783
                    float y;
784
                    // Las etiquetas que pongamos a nulo ser? porque no la queremos dibujar.
785
                    // ?til para cuando queramos eliminar duplicados.
786
                    if (text == null) {
787
                            return;
788
                    }
789
                    int size=theSymbol.getFont().getSize();
790
                    double resolutionPrinting=0;
791
                    if (!theSymbol.isFontSizeInPixels()){
792
                            size=viewPort.fromMapDistance(size);
793
                    }
794
                    if (properties!=null){
795
                            PrintQuality resolution=(PrintQuality)properties.get(PrintQuality.class);
796
                            if (resolution.equals(PrintQuality.NORMAL)){
797
                                    resolutionPrinting=300/72;
798
                            }else if (resolution.equals(PrintQuality.HIGH)){
799
                                    resolutionPrinting=600/72;
800
                            }else if (resolution.equals(PrintQuality.DRAFT)){
801
                                    resolutionPrinting=1;
802
                            }
803
                            size=(int)(size*resolutionPrinting);
804
                    }
805
                    Font font=new Font(theSymbol.getFont().getName(),theSymbol.getFont().getStyle(),size);
806
                           g2.setFont(font);
807
                    g2.setColor(theSymbol.getFontColor());
808
                    AffineTransform ant = g2.getTransform();
809

    
810
                    x = (float) pAux.getX();
811
                    y = (float) pAux.getY();
812

    
813
                    AffineTransform Tx = (AffineTransform) ant.clone();
814
                    Tx.translate(x, y); // S3: final translation
815
                    Tx.rotate(Math.toRadians(-theSymbol.getRotation())); // S2: rotate around anchor
816
                    g2.setTransform(Tx);
817
                        g2.drawString(text, 0, 0);
818
                    g2.setTransform(ant);
819
            }
820

    
821
}