Statistics
| Revision:

svn-gvsig-desktop / trunk / applications / appgvSIG / src / com / iver / cit / gvsig / gui / layout / fframes / FFrameScaleBar.java @ 3183

History | View | Annotate | Download (36.7 KB)

1
/*
2
 * Created on 20-feb-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 com.iver.andami.PluginServices;
48

    
49
import com.iver.cit.gvsig.fmap.DriverException;
50
import com.iver.cit.gvsig.fmap.FMap;
51
import com.iver.cit.gvsig.gui.layout.Attributes;
52
import com.iver.cit.gvsig.gui.layout.FLayoutUtilities;
53
import com.iver.cit.gvsig.gui.layout.Layout;
54
import com.iver.cit.gvsig.gui.project.SaveException;
55

    
56
import com.iver.utiles.StringUtilities;
57
import com.iver.utiles.XMLEntity;
58

    
59
import java.awt.BasicStroke;
60
import java.awt.Color;
61
import java.awt.Font;
62
import java.awt.Graphics;
63
import java.awt.Graphics2D;
64
import java.awt.geom.AffineTransform;
65
import java.awt.geom.Point2D;
66
import java.awt.geom.Rectangle2D;
67
import java.awt.image.BufferedImage;
68

    
69
import java.util.ArrayList;
70

    
71

    
72
/**
73
 * FFrame para introducir una barra de escala en el Layout.
74
 *
75
 * @author Vicente Caballero Navarro
76
 */
