Statistics
| Revision:

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

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

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

    
55
import javax.print.attribute.PrintRequestAttributeSet;
56

    
57
import org.cresques.cts.ICoordTrans;
58

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

    
90

    
91
/**
92
 * Esta clase se encargar? de dibujar de la forma m?s eficiente los temas de
93
 * anotaciones.
94
 *
95
 * @author Vicente Caballero Navarro
96
 */
97
public class Annotation_Strategy extends DefaultStrategy {
98
    private FSymbol symbolPoint = new FSymbol(FShape.POINT, Color.black);
99
    private Annotation_Layer capa;
100
    private Geometry geometry;
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
        BufferedImage bi=new BufferedImage(image.getWidth(),image.getHeight(),BufferedImage.TYPE_INT_ARGB);
116
        Graphics2D gBi=(Graphics2D)bi.getGraphics();
117
        Point2D offset=viewPort.getOffset();
118
        gBi.translate(-offset.getX(),-offset.getY());
119
        Annotation_Legend l = (Annotation_Legend) capa.getLegend();
120
        FSymbol sym = (FSymbol) l.getDefaultSymbol();
121

    
122
        try {
123
            ReadableVectorial source = capa.getSource();
124
            // limit the labeling to the visible extent
125
            FBitSet bs = capa.queryByRect(viewPort.getAdjustedExtent());
126

    
127
            SelectableDataSource recordSet = source.getRecordset();
128
            FBitSet bitSet = recordSet.getSelection();
129
            FontMetrics metrics = g.getFontMetrics();
130
            Annotation_Mapping mapping = ((Annotation_Layer) capa).getAnnotatonMapping();
131
            int idHeightField = mapping.getColumnHeight();
132
            int idFontName = mapping.getColumnTypeFont();
133
            int idFontStyle = mapping.getColumnStyleFont();
134
            int idRotationField = mapping.getColumnRotate();
135
            int idFontColor = mapping.getColumnColor();
136
            int idTextField = mapping.getColumnText();
137

    
138
            double rotation = 0D;
139
            float size = sym.getFont().getSize();
140

    
141
            String fontName = "Dialog";
142
            int fontStyle = sym.getFont().getStyle();
143
            int fontColor = sym.getFontColor().getRGB();
144
            long t1 = System.currentTimeMillis();
145

    
146
            for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1)) {
147
                if (cancel.isCanceled()) {
148
                    break;
149
                }
150

    
151
                Value[] vv = recordSet.getRow(i);
152

    
153
                if (idHeightField != -1) {
154
                    // text size is defined in the table
155
                    try {
156
                        size = (float)(((NumericValue) vv[idHeightField]).doubleValue() * FConstant.FONT_HEIGHT_SCALE_FACTOR);
157
                    } catch (ClassCastException ccEx) {
158
                        if (!NullValue.class.equals(
159
                                    vv[idHeightField].getClass())) {
160
                            // throw new ReadDriverException("Unknown", ccEx);
161
                        }
162
                        continue;
163
                    }
164
                }
165

    
166
                if (idFontName != -1) {
167
                    fontName = ((StringValue) vv[idFontName]).toString();
168
                }
169

    
170
                if (idFontStyle != -1) {
171
                    fontStyle = ((NumericValue) vv[idFontStyle]).intValue();
172
                }
173

    
174
                if (idRotationField != -1) {
175
                    // text rotation is defined in the table
176
                    rotation = ((NumericValue) vv[idRotationField]).doubleValue();
177
                }
178

    
179
                if (idFontColor != -1) {
180
                    // text rotation is defined in the table
181
                    fontColor = ((NumericValue) vv[idFontColor]).intValue();
182
                    sym.setFontColor(new Color(fontColor));
183
                }
184

    
185
                if (bitSet.get(i)) {
186
                    sym = (FSymbol) sym.getSymbolForSelection();
187
                }
188

    
189
                sym.setFont(new Font(fontName, fontStyle, (int) size));
190

    
191
                //Si el tama?o de la fuente est? en unidades de mapa.
192
                if (!sym.isFontSizeInPixels()){
193
                        boolean draw=false;
194
                        Rectangle2D r=capa.getTextWrappingGeometry(size,vv[idTextField].toString(),rotation,fontName, fontStyle,i,viewPort).getBounds2D();
195
                        Rectangle2D rPixels=viewPort.fromMapRectangle(r);
196
                        //Point2D fp=new Point2D.Double(r.getX(),r.getY());
197
                        Point2D p=new Point2D.Double(rPixels.getX(),rPixels.getY());
198
                        FPoint2D fpPixels=new FPoint2D(rPixels.getX(),rPixels.getY());
199
                        rPixels.setRect(rPixels.getX(),rPixels.getY()-rPixels.getHeight(),rPixels.getWidth(),rPixels.getHeight());
200

    
201
                        if (!capa.isEditing() && l.isAvoidOverLapping()){
202
                                p=getPoint(bi,rPixels,l.isDelOverLapping());
203
                                draw=true;
204
                        }else{
205
                                if (!capa.isEditing() && l.isDelOverLapping()){
206
                                        if (isOverlapping(bi,rPixels)){
207
                                                draw=true;
208
                                        }
209
                                }else{
210
                                        draw=true;
211
                                }
212
                        }
213
                        if (draw){
214
                                FLabel[] aux = new FLabel[]{new FLabel()};//geom.createLabels(0, true);
215
                            aux[0].setOrig(viewPort.toMapPoint(p));
216
                            aux[0].setHeight(size);
217
                            aux[0].setRotation((int) rotation);
218
                            aux[0].setString(vv[idTextField].toString());
219
                            AffineTransform at = viewPort.getAffineTransform();
220
                            if (sym.isShapeVisible()) {
221
                                symbolPoint.draw(gBi,
222
                                       at,
223
                                       fpPixels);
224
                            }
225
//                            g.drawRect((int)rPixels.getX(),(int)rPixels.getY(),(int)rPixels.getWidth(),(int)rPixels.getHeight());
226
                            FGraphicUtilities.DrawAnnotation(gBi,
227
                                    at, sym, aux[0], metrics, false);
228
                        }
229
                }else{
230

    
231
                        // Si el tama?o de la fuente est? en pixels.
232
                        boolean draw=false;
233
                        Rectangle2D r=capa.getTextWrappingGeometryInPixels(size,vv[idTextField].toString(),rotation,fontName,fontStyle,i,viewPort).getBounds2D();
234
                        Rectangle2D rPixels=r;//capa.getMapContext().getViewPort().fromMapRectangle(r);
235
                        FPoint2D fp=new FPoint2D(rPixels.getX(),rPixels.getY());
236
                        Point2D p=new Point2D.Double(rPixels.getX(),rPixels.getY());
237
                        rPixels.setRect(rPixels.getX(),rPixels.getY()-rPixels.getHeight(),rPixels.getWidth(),rPixels.getHeight());
238
                        if (!capa.isEditing() && l.isAvoidOverLapping()){
239
                                p=getPoint(bi,rPixels,l.isDelOverLapping());
240
                                if (p==null){
241
                                        draw=false;
242
                                }else{
243
                                        //fp=new FPoint2D(p);
244
                                        draw=true;
245
                                }
246
                        }else{
247
                                if (!capa.isEditing() && l.isDelOverLapping()){
248
                                        if (isOverlapping(bi,rPixels)){
249
                                                draw=true;
250
                                        }
251
                                }else{
252
                                        draw=true;
253
                                }
254
                        }
255
                        if (draw){
256
                            FLabel[] aux = new FLabel[]{new FLabel()};//geom.createLabels(0, true);
257
                            aux[0].setOrig(p);
258
                            aux[0].setHeight(size);
259
                            aux[0].setRotation((int) rotation);
260
                            aux[0].setString(vv[idTextField].toString());
261

    
262
                            if (sym.isShapeVisible()) {
263
                                symbolPoint.draw(gBi,
264
                                       ati,
265
                                       fp);
266
                            }
267
                           // g.drawRect((int)p.getX(),(int)(p.getY()-rPixels.getHeight()),(int)rPixels.getWidth(),(int)rPixels.getHeight());
268
                            FGraphicUtilities.DrawAnnotation(gBi,
269
                                    ati, sym, aux[0], metrics, false);
270

    
271
                        }
272
                }
273
                //Al dibujar esta imagen sobre el graphics la trasparencia no puede existir.
274
                if (i%1000==0){
275
                         g.drawImage(bi,0,0,null);
276
                }
277
            }
