Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / core / v02 / FGraphicUtilities.java @ 597

History | View | Annotate | Download (19.6 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.FPoint2D;
19
import com.iver.cit.gvsig.fmap.core.FPolygon2D;
20
import com.iver.cit.gvsig.fmap.core.FPolyline2D;
21
import com.iver.cit.gvsig.fmap.core.FShape;
22
import com.iver.cit.gvsig.fmap.core.GeneralPathX;
23
import com.vividsolutions.jts.geom.Geometry;
24
import com.vividsolutions.jts.geom.Point;
25

    
26

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

    
47
        AffineTransform mT = new AffineTransform();
48
        mT.setToIdentity();
49

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

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

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

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

    
71
                if (bAux22) {
72
                    symbol.setSize(alturaMetros2);
73
                    symbol.setSizeInPixels(bAux22);
74
                }
75

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

    
85
                break;
86

    
87
            case FConstant.SYMBOL_TYPE_POINT:
88
            case FConstant.SYMBOL_TYPE_POINTZ:
89

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

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

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

    
102
                FGraphicUtilities.DrawShape(g2, mT, shp, symbol);
103

    
104
                if (bAux2) {
105
                    symbol.setSize(alturaMetros);
106
                    symbol.setSizeInPixels(bAux2);
107
                }
108

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

    
118
                break;
119

    
120
            case FConstant.SYMBOL_TYPE_LINE:
121
            case FConstant.SHAPE_TYPE_POLYLINEZ:
122

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

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

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

    
138
                break;
139

    
140
            case FConstant.SYMBOL_TYPE_FILL:
141
            case FConstant.SHAPE_TYPE_POLYGONZ:
142

    
143
                GeneralPathX rectAux = new GeneralPathX(r);
144
                rectAux.transform(mT2);
145
                shp = new FPolygon2D( rectAux);
146

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

    
150
                break;
151
        }
152
    }
153

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

    
169
        g2.setColor(theSymbol.getColor());
170

    
171
        switch (shp.getShapeType()) {
172
            case FShape.POINT: //Tipo punto
173
                drawSymbolPoint(g2, mT, (FPoint2D) shp, theSymbol);
174

    
175
                break;
176
            case FShape.LINE:
177

    
178
                // Shape theShp = mT.createTransformedShape(shp.m_Polyline);
179
                // g2.setColor(theSymbol.m_Color);
180
                if (theSymbol.getStroke() != null) {
181
                    g2.setStroke(theSymbol.getStroke());
182
                }
183

    
184
                g2.draw(shp);
185

    
186
                break;
187
                
188

    
189
            case FShape.POLYGON:
190
                g2.setPaint(theSymbol.getFill());
191

    
192
                if (theSymbol.getColor() != null) {
193
                    g2.fill(shp);
194
                }
195

    
196
                if (theSymbol.isOutlined()) {
197
                    g2.setColor(theSymbol.geOutlineColor());
198

    
199
                    if (theSymbol.getStroke() != null) {
200
                        g2.setStroke(theSymbol.getStroke());
201
                    }
202

    
203
                    g2.draw(shp);
204
                }
205

    
206
                break;
207
        }
208
    }
