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 @ 100

History | View | Annotate | Download (17.6 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 IMarkerSymbol) {
127
            symbol.setColor(Color.BLACK);
128
        }
129
        if (symbol instanceof IFillSymbol) {
130
            ((IFillSymbol) symbol).setHasFill(false);
131
        }
132
    }
133

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

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

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

    
175
            /*
176
             * Do not force point size to match square
177
            if (geometryType.isTypeOf(Geometry.TYPES.POINT)) {
178
                ((IMarkerSymbol) symbol)
179
                .setSize((int) (rect.getWidth() * 0.7));
180
            }
181
             */
182
            
183
            geometryAdapter.draw(g, at, symbol);
184

    
185
            if (editing) {
186
                g.setColor(Color.red);
187
                geometryAdapter.drawVertex(g, at);
188
            }
189
        }
190

    
191
        g.rotate(Math.toRadians(-getRotation()), rect.getCenterX(), rect.getCenterY());
192
    }
193

    
194
    /**
195
     * @see org.gvsig.app.project.documents.layout.fframes.IFFrame#updateNum()
196
     */
197
    public void updateNum() {
198
    }
199

    
200
    /**
201
     * @see org.gvsig.app.project.documents.layout.fframes.IFFrame#getNum()
202
     */
203
    public int getNum() {
204
        return 0;
205
    }
206

    
207
    /**
208
     * @see org.gvsig.app.project.documents.layout.fframes.IFFrame#getNameFFrame()
209
     */
210
    public String getNameFFrame() {
211
        return PluginServices.getText(this, "Graficos") + num;
212
    }
213

    
214
    public String getName() {
215
        return PERSISTENCE_DEFINITION_NAME;
216
    }
217

    
218
    /**
219
     * Inserta el tama?o del punto.
220
     * 
221
     * @param size
222
     *            entero que representa el tama?o del punto.
223
     */
224
    public void setSize(double size) {
225
        this.size = size;
226
        Rectangle2D r = geometryAdapter.getBounds2D();
227
        super.setBoundBox(new Rectangle2D.Double(r.getX() - size, r.getY()
228
            - size, size * 2, size * 2));
229
    }
230

    
231
    /**
232
     * Devuelve el tipo de gr?fico que contiene el fframe.
233
     * 
234
     * @return tipo de
235
     */
236
    public GeometryType getType(){
237
        return geometryType;
238
    }
239

    
240
    public void setType(int type) {
241
        try {
242
            geometryType = GEOMETRY_MANAGER.getGeometryType(type, SUBTYPES.GEOM2D);
243
        } catch (GeometryTypeNotSupportedException e) {
244
            LOG.error("Error setting the geometry type", e);
245
        } catch (GeometryTypeNotValidException e) {
246
            LOG.error("Error setting the geometry type", e);
247
        }
248
    }
249

    
250
    /**
251
     * DOCUMENT ME!
252
     * 
253
     * @param r
254
     *            DOCUMENT ME!
255
     */
256
    public void setBoundBox(Rectangle2D r) {      
257
        AffineTransform aT = new AffineTransform();
258

    
259
        if (getBoundBox().getWidth() != 0) {
260
            double w = r.getWidth() / getBoundBox().getWidth();
261
            double h = r.getHeight() / getBoundBox().getHeight();
262

    
263
            AffineTransform trans2 =
264
                AffineTransform.getTranslateInstance(r.getX(), r.getY());
265
            aT.concatenate(trans2);
266

    
267
            AffineTransform scale1 = AffineTransform.getScaleInstance(w, h);
268
            aT.concatenate(scale1);
269

    
270
            AffineTransform trans1 =
271
                AffineTransform.getTranslateInstance(-getBoundBox().getX(),
272
                    -getBoundBox().getY());
273
            aT.concatenate(trans1);
274
            geometryAdapter.applyTransform(aT);
275

    
276
            size = aT.getScaleX() * size;
277
        }
278

    
279
        super.setBoundBox(r);
280
    }
281

    
282
    /**
283
     * DOCUMENT ME!
284
     */
285
    public void startEditing() {
286
        editing = true;
287
    }
288

    
289
    /**
290
     * DOCUMENT ME!
291
     */
292
    public void stopEditing() {
293
        editing = false;
294
    }
295

    
296
    /**
297
     * DOCUMENT ME!
298
     * 
299
     * @return DOCUMENT ME!
300
     */
301
    public boolean isEditing() {
302
        return editing;
303
    }
304

    
305
    /**
306
     * DOCUMENT ME!
307
     * 
308
     * @param point
309
     *            DOCUMENT ME!
310
     * @param geom
311
     *            DOCUMENT ME!
312
     */
313
    public void pointReleased(Point2D point, GeometryAdapter geom) {
314
        index.clear();
315
        geometryAdapter = geom;
316

    
317
        Rectangle2D r = geometryAdapter.getBounds2D();
318
        super.setBoundBox(r);
319
    }