278
            gBi.translate(offset.getX(),offset.getY());
279
            g.drawImage(bi,(int)offset.getX(),(int)offset.getY(),null);
280
            System.err.println(System.currentTimeMillis()-t1+"millis");
281

    
282
        } catch (Exception e) {
283
            // Logger.getAnonymousLogger().log(Level.SEVERE, "Could not get the
284
            // layer extent.\n" +
285
            // e.getMessage());
286
            NotificationManager.addError(e);
287
        }
288

    
289
        // }
290
    }
291

    
292
    // /**
293
    // * @see
294
    // com.iver.cit.gvsig.fmap.operations.LayerOperations#draw(java.awt.image.BufferedImage,
295
    // * java.awt.Graphics2D, ISymbol)
296
    // */
297
    // public void print(BufferedImage image, Graphics2D g, ViewPort viewPort,
298
    // Cancellable cancel) throws DriverException {
299
    //
300
    // // Rectangle2D elExtent = viewPort.getAdjustedExtent();
301
    // // graphics=g;
302
    // // Annotation_Layer lyrAnnotation=(Annotation_Layer)capa;
303
    // // List lstIndexes=null;
304
    // //
305
    // // VectorialLegend l=(VectorialLegend)lyrAnnotation.getLegend();
306
    // // FBitSet bitSet=lyrAnnotation.getRecordset().getSelection();
