Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / core / v02 / FGraphicUtilities.java @ 787

History | View | Annotate | Download (19.8 KB)

1
/*
2
 * Created on 28-abr-2004
3
 *
4
 * To change the template for this generated file go to
5
 * Window>Preferences>Java>Code Generation>Code and Comments
6
 */
7
package com.iver.cit.gvsig.fmap.core.v02;
8

    
9
import java.awt.Font;
10
import java.awt.FontMetrics;
11
import java.awt.Graphics2D;
12
import java.awt.Rectangle;
13
import java.awt.geom.AffineTransform;
14
import java.awt.geom.Point2D;
15

    
16
import org.apache.batik.ext.awt.geom.PathLength;
17

    
18
import com.iver.cit.gvsig.fmap.core.FGeometry;
19
import com.iver.cit.gvsig.fmap.core.FPoint2D;
20
import com.iver.cit.gvsig.fmap.core.FPolygon2D;
21
import com.iver.cit.gvsig.fmap.core.FPolyline2D;
22
import com.iver.cit.gvsig.fmap.core.FShape;
23
import com.iver.cit.gvsig.fmap.core.GeneralPathX;
24
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
25
import com.vividsolutions.jts.geom.Geometry;
26
import com.vividsolutions.jts.geom.Point;
27

    
28

    
29
/**
30
 * DOCUMENT ME!
31
 *
32
 * @author fjp To change the template for this generated type comment go to
33
 *         Window>Preferences>Java>Code Generation>Code and
34
 *         Comments
35
 */