209

    
210
    public static void DrawLabel(Graphics2D g2, AffineTransform mT, FShape shp,
211
        FSymbol theSymbol, FLabel theLabel) {
212
        float angle;
213
        float x;
214
        float y;
215
        Point2D pAux = null;
216

    
217
        // USAR TEXTLAYOUT SI QUEREMOS PERMITIR SELECCIONAR UN TEXTO
218
        // Y/O EDITARLO "IN SITU"
219

    
220
        /* if (m_labelValues[numReg].length() > 0)
221
           {
222
                   TextLayout layout = new TextLayout(m_labelValues[numReg], font, frc);
223
                   layout.draw(g2, x, y);
224
           } */
225
        if (shp == null) {
226
            return;
227
        }
228

    
229
        // Las etiquetas que pongamos a nulo ser? porque no la queremos dibujar.
230
        // ?til para cuando queramos eliminar duplicados.
231
        if (theLabel.getString() == null) {
232
            return;
233
        }
234

    
235
        FontMetrics metrics = g2.getFontMetrics();
236
        int width = metrics.stringWidth(theLabel.getString());
237
        int height = metrics.getMaxAscent();
238

    
239
        // int height = metrics.getHeight();
240
        g2.setFont(theSymbol.getFont());
241
        g2.setColor(theSymbol.getFontColor());
242

    
243
        // Aqu? hay que mirar m_Size y m_useSize...
244
        if (theSymbol.isFontSizeInPixels()) {
245
            // Suponemos que m_Size viene en coordenadas de mundo real
246
            // Esto habr? que cambiarlo. Probablemente usar Style2d de geotools en lugar
247
            // de FSymbol.
248
            // CAMBIO: La altura del texto la miramos en FLabel
249
            // float alturaPixels = (float) (theSymbol.m_FontSize * mT.getScaleX());
250
            float alturaPixels = (float) (theLabel.getHeight() * mT.getScaleX());
251

    
252
            /* System.out.println("m_bUseSize = " + theSymbol.m_bUseSize +
253
               " Escala: " + mT.getScaleX() + " alturaPixels = " + alturaPixels); */
254
            if (alturaPixels < 3) {
255
                return; // No leemos nada
256
            }
257

    
258
            Font nuevaFuente = theSymbol.getFont().deriveFont(alturaPixels);
259
            g2.setFont(nuevaFuente);
260
            width = g2.getFontMetrics().stringWidth(theLabel.getString());
261
        }
262

    
263
        switch (shp.getShapeType()) {
264
            case FShape.POINT: //Tipo punto
265
                    
266
                    pAux = new Point2D.Double(((FPoint2D)shp).getX(), ((FPoint2D)shp).getY());
267
                pAux = mT.transform(pAux, null);
268

    
269
                break;
270

    
271
            case FShape.LINE:
272

    
273
                // 
274
                if (theLabel.getOrig() == null) // Calculamos el punto y la orientaci?n solo la primera vez
275
                 {
276
                    PathLength pathLen = new PathLength(shp);
277

    
278
                    // if (pathLen.lengthOfPath() < width / mT.getScaleX()) return;
279
                    float midDistance = pathLen.lengthOfPath() / 2;
280
                    pAux = pathLen.pointAtLength(midDistance);
281
                    angle = pathLen.angleAtLength(midDistance);
282

    
283
                    if (angle < 0) {
284
                        angle = angle + (float) (2 * Math.PI);
285
                    }
286

    
287
                    if ((angle > (Math.PI / 2)) &&
288
                            (angle < ((3 * Math.PI) / 2))) {
289
                        angle = angle - (float) Math.PI;
290
                    }
291

    
292
                    theLabel.setRotation(Math.toDegrees(angle));
293
                    theLabel.setOrig(pAux);
294
                }
295

    
296
                pAux = mT.transform(theLabel.getOrig(), null);
297

    
298
                // pAux = theLabel.getOrig();
299
                // GlyphVector theGlyphs = theSymbol.m_Font.createGlyphVector(g2.getFontRenderContext(), theLabel);
300
                // Shape txtShp = TextPathLayout.layoutGlyphVector(theGlyphs, shp.m_Polyline,TextPathLayout.ALIGN_MIDDLE);                                
301
                // g2.draw(txtShp);
302
                // System.out.println("Pintando etiqueta " + theLabel );
303
                break;
304

    
305
            case FShape.POLYGON:
306
                if (theLabel.getOrig() == null) // Calculamos el punto solo la primera vez
307
                 {
308
                    Geometry geo = FConverter.java2d_to_jts(shp);
309

    
310
                    // System.out.println("Area de " + m_labelValues[numReg] + " = "
311
                    //   + geo.getArea());
312
                    //   System.out.println(geo.toText()); 
313
                    Point pJTS = geo.getInteriorPoint();
314
                    FShape pLabel = FConverter.jts_to_java2d(pJTS);
315
                    theLabel.setRotation(0);
316
                    theLabel.setOrig(new Point2D.Double(((FPoint2D)pLabel).getX(), ((FPoint2D)pLabel).getX()));
317
                }
318

    
319
                pAux = mT.transform(theLabel.getOrig(), null);
320

    
321
                break;
322
        }
323

    
324
        AffineTransform ant = g2.getTransform();
325

    
326
        x = (float) pAux.getX();
327
        y = (float) pAux.getY();
328

    
329
        AffineTransform Tx = (AffineTransform) ant.clone();
330
        Tx.translate(x, y); // S3: final translation
331
        Tx.rotate(Math.toRadians(-theLabel.getRotation())); // S2: rotate around anchor
332
        g2.setTransform(Tx);
333

    
334
        switch (theLabel.getJustification()) {
335
            case FLabel.LEFT_BOTTOM:
336
                g2.drawString(theLabel.getString(), 0, 0 - 3);
337

    
338
                break;
339

    
340
            case FLabel.LEFT_CENTER:
341
                g2.drawString(theLabel.getString(), 0, 0 - (height / 2));
342

    
343
                break;
344

    
345
            case FLabel.LEFT_TOP:
346
                g2.drawString(theLabel.getString(), 0, 0 - height);
347

    
348
                break;
349

    
350
            case FLabel.CENTER_BOTTOM:
351
                g2.drawString(theLabel.getString(), 0 - (width / 2), 0 - 3);
352

    
353
                break;
354

    
355
            case FLabel.CENTER_CENTER:
356
                g2.drawString(theLabel.getString(), 0 - (width / 2),
357
                    0 - (height / 2));
358

    
359
                break;
360

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

    
365
                break;
366

    
367
            case FLabel.RIGHT_BOTTOM:
368
                g2.drawString(theLabel.getString(), 0 - width, 0 - 3);
369

    
370
                break;
371

    
372
            case FLabel.RIGHT_CENTER:
373
                g2.drawString(theLabel.getString(), 0 - width, 0 -
374
                    (height / 2));
375

    
376
                break;
377

    
378
            case FLabel.RIGHT_TOP:
379
                g2.drawString(theLabel.getString(), 0 - width, 0 - height);
380

    
381
                break;
382
        }
383

    
384
        // Restauramos
385
        g2.setTransform(ant);
386
    }