307
    // //
308
    // // boolean inPixels=lyrAnnotation.isInPixels();
309
    // // FSymbol theSymbol = (FSymbol) l.getDefaultSymbol();
310
    // // theSymbol.setFontSizeInPixels(inPixels);
311
    // // this.viewPort=viewPort;//capa.getFMap().getViewPort();
312
    // // AffineTransform at=viewPort.getAffineTransform();
313
    // // try {
314
    // // int sc;
315
    // // sc=lyrAnnotation.getSource().getShapeCount();
316
    // // // If area of needed extent is less than fullExtent / 4,
317
    // // // it will be worthy to use SpatialIndex.
318
    // // // Otherwhise, we will not use it.
319
    // // boolean bUseSpatialIndex = false;
320
    // // if(lyrAnnotation.getISpatialIndex() != null)
321
    // // {
322
    // // if(isSpatialIndexNecessary(elExtent)){
323
    // // lstIndexes = lyrAnnotation.getISpatialIndex().query(elExtent);
324
    // // sc = lstIndexes.size();
325
    // // bUseSpatialIndex = true;
326
    // // }//if
327
    // // }//if
328
    // //
329
    // // FontMetrics metrics = g.getFontMetrics();
330
    // // //SpatialCache cache = lyrAnnotation.createSpatialCache();
331
    // // int numOriginal;
332
    // // for (int numReg = 0; numReg < sc; numReg++) {
333
    // // if (cancel.isCanceled()){
334
    // // break;
335
    // // }
336
    // // if (bUseSpatialIndex){
337
    // // Integer idRec = (Integer) lstIndexes.get(numReg);
338
    // // numOriginal = idRec.intValue();
339
    // // }else{
340
    // // numOriginal = numReg;
341
    // // }
342
    // // /* if (lyrAnnotation.getSource() instanceof EditableAdapter)
343
    // //
344
    // numOriginal=((EditableAdapter)lyrAnnotation.getSource()).getCalculatedIndex(numOriginal);*/
345
    // //
346
    // // FLabel theLabel = lyrAnnotation.getLabel(numOriginal);
347
    // // if ((theLabel == null) || (theLabel.getOrig() == null))
348
    // // continue;
349
    // //
350
    // //
351
    // // Rectangle2D r=null;
352
    // // if (inPixels && lyrAnnotation.getMapping().getColumnHeight()==-1) {
353
    // //
354
    // r=getDefaultBoundBoxinPixels(metrics,theLabel.getOrig(),theLabel.getString());
355
    // // }else {
356
    // // r=getBoundBox(theLabel.getOrig(),(float)theLabel.getHeight(),
357
    // theLabel.getJustification(),theLabel.getString());
358
    // // }
359
    // // theLabel.setBoundBox(r);
360
    // //
361
    // // if (elExtent.intersects(r))
362
    // // {
363
    // // FPoint2D p=new FPoint2D(viewPort.fromMapPoint(new
364
    // Point2D.Double(r.getX(),r.getY())));
365
    // // FGraphicUtilities.DrawShape(g,at,p,symbolPoint);
