Statistics
| Revision:

svn-document-layout / trunk / org.gvsig.app.document.layout.app / org.gvsig.app.document.layout.app.mainplugin / src / main / java / org / gvsig / app / project / documents / layout / fframes / FFrameGraphics.java @ 31

History | View | Annotate | Download (17.4 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
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., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.app.project.documents.layout.fframes;
23

    
24
import java.awt.Color;
25
import java.awt.Graphics2D;
26
import java.awt.geom.AffineTransform;
27
import java.awt.geom.Point2D;
28
import java.awt.geom.Rectangle2D;
29
import java.awt.image.BufferedImage;
30
import java.util.BitSet;
31

    
32
import org.gvsig.andami.PluginServices;
33
import org.gvsig.app.project.documents.layout.geometryadapters.CircleAdapter;
34
import org.gvsig.app.project.documents.layout.geometryadapters.GeometryAdapter;
35
import org.gvsig.compat.print.PrintAttributes;
36
import org.gvsig.fmap.geom.Geometry;
37
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
38
import org.gvsig.fmap.geom.GeometryLocator;
39
import org.gvsig.fmap.geom.GeometryManager;
40
import org.gvsig.fmap.geom.type.GeometryType;
41
import org.gvsig.fmap.geom.type.GeometryTypeNotSupportedException;
42
import org.gvsig.fmap.geom.type.GeometryTypeNotValidException;
43
import org.gvsig.fmap.mapcontext.MapContextLocator;
44
import org.gvsig.fmap.mapcontext.MapContextManager;
45
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
46
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.IFillSymbol;
47
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.IMarkerSymbol;
48
import org.gvsig.tools.ToolsLocator;
49
import org.gvsig.tools.dynobject.DynStruct;
50
import org.gvsig.tools.persistence.PersistenceManager;
51
import org.gvsig.tools.persistence.PersistentState;
52
import org.gvsig.tools.persistence.exception.PersistenceException;
53

    
54
/**
55
 * FFrame para contener un gr?fico.
56
 * 
57
 * @author Vicente Caballero Navarro
58
 */
59
public class FFrameGraphics extends FFrame implements IFFrameEditableVertex {
60
    private static final GeometryManager GEOMETRY_MANAGER =
61
        GeometryLocator.getGeometryManager();
62
    
63
    public static final String PERSISTENCE_DEFINITION_NAME = "FFrameGraphics";
64

    
65
    private static final String TYPE_FIELD = "type";
66
    private static final String SYMBOL_FIELD = "symbol";
67
    private static final String GEOMETRYADAPTER_FIELD = "geometryAdapter";
68

    
69
    private static double TOL = 0.2;
70
   
71
    protected GeometryType geometryType = null;
72
    private ISymbol symbol = null;
73
    private Color color = null;
74
    private GeometryAdapter geometryAdapter;
75
    private GeometryAdapter geometryEdit;
76
    private boolean editing = false;
77
    private double size = 0.5;
78
    private BitSet index = new BitSet();
79

    
80
    private MapContextManager mapContextManager = MapContextLocator
81
        .getMapContextManager();
82

    
83
    /**
84
     * Crea un nuevo FFrameGraphics.
85
     */
86
    public FFrameGraphics() {
87
       
88
    }
89

    
90
    /**
91
     * DOCUMENT ME!
92
     * 
93
     * @param geom
94
     *            DOCUMENT ME!
95
     */
96
    public void setGeometryAdapter(GeometryAdapter geom) {
97
        geometryAdapter = geom;
98
    }
99

    
100
    /**
101
     * Rellena el color que se utlizar? para dibujar el s?mbolo.
102
     * 
103
     * @param color
104
     */
105
    public void setColor(Color color) {
106
        this.color = color;
107
    }
108

    
109
    /**
110
     * Actualiza el Fsymbol a partir del tipo de Gr?fico que se pase como
111
     * par?metro.
112
     * 
113
     * @param type
114
     *            tipo de gr?fico.
115
     * @param at
116
     *            Transformada.
117
     */
118
    public void update(int type, AffineTransform at) {
119
        setType(type);
120
        
121
        if (color == null) {
122
            color = Color.black;
123
        }
124

    
125
        symbol = mapContextManager.getSymbolManager().createSymbol(type);
126
        if (symbol instanceof IFillSymbol) {
127
            ((IFillSymbol) symbol).setHasFill(false);
128
        }
129
    }
130

    
131
    /**
132
     * Devuelve el FSymbol que se representa.
133
     * 
134
     * @return DOCUMENT ME!
135
     */
136
    public ISymbol getFSymbol() {
137
        return symbol;
138
    }
139

    
140
    /**
141
     * Rellena el FSymbol que se representara al dibujar.
142
     * 
143
     * @param fs2d
144
     */
145
    public void setSymbol(ISymbol symbol) {
146
        this.symbol = symbol;
147
    }
148

    
149
    /**
150
     * M?todo que dibuja sobre el graphics que se le pasa como par?metro, seg?n
151
     * la transformada afin que se debe de aplicar y el rect?ngulo que se debe
152
     * de dibujar.
153
     * 
154
     * @param g
155
     *            Graphics
156
     * @param at
157
     *            Transformada afin.
158
     * @param rv
159
     *            rect?ngulo sobre el que hacer un clip.
160
     * @param imgBase
161
     *            DOCUMENT ME!
162
     */
163
    public void draw(Graphics2D g, AffineTransform at, Rectangle2D rv,
164
        BufferedImage imgBase) {
165
        Rectangle2D.Double rect = getBoundingBox(at);
166
        
167
        g.rotate(Math.toRadians(getRotation()), rect.getCenterX(), rect.getCenterY());
168
        
169
        if (intersects(rv, rect)) {
170
            g.setColor(Color.black);
171

    
172
            if (geometryType.isTypeOf(Geometry.TYPES.POINT)) {
173
                ((IMarkerSymbol) symbol)
174
                .setSize((int) (rect.getWidth() * 0.7));
175
            }
176
            
177
            geometryAdapter.draw(g, at, symbol);
178

    
179
            if (editing) {
180
                g.setColor(Color.red);
181
                geometryAdapter.drawVertex(g, at);
182
            }
183
        }
184

    
185
        g.rotate(Math.toRadians(-getRotation()), rect.getCenterX(), rect.getCenterY());
186
    }
187

    
188
    /**
189
     * @see org.gvsig.app.project.documents.layout.fframes.IFFrame#updateNum()
190
     */
191
    public void updateNum() {
192
    }
193

    
194
    /**
195
     * @see org.gvsig.app.project.documents.layout.fframes.IFFrame#getNum()
196
     */
197
    public int getNum() {
198
        return 0;
199
    }
200

    
201
    /**
202
     * @see org.gvsig.app.project.documents.layout.fframes.IFFrame#getNameFFrame()
203
     */
204
    public String getNameFFrame() {
205
        return PluginServices.getText(this, "Graficos") + num;
206
    }
207

    
208
    public String getName() {
209
        return PERSISTENCE_DEFINITION_NAME;
210
    }
211

    
212
    /**
213
     * Inserta el tama?o del punto.
214
     * 
215
     * @param size
216
     *            entero que representa el tama?o del punto.
217
     */
218
    public void setSize(double size) {
219
        this.size = size;
220
        Rectangle2D r = geometryAdapter.getBounds2D();
221
        super.setBoundBox(new Rectangle2D.Double(r.getX() - size, r.getY()
222
            - size, size * 2, size * 2));
223
    }
224

    
225
    /**
226
     * Devuelve el tipo de gr?fico que contiene el fframe.
227
     * 
228
     * @return tipo de
229
     */
230
    public GeometryType getType(){
231
        return geometryType;
232
    }
233

    
234
    public void setType(int type) {
235
        try {
236
            geometryType = GEOMETRY_MANAGER.getGeometryType(type, SUBTYPES.GEOM2D);
237
        } catch (GeometryTypeNotSupportedException e) {
238
            LOG.error("Error setting the geometry type", e);
239
        } catch (GeometryTypeNotValidException e) {
240
            LOG.error("Error setting the geometry type", e);
241
        }
242
    }
243

    
244
    /**
245
     * DOCUMENT ME!
246
     * 
247
     * @param r
248
     *            DOCUMENT ME!
249
     */
250
    public void setBoundBox(Rectangle2D r) {      
251
        AffineTransform aT = new AffineTransform();
252

    
253
        if (getBoundBox().getWidth() != 0) {
254
            double w = r.getWidth() / getBoundBox().getWidth();
255
            double h = r.getHeight() / getBoundBox().getHeight();
256

    
257
            AffineTransform trans2 =
258
                AffineTransform.getTranslateInstance(r.getX(), r.getY());
259
            aT.concatenate(trans2);
260

    
261
            AffineTransform scale1 = AffineTransform.getScaleInstance(w, h);
262
            aT.concatenate(scale1);
263

    
264
            AffineTransform trans1 =
265
                AffineTransform.getTranslateInstance(-getBoundBox().getX(),
266
                    -getBoundBox().getY());
267
            aT.concatenate(trans1);
268
            geometryAdapter.applyTransform(aT);
269

    
270
            size = aT.getScaleX() * size;
271
        }
272

    
273
        super.setBoundBox(r);
274
    }
275

    
276
    /**
277
     * DOCUMENT ME!
278
     */
279
    public void startEditing() {
280
        editing = true;
281
    }
282

    
283
    /**
284
     * DOCUMENT ME!
285
     */
286
    public void stopEditing() {
287
        editing = false;
288
    }
289

    
290
    /**
291
     * DOCUMENT ME!
292
     * 
293
     * @return DOCUMENT ME!
294
     */
295
    public boolean isEditing() {
296
        return editing;
297
    }
298

    
299
    /**
300
     * DOCUMENT ME!
301
     * 
302
     * @param point
303
     *            DOCUMENT ME!
304
     * @param geom
305
     *            DOCUMENT ME!
306
     */
307
    public void pointReleased(Point2D point, GeometryAdapter geom) {
308
        index.clear();
309
        geometryAdapter = geom;
310

    
311
        Rectangle2D r = geometryAdapter.getBounds2D();
312
        super.setBoundBox(r);
313
    }
314

    
315
    /**
316
     * DOCUMENT ME!
317
     * 
318
     * @param point
319
     *            DOCUMENT ME!
320
     */
321
    public void pointPressed(Point2D point) {
322
        Rectangle2D.Double rect = getBoundBox();
323
        Point2D[] points = geometryAdapter.getPoints();
324
        try {
325
            geometryEdit = (GeometryAdapter) geometryAdapter.clone();
326
        } catch (CloneNotSupportedException e) {
327
            LOG.error("Error clonning the geometry", e);
328
        }
329

    
330
        Point2D pAux1 = new Point2D.Double();
331
        index.clear();
332
        for (int i = 0; i < points.length; i++) {
333
            if (getRotation() != 0) {
334
                AffineTransform af =
335
                    AffineTransform.getRotateInstance(
336
                        Math.toRadians(-getRotation()), rect.x
337
                            + (rect.width / 2), rect.y + (rect.height / 2));
338
                af.transform(point, pAux1);
339

    
340
                if (points[i].distance(pAux1) <= TOL) {
341
                    index.set(i);
342
                }
343
            } else {
344
                if (points[i].distance(point) <= TOL) {
345
                    index.set(i);
346
                }
347
            }
348
        }
349
    }
350

    
351
    /**
352
     * DOCUMENT ME!
353
     * 
354
     * @param point
355
     *            DOCUMENT ME!
356
     */
357
    public void pointDragged(Point2D point) {
358
        // Point2D[] points = geometry.getPoints();
359

    
360
        for (int j = index.nextSetBit(0); j >= 0; j = index.nextSetBit(j + 1)) {
361
            if (getRotation() != 0) {
362
                Rectangle2D.Double rect = getBoundBox();
363
                AffineTransform af =
364
                    AffineTransform.getRotateInstance(
365
                        Math.toRadians(-getRotation()), rect.x
366
                            + (rect.width / 2), rect.y + (rect.height / 2));
367
                af.transform(point, point);
368
            }
369

    
370
            geometryEdit.changePoint(j, point);
371
        }
372
        geometryEdit.end();
373
    }
374

    
375
    /**
376
     * DOCUMENT ME!
377
     * 
378
     * @param g
379
     *            DOCUMENT ME!
380
     * @param at
381
     *            DOCUMENT ME!
382
     */
383
    public void paint(Graphics2D g, AffineTransform at) {
384
        if (geometryEdit != null) {
385
            Rectangle2D.Double rect = getBoundingBox(at);
386
            if (getRotation() != 0) {
387
                g.rotate(Math.toRadians(getRotation()), rect.x
388
                    + (rect.width / 2), rect.y + (rect.height / 2));
389
                geometryEdit.paint(g, at, false);
390
                g.rotate(Math.toRadians(-getRotation()), rect.x
391
                    + (rect.width / 2), rect.y + (rect.height / 2));
392
            } else {
393
                geometryEdit.paint(g, at, false);
394
            }
395
        }
396
    }
397

    
398
    /**
399
     * DOCUMENT ME!
400
     * 
401
     * @return DOCUMENT ME!
402
     */
403
    public GeometryAdapter getGeometry() {
404
        return geometryEdit;
405
    }
406

    
407
    public void initialize() {
408

    
409
    }
410

    
411
    /**
412
     * Devuelve un entero que representa donde esta contenido el punto que se
413
     * pasa como par?metro.
414
     * 
415
     * @param p
416
     *            punto a comparar.
417
     * 
418
     * @return entero que representa como esta contenido el punto.
419
     */
420
    public int getContains(Point2D p) {
421
        if (geometryAdapter instanceof CircleAdapter) {
422
            if (ne.contains(p.getX(), p.getY())) {
423
                return NE;
424
            } else
425
                if (se.contains(p.getX(), p.getY())) {
426
                    return SE;
427
                } else
428
                    if (so.contains(p.getX(), p.getY())) {
429
                        return SO;
430
                    } else
431
                        if (no.contains(p.getX(), p.getY())) {
432
                            return NO;
433
                        } else
434
                            if (getBoundingBox(null).contains(p.getX(),
435
                                p.getY())) {
436
                                return RECT;
437
                            }
438
            return NOSELECT;
439
        }
440
        return super.getContains(p);
441
    }
442

    
443
    /**
444
     * Dibuja los handlers sobre el boundingBox en el graphics que se pasa como
445
     * par?metro.
446
     * 
447
     * @param g
448
     *            Graphics sobre el que dibujar.
449
     */
450
    public void drawHandlers(Graphics2D g) {
451
        if (geometryAdapter instanceof CircleAdapter) {
452
            int size = 10;
453
            Rectangle2D r = getBoundingBox(null);
454
            Point2D p = new Point2D.Double();
455
            g.rotate(Math.toRadians(getRotation()), r.getX()
456
                + (r.getWidth() / 2), r.getY() + (r.getHeight() / 2));
457

    
458
            AffineTransform atRotate = new AffineTransform();
459
            atRotate.rotate(Math.toRadians(getRotation()),
460
                r.getX() + (r.getWidth() / 2), r.getY() + (r.getHeight() / 2));
461

    
462
            g.fillRect((int) r.getX() - size, (int) r.getY() - size, size, size);
463
            atRotate.transform(new Point2D.Double(r.getX() - size, r.getY()
464
                - size), p);
465
            no.setRect((int) p.getX(), (int) p.getY(), size, size);
466

    
467
            g.fillRect((int) r.getMaxX(), (int) r.getY() - size, size, size);
468
            atRotate.transform(
469
                new Point2D.Double(r.getMaxX(), r.getY() - size), p);
470
            ne.setRect((int) p.getX(), (int) p.getY(), size, size);
471

    
472
            g.fillRect((int) r.getX() - size, (int) r.getMaxY(), size, size);
473
            atRotate.transform(
474
                new Point2D.Double(r.getX() - size, r.getMaxY()), p);
475
            so.setRect((int) p.getX(), (int) p.getY(), size, size);
476

    
477
            g.fillRect((int) r.getMaxX(), (int) r.getMaxY(), size, size);
478
            atRotate.transform(new Point2D.Double(r.getMaxX(), r.getMaxY()), p);
479
            se.setRect((int) p.getX(), (int) p.getY(), size, size);
480

    
481
            g.rotate(Math.toRadians(-getRotation()), r.getX()
482
                + (r.getWidth() / 2), r.getY() + (r.getHeight() / 2));
483
        } else {
484
            super.drawHandlers(g);
485
        }
486
    }
487

    
488
    public void print(Graphics2D g, AffineTransform at, Geometry geom,
489
        PrintAttributes printingProperties) {
490
        Rectangle2D.Double rect = getBoundingBox(at);
491
        g.rotate(Math.toRadians(getRotation()), rect.x + (rect.width / 2),
492
            rect.y + (rect.height / 2));
493
        g.setColor(Color.black);
494

    
495
        geometryAdapter.print(g, at, symbol, printingProperties);
496

    
497
        if (editing) {
498
            g.setColor(Color.red);
499
            geometryAdapter.drawVertex(g, at);
500
        }
501

    
502
        g.rotate(Math.toRadians(-getRotation()), rect.x + (rect.width / 2),
503
            rect.y + (rect.height / 2));
504
    }
505

    
506
    public static void registerPersistent() {
507
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
508
        if (manager.getDefinition(PERSISTENCE_DEFINITION_NAME) == null) {
509
            DynStruct definition =
510
                manager.addDefinition(FFrameGraphics.class,
511
                    PERSISTENCE_DEFINITION_NAME,
512
                    "FFrameGraphics persistence definition", null, null);
513

    
514
            definition.extend(manager
515
                .getDefinition(FFrame.PERSISTENCE_DEFINITION_NAME));
516

    
517
            definition.addDynFieldInt(TYPE_FIELD).setMandatory(true);
518
            definition.addDynFieldObject(SYMBOL_FIELD).setMandatory(true)
519
                .setClassOfValue(ISymbol.class);
520
            definition.addDynFieldObject(GEOMETRYADAPTER_FIELD)
521
                .setClassOfValue(GeometryAdapter.class);
522
        }
523

    
524
        GeometryAdapter.registerPersistent();
525
    }
526

    
527
    @Override
528
    public void loadFromState(PersistentState state)
529
        throws PersistenceException {
530
        super.loadFromState(state);
531
        try {
532
            geometryType =  GEOMETRY_MANAGER.getGeometryType(state.getInt(TYPE_FIELD), SUBTYPES.GEOM2D);
533
        } catch (GeometryTypeNotSupportedException e) {
534
            LOG.error("Error loading the geometry type", e);
535
        } catch (GeometryTypeNotValidException e) {
536
            LOG.error("Error loading the geometry type", e);
537
        }
538
        symbol = (ISymbol) state.get(SYMBOL_FIELD);
539
        geometryAdapter = (GeometryAdapter) state.get(GEOMETRYADAPTER_FIELD);
540
    }
541

    
542
    @Override
543
    public void saveToState(PersistentState state) throws PersistenceException {
544
        super.saveToState(state);
545
        state.set(TYPE_FIELD, geometryType.getType());
546
        state.set(SYMBOL_FIELD, symbol);
547
        state.set(GEOMETRYADAPTER_FIELD, geometryAdapter);
548
    }
549
    
550
    public Object clone() throws CloneNotSupportedException {
551
        FFrameGraphics resp = (FFrameGraphics) super.clone();
552
        
553
        GeometryAdapter nga = null;
554
        if (geometryAdapter != null) {
555
            nga = (GeometryAdapter) geometryAdapter.clone();
556
        }
557
        resp.setGeometryAdapter(nga);
558
        return resp;
559
    }
560
}