387

    
388
    /**
389
     * DOCUMENT ME!
390
     *
391
     * @param g2 DOCUMENT ME!
392
     * @param mT DOCUMENT ME!
393
     * @param shp DOCUMENT ME!
394
     * @param theSymbol DOCUMENT ME!
395
     */
396
    private static void drawSymbolPoint(Graphics2D g2, AffineTransform mT, FPoint2D pAux, FSymbol theSymbol) {
397
        int x;
398
        int y;
399
        x = (int) pAux.getX();
400
        y = (int) pAux.getY();
401
                /*if (x==0){
402
                        x=100;
403
                }
404
                if (y==0){
405
                        y=100;
406
                }
407
                */
408
        Rectangle rectAux = new Rectangle();
409

    
410
        // Aqu? hay que mirar m_Size y m_useSize...
411
        float radio_simbolo;
412
        radio_simbolo = theSymbol.getSize() / 2;
413

    
414
        if (theSymbol.isSizeInPixels()) {
415
            // Suponemos que m_Size viene en coordenadas de mundo real
416
            radio_simbolo = (float) (theSymbol.getSize() * mT.getScaleX());
417

    
418
            /* System.out.println("m_bUseSize = " + theSymbol.m_bUseSize +
419
               " Escala: " + mT.getScaleX() + " alturaPixels = " + alturaPixels); */
420
            // if (radio_simbolo < 1) return; // No dibujamos nada
421
            rectAux.setRect(x - radio_simbolo, y - radio_simbolo,
422
                radio_simbolo * 2, radio_simbolo * 2);
423
        } else {
424
            // m_Size viene en pixels
425
            rectAux.setRect(x - radio_simbolo, y - radio_simbolo,
426
                theSymbol.getSize(), theSymbol.getSize());
427
        }
428

    
429
        //         continue; //radioSimbolo_en_pixels = 3;
430
        if (theSymbol.getFill() != null) {
431
            g2.setPaint(theSymbol.getFill());
432
        }
433

    
434
        if (theSymbol.getStroke() != null) {
435
            g2.setStroke(theSymbol.getStroke());
436
        }
437

    
438
        if (radio_simbolo < 2) {
439
            g2.fillRect(rectAux.x, rectAux.y, rectAux.width, rectAux.height);
440

    
441
            return;
442
        }
443

    
444
        switch (theSymbol.getStyle()) {
445
            case FConstant.SYMBOL_STYLE_MARKER_CIRCLE: // Circulito
446

    
447
                if (theSymbol.getColor() != null) {
448
                    g2.fillOval(rectAux.x, rectAux.y, rectAux.width,
449
                        rectAux.height);
450
                }
451

    
452
                if (theSymbol.isOutlined()) {
453
                    g2.setColor(theSymbol.geOutlineColor());
454
                    g2.drawOval(rectAux.x, rectAux.y, rectAux.width,
455
                        rectAux.height);
456
                }
457

    
458
                break;
459

    
460
            case FConstant.SYMBOL_STYLE_MARKER_SQUARE: // Cuadrado
461
                g2.fillRect(rectAux.x, rectAux.y, rectAux.width, rectAux.height);
462

    
463
                if (theSymbol.isOutlined()) {
464
                    g2.setColor(theSymbol.geOutlineColor());
465
                    g2.drawRect(rectAux.x, rectAux.y, rectAux.width,
466
                        rectAux.height);
467
                }
468

    
469
                break;
470

    
471
            case FConstant.SYMBOL_STYLE_MARKER_TRIANGLE: // Triangulo
472

    
473
                // y = r*sin30, x = r*cos30
474
                GeneralPathX genPath = new GeneralPathX();
475
                genPath.moveTo(x - (int) (radio_simbolo * 0.866),
476
                    y + (int) (radio_simbolo * 0.5));
477
                genPath.lineTo(x + (int) (radio_simbolo * 0.866),
478
                    y + (int) (radio_simbolo * 0.5));
479
                genPath.lineTo(x, y - (float) radio_simbolo);
480
                genPath.closePath();
481

    
482
                g2.fill(genPath);
483

    
484
                break;
485

    
486
            case FConstant.SYMBOL_STYLE_MARKER_CROSS: // Cruz
487

    
488
                GeneralPathX genPathCruz = new GeneralPathX();
489
                genPathCruz.moveTo(x, y - radio_simbolo);
490
                genPathCruz.lineTo(x, y + radio_simbolo);
491
                genPathCruz.moveTo(x - radio_simbolo, y);
492
                genPathCruz.lineTo(x + radio_simbolo, y);
493
                g2.draw(genPathCruz);
494

    
495
                break;
496

    
497
            case 34: // TrueType marker
498

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

    
526
                        rectAux.setRect(x - w, y - h,
527
                            w * 2, h * 2);
528
                    } else {
529
                        // m_Size viene en pixels
530
                            w = theSymbol.getSize();
531
                        h = theSymbol.geIcon().getHeight(null) * w / theSymbol.geIcon().getWidth(null);                            
532
                        rectAux.setRect(x - w, y - h, w, h);
533
                    }
534
                            
535
                            g2.drawImage(theSymbol.geIcon(), rectAux.x, rectAux.y, rectAux.width, rectAux.height, null);
536
                    }