366
    // // if (bitSet.get(numOriginal)) {
367
    // // FGraphicUtilities.DrawAnnotation(g, at, theSymbol,
368
    // theLabel,metrics,true);
369
    // // }else{
370
    // // FGraphicUtilities.DrawAnnotation(g, at, theSymbol,
371
    // theLabel,metrics,false);
372
    // // }
373
    // //
374
    // //
375
    // // } // XIntersects
376
    // //
377
    // //
378
    // // }
379
    // //
380
    // // } catch (DriverIOException e) {
381
    // // e.printStackTrace();
382
    // // }
383
    // // heightDefault=-1;
384
    // }
385
    // public Rectangle2D getDefaultBoundBoxinPixels(FontMetrics metrics,
386
    // Point2D p, String s) {
387
    // int w = metrics.stringWidth(s);
388
    // double width = viewPort.toMapDistance(w);
389
    // if (heightDefault == -1) {
390
    // int h = metrics.getMaxAscent();
391
    // heightDefault = viewPort.toMapDistance(h);
392
    // }
393
    // return new Rectangle2D.Double(p.getX(), p.getY(), width, heightDefault);
394
    //
395
    // }
396

    
397
    private Point2D getPoint(BufferedImage bi, Rectangle2D rec, boolean b) {
398
                Rectangle2D r=new Rectangle2D.Double(rec.getX(),rec.getY(),rec.getWidth(),rec.getHeight());
399
                if (isOverlapping(bi,r))
400
                        return new Point2D.Double(r.getX(),r.getY()+r.getHeight());
401
                r.setFrame(rec.getX(),rec.getY()+rec.getHeight(),rec.getWidth(),rec.getHeight());
402
                if (isOverlapping(bi,r))
403
                        return new Point2D.Double(r.getX(),r.getY()+r.getHeight());
404
                r.setFrame(rec.getX()-rec.getWidth(),rec.getY()+rec.getHeight(),rec.getWidth(),rec.getHeight());
405
                if (isOverlapping(bi,r))
406
                        return new Point2D.Double(r.getX(),r.getY()+r.getHeight());
407
                r.setFrame(rec.getX()-rec.getWidth(),rec.getY(),rec.getWidth(),rec.getHeight());
408
                if (isOverlapping(bi,r))
409
                        return new Point2D.Double(r.getX(),r.getY()+r.getHeight());
410
                r.setFrame(rec.getX()-rec.getWidth()/2,rec.getY(),rec.getWidth(),rec.getHeight());
411
                if (isOverlapping(bi,r))
412
                        return new Point2D.Double(r.getX(),r.getY()+r.getHeight());
413
                r.setFrame(rec.getX()-rec.getWidth()/2,rec.getY()+rec.getHeight(),rec.getWidth(),rec.getHeight());
414
                if (isOverlapping(bi,r))
415
                        return new Point2D.Double(r.getX(),r.getY()+r.getHeight());
416
                r.setFrame(rec.getX()-rec.getWidth(),rec.getY()+rec.getHeight()/2,rec.getWidth(),rec.getHeight());
417
                if (isOverlapping(bi,r))
418
                        return new Point2D.Double(r.getX(),r.getY()+r.getHeight());
419
                r.setFrame(rec.getX(),rec.getY()+rec.getHeight()/2,rec.getWidth(),rec.getHeight());
420
                if (isOverlapping(bi,r))
421
                        return new Point2D.Double(r.getX(),r.getY()+r.getHeight());
422
//                r.setFrame(rec.getX()-rec.getWidth(),rec.getY()+rec.getHeight()/2,rec.getWidth(),rec.getHeight());
423
//                if (isTrasparent(bi,r))
424
//                        return new Point2D.Double(r.getX(),r.getY());
425

    
426
                if (!b)
427
                        return new Point2D.Double(rec.getX(),rec.getY()+rec.getHeight());
428
                else
429
                        return null;
430
        }
431

    
432
        private boolean isOverlapping(BufferedImage bi, Rectangle2D rPixels) {
433
        for (int i=(int)rPixels.getX();i<rPixels.getMaxX();i++){
434
            for (int j=(int)rPixels.getY();j<rPixels.getMaxY();j++){
435
                if (i<0 || j<0 || bi.getWidth()<i+1 || bi.getHeight()<j+1)
436
                    continue;
437
                if (bi.getRGB(i,j)!=0){
438
                    return false;
439
                }
440
            }
441
        }
442
        return true;
443
    }