320

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

    
336
        Point2D pAux1 = new Point2D.Double();
337
        index.clear();
338
        for (int i = 0; i < points.length; i++) {
339
            if (getRotation() != 0) {
340
                AffineTransform af =
341
                    AffineTransform.getRotateInstance(
342
                        Math.toRadians(-getRotation()), rect.x
343
                            + (rect.width / 2), rect.y + (rect.height / 2));
344
                af.transform(point, pAux1);
345

    
346
                if (points[i].distance(pAux1) <= TOL) {
347
                    index.set(i);
348
                }
349
            } else {
350
                if (points[i].distance(point) <= TOL) {
351
                    index.set(i);
352
                }
353
            }
354
        }
355
    }
356

    
357
    /**
358
     * DOCUMENT ME!
359
     * 
360
     * @param point
361
     *            DOCUMENT ME!
362
     */
363
    public void pointDragged(Point2D point) {
364
        // Point2D[] points = geometry.getPoints();
365

    
366
        for (int j = index.nextSetBit(0); j >= 0; j = index.nextSetBit(j + 1)) {
367
            if (getRotation() != 0) {
368
                Rectangle2D.Double rect = getBoundBox();
369
                AffineTransform af =
370
                    AffineTransform.getRotateInstance(
371
                        Math.toRadians(-getRotation()), rect.x
372
                            + (rect.width / 2), rect.y + (rect.height / 2));
373
                af.transform(point, point);
374
            }
375

    
376
            geometryEdit.changePoint(j, point);
377
        }
378
        geometryEdit.end();
379
    }
380

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

    
404
    /**
405
     * DOCUMENT ME!
406
     * 
407
     * @return DOCUMENT ME!
408
     */
409
    public GeometryAdapter getGeometry() {
410
        return geometryEdit;
411
    }
412

    
413
    public void initialize() {
414

    
415
    }
416

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

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

    
464
            AffineTransform atRotate = new AffineTransform();
465
            atRotate.rotate(Math.toRadians(getRotation()),
466
                r.getX() + (r.getWidth() / 2), r.getY() + (r.getHeight() / 2));
467

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

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

    
478
            g.fillRect((int) r.getX() - size, (int) r.getMaxY(), size, size);
479
            atRotate.transform(
480
                new Point2D.Double(r.getX() - size, r.getMaxY()), p);
481
            so.setRect((int) p.getX(), (int) p.getY(), size, size);
482

    
483
            g.fillRect((int) r.getMaxX(), (int) r.getMaxY(), size, size);
484
            atRotate.transform(new Point2D.Double(r.getMaxX(), r.getMaxY()), p);
485
            se.setRect((int) p.getX(), (int) p.getY(), size, size);
486

    
487
            g.rotate(Math.toRadians(-getRotation()), r.getX()
488
                + (r.getWidth() / 2), r.getY() + (r.getHeight() / 2));
489
        } else {
490
            super.drawHandlers(g);
491
        }
492
    }
493

    
494
    public void print(Graphics2D g, AffineTransform at, Geometry geom,
495
        PrintAttributes printingProperties) {
496
        Rectangle2D.Double rect = getBoundingBox(at);
497
        g.rotate(Math.toRadians(getRotation()), rect.x + (rect.width / 2),
498
            rect.y + (rect.height / 2));
499
        g.setColor(Color.black);
500

    
501
        geometryAdapter.print(g, at, symbol, printingProperties);
502

    
503
        if (editing) {
504
            g.setColor(Color.red);
505
            geometryAdapter.drawVertex(g, at);
506
        }
507

    
508
        g.rotate(Math.toRadians(-getRotation()), rect.x + (rect.width / 2),
509
            rect.y + (rect.height / 2));
510
    }
511

    
512
    public static void registerPersistent() {
513
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
514
        if (manager.getDefinition(PERSISTENCE_DEFINITION_NAME) == null) {
515
            DynStruct definition =
516
                manager.addDefinition(FFrameGraphics.class,
517
                    PERSISTENCE_DEFINITION_NAME,
518
                    "FFrameGraphics persistence definition", null, null);
519

    
520
            definition.extend(manager
521
                .getDefinition(FFrame.PERSISTENCE_DEFINITION_NAME));
522

    
523
            definition.addDynFieldInt(TYPE_FIELD).setMandatory(true);
524
            definition.addDynFieldObject(SYMBOL_FIELD).setMandatory(true)
525
                .setClassOfValue(ISymbol.class);
526
            definition.addDynFieldObject(GEOMETRYADAPTER_FIELD)
527
                .setClassOfValue(GeometryAdapter.class);
528
        }
529

    
530
        GeometryAdapter.registerPersistent();
531
    }
532

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

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