36
public class FGraphicUtilities {
37
    /**
38
     * DOCUMENT ME!
39
     *
40
     * @param g2 DOCUMENT ME!
41
     * @param mT2 DOCUMENT ME!
42
     * @param r DOCUMENT ME!
43
     * @param symbol DOCUMENT ME!
44
     */
45
    public static void DrawSymbol(Graphics2D g2, AffineTransform mT2,
46
        Rectangle r, FSymbol symbol) {
47
        FShape shp;
48

    
49
        AffineTransform mT = new AffineTransform();
50
        mT.setToIdentity();
51

    
52
        // g2.clearRect(r.x, r.y, r.width, r.height);
53
        // System.out.println("r = " + r.toString() + " Color preview:" + symbol.m_Color.toString());
54
        // System.out.println("symbol.m_symbolType= "+symbol.m_symbolType);
55
        switch (symbol.getSymbolType()) {
56
            case FConstant.SYMBOL_TYPE_MULTIPOINT:
57

    
58
                shp = new FPoint2D(r.x + (r.width / 2),
59
                        r.y + (r.height / 2));
60
                
61

    
62
                //  Para no tener que clonarlo si viene en unidades de mapa
63
                boolean bAux22 = symbol.isSizeInPixels();
64
                int alturaMetros2 = symbol.getSize(); // Nota: Cambiar m_Size a float
65

    
66
                if (symbol.isSizeInPixels()) {
67
                    symbol.setSize(8); // tama?o fijo
68
                    symbol.setSizeInPixels(false);
69
                }
70
                                //FShape auxshp=new FShape(shp.multipoint.getPoint(0));
71
                FGraphicUtilities.DrawShape(g2, mT, shp, symbol);
72

    
73
                if (bAux22) {
74
                    symbol.setSize(alturaMetros2);
75
                    symbol.setSizeInPixels(bAux22);
76
                }
77

    
78
                if (symbol.getFont() != null) {
79
                    // Para no tener que clonarlo si viene en unidades de mapa
80
                    boolean bAux = symbol.isFontSizeInPixels();
81
                    symbol.setFontSizeInPixels(false);
82
                    FGraphicUtilities.DrawLabel(g2, mT, shp, symbol,
83
                        new FLabel("Abcd"));
84
                    symbol.setFontSizeInPixels(bAux);
85
                }
86

    
87
                break;
88

    
89
            case FConstant.SYMBOL_TYPE_POINT:
90
            case FConstant.SYMBOL_TYPE_POINTZ:
91

    
92
                shp = new FPoint2D(r.x + (r.width / 2),
93
                        r.y + (r.height / 2));
94

    
95
                //  Para no tener que clonarlo si viene en unidades de mapa
96
                boolean bAux2 = symbol.isSizeInPixels();
97
                int alturaMetros = symbol.getSize(); // Nota: Cambiar m_Size a float
98

    
99
                if (symbol.isSizeInPixels()) {
100
                    symbol.setSize(8); // tama?o fijo
101
                    symbol.setSizeInPixels(false);
102
                }
103

    
104
                FGraphicUtilities.DrawShape(g2, mT, shp, symbol);
105

    
106
                if (bAux2) {
107
                    symbol.setSize(alturaMetros);
108
                    symbol.setSizeInPixels(bAux2);
109
                }
110

    
111
                if (symbol.getFont() != null) {
112
                    // Para no tener que clonarlo si viene en unidades de mapa
113
                    boolean bAux = symbol.isFontSizeInPixels();
114
                    symbol.setFontSizeInPixels(false);
115
                    FGraphicUtilities.DrawLabel(g2, mT, shp, symbol,
116
                        new FLabel("Abcd"));
117
                    symbol.setFontSizeInPixels(bAux);
118
                }
119

    
120
                break;
121

    
122
            case FConstant.SYMBOL_TYPE_LINE:
123
            case FConstant.SHAPE_TYPE_POLYLINEZ:
124

    
125
                Rectangle rect = mT2.createTransformedShape(r).getBounds();
126
                GeneralPathX line = new GeneralPathX();
127
                line.moveTo(rect.x, rect.y + (rect.height / 2));
128

    
129
                // line.lineTo(rect.x + rect.width/3, rect.y + rect.height);                                                                
130
                // line.lineTo(rect.x + 2*rect.width/3, rect.y);                                
131
                // line.lineTo(rect.x + rect.width, rect.y + rect.height/2);
132
                line.curveTo(rect.x + (rect.width / 3),
133
                    rect.y + (2 * rect.height),
134
                    rect.x + ((2 * rect.width) / 3), rect.y - rect.height,
135
                    rect.x + rect.width, rect.y + (rect.height / 2));
136

    
137
                shp = new FPolyline2D(line);
138
                FGraphicUtilities.DrawShape(g2, mT, shp, symbol);
139

    
140
                break;
141

    
142
            case FConstant.SYMBOL_TYPE_FILL:
143
            case FConstant.SHAPE_TYPE_POLYGONZ:
144

    
145
                GeneralPathX rectAux = new GeneralPathX(r);
146
                rectAux.transform(mT2);
147
                shp = new FPolygon2D( rectAux);
148

    
149
                // System.out.println("rect = "+rectAux.getBounds());
150
                FGraphicUtilities.DrawShape(g2, mT, shp, symbol);
151

    
152
                break;
153
        }
154
    }
155

    
156
    /**
157
     * DOCUMENT ME!
158
     *
159
     * @param g2 DOCUMENT ME!
160
     * @param mT DOCUMENT ME!
161
     * @param shp DOCUMENT ME!
162
     * @param theSymbol DOCUMENT ME!
163
     */
164
    public static void DrawShape(Graphics2D g2, AffineTransform mT, FShape shp,
165
        FSymbol theSymbol) {
166
        // Hacemos la transformaci?n del shape aqu? dentro... por ahora.
167
        if (shp == null) {
168
            return;
169
        }
170

    
171
        g2.setColor(theSymbol.getColor());
172
        
173
        /* if (shp instanceof FPolygon2D)
174
        {
175
                System.out.println("Entra pol?gono");
176
        } */
177

    
178
        switch (shp.getShapeType()) {
179
            case FShape.POINT: //Tipo punto
180
                drawSymbolPoint(g2, mT, (FPoint2D) shp, theSymbol);
181

    
182
                break;
183
            case FShape.LINE:
184

    
185
                // Shape theShp = mT.createTransformedShape(shp.m_Polyline);
186
                // g2.setColor(theSymbol.m_Color);
187
                if (theSymbol.getStroke() != null) {
188
                    g2.setStroke(theSymbol.getStroke());
189
                }
190

    
191
                g2.draw(shp);
192

    
193
                break;
194
                
195

    
196
            case FShape.POLYGON:
197
                g2.setPaint(theSymbol.getFill());
198

    
199
                if (theSymbol.getColor() != null) {
200
                    g2.fill(shp);
201
                }
202

    
203
                if (theSymbol.isOutlined()) {
204
                    g2.setColor(theSymbol.getOutlineColor());
205

    
206
                    if (theSymbol.getStroke() != null) {
207
                        g2.setStroke(theSymbol.getStroke());
208
                    }
209

    
210
                    g2.draw(shp);
211
                }
212

    
213
                break;
214
        }
215
    }
216

    
217
    public static void DrawLabel(Graphics2D g2, AffineTransform mT, FShape shp,
218
        FSymbol theSymbol, FLabel theLabel) {
219
        float angle;
220
        float x;
221
        float y;
222
        Point2D pAux = null;
223

    
224
        // USAR TEXTLAYOUT SI QUEREMOS PERMITIR SELECCIONAR UN TEXTO
225
        // Y/O EDITARLO "IN SITU"
226

    
227
        /* if (m_labelValues[numReg].length() > 0)
228
           {
229
                   TextLayout layout = new TextLayout(m_labelValues[numReg], font, frc);
230
                   layout.draw(g2, x, y);
231
           } */
232
        if (shp == null) {
233
            return;
234
        }
235

    
236
        // Las etiquetas que pongamos a nulo ser? porque no la queremos dibujar.
237
        // ?til para cuando queramos eliminar duplicados.
238
        if (theLabel.getString() == null) {
239
            return;
240
        }
241

    
242
        FontMetrics metrics = g2.getFontMetrics();
243
        int width = metrics.stringWidth(theLabel.getString());
244
        int height = metrics.getMaxAscent();
245

    
246
        // int height = metrics.getHeight();
247
        g2.setFont(theSymbol.getFont());
248
        g2.setColor(theSymbol.getFontColor());
249

    
250
        // Aqu? hay que mirar m_Size y m_useSize...
251
        if (theSymbol.isFontSizeInPixels()) {
252
            // Suponemos que m_Size viene en coordenadas de mundo real
253
            // Esto habr? que cambiarlo. Probablemente usar Style2d de geotools en lugar
254
            // de FSymbol.
255
            // CAMBIO: La altura del texto la miramos en FLabel
256
            // float alturaPixels = (float) (theSymbol.m_FontSize * mT.getScaleX());
257
            float alturaPixels = (float) (theLabel.getHeight() * mT.getScaleX());
258

    
259
            /* System.out.println("m_bUseSize = " + theSymbol.m_bUseSize +
260
               " Escala: " + mT.getScaleX() + " alturaPixels = " + alturaPixels); */
261
            if (alturaPixels < 3) {
262
                return; // No leemos nada
263
            }
264

    
265
            Font nuevaFuente = theSymbol.getFont().deriveFont(alturaPixels);
266
            g2.setFont(nuevaFuente);
267
            width = g2.getFontMetrics().stringWidth(theLabel.getString());
268
        }
269

    
270
        switch (shp.getShapeType()) {
271
            case FShape.POINT: //Tipo punto
272
                    
273
                    pAux = new Point2D.Double(((FPoint2D)shp).getX(), ((FPoint2D)shp).getY());
274
                pAux = mT.transform(pAux, null);
275

    
276
                break;
277

    
278
            case FShape.LINE:
279

    
280
                // 
281
                if (theLabel.getOrig() == null) // Calculamos el punto y la orientaci?n solo la primera vez
282
                 {
283
                    PathLength pathLen = new PathLength(shp);
284

    
285
                    // if (pathLen.lengthOfPath() < width / mT.getScaleX()) return;
286
                    float midDistance = pathLen.lengthOfPath() / 2;
287
                    pAux = pathLen.pointAtLength(midDistance);
288
                    angle = pathLen.angleAtLength(midDistance);
289

    
290
                    if (angle < 0) {
291
                        angle = angle + (float) (2 * Math.PI);
292
                    }
293

    
294
                    if ((angle > (Math.PI / 2)) &&
295
                            (angle < ((3 * Math.PI) / 2))) {
296
                        angle = angle - (float) Math.PI;
297
                    }
298

    
299
                    theLabel.setRotation(Math.toDegrees(angle));
300
                    theLabel.setOrig(pAux);
301
                }
302

    
303
                pAux = mT.transform(theLabel.getOrig(), null);
304

    
305
                // pAux = theLabel.getOrig();
306
                // GlyphVector theGlyphs = theSymbol.m_Font.createGlyphVector(g2.getFontRenderContext(), theLabel);
307
                // Shape txtShp = TextPathLayout.layoutGlyphVector(theGlyphs, shp.m_Polyline,TextPathLayout.ALIGN_MIDDLE);                                
308
                // g2.draw(txtShp);
309
                // System.out.println("Pintando etiqueta " + theLabel );
310
                break;
311

    
312
            case FShape.POLYGON:
313
                if (theLabel.getOrig() == null) // Calculamos el punto solo la primera vez
314
                 {
315
                    Geometry geo = FConverter.java2d_to_jts(shp);
316

    
317
                    // System.out.println("Area de " + m_labelValues[numReg] + " = "
318
                    //   + geo.getArea());
319
                    //   System.out.println(geo.toText()); 
320
                    Point pJTS = geo.getInteriorPoint();
321
                    FShape pLabel = FConverter.jts_to_java2d(pJTS);
322
                    theLabel.setRotation(0);
323
                    theLabel.setOrig(new Point2D.Double(((FPoint2D)pLabel).getX(), ((FPoint2D)pLabel).getX()));
324
                }
325

    
326
                pAux = mT.transform(theLabel.getOrig(), null);
327

    
328
                break;
329
        }
330

    
331
        AffineTransform ant = g2.getTransform();
332

    
333
        x = (float) pAux.getX();
334
        y = (float) pAux.getY();
335

    
336
        AffineTransform Tx = (AffineTransform) ant.clone();
337
        Tx.translate(x, y); // S3: final translation
338
        Tx.rotate(Math.toRadians(-theLabel.getRotation())); // S2: rotate around anchor
339
        g2.setTransform(Tx);
340

    
341
        switch (theLabel.getJustification()) {
342
            case FLabel.LEFT_BOTTOM:
343
                g2.drawString(theLabel.getString(), 0, 0 - 3);
344

    
345
                break;
346

    
347
            case FLabel.LEFT_CENTER:
348
                g2.drawString(theLabel.getString(), 0, 0 - (height / 2));
349

    
350
                break;
351

    
352
            case FLabel.LEFT_TOP:
353
                g2.drawString(theLabel.getString(), 0, 0 - height);
354

    
355
                break;
356

    
357
            case FLabel.CENTER_BOTTOM:
358
                g2.drawString(theLabel.getString(), 0 - (width / 2), 0 - 3);
359

    
360
                break;
361

    
362
            case FLabel.CENTER_CENTER:
363
                g2.drawString(theLabel.getString(), 0 - (width / 2),
364
                    0 - (height / 2));
365

    
366
                break;
367

    
368
            case FLabel.CENTER_TOP:
369
                g2.drawString(theLabel.getString(), 0 - (width / 2), 0 -
370
                    height);
371

    
372
                break;
373

    
374
            case FLabel.RIGHT_BOTTOM:
375
                g2.drawString(theLabel.getString(), 0 - width, 0 - 3);
376

    
377
                break;
378

    
379
            case FLabel.RIGHT_CENTER:
380
                g2.drawString(theLabel.getString(), 0 - width, 0 -
381
                    (height / 2));
382

    
383
                break;
384

    
385
            case FLabel.RIGHT_TOP:
386
                g2.drawString(theLabel.getString(), 0 - width, 0 - height);
387

    
388
                break;
389
        }
390

    
391
        // Restauramos
392
        g2.setTransform(ant);
393
    }
394

    
395
    /**
396
     * DOCUMENT ME!
397
     *
398
     * @param g2 DOCUMENT ME!
399
     * @param mT DOCUMENT ME!
400
     * @param shp DOCUMENT ME!
401
     * @param theSymbol DOCUMENT ME!
402
     */
403
    private static void drawSymbolPoint(Graphics2D g2, AffineTransform mT, FPoint2D pAux, FSymbol theSymbol) {
404
        int x;
405
        int y;
406
        x = (int) pAux.getX();
407
        y = (int) pAux.getY();
408
                /*if (x==0){
409
                        x=100;
410
                }
411
                if (y==0){
412
                        y=100;
413
                }
414
                */
415
        Rectangle rectAux = new Rectangle();
416

    
417
        // Aqu? hay que mirar m_Size y m_useSize...
418
        float radio_simbolo;
419
        radio_simbolo = theSymbol.getSize() / 2;
420

    
421
        if (theSymbol.isSizeInPixels()) {
422
            // Suponemos que m_Size viene en coordenadas de mundo real
423
            radio_simbolo = (float) (theSymbol.getSize() * mT.getScaleX());
424

    
425
            /* System.out.println("m_bUseSize = " + theSymbol.m_bUseSize +
426
               " Escala: " + mT.getScaleX() + " alturaPixels = " + alturaPixels); */
427
            // if (radio_simbolo < 1) return; // No dibujamos nada
428
            rectAux.setRect(x - radio_simbolo, y - radio_simbolo,
429
                radio_simbolo * 2, radio_simbolo * 2);
430
        } else {
431
            // m_Size viene en pixels
432
            rectAux.setRect(x - radio_simbolo, y - radio_simbolo,
433
                theSymbol.getSize(), theSymbol.getSize());
434
        }
435

    
436
        //         continue; //radioSimbolo_en_pixels = 3;
437
        if (theSymbol.getFill() != null) {
438
            g2.setPaint(theSymbol.getFill());
439
        }
440

    
441
        if (theSymbol.getStroke() != null) {
442
            g2.setStroke(theSymbol.getStroke());
443
        }
444

    
445
        if (radio_simbolo < 2) {
446
            g2.fillRect(rectAux.x, rectAux.y, rectAux.width, rectAux.height);
447

    
448
            return;
449
        }
450

    
451
        switch (theSymbol.getStyle()) {
452
            case FConstant.SYMBOL_STYLE_MARKER_CIRCLE: // Circulito
453

    
454
                if (theSymbol.getColor() != null) {
455
                    g2.fillOval(rectAux.x, rectAux.y, rectAux.width,
456
                        rectAux.height);
457
                }
458

    
459
                if (theSymbol.isOutlined()) {
460
                    g2.setColor(theSymbol.getOutlineColor());
461
                    g2.drawOval(rectAux.x, rectAux.y, rectAux.width,
462
                        rectAux.height);
463
                }
464

    
465
                break;
466

    
467
            case FConstant.SYMBOL_STYLE_MARKER_SQUARE: // Cuadrado
468
                g2.fillRect(rectAux.x, rectAux.y, rectAux.width, rectAux.height);
469

    
470
                if (theSymbol.isOutlined()) {
471
                    g2.setColor(theSymbol.getOutlineColor());
472
                    g2.drawRect(rectAux.x, rectAux.y, rectAux.width,
473
                        rectAux.height);
474
                }
475

    
476
                break;
477

    
478
            case FConstant.SYMBOL_STYLE_MARKER_TRIANGLE: // Triangulo
479

    
480
                // y = r*sin30, x = r*cos30
481
                GeneralPathX genPath = new GeneralPathX();
482
                genPath.moveTo(x - (int) (radio_simbolo * 0.866),
483
                    y + (int) (radio_simbolo * 0.5));
484
                genPath.lineTo(x + (int) (radio_simbolo * 0.866),
485
                    y + (int) (radio_simbolo * 0.5));
486
                genPath.lineTo(x, y - (float) radio_simbolo);
487
                genPath.closePath();
488

    
489
                g2.fill(genPath);
490

    
491
                break;
492

    
493
            case FConstant.SYMBOL_STYLE_MARKER_CROSS: // Cruz
494

    
495
                GeneralPathX genPathCruz = new GeneralPathX();
496
                genPathCruz.moveTo(x, y - radio_simbolo);
497
                genPathCruz.lineTo(x, y + radio_simbolo);
498
                genPathCruz.moveTo(x - radio_simbolo, y);
499
                genPathCruz.lineTo(x + radio_simbolo, y);
500
                g2.draw(genPathCruz);
501

    
502
                break;
503

    
504
            case 34: // TrueType marker
505

    
506
            /* lf.lfHeight = -radioSimbolo_en_pixels;
507
               angulo = pSimbolo->m_Rotation;  // En radianes, de -pi a pi
508
               angulo = -180.0 * angulo / PI;
509
            
510
               lf.lfEscapement = (long) angulo*10;
511
               lf.lfOrientation = (long) angulo*10;
512
            
513
               fuente.CreateFontIndirect(&lf);
514
               pOldFont = pDC->SelectObject(&fuente);
515
            
516
               pDC->TextOut(pAPI.x, pAPI.y+radioSimbolo_en_pixels/2,elChar,1);
517
            
518
               pDC->SelectObject(pOldFont);
519
               fuente.DeleteObject();
520
            
521
               break; */
522
            case FConstant.SYMBOL_STYLE_MARKER_IMAGEN: // Icono
523
            {
524
                    if (theSymbol.getIcon() != null)
525
                    {
526
                            float w, h;
527
                    if (theSymbol.isSizeInPixels()) {
528
                        // Suponemos que m_Size viene en coordenadas de mundo real
529
                            // Por ejemplo, nos valemos del ancho para fijar la escala
530
                        w = (float) (theSymbol.getSize() * mT.getScaleX());
531
                        h = theSymbol.getIcon().getHeight(null) * w / theSymbol.getIcon().getWidth(null);  
532

    
533
                        rectAux.setRect(x - w, y - h,
534
                            w * 2, h * 2);
535
                    } else {
536
                        // m_Size viene en pixels
537
                            w = theSymbol.getSize();
538
                        h = theSymbol.getIcon().getHeight(null) * w / theSymbol.getIcon().getWidth(null);                            
539
                        rectAux.setRect(x - w, y - h, w, h);
540
                    }
541
                            
542
                            g2.drawImage(theSymbol.getIcon(), rectAux.x, rectAux.y, rectAux.width, rectAux.height, null);
543
                    }
544
                    else
545
                    {
546
                            String strImg = "Image"; // Utilities.getMessage(FGraphicUtilities.class,"imagen"); 
547
                    FontMetrics metrics = g2.getFontMetrics();
548
                    int width = metrics.stringWidth(strImg);
549
                    int height = metrics.getMaxAscent();
550

    
551
                            g2.drawString(strImg, x - width/2, y -2 + height/2);
552
                    }
553
                    break;
554
            }
555

    
556
            /* DrawIconEx(pDC->m_hDC, pAPI.x-(pSimbolo->m_widthIco/2), pAPI.y-(pSimbolo->m_heightIco/2),
557
               pSimbolo->m_hIcon, pSimbolo->m_widthIco, pSimbolo->m_heightIco, 0 , NULL, DI_NORMAL);
558
               break; */
559
            case FConstant.SYMBOL_STYLE_POINTZ: // Circulito
560

    
561
                if (theSymbol.getColor() != null) {
562
                    g2.fillOval(rectAux.x, rectAux.y, rectAux.width,
563
                        rectAux.height);
564
                }
565

    
566
                if (theSymbol.isOutlined()) {
567
                    g2.setColor(theSymbol.getOutlineColor());
568
                    g2.drawOval(rectAux.x, rectAux.y, rectAux.width,
569
                        rectAux.height);
570
                }
571

    
572
                break;
573
        } // del switch estilo
574
    }
575
}