444

    
445
    /**
446
     * Construcci?n del rect?ngulo
447
     *
448
     * @param g DOCUMENT ME!
449
     * @param relationship
450
     *
451
     * @return
452
     *
453
     * @throws DriverException DOCUMENT ME!
454
     * @throws VisitException DOCUMENT ME!
455
     */
456

    
457
    // public Rectangle2D getBoundBox(Point2D p, float hp,
458
    // int justification,String s) {
459
    // //Rectangle2D bounding=null;
460
    // if (((Annotation_Layer)capa).isInPixels()){
461
    // graphics.setFont(graphics.getFont().deriveFont(hp));
462
    // }else{
463
    // float alturaPixels = (float) ((hp *
464
    // viewPort.getAffineTransform().getScaleX())*FConstant.FONT_HEIGHT_SCALE_FACTOR);
465
    // graphics.setFont(graphics.getFont().deriveFont(alturaPixels));
466
    // }
467
    // FontMetrics metrics = graphics.getFontMetrics();
468
    // int w = metrics.stringWidth(s);
469
    // double width = viewPort.toMapDistance(w);
470
    // int h = metrics.getMaxAscent();
471
    // double height = viewPort.toMapDistance(h);
472
    // //double dist = viewPort.toMapDistance(3);
473
    // return new Rectangle2D.Double(p.getX(), p.getY(), width, height);
474
    // /* switch (justification) {
475
    // case FLabel.LEFT_BOTTOM:
476
    // bounding=justification(p, width,height, 0, 0);
477
    //
478
    // break;
479
    //
480
    // case FLabel.LEFT_CENTER:
481
    // bounding=justification(p, width,height, 0, -(height / 2));
482
    //
483
    // break;
484
    //
485
    // case FLabel.LEFT_TOP:
486
    // bounding=justification(p,width,height, 0, -height);
487
    //
488
    // break;
489
    //
490
    // case FLabel.CENTER_BOTTOM:
491
    // bounding=justification(p, width,height, -(width / 2), -dist);
492
    //
493
    // break;
494
    //
495
    // case FLabel.CENTER_CENTER:
496
    // bounding=justification(p, width,height, -(width / 2), -(height / 2));
497
    //
498
    // break;
499
    //
500
    // case FLabel.CENTER_TOP:
501
    // bounding=justification(p, width,height, -(width / 2), -height);
502
    //
503
    // break;
504
    //
505
    // case FLabel.RIGHT_BOTTOM:
506
    // bounding=justification(p, width,height, -width, -dist);
507
    //
508
    // break;
509
    //
510
    // case FLabel.RIGHT_CENTER:
511
    // bounding=justification(p, width,height, -width, -(height / 2));
512
    //
513
    // break;
514
    //
515
    // case FLabel.RIGHT_TOP:
516
    // bounding=justification(p, width,height, -width, -height);
517
    //
518
    // break;
519
    // }
520
    //
521
    // return bounding;
522
    // */
523
    // }
524

    
525
    /*
526
     * private Rectangle2D justification(Point2D p, double w,double h, double x,
527
     * double y) { Rectangle2D r=new Rectangle2D.Double(p.getX() + x, p.getY() -
528
     * y, w, h); return r; }
529
     */
530
    /*
531
     * (non-Javadoc)
532
     *
533
     * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#queryByShape(com.iver.cit.gvsig.fmap.core.IGeometry,
534
     *      int)
535
     */
536
    public FBitSet queryByShape(IGeometry g, int relationship)