77
public class FFrameScaleBar extends FFrame implements IFFrameViewDependence {
78
    private static final int NUMERO = 0;
79
    private static final int BARRA1 = 1;
80
    private static final int BARRA2 = 2;
81
    private static final int BARRA3 = 3;
82
    private static final int BARRA4 = 4;
83
    private double DIFDOWN = 1.5;
84
    private double DIFL = 30;
85
    private double DIFR = 30;
86
    private double DIFUP = 10;
87
    private boolean m_bIntervalSet = false;
88
    private int m_style = NUMERO;
89
    private int m_units = 1; //Metros
90
    private int m_mapUnits = 1; //unidad de medida de la vista(Metros)
91
    private long m_interval = 1;
92
    private int m_numinterval = 3;
93
    private int m_numleft = 2;
94
    private double m_height = 0;
95
    private FFrameView fframeview = null;
96
    private double m_typeUnit = Attributes.CHANGE[1]; //METROS;
97
    private String m_nameUnit = null;
98
    private double m_numUnit = 0;
99
    private double m_dif = 1;
100
    private int m_hasleft = 0;
101
    private Font m_f = new Font("SansSerif", Font.PLAIN, 9);
102
    private Color barcolor = Color.black;
103
    private Color textcolor = Color.black;
104
    private boolean showNameUnits = true;
105
    private boolean showDescription = false;
106
    private boolean aboveName = false;
107
    private boolean aboveIntervals = true;
108
    private boolean aboveDescription = false;
109
    private String description = "";
110
    private int dependenceIndex;
111

    
112
    /**
113
     * Creates a new FFrameScaleBar object.
114
     */
115
    public FFrameScaleBar() {
116
    }
117

    
118
    /**
119
     * Inserta el FFrameView sobre el que obtener la escala gr?fica.
120
     *
121
     * @param f FFrameView sobre  el que obtener la escala.
122
     */
123
    public void setFFrameDependence(IFFrame f) {
124
        fframeview = (FFrameView) f;
125
        setMapUnits(fframeview.getMapUnits());
126
        setHeight(f.getBoundBox().height);
127
        description = "escala 1:" + String.valueOf(fframeview.getScale());
128
    }
129

    
130
    /**
131
     * Devuelve el FFrameView que se representa con la escala.
132
     *
133
     * @return FFrameView a representar.
134
     */
135
    public IFFrame getFFrameDependence() {
136
        return fframeview;
137
    }
138

    
139
    /**
140
     * Devuelve el FMap de la vista que se representa en la escala.
141
     *
142
     * @return FMap.
143
     */
144
    public FMap getFMap() {
145
        return fframeview.getFMap();
146
    }
147

    
148
    /**
149
     * Rellenar el estilo de barra de escala que se elige.
150
     *
151
     * @param s entero que representa el tipo de barra seleccionada.
152
     */
153
    public void setStyle(int s) {
154
        m_style = s;
155
    }
156

    
157
    /**
158
     * Devuelve el tipo de escala a dibujar.
159
     *
160
     * @return entero.
161
     */
162
    public int getStyle() {
163
        return m_style;
164
    }
165

    
166
    /**
167
     * Rellenar el tama?o de un intervalo.
168
     *
169
     * @param s tama?o de un intervalo.
170
     */
171
    public void setInterval(long s) {
172
        m_interval = s;
173

    
174
        if (m_numleft != 0) {
175
            m_hasleft = 1;
176
        }
177

    
178
        Rectangle2D.Double rect = getBoundBox();
179
        double difL = (rect.width / DIFL);
180
        double difR = (rect.width / DIFR);
181
        double n = (rect.width - difL - difR);
182
        m_numUnit = (m_interval * m_typeUnit) / getScaleView();
183
        m_numinterval = (int) (n / m_numUnit) - m_hasleft;
184
        m_dif = 1;
185
    }
186

    
187
    /**
188
     * Devuelve el valor del intervalo.
189
     *
190
     * @return long.
191
     */
192
    public long obtainInterval() {
193
        if (fframeview != null) {
194
            Rectangle2D.Double rect = getBoundBox();
195

    
196
            if (m_numleft != 0) {
197
                m_hasleft = 1;
198
            }
199

    
200
            double difL = (rect.width / DIFL);
201
            double difR = (rect.width / DIFR);
202
            double n = (rect.width - difL - difR);
203
            m_numUnit = n / (m_numinterval + m_hasleft);
204

    
205
            double scaleXunit = (m_numUnit * getScaleView()) / m_typeUnit;
206
            m_dif = getExact(scaleXunit);
207
            m_numUnit = m_numUnit * m_dif;
208
            m_interval = (long) (scaleXunit * m_dif);
209

    
210
            return m_interval;
211
        }
212

    
213
        return 0;
214
    }
215

    
216
    /**
217
     * Rellenar el n?mero de intervalos.
218
     *
219
     * @param s n?mero de intervalos.
220
     */
221
    public void setNumInterval(int s) {
222
        m_numinterval = s;
223

    
224
        if (m_numleft != 0) {
225
            m_hasleft = 1;
226
        }
227

    
228
        Rectangle2D.Double rect = getBoundBox();
229
        double difL = (rect.width / DIFL);
230
        double difR = (rect.width / DIFR);
231
        double n = (rect.width - difL - difR);
232
        m_numUnit = n / (m_numinterval + m_hasleft);
233

    
234
        double scaleXunit = (m_numUnit * getScaleView()) / m_typeUnit;
235
        m_dif = getExact(scaleXunit);
236
        m_numUnit = m_numUnit * m_dif;
237
        m_interval = (long) (scaleXunit * m_dif);
238
    }
239

    
240
    /**
241
     * Devuelve el n?mero de intervalos por encima del cero.
242
     *
243
     * @return entero.
244
     */
245
    public int getNumInterval() {
246
        return m_numinterval;
247
    }
248

    
249
    /**
250
     * Rellenar el n?mero de intervalos a la izquierda del cero.
251
     *
252
     * @param s n?mero de intervalos a la izquierda.
253
     */
254
    public void setNumLeft(int s) {
255
        m_numleft = s;
256
    }
257

    
258
    /**
259
     * Devuelve el n?mero de intervalos  en los que se quiere particionar el
260
     * intervalo  que se queda por debajo del cero.
261
     *
262
     * @return entero.
263
     */
264
    public int getNumLeft() {
265
        return m_numleft;
266
    }
267

    
268
    /**
269
     * Seleccionar ,a true, si se quiere o, a false, si no mantener los
270
     * intervalos.
271
     *
272
     * @param b boolean a true si se quiere mantener los intervalos.
273
     */
274
    public void setIntervalSet(boolean b) {
275
        m_bIntervalSet = b;
276
    }
277

    
278
    /**
279
     * Seleccionar la unidad de medida a representar en la barra de escala.
280
     *
281
     * @param s entero que representa la unidad de medida que se selecciona.
282
     */
283
    public void setUnits(int s) {
284
        m_units = s;
285
        m_typeUnit = Attributes.CHANGE[s];
286
        m_nameUnit = Attributes.NAMES[s];
287
    }
288

    
289
    /**
290
     * Devuelve un entero que representa el tipo de unidades que representamos.
291
     *
292
     * @return entero.
293
     */
294
    public int getUnits() {
295
        return m_units;
296
    }
297

    
298
    /**
299
     * Devuelve el long que representa el intervalo.
300
     *
301
     * @return Intervalo.
302
     */
303
    public long getInterval() {
304
        return m_interval;
305
    }
306

    
307
    /**
308
     * Rellenar el rect?ngulo de la vista sobre la que se obtiene la escala.
309
     *
310
     * @param d Rect?ngulo.
311
     */
312
    public void setHeight(double d) {
313
        m_height = d;
314
    }
315

    
316
    /**
317
     * Rellena la unidad de medida en la que est? la vista.
318
     *
319
     * @param i entero que representa la unidad de medida de la vista.
320
     */
321
    public void setMapUnits(int i) {
322
        m_mapUnits = i;
323
    }
324

    
325
    /**
326
     * Devuelve la escala de la vista seleccionada.
327
     *
328
     * @return la escala de la vista.
329
     */
330
    private long getScaleView() {
331
        return fframeview.getScale();
332
    }
333

    
334
    /**
335
     * M?todo que dibuja sobre el graphics que se le pasa como par?metro, seg?n
336
     * la transformada afin que se debe de aplicar y el rect?ngulo que se debe
337
     * de dibujar.
338
     *
339
     * @param g Graphics
340
     * @param at Transformada afin.
341
     * @param rv rect?ngulo sobre el que hacer un clip.
342
     * @param imgBase Image para acelerar el dibujado.
343
     */
344
    public void draw(Graphics2D g, AffineTransform at, Rectangle2D rv,
345
        BufferedImage imgBase) {
346
        Rectangle2D.Double r = getBoundingBox(at);
347
        g.rotate(Math.toRadians(getRotation()), r.x + (r.width / 2),
348
            r.y + (r.height / 2));
349

    
350
        if (intersects(rv, r)) {
351
            if ((fframeview == null) || (fframeview.getFMap() == null)) {
352
                drawEmpty(g);
353
            } else {
354
                switch (m_style) {
355
                    case (NUMERO):
356

    
357
                        double scalex = r.getWidth() / (8);
358
                        g.setColor(textcolor);
359

    
360
                        if (m_f != null) {
361
                            m_f = new Font(m_f.getFontName(), m_f.getStyle(),
362
                                    (int) (scalex));
363
                            g.setFont(m_f);
364
                        }
365

    
366
                        g.drawString(" 1:" + getScaleView(), (int) r.x,
367
                            (int) (r.y + (r.height / 2)));
368

    
369
                        break;
370

    
371
                    case (BARRA1):
372
                    case (BARRA2):
373
                    case (BARRA3):
374
                    case (BARRA4):
375
                        drawBar(m_style, g, at);
376

    
377
                        break;
378
                }
379
            }
380
        }
381

    
382
        g.rotate(Math.toRadians(-getRotation()), r.x + (r.width / 2),
383
            r.y + (r.height / 2));
384
    }
385

    
386
    /**
387
     * Rellena con el rect?ngulo que se pasa como par?metro el boundBox(en
388
     * cent?metros) del fframe del cual con una transformaci?n se podr?
389
     * calcular el BoundingBox (en pixels).
390
     *
391
     * @param r Rect?ngulo en cent?metros.
392
     */
393
    public void setBoundBox(Rectangle2D.Double r) {
394
        if ((m_numUnit < 1) || (fframeview == null) ||
395
                (fframeview.getFMap() == null)) {
396
            super.setBoundBox(r);
397

    
398
            return;
399
        }
400

    
401
        double difL = (r.width / DIFL);
402
        double difR = (r.width / DIFR);
403

    
404
        if (m_bIntervalSet) {
405
            m_numinterval = (int) (((r.width - (difL + difR)) * m_dif) / m_numUnit) -
406
                m_hasleft;
407
        }
408

    
409
        if (m_numinterval < 1) {
410
            m_numinterval = 1;
411
            r.width = ((m_numinterval + m_hasleft) * m_numUnit) + difL + difR;
412
        }
413

    
414
        getBoundBox().setRect(r.getX(), r.getY(), r.getWidth(), r.getHeight());
415
    }
416

    
417
    /**
418
     * Dibuja sobre el Graphics la escala gr?fica.
419
     *
420
     * @param type Tipo de barra.
421
     * @param g Graphics sobre el que dibujar.
422
     * @param at Matriz de transformaci?n.
423
     */
424
    private void drawBar(int type, Graphics2D g, AffineTransform at) {
425
        Rectangle2D.Double rect = getBoundBox();
426
        Rectangle2D.Double r = getBoundingBox(at);
427
        double numleft = m_numleft;
428
        initDistances();
429

    
430
        double difDown = (rect.height / DIFDOWN);
431
        double difUp = (rect.height / DIFUP);
432
        double difL = (rect.width / DIFL);
433
        double difR = (rect.width / DIFR);
434
        double n = (rect.width - difL - difR);
435

    
436
        setDescripcion("escala 1:" + String.valueOf(fframeview.getScale()));
437
        g.setStroke(new BasicStroke(0));
438

    
439
        if (!m_bIntervalSet) {
440
            m_numUnit = n / (m_numinterval + m_hasleft);
441

    
442
            double scaleXunit = (m_numUnit * getScaleView()) / m_typeUnit;
443
            m_dif = getExact(scaleXunit);
444
            m_numUnit = m_numUnit * m_dif;
445
            m_interval = (long) (scaleXunit * m_dif);
446
        }
447

    
448
        if (m_bIntervalSet) {
449
            m_numUnit = (m_interval * m_typeUnit) / (m_dif * getScaleView());
450
            m_numinterval = (int) (((rect.width - (difL + difR)) * m_dif) / m_numUnit) -
451
                m_hasleft;
452
        }
453

    
454
        if (m_numinterval < 1) {
455
            m_numinterval = 1;
456
            rect.width = ((m_numinterval + m_hasleft) * m_numUnit) + difL +
457
                difR;
458
        }
459

    
460
        double h = 0;
461

    
462
        if (type == BARRA1) {
463
            h = (rect.height - (difUp + difDown));
464
        } else if ((type == BARRA2) || (type == BARRA3)) {
465
            h = (rect.height - (difUp + difDown)) / 2;
466
        }
467

    
468
        //Dibujar el rect?ngulo que bordea todo.
469
        Rectangle2D.Double rectotal = (FLayoutUtilities.fromSheetRect(new Rectangle2D.Double((rect.x +
470
                    difL), (rect.y + difUp),
471
                    m_numUnit * (m_hasleft + m_numinterval), h), at));
472
        g.setColor(Color.white);
473
        g.fillRect((int) rectotal.x, (int) rectotal.y, (int) (rectotal.width),
474
            (int) rectotal.height);
475
        g.setColor(barcolor);
476

    
477
        if (m_f != null) {
478
            m_f = new Font(m_f.getFontName(), m_f.getStyle(),
479
                    (int) (r.getHeight() / 4));
480
        } else {
481
            m_f = new Font("SansSerif", Font.PLAIN, (int) (r.getHeight() / 4));
482
        }
483

    
484
        g.setFont(m_f);
485

    
486
        //Derecha del cero
487
        for (int i = 0; i < m_numinterval; i++) {
488
            Rectangle2D.Double recder = FLayoutUtilities.fromSheetRect(new Rectangle2D.Double((rect.x +
489
                        (difL) + ((m_numUnit * i) + (m_hasleft * m_numUnit))),
490
                        (rect.y + (difUp)), (m_numUnit),
491
                        (rect.height - (difUp + difDown)) / 2), at);
492
            Rectangle2D.Double recderB = FLayoutUtilities.fromSheetRect(new Rectangle2D.Double((rect.x +
493
                        (difL) + ((m_numUnit * i) + (m_hasleft * m_numUnit))),
494
                        (rect.y + difUp) +
495
                        ((rect.height - (difUp + difDown)) / 2), (m_numUnit),
496
                        ((rect.height - (difUp + difDown)) / 2)), at);
497

    
498
            //                        Correcci?n cuando la altura en pixels del rect?ngulo es impar.
499
            rectotal.y = recder.y;
500
            recderB.height = rectotal.height - recder.height + 0.5;
501

    
502
            /**
503
             * if (i == (m_numinterval - 1)) { if (recder.getMaxX() !=
504
             * rectotal.getMaxX()) { recder.width = (recder.width +
505
             * recder.getMaxX()) - rectotal.getMaxX(); } if (recderB.getMaxX()
506
             * != rectotal.getMaxX()) { recderB.width = (recderB.width +
507
             * recderB.getMaxX()) - rectotal.getMaxX(); }} if
508
             * (recderB.getMaxY() != rectotal.getMaxY()) { recderB.height =
509
             * (recderB.height + recderB.getMaxY()) - rectotal.getMaxY(); }
510
             */
511
            if ((m_numleft % 2) == 0) {
512
                if ((i % 2) == 0) {
513
                    if ((type == BARRA1) || (type == BARRA2)) {
514
                        fillRect(g, recder);
515
                    } else if (type == BARRA3) {
516
                        g.drawRect((int) recder.x, (int) recder.y,
517
                            (int) recder.width, (int) recder.height);
518
                    }
519
                } else if (type == BARRA1) {
520
                    fillRect(g, recderB);
521
                }
522
            } else {
523
                if ((i % 2) != 0) {
524
                    if ((type == BARRA1) || (type == BARRA2)) {
525
                        fillRect(g, recder);
526
                    } else if (type == BARRA3) {
527
                        g.drawRect((int) recderB.x, (int) recderB.y,
528
                            (int) recderB.width, (int) recderB.height);
529
                    }
530
                } else if (type == BARRA1) {
531
                    fillRect(g, recderB);
532
                }
533
            }
534

    
535
            long inter = (long) (m_interval * i);
536
            Long l = new Long(inter);
537

    
538
            int pos = ((int) (r.getHeight() / 4) * l.toString().length()) / 4;
539

    
540
            Point2D.Double p = null;
541

    
542
            if (isAboveIntervals()) {
543
                p = new Point2D.Double(recder.x - pos,
544
                        r.getMinY() + (r.getHeight() / DIFUP));
545
            } else {
546
                p = new Point2D.Double(recder.x - pos,
547
                        ((r.getHeight() / 4) + r.getMaxY()) -
548
                        (r.getHeight() / DIFDOWN));
549
            }
550

    
551
            drawInterval(g, inter, p);
552
        }
553

    
554
        //?ltimo n?mero a dibujar.
555
        long inter = (long) (m_interval * m_numinterval);
556
        Long l = new Long(inter);
557

    
558
        int pos = ((int) (r.getHeight() / 4) * l.toString().length()) / 4;
559

    
560
        Point2D.Double p = null;
561

    
562
        if (isAboveIntervals()) {
563
            p = new Point2D.Double(rectotal.getMaxX() - pos,
564
                    r.getMinY() + (r.getHeight() / DIFUP));
565
        } else {
566
            p = new Point2D.Double(rectotal.getMaxX() - pos,
567
                    ((r.getHeight() / 4) + r.getMaxY()) -
568
                    (r.getHeight() / DIFDOWN));
569
        }
570

    
571
        drawInterval(g, inter, p);
572

    
573
        //Izquierda del cero
574
        for (int i = 0; i < m_numleft; i++) {
575
            Rectangle2D.Double reciz = FLayoutUtilities.fromSheetRect(new Rectangle2D.Double((rect.x +
576
                        difL + ((m_numUnit / m_numleft) * i)),
577
                        (rect.y + difUp), (m_numUnit / numleft),
578
                        (rect.height - (difUp + difDown)) / 2), at);
579
            Rectangle2D.Double recizB = FLayoutUtilities.fromSheetRect(new Rectangle2D.Double((rect.x +
580
                        difL + ((m_numUnit / m_numleft) * i)),
581
                        (rect.y + difUp) +
582
                        ((rect.height - (difUp + difDown)) / 2),
583
                        (m_numUnit / numleft),
584
                        ((rect.height - (difUp + difDown)) / 2)), at);
585

    
586
            //Correcci?n cuando la altura en pixels del rectangulo es impar.
587
            reciz.y = rectotal.y;
588
            recizB.height = rectotal.height - reciz.height + 0.5;
589

    
590
            if ((i % 2) == 0) {
591
                if ((type == BARRA1) || (type == BARRA2)) {
592
                    fillRect(g, reciz);
593
                } else if (type == BARRA3) {
594
                    g.drawRect((int) reciz.x, (int) reciz.y, (int) reciz.width,
595
                        (int) reciz.height);
596
                }
597
            } else if (type == BARRA1) {
598
                fillRect(g, recizB);
599
            }
600
        }
601

    
602
        if (m_numleft > 0) {
603
            inter = (long) (m_interval);
604
            l = new Long(inter);
605

    
606
            pos = ((int) (r.getHeight() / 4) * l.toString().length()) / 4;
607

    
608
            if (isAboveIntervals()) {
609
                p = new Point2D.Double(rectotal.x - pos,
610
                        r.getMinY() + (r.getHeight() / DIFUP));
611
            } else {
612
                p = new Point2D.Double(rectotal.x - pos,
613
                        ((r.getHeight() / 4) + r.getMaxY()) -
614
                        (r.getHeight() / DIFDOWN));
615
            }
616

    
617
            drawInterval(g, inter, p);
618
        }
619

    
620
        //En el caso de que se pida como n?mro de intervalos a la izquierda del 0, se reajusta el tama?o del rect?ngulo exterior de la escala gr?fica.
621
        if (m_numleft == 0) {
622
            Rectangle2D.Double recAux = FLayoutUtilities.fromSheetRect(new Rectangle2D.Double((rect.x +
623
                        difL + ((m_numUnit / 1) * 0)), (rect.y + difUp),
624
                        (m_numUnit / 1), (rect.height - (difUp + difDown)) / 2),
625
                    at);
626
            rectotal.x = rectotal.x + recAux.width;
627
            rectotal.width = rectotal.width - recAux.width;
628
        }
629

    
630
        //Se dibuja el rect?ngulo que bordea toda la escala gr?fica.
631
        g.drawRect((int) rectotal.x, (int) rectotal.y, (int) (rectotal.width),
632
            (int) rectotal.height);
633

    
634
        drawNameUnits(g, rect, at);
635
        drawDescription(g, rect, at);
636
    }
637

    
638
    /**
639
     * Inicializa las distancias de la barra de escala.
640
     */
641
    private void initDistances() {
642
        int numUp = 0;
643
        int numDown = 0;
644

    
645
        DIFDOWN = 30;
646
        DIFL = 40;
647
        DIFR = 40;
648
        DIFUP = 30;
649

    
650
        if (isAboveName()) {
651
            numUp++;
652
        } else {
653
            numDown++;
654
        }
655

    
656
        if (isAboveIntervals()) {
657
            numUp++;
658
        } else {
659
            numDown++;
660
        }
661

    
662
        if (isAboveDescription()) {
663
            numUp++;
664
        } else {
665
            numDown++;
666
        }
667

    
668
        if (numDown == 1) {
669
            DIFDOWN = 3;
670
        } else if (numDown == 2) {
671
            DIFDOWN = 2;
672
        } else if (numDown == 3) {
673
            DIFDOWN = 1.2;
674
        }
675

    
676
        if (numUp == 1) {
677
            DIFUP = 3;
678
        } else if (numUp == 2) {
679
            DIFUP = 2;
680
        } else if (numUp == 3) {
681
            DIFUP = 1.2;
682
        }
683
    }
684

    
685
    /**
686
     * Dibuja sobre el Graphics el nombre de la unidad de medida de la escala.
687
     *
688
     * @param g Graphics sobre el que se dibuja.
689
     * @param rec Rect?ngulo que ocupa la escala gr?fica.
690
     * @param at Matriz de transformaci?n.
691
     */
692
    private void drawNameUnits(Graphics g, Rectangle2D.Double rec,
693
        AffineTransform at) {
694
        //        Nombre de las unidades utilizadas.
695
        Point2D.Double p = null;
696

    
697
        if (isShowNameUnits()) {
698
            if (isAboveName()) {
699
                p = new Point2D.Double(rec.getCenterX() -
700
                        ((rec.getHeight() * (m_nameUnit.length() / 6)) / 4),
701
                        (rec.getMinY() + (rec.getHeight() / (DIFUP))) -
702
                        (rec.getHeight() / 2));
703
            } else {
704
                p = new Point2D.Double(rec.getCenterX() -
705
                        ((rec.getHeight() * (m_nameUnit.length() / 6)) / 4),
706
                        (rec.getHeight() / 1.4) +
707
                        (rec.getMaxY() - (rec.getHeight() / (DIFDOWN))));
708
            }
709

    
710
            p = FLayoutUtilities.fromSheetPoint(p, at);
711
            g.setColor(textcolor);
712
            g.drawString(m_nameUnit, (int) p.x, (int) p.y);
713
        }
714
    }
715

    
716
    /**
717
     * Dibuja sobre el Graphics la descripci?n que por defecto sera la escala.
718
     *
719
     * @param g Graphics sobre el que se dibuja.
720
     * @param rec Rect?ngulo que ocupa la escala gr?fica.
721
     * @param at Matriz de transformaci?n.
722
     */
723
    private void drawDescription(Graphics g, Rectangle2D.Double rec,
724
        AffineTransform at) {
725
        Point2D.Double p = null;
726

    
727
        if (isShowDescription()) {
728
            if (isAboveDescription()) {
729
                p = new Point2D.Double(rec.getCenterX() -
730
                        ((rec.getHeight() * (getDescripcion().length() / 6)) / 4),
731
                        (rec.getMinY() + (rec.getHeight() / (DIFUP))) -
732
                        (rec.getHeight() / 5));
733
            } else {
734
                p = new Point2D.Double(rec.getCenterX() -
735
                        ((rec.getHeight() * (getDescripcion().length() / 6)) / 4),
736
                        (rec.getHeight() / 2) +
737
                        (rec.getMaxY() - (rec.getHeight() / (DIFDOWN))));
738
            }
739

    
740
            p = FLayoutUtilities.fromSheetPoint(p, at);
741
            g.setColor(textcolor);
742
            g.drawString(getDescripcion(), (int) p.x, (int) p.y);
743
        }
744
    }
745

    
746
    /**
747
     * Rellena la fuente utilizada para dibujar los intervalos y la unidad de
748
     * medida utilizada.
749
     *
750
     * @param f fuente a utilizar.
751
     */
752
    public void setFont(Font f) {
753
        m_f = f;
754
    }
755

    
756
    /**
757
     * Devuelve la fuente con la que se est? dibujando sobre el graphics.
758
     *
759
     * @return fuente utilizada.
760
     */
761
    public Font getFont() {
762
        return new Font(m_f.getFontName(), m_f.getStyle(), 9);
763
    }
764

    
765
    /**
766
     * Devuelve si el intervalo es variable o si por el contrario es fijo.
767
     *
768
     * @return true si el intervalo es fijo.
769
     */
770
    public boolean isbIntervalSet() {
771
        return m_bIntervalSet;
772
    }
773

    
774
    /**
775
     * Especificar si el intervalo se debe mantener o es variable.
776
     *
777
     * @param b si se quiere mantener el intervalo especificado.
778
     */
779
    public void setbIntervalSet(boolean b) {
780
        m_bIntervalSet = b;
781
    }
782

    
783
    /**
784
     * Devuelve el porcentaje por el cual hay que multiplicar  el intervalo
785
     * para conseguir un intervalo redondeado,  de momento con una cifra
786
     * significativas(NUM=1).
787
     *
788
     * @param total intervalo.
789
     *
790
     * @return Porcentaje
791
     */
792
    private double getExact(double total) {
793
        int NUM = 1;
794
        double t = 0;
795
        double dif = 1;
796
        Double d = new Double(total);
797
        Long l = new Long(d.longValue());
798
        int num = l.toString().length();
799
        t = ((long) (total / Math.pow(10, num - NUM)) * Math.pow(10, num - NUM));
800
        dif = t / total;
801

    
802
        return dif;
803
    }
804

    
805
    /**
806
     * Rellena un rect?ngulo.
807
     *
808
     * @param g Graphics sobre el que dibujar.
809
     * @param r Rect?ngulo a rellenar.
810
     */
811
    private void fillRect(Graphics2D g, Rectangle2D.Double r) {
812
        g.fillRect((int) r.x, (int) r.y, (int) r.width, (int) r.height);
813
    }
814

    
815
    /**
816
     * Escribe sobre el Graphics y en la posici?n indicada el tama?o del
817
     * intervalo.
818
     *
819
     * @param g Graphics sobre el que dibujar.
820
     * @param inter Valor del intervalo.
821
     * @param p Punto donde dibujarlo.
822
     */
823
    private void drawInterval(Graphics2D g, long inter, Point2D.Double p) {
824
        Long l = new Long(inter);
825
        g.setColor(textcolor);
826
        g.drawString(l.toString(), (int) p.x, (int) p.y);
827
        g.setColor(barcolor);
828
    }
829

    
830
    /**
831
     * @throws SaveException 
832
     * @see com.iver.cit.gvsig.gui.layout.fframes.IFFrame#getXMLEntity()
833
     */
834
    public XMLEntity getXMLEntity() throws SaveException {
835
        XMLEntity xml = new XMLEntity();
836
        try{
837
        xml.putProperty("className", this.getClass().getName());
838
        xml.putProperty("m_name", m_name);
839
        xml.putProperty("x", getBoundBox().x);
840
        xml.putProperty("y", getBoundBox().y);
841
        xml.putProperty("w", getBoundBox().width);
842
        xml.putProperty("h", getBoundBox().height);
843
        xml.putProperty("m_Selected", m_Selected);
844
        xml.putProperty("type", Layout.RECTANGLESCALEBAR);
845
        xml.putProperty("m_bIntervalSet", m_bIntervalSet);
846
        xml.putProperty("m_dif", m_dif);
847
        xml.putProperty("m_hasleft", m_hasleft);
848
        xml.putProperty("m_nameUnit", m_nameUnit);
849
        xml.putProperty("m_numUnit", m_numUnit);
850

    
851
        xml.putProperty("m_height", m_height);
852

    
853
        xml.putProperty("m_style", m_style);
854
        xml.putProperty("m_units", m_units);
855
        xml.putProperty("m_interval", m_interval);
856
        xml.putProperty("m_numinterval", m_numinterval);
857
        xml.putProperty("m_numleft", m_numleft);
858
        xml.putProperty("m_mapUnits", m_mapUnits);
859
        xml.putProperty("fontName", m_f.getFontName());
860
        xml.putProperty("fontStyle", m_f.getStyle());
861
        xml.putProperty("tag", getTag());
862
        xml.putProperty("m_rotation", getRotation());
863

    
864
        Layout layout = fframeview.getLayout();
865
        IFFrame[] fframes = layout.getAllFFrames();
866

    
867
        for (int i = 0; i < fframes.length; i++) {
868
            if ((fframeview != null) &&
869
                    fframeview.getName().equals(fframes[i].getName())) {
870
                xml.putProperty("index", i);
871
            }
872
        }
873

    
874
        xml.putProperty("barcolor", StringUtilities.color2String(barcolor));
875
        xml.putProperty("textcolor", StringUtilities.color2String(textcolor));
876
        xml.putProperty("showNameUnits", showNameUnits);
877
        xml.putProperty("showDescription", showDescription);
878
        xml.putProperty("aboveName", aboveName);
879
        xml.putProperty("aboveIntervals", aboveIntervals);
880
        xml.putProperty("aboveDescription", aboveDescription);
881
        xml.putProperty("description", description);
882
        }catch (Exception e) {
883
                        throw new SaveException(e,this.getClass().getName());
884
                }
885
        return xml;
886
    }
887

    
888
    /**
889
     * @see com.iver.cit.gvsig.gui.layout.fframes.IFFrame#setXMLEntity(com.iver.utiles.XMLEntity,
890
     *      com.iver.cit.gvsig.project.Project)
891
     */
892
    public void setXMLEntity03(XMLEntity xml, Layout l) {
893
        if (xml.getIntProperty("m_Selected") != 0) {
894
            this.setSelected(true);
895
        } else {
896
            this.setSelected(false);
897
        }
898

    
899
        this.m_bIntervalSet = xml.getBooleanProperty("m_bIntervalSet");
900
        this.m_dif = xml.getDoubleProperty("m_dif");
901
        this.m_hasleft = xml.getIntProperty("m_hasleft");
902
        this.m_nameUnit = xml.getStringProperty("m_nameUnit");
903
        this.m_numUnit = xml.getDoubleProperty("m_numUnit");
904

    
905
        this.m_height = xml.getDoubleProperty("m_height");
906

    
907
        this.m_style = xml.getIntProperty("m_style");
908
        this.m_interval = xml.getLongProperty("m_interval");
909
        this.m_numinterval = xml.getIntProperty("m_numinterval");
910
        this.m_numleft = xml.getIntProperty("m_numleft");
911
        this.m_mapUnits = xml.getIntProperty("m_mapUnits");
912
        this.m_f = new Font(xml.getStringProperty("fontName"),
913
                xml.getIntProperty("fontStyle"), 9);
914

    
915
        ArrayList fframes = l.getFFrames();
916
        fframeview = (FFrameView) fframes.get(xml.getIntProperty("index"));
917

    
918
        if (xml.contains("description")) { //Comprobar que es de la versi?n que cambia el di?logo.
919
            this.barcolor = StringUtilities.string2Color(xml.getStringProperty(
920
                        "barcolor"));
921
            this.textcolor = StringUtilities.string2Color(xml.getStringProperty(
922
                        "textcolor"));
923
            this.showNameUnits = xml.getBooleanProperty("showNameUnits");
924
            this.showDescription = xml.getBooleanProperty("showDescription");
925
            this.aboveName = xml.getBooleanProperty("aboveName");
926
            this.aboveIntervals = xml.getBooleanProperty("aboveIntervals");
927
            this.aboveDescription = xml.getBooleanProperty("aboveDescription");
928
            this.description = xml.getStringProperty("description");
929
        }
930
    }
931

    
932
    /**
933
     * @see com.iver.cit.gvsig.gui.layout.fframes.IFFrame#setXMLEntity(com.iver.utiles.XMLEntity,
934
     *      com.iver.cit.gvsig.project.Project)
935
     */
936
    public void setXMLEntity(XMLEntity xml) {
937
        if (xml.getIntProperty("m_Selected") != 0) {
938
            this.setSelected(true);
939
        } else {
940
            this.setSelected(false);
941
        }
942

    
943
        this.m_bIntervalSet = xml.getBooleanProperty("m_bIntervalSet");
944
        this.m_dif = xml.getDoubleProperty("m_dif");
945
        this.m_hasleft = xml.getIntProperty("m_hasleft");
946
        this.m_nameUnit = xml.getStringProperty("m_nameUnit");
947
        this.m_numUnit = xml.getDoubleProperty("m_numUnit");
948

    
949
        this.m_height = xml.getDoubleProperty("m_height");
950

    
951
        this.m_style = xml.getIntProperty("m_style");
952
        this.m_interval = xml.getLongProperty("m_interval");
953
        this.m_numinterval = xml.getIntProperty("m_numinterval");
954
        this.m_numleft = xml.getIntProperty("m_numleft");
955
        this.m_mapUnits = xml.getIntProperty("m_mapUnits");
956
        this.m_f = new Font(xml.getStringProperty("fontName"),
957
                xml.getIntProperty("fontStyle"), 9);
958
        setRotation(xml.getDoubleProperty("m_rotation"));
959

    
960
        if (xml.contains("index")) {
961
            dependenceIndex = xml.getIntProperty("index");
962
        }
963

    
964
        if (xml.contains("description")) { //Comprobar que es de la versi?n que cambia el di?logo.
965
            this.barcolor = StringUtilities.string2Color(xml.getStringProperty(
966
                        "barcolor"));
967
            this.textcolor = StringUtilities.string2Color(xml.getStringProperty(
968
                        "textcolor"));
969
            this.showNameUnits = xml.getBooleanProperty("showNameUnits");
970
            this.showDescription = xml.getBooleanProperty("showDescription");
971
            this.aboveName = xml.getBooleanProperty("aboveName");
972
            this.aboveIntervals = xml.getBooleanProperty("aboveIntervals");
973
            this.aboveDescription = xml.getBooleanProperty("aboveDescription");
974
            this.description = xml.getStringProperty("description");
975
        }
976
    }
977

    
978
    /**
979
     * @see com.iver.cit.gvsig.gui.layout.fframes.IFFrame#getNameFFrame()
980
     */
981
    public String getNameFFrame() {
982
        return PluginServices.getText(this, "escala") + num;
983
    }
984

    
985
    /**
986
     * Inserta el color de la escala gr?fica.
987
     *
988
     * @param color Color de la escala gr?fica.
989
     */
990
    public void setBarColor(Color color) {
991
        barcolor = color;
992
    }
993

    
994
    /**
995
     * Inserta el color del texto.
996
     *
997
     * @param color Color del texto.
998
     */
999
    public void setTextColor(Color color) {
1000
        textcolor = color;
1001
    }
1002

    
1003
    /**
1004
     * Devuelve el color de la escala gr?fica.
1005
     *
1006
     * @return Color de la escala gr?fica.
1007
     */
1008
    public Color getBarColor() {
1009
        return barcolor;
1010
    }
1011

    
1012
    /**
1013
     * Devuelve el color del texto.
1014
     *
1015
     * @return Color del texto.
1016
     */
1017
    public Color getTextColor() {
1018
        return textcolor;
1019
    }
1020

    
1021
    /**
1022
     * Devuelve true si se debe mostrar el nombre de las unidades de medida de
1023
     * la escala gr?fica.
1024
     *
1025
     * @return True si se muestra las unidades de medida.
1026
     */
1027
    public boolean isShowNameUnits() {
1028
        return showNameUnits;
1029
    }
1030

    
1031
    /**
1032
     * Inserta si se debe de mostrar el nombre de las unidades de medida o no.
1033
     *
1034
     * @param showNameUnits True si se muestra el nombre de las unidades de
1035
     *        medida.
1036
     */
1037
    public void setShowNameUnits(boolean showNameUnits) {
1038
        this.showNameUnits = showNameUnits;
1039
    }
1040

    
1041
    /**
1042
     * Devuelve true si se muestra la descripci?n a la parte de arriba de la
1043
     * escala gr?fica.
1044
     *
1045
     * @return True si se muestra arriba de la escala gr?fica.
1046
     */
1047
    public boolean isAboveDescription() {
1048
        return aboveDescription;
1049
    }
1050

    
1051
    /**
1052
     * Introduce true si se muestra arriba de la escala gr?fica la descripci?n.
1053
     *
1054
     * @param aboveDescription True si se muestra arriba la descripci?n.
1055
     */
1056
    public void setAboveDescription(boolean aboveDescription) {
1057
        this.aboveDescription = aboveDescription;
1058
    }
1059

    
1060
    /**
1061
     * Devuelve true si se muestran a la parte de arriba los valores de los
1062
     * intervalos.
1063
     *
1064
     * @return True si se muestran arriba de la escala gr?fica.
1065
     */
1066
    public boolean isAboveIntervals() {
1067
        return aboveIntervals;
1068
    }
1069

    
1070
    /**
1071
     * Inserta si se muestran los valores de los intervalos a la parte de
1072
     * arriba de la escala o debajo.
1073
     *
1074
     * @param aboveIntervals True si se muestran los valores de los intervalos
1075
     *        a la parte de arriba de la escala gr?fica.
1076
     */
1077
    public void setAboveIntervals(boolean aboveIntervals) {
1078
        this.aboveIntervals = aboveIntervals;
1079
    }
1080

    
1081
    /**
1082
     * Devuelve si se muestra a la parte de arriba de la escala gr?fica el
1083
     * nombre de las unidades de medida o debajo.
1084
     *
1085
     * @return True si se muestra a la parte de arriba de la escala gr?fica.
1086
     */
1087
    public boolean isAboveName() {
1088
        return aboveName;
1089
    }
1090

    
1091
    /**
1092
     * Inserta si el nombre se muestra a la parte de arriba de la escala
1093
     * gr?fica o a la parte de abajo.
1094
     *
1095
     * @param aboveName True si se muestra a la parte de arriba de la escala
1096
     *        gr?fica.
1097
     */
1098
    public void setAboveName(boolean aboveName) {
1099
        this.aboveName = aboveName;
1100
    }
1101

    
1102
    /**
1103
     * Devuelve si se debe mostrar la descripci?n o no.
1104
     *
1105
     * @return True si se muestra la descripci?n.
1106
     */
1107
    public boolean isShowDescription() {
1108
        return showDescription;
1109
    }
1110

    
1111
    /**
1112
     * Inserta si se muestra o no la descripci?n.
1113
     *
1114
     * @param showDescription True si se muestra la descripci?n.
1115
     */
1116
    public void setShowDescription(boolean showDescription) {
1117
        this.showDescription = showDescription;
1118
    }
1119

    
1120
    /**
1121
     * Devuelve la descripci?n de la escala.
1122
     *
1123
     * @return Descripci?n de la escala.
1124
     */
1125
    public String getDescripcion() {
1126
        return description;
1127
    }
1128

    
1129
    /**
1130
     * Inserta la descripci?n de la escala.
1131
     *
1132
     * @param descripcion Descripci?n de la escala.
1133
     */
1134
    public void setDescripcion(String descripcion) {
1135
        this.description = descripcion;
1136
    }
1137

    
1138
    /**
1139
     * @see com.iver.cit.gvsig.gui.layout.fframes.IFFrame#print(java.awt.Graphics2D,
1140
     *      java.awt.geom.AffineTransform)
1141
     */
1142
    public void print(Graphics2D g, AffineTransform at)
1143
        throws DriverException {
1144
        draw(g, at, null, null);
1145
    }
1146

    
1147
    /**
1148
     * Update the dependences that have this FFrame with the other FFrame.
1149
     *
1150
     * @param fframes Other FFrames.
1151
     */
1152
    public void initDependence(IFFrame[] fframes) {
1153
        fframeview = (FFrameView) fframes[dependenceIndex];
1154
    }
1155
}