537
                    else
538
                    {
539
                            String strImg = "Image"; // Utilities.getMessage(FGraphicUtilities.class,"imagen"); 
540
                    FontMetrics metrics = g2.getFontMetrics();
541
                    int width = metrics.stringWidth(strImg);
542
                    int height = metrics.getMaxAscent();
543

    
544
                            g2.drawString(strImg, x - width/2, y -2 + height/2);
545
                    }
546
                    break;
547
            }
548

    
549
            /* DrawIconEx(pDC->m_hDC, pAPI.x-(pSimbolo->m_widthIco/2), pAPI.y-(pSimbolo->m_heightIco/2),
550
               pSimbolo->m_hIcon, pSimbolo->m_widthIco, pSimbolo->m_heightIco, 0 , NULL, DI_NORMAL);
551
               break; */
552
            case FConstant.SYMBOL_STYLE_POINTZ: // Circulito
553

    
554
                if (theSymbol.getColor() != null) {
555
                    g2.fillOval(rectAux.x, rectAux.y, rectAux.width,
556
                        rectAux.height);
557
                }
558

    
559
                if (theSymbol.isOutlined()) {
560
                    g2.setColor(theSymbol.geOutlineColor());
561
                    g2.drawOval(rectAux.x, rectAux.y, rectAux.width,
562
                        rectAux.height);
563
                }
564

    
565
                break;
566
        } // del switch estilo
567
    }
568
}