537
        throws DriverException, VisitException {
538
        // Si hay un ?ndice espacial, lo usamos para hacer el query.
539
        FLyrVect lyr = (FLyrVect) capa;
540

    
541
        // if (lyr.getSpatialIndex() == null)
542
        if (lyr.getISpatialIndex() == null) {
543
            return super.queryByShape(g, relationship);
544
        }
545

    
546
        long t1 = System.currentTimeMillis();
547
        ReadableVectorial va = lyr.getSource();
548
        ICoordTrans ct = lyr.getCoordTrans();
549
        Rectangle2D bounds = g.getBounds2D();
550

    
551
        // Coordinate c1 = new Coordinate(bounds.getMinX(), bounds.getMinY());
552
        // Coordinate c2 = new Coordinate(bounds.getMaxX(), bounds.getMaxY());
553
        // Envelope env = new Envelope(c1, c2);
554
        // List lstRecs = lyr.getSpatialIndex().query(env);
555
        List lstRecs = lyr.getISpatialIndex().query(bounds);
556
        Integer idRec;
557
        FBitSet bitset = new FBitSet();
558
        Geometry jtsShape = g.toJTSGeometry();
559
        IntersectionMatrix m;
560
        int index;
561

    
562
        try {
563
            va.start();
564

    
565
            // Annotation_Legend aLegend=(Annotation_Legend)capa.getLegend();
566
            for (int i = 0; i < lstRecs.size(); i++) {
567
                idRec = (Integer) lstRecs.get(i);
568
                index = idRec.intValue();
569

    
570
                IGeometry geom = va.getShape(index);
571

    
572
                // FSymbol symbol=(FSymbol)aLegend.getSymbol(index);
573
                // IGeometry geom=aLegend.getTextWrappingGeometry(symbol,index);
574
                // IGeometry
575
                // geom=getGeometry(((Annotation_Layer)capa).getLabel(index).getBoundBox());
576
                if (ct != null) {
577
                    geom.reProject(ct);
578
                }
579

    
580
                Geometry jtsGeom = geom.toJTSGeometry();
581

    
582
                switch (relationship) {
583
                case CONTAINS:
584
                    m = jtsShape.relate(jtsGeom);
585

    
586
                    if (m.isContains()) {
587
                        bitset.set(index, true);
588
                    }
589

    
590
                    break;
591

    
592
                case CROSSES:
593
                    m = jtsShape.relate(jtsGeom);
594

    
595
                    if (m.isCrosses(jtsGeom.getDimension(),
596
                                jtsShape.getDimension())) {
597
                        bitset.set(index, true);
598
                    }
599

    
600
                    break;
601

    
602
                case DISJOINT:
603

    
604
                    // TODO: CREO QUE EL DISJOINT NO SE PUEDE METER AQUI
605
                    m = jtsShape.relate(jtsGeom);
606

    
607
                    if (m.isDisjoint()) {
608
                        bitset.set(index, true);
609
                    }
610

    
611
                    break;
612

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

    
616
                    if (m.isEquals(jtsGeom.getDimension(),
617
                                jtsShape.getDimension())) {
618
                        bitset.set(index, true);
619
                    }
620

    
621
                    break;
622

    
623
                case INTERSECTS:
624
                    m = jtsShape.relate(jtsGeom);
625

    
626
                    if (m.isIntersects()) {
627
                        bitset.set(index, true);
628
                    }
629

    
630
                    break;
631

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

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

    
640
                    break;
641

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

    
645
                    if (m.isTouches(jtsGeom.getDimension(),
646
                                jtsShape.getDimension())) {
647
                        bitset.set(index, true);
648
                    }
649

    
650
                    break;
651

    
652
                case WITHIN:
653
                    m = jtsShape.relate(jtsGeom);
654

    
655
                    if (m.isWithin()) {
656
                        bitset.set(index, true);
657
                    }
658

    
659
                    break;
660
                }
661
            }
662

    
663
            va.stop();
664
        } catch (DriverIOException e) {
665
                throw new DriverException(e);
666
        }
667

    
668
        long t2 = System.currentTimeMillis();
669

    
670
        // logger.debug("queryByShape optimizado sobre la capa " + lyr.getName()
671
        // + ". " + (t2-t1) + " mseg.");
672
        return bitset;
673
    }
