Statistics
| Revision:

root / trunk / applications / appgvSIG / src / com / iver / cit / gvsig / gui / layout / fframes / FFrameGraphics.java @ 7304

History | View | Annotate | Download (20.3 KB)

1
/*
2
 * Created on 22-jun-2004
3
 *
4
 */
5
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
6
 *
7
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
8
 *
9
 * This program is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU General Public License
11
 * as published by the Free Software Foundation; either version 2
12
 * of the License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
22
 *
23
 * For more information, contact:
24
 *
25
 *  Generalitat Valenciana
26
 *   Conselleria d'Infraestructures i Transport
27
 *   Av. Blasco Ib??ez, 50
28
 *   46010 VALENCIA
29
 *   SPAIN
30
 *
31
 *      +34 963862235
32
 *   gvsig@gva.es
33
 *      www.gvsig.gva.es
34
 *
35
 *    or
36
 *
37
 *   IVER T.I. S.A
38
 *   Salamanca 50
39
 *   46005 Valencia
40
 *   Spain
41
 *
42
 *   +34 963163400
43
 *   dac@iver.es
44
 */
45
package com.iver.cit.gvsig.gui.layout.fframes;
46

    
47
import java.awt.BasicStroke;
48
import java.awt.Color;
49
import java.awt.Graphics2D;
50
import java.awt.geom.AffineTransform;
51
import java.awt.geom.Point2D;
52
import java.awt.geom.Rectangle2D;
53
import java.awt.image.BufferedImage;
54
import java.util.BitSet;
55

    
56
import com.iver.andami.PluginServices;
57
import com.iver.cit.gvsig.fmap.DriverException;
58
import com.iver.cit.gvsig.fmap.core.adapter.CircleAdapter;
59
import com.iver.cit.gvsig.fmap.core.adapter.GeometryAdapter;
60
import com.iver.cit.gvsig.fmap.core.adapter.PointAdapter;
61
import com.iver.cit.gvsig.fmap.core.adapter.PolyLineAdapter;
62
import com.iver.cit.gvsig.fmap.core.adapter.PolygonAdapter;
63
import com.iver.cit.gvsig.fmap.core.adapter.RectangleAdapter;
64
import com.iver.cit.gvsig.fmap.core.v02.FConstant;
65
import com.iver.cit.gvsig.fmap.core.v02.FSymbol;
66
import com.iver.cit.gvsig.gui.layout.Layout;
67
import com.iver.cit.gvsig.project.documents.exceptions.SaveException;
68
import com.iver.cit.gvsig.project.documents.layout.FLayoutUtilities;
69
import com.iver.cit.gvsig.project.documents.layout.fframes.IFFrame;
70
import com.iver.cit.gvsig.project.documents.layout.fframes.IFFrameEditableVertex;
71
import com.iver.utiles.XMLEntity;
72

    
73

    
74
/**
75
 * FFrame para contener un gr?fico.
76
 *
77
 * @author Vicente Caballero Navarro
78
 */