674

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

    
705
        try {
706
            va.start();
707

    
708
            DriverAttributes attr = va.getDriverAttributes();
709
            boolean bMustClone = false;
710

    
711
            if (attr != null) {
712
                if (attr.isLoadedInMemory()) {
713
                    bMustClone = attr.isLoadedInMemory();
714
                }
715
            }
716
            ViewPort vp=getCapa().getMapContext().getViewPort();
717
            SelectableDataSource sds=va.getRecordset();
718
            // Annotation_Legend aLegend=(Annotation_Legend)capa.getLegend();
719
            for (int i = 0; i < lstRecs.size(); i++) {
720
                idRec = (Integer) lstRecs.get(i);
721
                index = idRec.intValue();
722

    
723
                Annotation_Mapping mapping = ((Annotation_Layer) capa).getAnnotatonMapping();
724
                NumericValue vRotation = (NumericValue) sds.getFieldValue(index,
725
                        mapping.getColumnRotate());
726
                NumericValue vHeight = (NumericValue) sds.getFieldValue(index,
727
                        mapping.getColumnHeight());
728
                NumericValue vStyle = (NumericValue) sds.getFieldValue(index,mapping.getColumnStyleFont());
729
                StringValue vType = (StringValue) sds.getFieldValue(index,mapping.getColumnTypeFont());
730
                Value vText = sds.getFieldValue(index,
731
                        mapping.getColumnText());
732
                IGeometry geom = ((Annotation_Layer) capa).getTextWrappingGeometry(vHeight.floatValue(),
733
                        vText.toString(), vRotation.doubleValue(),vType.getValue(),vStyle.intValue(), index, vp);
734

    
735
                if (ct != null) {
736
                    if (bMustClone) {
737
                        geom = geom.cloneGeometry();
738
                    }
739

    
740
                    geom.reProject(ct);
741
                }
742

    
743
                if (geom.intersects(rect)) {
744
                    bitset.set(index, true);
745
                }
746
            }
747

    
748
            va.stop();
749
        } catch (DriverIOException e) {
750
            throw new DriverException(e);
751
        } catch (DriverLoadException e) {
752
                throw new DriverException(e);
753
        } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
754
                throw new DriverException(e);
755
        }
756

    
757
        return bitset;
758
    }
759

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

    
775
        return queryByRect(recPoint);
776
    }
777

    
778
    // private IGeometry getGeometry(Rectangle2D r){
779
    // GeneralPathX resul = new GeneralPathX();
780
    // Point2D[] vs=new Point2D[4];
781
    // vs[0]=new Point2D.Double(r.getX(),r.getY());
782
    // vs[1]=new Point2D.Double(r.getMaxX(),r.getY());
783
    // vs[2]=new Point2D.Double(r.getMaxX(),r.getMaxY());
784
    // vs[3]=new Point2D.Double(r.getX(),r.getMaxY());
785
    // //vs[4]=new Point2D.Double(r.getX(),r.getY());
786
    // for (int i = 0; i < vs.length; i++) {
787
    // if (i == 0) {
788
    // resul.moveTo(vs[i].getX(),vs[i].getY());
789
    // } else {
790
    // resul.lineTo(vs[i].getX(),vs[i].getY());
791
    // }
792
    // }
793
    // resul.closePath();
794
    // return ShapeFactory.createPolygon2D(resul);
795
    // }
796
    public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
797
        PrintRequestAttributeSet properties) throws DriverException {
798
        capa.beforePrinting(properties);
799
        drawAllAnnotations(g, viewPort, cancel);
800
        capa.afterPrinting();
801
    }
802
    private void drawAllAnnotations(Graphics2D g, ViewPort viewPort,
803
            Cancellable cancel){
804
        Annotation_Legend l = (Annotation_Legend) capa.getLegend();
805
        FSymbol sym = (FSymbol) l.getDefaultSymbol();
806

    
807
        try {
808
            ReadableVectorial source = capa.getSource();
809
            FBitSet bs = capa.queryByRect(viewPort.getAdjustedExtent());
810

    
811
            SelectableDataSource recordSet = source.getRecordset();
812
            FBitSet bitSet = recordSet.getSelection();
813
            FontMetrics metrics = g.getFontMetrics();
814
            Annotation_Mapping mapping = ((Annotation_Layer) capa).getAnnotatonMapping();
815
            int idHeightField = mapping.getColumnHeight();
816
            int idFontName = mapping.getColumnTypeFont();
817
            int idFontStyle = mapping.getColumnStyleFont();
818
            int idRotationField = mapping.getColumnRotate();
819
            int idFontColor = mapping.getColumnColor();
820
            int idTextField = mapping.getColumnText();
821

    
822
            double rotation = 0D;
823
            float size = sym.getFont().getSize();
824
            String fontName = "Dialog";
825
            int fontStyle = sym.getFont().getStyle();
826
            int fontColor = sym.getFontColor().getRGB();
827
            ViewPort vp=getCapa().getMapContext().getViewPort();
828
            for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1)) {
829
                if (cancel.isCanceled()) {
830
                    break;
831
                }
832

    
833
                Value[] vv = recordSet.getRow(i);
834

    
835
                if (idHeightField != -1) {
836
                    // text size is defined in the table
837
                    try {
838
                        size = (float)(((NumericValue) vv[idHeightField]).doubleValue() * FConstant.FONT_HEIGHT_SCALE_FACTOR);
839
                    } catch (ClassCastException ccEx) {
840
                        if (!NullValue.class.equals(
841
                                    vv[idHeightField].getClass())) {
842
                            // throw new ReadDriverException("Unknown", ccEx);
843
                        }
844
                        continue;
845
                    }
846
                } else {
847
                    // otherwise will use the size in the symbol
848
                }
849

    
850
                if (idFontName != -1) {
851
                    fontName = ((StringValue) vv[idFontName]).toString();
852
                }
853
                if (idFontStyle != -1) {
854
                    fontStyle = ((NumericValue) vv[idFontStyle]).intValue();
855
                }
856
                if (idRotationField != -1) {
857
                    // text rotation is defined in the table
858
                    rotation = ((NumericValue) vv[idRotationField]).doubleValue();
859
                }
860
                if (idFontColor != -1) {
861
                    // text rotation is defined in the table
862
                    fontColor = ((NumericValue) vv[idFontColor]).intValue();
863
                    sym.setFontColor(new Color(fontColor));
864
                }
865
                if (bitSet.get(i)) {
866
                    sym = (FSymbol) sym.getSymbolForSelection();
867
                }
868
                sym.setFont(new Font(fontName, fontStyle, (int) size));
869

    
870
                //Si el tama?o de la fuente est? en unidades de mapa.
871
                if (!sym.isFontSizeInPixels()){
872
                        Rectangle2D r=capa.getTextWrappingGeometry(size,vv[idTextField].toString(),rotation,fontName,fontStyle,i,vp).getBounds2D();
873
                        Rectangle2D rPixels=viewPort.fromMapRectangle(r);
874
                        Point2D p = vp.fromMapPoint((int)r.getX(),(int)r.getY());
875
                        FPoint2D fpPixels=new FPoint2D(rPixels.getX(),rPixels.getY());
876
                        rPixels.setRect(rPixels.getX(),rPixels.getY()-rPixels.getHeight(),rPixels.getWidth(),rPixels.getHeight());
877

    
878
                        FLabel[] aux = new FLabel[]{new FLabel()};//geom.createLabels(0, true);
879
                        aux[0].setOrig(viewPort.toMapPoint(p));
880
                        aux[0].setHeight(size);
881
                        aux[0].setRotation((int) rotation);
882
                        aux[0].setString(vv[idTextField].toString());
883
                    if (sym.isShapeVisible()) {
884
                        symbolPoint.draw(g,
885
                               viewPort.getAffineTransform(),
886
                               fpPixels);
887
                    }
888
                    FGraphicUtilities.DrawAnnotation(g,
889
                                    viewPort.getAffineTransform(), sym, aux[0], metrics, false);
890
                    }else{
891
                        // Si el tama?o de la fuente est? en pixels.
892
                        Rectangle2D r=capa.getTextWrappingGeometryInPixels(size,vv[idTextField].toString(),rotation,fontName,fontStyle,i,viewPort).getBounds2D();
893
                        Rectangle2D rPixels=r;//capa.getMapContext().getViewPort().fromMapRectangle(r);
894
                        FPoint2D fp=new FPoint2D(rPixels.getX(),rPixels.getY());
895
                        Point2D p=new Point2D.Double(rPixels.getX(),rPixels.getY());
896
                        rPixels.setRect(rPixels.getX(),rPixels.getY()-rPixels.getHeight(),rPixels.getWidth(),rPixels.getHeight());
897
                        FLabel[] aux = new FLabel[]{new FLabel()};//geom.createLabels(0, true);
898
                        aux[0].setOrig(p);
899
                        aux[0].setHeight(size);
900
                        aux[0].setRotation((int) rotation);
901
                        aux[0].setString(vv[idTextField].toString());
902
                        if (sym.isShapeVisible()) {
903
                            symbolPoint.draw(g,
904
                                 ati,
905
                                 fp);
906
                        }
907
                        FGraphicUtilities.DrawAnnotation(g,
908
                                 ati, sym, aux[0], metrics, false);
909

    
910
                    }
911
            }
912
        } catch (Exception e) {
913
            NotificationManager.addError(e);
914
        }
915
    }
916
}