79
public class FFrameGraphics extends FFrame implements IFFrameEditableVertex {
80
    private static double TOL = 0.2;
81
    private int m_type = FConstant.SHAPE_TYPE_POINT;
82
    private FSymbol m_symbol = null;
83
    private Color m_color = null;
84
    private GeometryAdapter geometry;
85
    private GeometryAdapter geometryEdit;
86
    private boolean editing = false;
87
    private double size = 0.5;
88
    private BitSet index = new BitSet();
89

    
90
    /**
91
     * Crea un nuevo FFrameGraphics.
92
     */
93
    public FFrameGraphics() {
94
    }
95

    
96
    /**
97
     * DOCUMENT ME!
98
     *
99
     * @param geom DOCUMENT ME!
100
     */
101
    public void setGeometryAdapter(GeometryAdapter geom) {
102
        geometry = geom;
103
    }
104

    
105
    /**
106
     * Rellena el color que se utlizar? para dibujar el s?mbolo.
107
     *
108
     * @param color
109
     */
110
    public void setColor(Color color) {
111
        m_color = color;
112
    }
113

    
114
    /**
115
     * Actualiza el Fsymbol a partir del tipo de Gr?fico que se pase como
116
     * par?metro.
117
     *
118
     * @param type tipo de gr?fico.
119
     * @param at Transformada.
120
     */
121
    public void update(int type, AffineTransform at) {
122
        m_type = type;
123

    
124
        //aT = at;
125
        if (m_color == null) {
126
            m_color = Color.black;
127
        }
128

    
129
        switch (m_type) {
130
            case (Layout.POINT):
131
                m_symbol = new FSymbol(FConstant.SHAPE_TYPE_POINT, m_color);
132
                m_symbol.setSize((int) FLayoutUtilities.fromSheetDistance(
133
                        size, at));
134

    
135
                break;
136

    
137
            case (Layout.RECTANGLESIMPLE):
138
                m_symbol = new FSymbol(FConstant.SYMBOL_TYPE_FILL, m_color);
139
                m_symbol.setColor(null);
140

    
141
                break;
142

    
143
            case (Layout.LINE):
144
                m_symbol = new FSymbol(FConstant.SYMBOL_TYPE_LINE, m_color);
145

    
146
                break;
147

    
148
            case (Layout.POLYLINE):
149
                m_symbol = new FSymbol(FConstant.SYMBOL_TYPE_LINE, m_color);
150

    
151
                break;
152

    
153
            case (Layout.POLYGON):
154
                m_symbol = new FSymbol(FConstant.SYMBOL_TYPE_FILL, m_color);
155
                m_symbol.setStyle(FConstant.SYMBOL_STYLE_FILL_SOLID);
156
                m_symbol.setOutlined(true);
157
                m_symbol.setOutlineColor(m_color);
158
                m_symbol.setColor(null);
159

    
160
                break;
161

    
162
            case (Layout.CIRCLE):
163
                m_symbol = new FSymbol(FConstant.SYMBOL_TYPE_FILL, m_color);
164
                m_symbol.setStyle(FConstant.SYMBOL_STYLE_FILL_SOLID);
165
                m_symbol.setOutlined(true);
166
                m_symbol.setOutlineColor(m_color);
167
                m_symbol.setColor(null);
168

    
169
                break;
170
        }
171
    }
172

    
173
    /**
174
     * Devuelve el FSymbol que se representa.
175
     *
176
     * @return DOCUMENT ME!
177
     */
178
    public FSymbol getFSymbol() {
179
        return m_symbol;
180
    }
181

    
182
    /**
183
     * Rellena el FSymbol que se representara al dibujar.
184
     *
185
     * @param symbol
186
     */
187
    public void setFSymbol(FSymbol symbol) {
188
        m_symbol = symbol;
189
    }
190

    
191
    /**
192
     * M?todo que dibuja sobre el graphics que se le pasa como par?metro, seg?n
193
     * la transformada afin que se debe de aplicar y el rect?ngulo que se debe
194
     * de dibujar.
195
     *
196
     * @param g Graphics
197
     * @param at Transformada afin.
198
     * @param rv rect?ngulo sobre el que hacer un clip.
199
     * @param imgBase DOCUMENT ME!
200
     */
201
    public void draw(Graphics2D g, AffineTransform at, Rectangle2D rv,
202
        BufferedImage imgBase) {
203
        Rectangle2D.Double rect = getBoundingBox(at);
204
        g.rotate(Math.toRadians(getRotation()), rect.x + (rect.width / 2),
205
            rect.y + (rect.height / 2));
206

    
207
        if (intersects(rv, rect)) {
208
            g.setColor(Color.black);
209

    
210
            if (m_type == Layout.POINT) {
211
                m_symbol.setSize((int) (rect.getWidth() * 0.7));
212
            }
213
            float stroke=0;
214
            if (m_symbol.getStroke() != null) {
215
                    stroke=((BasicStroke)m_symbol.getStroke()).getLineWidth();
216
                BasicStroke basicStroke = new BasicStroke((float)FLayoutUtilities.fromSheetDistance(stroke,at)/100);
217
                m_symbol.setStroke(basicStroke);
218
            }
219

    
220
            geometry.draw(g, at, m_symbol);
221

    
222
            if (m_symbol.getStroke() != null) {
223
                BasicStroke basicStroke = new BasicStroke(stroke);
224
                m_symbol.setStroke(basicStroke);
225
            }
226

    
227
            if (editing) {
228
                g.setColor(Color.red);
229
                geometry.drawVertex(g, at);
230
            }
231
        }
232

    
233
        g.rotate(Math.toRadians(-getRotation()), rect.x + (rect.width / 2),
234
            rect.y + (rect.height / 2));
235
    }
236

    
237
    /**
238
     * @see com.iver.cit.gvsig.project.documents.layout.fframes.IFFrame#getXMLEntity()
239
     */
240
    public XMLEntity getXMLEntity() throws SaveException {
241
        XMLEntity xml = super.getXMLEntity();
242

    
243
        try {
244
            xml.putProperty("type", Layout.GRAPHICS);
245
            xml.putProperty("m_type", m_type);
246
            xml.addChild(m_symbol.getXMLEntity());
247
            if (geometry!=null) {
248
                xml.addChild(geometry.getXMLEntity());
249
            }
250
           // xml.addChild(geometryEdit.getXMLEntity());
251
        } catch (Exception e) {
252
            throw new SaveException(e, this.getClass().getName());
253
        }
254

    
255
        return xml;
256
    }
257

    
258
    /**
259
     * @see com.iver.cit.gvsig.project.documents.layout.fframes.IFFrame#updateNum()
260
     */
261
    public void updateNum() {
262
    }
263

    
264
    /**
265
     * @see com.iver.cit.gvsig.project.documents.layout.fframes.IFFrame#getNum()
266
     */
267
    public int getNum() {
268
        return 0;
269
    }
270

    
271
    /**
272
     * @see com.iver.cit.gvsig.project.documents.layout.fframes.IFFrame#setXMLEntity(com.iver.utiles.XMLEntity,
273
     *      com.iver.cit.gvsig.project.Project)
274
     */
275
    public void setXMLEntity(XMLEntity xml) {
276
        m_Selected = xml.getIntProperty("m_Selected");
277

    
278
        setRotation(xml.getDoubleProperty("m_rotation"));
279
        m_symbol = FSymbol.createFromXML(xml.getChild(0));
280
        if (xml.contains("m_type")) {
281
            m_type = xml.getIntProperty("m_type");
282
           // return;
283
        }
284
        if (m_type==Layout.RECTANGLESYMBOL)
285
            return;
286
        if (xml.getChildrenCount() ==1) {
287
            Rectangle2D r = (Rectangle2D) getBoundBox().clone();
288

    
289
            if (m_type == Layout.LINE) {
290
                geometry = new PolyLineAdapter();
291
            } else if (m_type == Layout.RECTANGLESIMPLE ||
292
                    m_type == Layout.RECTANGLEGROUP) {
293
                geometry = new RectangleAdapter();
294
                geometry.addPoint(new Point2D.Double(r.getX(), r.getY()));
295
                geometry.addPoint(new Point2D.Double(r.getMaxX(), r.getMaxY()));
296
            } else if (m_type == Layout.POLYLINE) {
297
                geometry = new PolyLineAdapter();
298
            } else if (m_type == Layout.POLYGON) {
299
                geometry = new PolygonAdapter();
300
            } else if (m_type == Layout.CIRCLE) {
301
                geometry = new CircleAdapter();
302
                geometry.addPoint(new Point2D.Double(r.getCenterX(),
303
                        r.getCenterY()));
304

    
305
                if (r.getWidth() < r.getHeight()) {
306
                    geometry.addPoint(new Point2D.Double(r.getMaxX(),
307
                            r.getCenterY()));
308
                } else {
309
                    geometry.addPoint(new Point2D.Double(r.getCenterX(),
310
                            r.getY()));
311
                }
312
            } else if (m_type == Layout.POINT) {
313
                geometry = new PointAdapter();
314
                geometry.addPoint(new Point2D.Double(r.getCenterX(),
315
                        r.getCenterY()));
316
            }
317

    
318
            geometry.end();
319
        } else {
320
            geometry = GeometryAdapter.createFromXML(xml.getChild(1));
321
           // geometryEdit = GeometryAdapter.createFromXML(xml.getChild(2));
322
        }
323
    }
324

    
325
    /**
326
     * @see com.iver.cit.gvsig.project.documents.layout.fframes.IFFrame#setXMLEntity(com.iver.utiles.XMLEntity,
327
     *      com.iver.cit.gvsig.project.Project)
328
     */
329
    public void setXMLEntity03(XMLEntity xml, Layout p) {
330
        m_Selected = xml.getIntProperty("m_Selected");
331
        m_type = xml.getIntProperty("m_type");
332
        m_symbol = FSymbol.createFromXML03(xml.getChild(0));
333

    
334
        Rectangle2D r = (Rectangle2D) getBoundBox().clone();
335

    
336
        if (m_type == Layout.LINE) {
337
            geometry = new PolyLineAdapter();
338
        } else if (m_type == Layout.RECTANGLESIMPLE) {
339
            geometry = new RectangleAdapter();
340
            geometry.addPoint(new Point2D.Double(r.getX(), r.getY()));
341
            geometry.addPoint(new Point2D.Double(r.getMaxX(), r.getMaxY()));
342
        } else if (m_type == Layout.POLYLINE) {
343
            geometry = new PolyLineAdapter();
344
        } else if (m_type == Layout.POLYGON) {
345
            geometry = new PolygonAdapter();
346
        } else if (m_type == Layout.CIRCLE) {
347
            geometry = new CircleAdapter();
348
            geometry.addPoint(new Point2D.Double(r.getCenterX(), r.getCenterY()));
349

    
350
            if (r.getWidth() < r.getHeight()) {
351
                geometry.addPoint(new Point2D.Double(r.getMaxX(), r.getCenterY()));
352
            } else {
353
                geometry.addPoint(new Point2D.Double(r.getCenterX(), r.getY()));
354
            }
355
        } else if (m_type == Layout.POINT) {
356
            geometry = new PointAdapter();
357
            geometry.addPoint(new Point2D.Double(r.getCenterX(), r.getCenterY()));
358
        }
359

    
360
        geometry.end();
361
    }
362

    
363
    /**
364
     * @see com.iver.cit.gvsig.project.documents.layout.fframes.IFFrame#getNameFFrame()
365
     */
366
    public String getNameFFrame() {
367
        return PluginServices.getText(this, "Graficos")+ num;
368
    }
369

    
370
    /**
371
     * @see com.iver.cit.gvsig.project.documents.layout.fframes.IFFrame#print(java.awt.Graphics2D,
372
     *      java.awt.geom.AffineTransform)
373
     */
374
    public void print(Graphics2D g, AffineTransform at)
375
        throws DriverException {
376
        draw(g, at, null, null);
377
    }
378

    
379
    /**
380
     * Inserta el tama?o del punto.
381
     *
382
     * @param size entero que representa el tama?o del punto.
383
     */
384
    public void setSize(double size) {
385
        this.size = size;
386
        if (m_type==Layout.RECTANGLESYMBOL) {
387
            return;
388
        }
389
        Rectangle2D r = geometry.getBounds2D();
390
        super.setBoundBox(new Rectangle2D.Double(r.getX() - size,
391
                r.getY() - size, size * 2, size * 2));
392
    }
393

    
394
    /**
395
     * Devuelve el tipo de gr?fico que contiene el fframe.
396
     *
397
     * @return tipo de
398
     */
399
    public int getType() {
400
        return m_type;
401
    }
402
    public void setType(int type) {
403
        m_type = type;
404
    }
405
    /**
406
     * DOCUMENT ME!
407
     *
408
     * @param r DOCUMENT ME!
409
     */
410
    public void setBoundBox(Rectangle2D r) {
411
        if (m_type==Layout.RECTANGLESYMBOL) {
412
            super.setBoundBox(r);
413
            return;
414
        }
415
        AffineTransform aT = new AffineTransform();
416

    
417
        if (getBoundBox().getWidth() != 0) {
418
            double w = r.getWidth() / getBoundBox().getWidth();
419
            double h = r.getHeight() / getBoundBox().getHeight();
420

    
421
            AffineTransform trans2 = AffineTransform.getTranslateInstance(r.getX(),
422
                    r.getY());
423
            aT.concatenate(trans2);
424

    
425
            AffineTransform scale1 = AffineTransform.getScaleInstance(w, h);
426
            aT.concatenate(scale1);
427

    
428
            AffineTransform trans1 = AffineTransform.getTranslateInstance(-getBoundBox()
429
                                                                               .getX(),
430
                    -getBoundBox().getY());
431
            aT.concatenate(trans1);
432
            geometry.applyTransform(aT);
433

    
434
            size = aT.getScaleX() * size;
435
        }
436

    
437
        super.setBoundBox(r);
438
    }
439

    
440
    /**
441
     * DOCUMENT ME!
442
     */
443
    public void startEditing() {
444
        editing = true;
445
    }
446

    
447
    /**
448
     * DOCUMENT ME!
449
     */
450
    public void stopEditing() {
451
        editing = false;
452
    }
453

    
454
    /**
455
     * DOCUMENT ME!
456
     *
457
     * @return DOCUMENT ME!
458
     */
459
    public boolean isEditing() {
460
        return editing;
461
    }
462

    
463
    /**
464
     * DOCUMENT ME!
465
     *
466
     * @param point DOCUMENT ME!
467
     * @param geom DOCUMENT ME!
468
     */
469
    public void pointReleased(Point2D point, GeometryAdapter geom) {
470
        index.clear();
471
        geometry = geom;
472

    
473
        Rectangle2D r = geometry.getBounds2D();
474
        super.setBoundBox(r);
475
    }
476

    
477
    /**
478
     * DOCUMENT ME!
479
     *
480
     * @param point DOCUMENT ME!
481
     */
482
    public void pointPressed(Point2D point) {
483
        Rectangle2D.Double rect = getBoundBox();
484
        Point2D[] points = geometry.getPoints();
485
        geometryEdit = geometry.cloneAdapter();//GeometryAdapter.createFromXML(geometry.getXMLEntity());
486

    
487
        Point2D pAux1 = new Point2D.Double();
488
        index.clear();
489
        for (int i = 0; i < points.length; i++) {
490
            if (getRotation() != 0) {
491
                AffineTransform af = AffineTransform.getRotateInstance(Math.toRadians(
492
                            -getRotation()), rect.x + (rect.width / 2),
493
                        rect.y + (rect.height / 2));
494
                af.transform(point, pAux1);
495

    
496
                if (points[i].distance(pAux1) <= TOL) {
497
                    index.set(i);
498
                }
499
            } else {
500
                if (points[i].distance(point) <= TOL) {
501
                    index.set(i);
502
                }
503
            }
504
        }
505
    }
506

    
507
    /**
508
     * DOCUMENT ME!
509
     *
510
     * @param point DOCUMENT ME!
511
     */
512
    public void pointDragged(Point2D point) {
513
        //Point2D[] points = geometry.getPoints();
514

    
515
        for (int j = index.nextSetBit(0); j >= 0;
516
                j = index.nextSetBit(j + 1)) {
517
            if (getRotation() != 0) {
518
                Rectangle2D.Double rect = getBoundBox();
519
                AffineTransform af = AffineTransform.getRotateInstance(Math.toRadians(
520
                            -getRotation()), rect.x + (rect.width / 2),
521
                        rect.y + (rect.height / 2));
522
                af.transform(point, point);
523
            }
524

    
525
            //points[j] = new Point2D.Double(point.getX(), point.getY());
526
            geometryEdit.changePoint(j,point);
527
        }
528
        //geometryEdit.setPoints(points);
529
        geometryEdit.end();
530
    }
531

    
532
    /**
533
     * DOCUMENT ME!
534
     *
535
     * @param g DOCUMENT ME!
536
     * @param at DOCUMENT ME!
537
     */
538
    public void paint(Graphics2D g, AffineTransform at) {
539
        if (geometryEdit != null) {
540
            Rectangle2D.Double rect = getBoundingBox(at);
541
            if (getRotation()!=0){
542
            g.rotate(Math.toRadians(getRotation()), rect.x + (rect.width / 2),
543
                rect.y + (rect.height / 2));
544
            geometryEdit.paint(g,at,false);
545
          /*  FShape m_shape = null;
546
            GeneralPathX polyLine = new GeneralPathX(geometryEdit.getShape());
547
            polyLine.transform(at);
548
            m_shape = new FPolyline2D(polyLine);
549
            FGraphicUtilities.DrawShape(g, mT, m_shape, m_symbol);
550
*/
551
            g.rotate(Math.toRadians(-getRotation()), rect.x + (rect.width / 2),
552
                rect.y + (rect.height / 2));
553
            }else{
554
                 geometryEdit.paint(g,at,false);
555
            }
556
        }
557
    }
558

    
559
    /**
560
     * DOCUMENT ME!
561
     *
562
     * @return DOCUMENT ME!
563
     */
564
    public GeometryAdapter getGeometry() {
565
        return geometryEdit;
566
    }
567

    
568
    public void initialize() {
569
        // TODO Auto-generated method stub
570

    
571
    }
572
     /**
573
     * Devuelve un entero que representa donde esta contenido el punto que se
574
     * pasa como par?metro.
575
     *
576
     * @param p punto a comparar.
577
     *
578
     * @return entero que representa como esta contenido el punto.
579
     */
580
    public int getContains(Point2D p) {
581
        if (geometry instanceof CircleAdapter) {
582
            if (ne.contains(p.getX(), p.getY())) {
583
                return NE;
584
            } else if (se.contains(p.getX(), p.getY())) {
585
                return SE;
586
            } else if (so.contains(p.getX(), p.getY())) {
587
                return SO;
588
            } else if (no.contains(p.getX(), p.getY())) {
589
                return NO;
590
            } else if (getBoundingBox(null).contains(p.getX(), p.getY())) {
591
                return RECT;
592
            }
593
            return NOSELECT;
594
        }
595
            return super.getContains(p);
596
    }
597

    
598
    /**
599
     * Dibuja los handlers sobre el boundingBox en el graphics que se pasa como
600
     * par?metro.
601
     *
602
     * @param g
603
     *            Graphics sobre el que dibujar.
604
     */
605
    public void drawHandlers(Graphics2D g) {
606
        if (geometry instanceof CircleAdapter) {
607
            int size = 10;
608
            Rectangle2D r = getBoundingBox(null);
609
            Point2D p = new Point2D.Double();
610
            g.rotate(Math.toRadians(getRotation()), r.getX()
611
                    + (r.getWidth() / 2), r.getY() + (r.getHeight() / 2));
612

    
613
            AffineTransform atRotate = new AffineTransform();
614
            atRotate.rotate(Math.toRadians(getRotation()), r.getX()
615
                    + (r.getWidth() / 2), r.getY() + (r.getHeight() / 2));
616

    
617
            g.fillRect((int) r.getX() - size, (int) r.getY() - size,
618
                            size, size);
619
            atRotate.transform(new Point2D.Double(r.getX() - size, r.getY()
620
                    - size), p);
621
            no.setRect((int) p.getX(), (int) p.getY(), size, size);
622

    
623
            g.fillRect((int) r.getMaxX(), (int) r.getY() - size, size, size);
624
            atRotate.transform(
625
                    new Point2D.Double(r.getMaxX(), r.getY() - size), p);
626
            ne.setRect((int) p.getX(), (int) p.getY(), size, size);
627

    
628
            g.fillRect((int) r.getX() - size, (int) r.getMaxY(), size, size);
629
            atRotate.transform(
630
                    new Point2D.Double(r.getX() - size, r.getMaxY()), p);
631
            so.setRect((int) p.getX(), (int) p.getY(), size, size);
632

    
633
            g.fillRect((int) r.getMaxX(), (int) r.getMaxY(), size, size);
634
            atRotate.transform(new Point2D.Double(r.getMaxX(), r.getMaxY()), p);
635
            se.setRect((int) p.getX(), (int) p.getY(), size, size);
636

    
637
            g.rotate(Math.toRadians(-getRotation()), r.getX()
638
                    + (r.getWidth() / 2), r.getY() + (r.getHeight() / 2));
639
        }
640
        else
641
            super.drawHandlers(g);
642
    }
643

    
644
}