Statistics
| Revision:

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

History | View | Annotate | Download (38.9 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.FontMetrics;
63
import java.awt.Graphics;
64
import java.awt.Graphics2D;
65
import java.awt.geom.AffineTransform;
66
import java.awt.geom.Point2D;
67
import java.awt.geom.Rectangle2D;
68
import java.awt.image.BufferedImage;
69

    
70
import java.text.NumberFormat;
71

    
72

    
73

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

    
115
    /**
116
     * Creates a new FFrameScaleBar object.
117
     */
118
    public FFrameScaleBar() {
119
    }
120

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

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

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

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

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

    
169
    /**
170
     * Rellenar el tama?o de un intervalo.
171
     *
172
     * @param s tama?o de un intervalo.
173
     */
174
    public void setInterval(double s) {
175
        m_interval = s;
176

    
177
        if (m_numleft != 0) {
178
            m_hasleft = 1;
179
        }
180

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

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

    
199
            if (m_numleft != 0) {
200
                m_hasleft = 1;
201
            }
202

    
203
            double difL = (rect.width / DIFL);
204
            double difR = (rect.width / DIFR);
205
            double n = (rect.width - difL - difR);
206
            m_numUnit = n / (m_numinterval + m_hasleft);
207

    
208
            double scaleXunit = (m_numUnit * getScaleView()) / m_typeUnit;
209
            m_dif = getExact(scaleXunit);
210
            m_numUnit = m_numUnit * m_dif;
211
            m_interval = scaleXunit;
212

    
213
            ///m_interval = (scaleXunit * m_dif);
214
            return format(m_interval);
215
        }
216

    
217
        return "0";
218
    }
219

    
220
    /**
221
     * Rellenar el n?mero de intervalos.
222
     *
223
     * @param s n?mero de intervalos.
224
     */
225
    public void setNumInterval(int s) {
226
        m_numinterval = s;
227

    
228
        if (m_numleft != 0) {
229
            m_hasleft = 1;
230
        }
231

    
232
        Rectangle2D.Double rect = getBoundBox();
233
        double difL = (rect.width / DIFL);
234
        double difR = (rect.width / DIFR);
235
        double n = (rect.width - difL - difR);
236
        m_numUnit = n / (m_numinterval + m_hasleft);
237

    
238
        double scaleXunit = (m_numUnit * getScaleView()) / m_typeUnit;
239
        m_dif = getExact(scaleXunit);
240
        m_numUnit = m_numUnit * m_dif;
241
        m_interval = (scaleXunit * m_dif);
242
    }
243

    
244
    /**
245
     * Devuelve el n?mero de intervalos por encima del cero.
246
     *
247
     * @return entero.
248
     */
249
    public int getNumInterval() {
250
        return m_numinterval;
251
    }
252

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

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

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

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

    
293
    /**
294
     * Devuelve un entero que representa el tipo de unidades que representamos.
295
     *
296
     * @return entero.
297
     */
298
    public int getUnits() {
299
        return m_units;
300
    }
301

    
302
    /**
303
     * Devuelve el long que representa el intervalo.
304
     *
305
     * @return Intervalo.
306
     */
307
    public String getInterval() {
308
        return format(m_interval);
309
    }
310

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

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

    
329
    /**
330
     * Devuelve la escala de la vista seleccionada.
331
     *
332
     * @return la escala de la vista.
333
     */
334
    private long getScaleView() {
335
        if (fframeview == null) {
336
            return 1;
337
        }
338

    
339
        return fframeview.getScale();
340
    }
341

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

    
358
        if (intersects(rv, r)) {
359
            if ((fframeview == null) || (fframeview.getFMap() == null)) {
360
                drawEmpty(g);
361
            } else {
362
                switch (m_style) {
363
                    case (NUMERO):
364

    
365
                        double scalex = r.getWidth() / (8);
366

    
367
                        if (scalex > (r.getHeight() / (8))) {
368
                            scalex = r.getHeight() / (2);
369
                        }
370

    
371
                        g.setColor(textcolor);
372

    
373
                        if (m_f != null) {
374
                            m_f = new Font(m_f.getFontName(), m_f.getStyle(),
375
                                    (int) (scalex));
376
                            g.setFont(m_f);
377
                        }
378

    
379
                        FontMetrics fm = g.getFontMetrics();
380
                        double d = r.getWidth();
381
                        String scale = " 1:" + getScaleView();
382

    
383
                        if (fm.stringWidth(String.valueOf(m_interval)) > (d * 0.8)) {
384
                            double dif = fm.stringWidth(String.valueOf(
385
                                        m_interval)) / (d * 0.8);
386
                            m_f = new Font(m_f.getName(), m_f.getStyle(),
387
                                    (int) (m_f.getSize() / dif));
388
                            g.setFont(m_f);
389
                        }
390

    
391
                        g.drawString(scale, (int) r.x,
392
                            (int) (r.y + (r.height / 2)));
393

    
394
                        break;
395

    
396
                    case (BARRA1):
397
                    case (BARRA2):
398
                    case (BARRA3):
399
                    case (BARRA4):
400
                        drawBar(m_style, g, at);
401

    
402
                        break;
403
                }
404
            }
405
        }
406

    
407
        g.rotate(Math.toRadians(-getRotation()), r.x + (r.width / 2),
408
            r.y + (r.height / 2));
409
    }
410

    
411
    /**
412
     * Rellena con el rect?ngulo que se pasa como par?metro el boundBox(en
413
     * cent?metros) del fframe del cual con una transformaci?n se podr?
414
     * calcular el BoundingBox (en pixels).
415
     *
416
     * @param r Rect?ngulo en cent?metros.
417
     */
418
    public void setBoundBox(Rectangle2D.Double r) {
419
        if ((m_numUnit < 1) || (fframeview == null) ||
420
                (fframeview.getFMap() == null)) {
421
            super.setBoundBox(r);
422

    
423
            return;
424
        }
425

    
426
        double difL = (r.width / DIFL);
427
        double difR = (r.width / DIFR);
428

    
429
        if (m_bIntervalSet) {
430
            m_numinterval = (int) (((r.width - (difL + difR)) * m_dif) / m_numUnit) -
431
                m_hasleft;
432
        }
433

    
434
        if (m_numinterval < 1) {
435
            m_numinterval = 1;
436
            r.width = ((m_numinterval + m_hasleft) * m_numUnit) + difL + difR;
437
        }
438

    
439
        getBoundBox().setRect(r.getX(), r.getY(), r.getWidth(), r.getHeight());
440
    }
441

    
442
    /**
443
     * Dibuja sobre el Graphics la escala gr?fica.
444
     *
445
     * @param type Tipo de barra.
446
     * @param g Graphics sobre el que dibujar.
447
     * @param at Matriz de transformaci?n.
448
     */
449
    private void drawBar(int type, Graphics2D g, AffineTransform at) {
450
        Rectangle2D.Double rect = getBoundBox();
451
        Rectangle2D.Double r = getBoundingBox(at);
452
        double numleft = m_numleft;
453
        initDistances();
454

    
455
        double difDown = (rect.height / DIFDOWN);
456
        double difUp = (rect.height / DIFUP);
457
        double difL = (rect.width / DIFL);
458
        double difR = (rect.width / DIFR);
459
        double n = (rect.width - difL - difR);
460

    
461
        //setDescripcion("escala 1:" + String.valueOf(fframeview.getScale()));
462
        g.setStroke(new BasicStroke(0));
463

    
464
        if (!m_bIntervalSet) {
465
            m_numUnit = n / (m_numinterval + m_hasleft);
466

    
467
            double scaleXunit = (m_numUnit * getScaleView()) / m_typeUnit;
468
            m_dif = getExact(scaleXunit);
469
            m_numUnit = m_numUnit * m_dif;
470
            m_interval = (scaleXunit * m_dif);
471
        }
472

    
473
        if (m_bIntervalSet) {
474
            m_numUnit = (m_interval * m_typeUnit) / (m_dif * getScaleView());
475
            m_numinterval = (int) (((rect.width - (difL + difR)) * m_dif) / m_numUnit) -
476
                m_hasleft;
477
        }
478

    
479
        if (m_numinterval < 1) {
480
            m_numinterval = 1;
481
            rect.width = ((m_numinterval + m_hasleft) * m_numUnit) + difL +
482
                difR;
483
        }
484

    
485
        double h = 0;
486

    
487
        if (type == BARRA1) {
488
            h = (rect.height - (difUp + difDown));
489
        } else if ((type == BARRA2) || (type == BARRA3)) {
490
            h = (rect.height - (difUp + difDown)) / 2;
491
        }
492

    
493
        //Dibujar el rect?ngulo que bordea todo.
494
        Rectangle2D.Double rectotal = (FLayoutUtilities.fromSheetRect(new Rectangle2D.Double((rect.x +
495
                    difL), (rect.y + difUp),
496
                    m_numUnit * (m_hasleft + m_numinterval), h), at));
497
        g.setColor(Color.white);
498
        g.fillRect((int) rectotal.x, (int) rectotal.y, (int) (rectotal.width),
499
            (int) rectotal.height);
500
        g.setColor(barcolor);
501

    
502
        if (m_f != null) {
503
            m_f = new Font(m_f.getFontName(), m_f.getStyle(),
504
                    (int) (r.getHeight() / 4));
505
        } else {
506
            m_f = new Font("SansSerif", Font.PLAIN, (int) (r.getHeight() / 4));
507
        }
508

    
509
        g.setFont(m_f);
510

    
511
        FontMetrics fm = g.getFontMetrics();
512
        String formatInterval = format(m_interval);
513
        double d = (rectotal.getWidth() / m_numinterval) + m_hasleft;
514
        double difpos = ((r.getHeight() / 4) * formatInterval.length()) / 4;
515

    
516
        if (fm.stringWidth(formatInterval) > (d * 0.7)) {
517
            double dif = fm.stringWidth(formatInterval) / (d * 0.7);
518
            difpos = (d * 0.7) / 2;
519
            m_f = new Font(m_f.getName(), m_f.getStyle(),
520
                    (int) (m_f.getSize() / dif));
521
            g.setFont(m_f);
522
        }
523

    
524
        //Derecha del cero
525
        for (int i = 0; i < m_numinterval; i++) {
526
            Rectangle2D.Double recder = FLayoutUtilities.fromSheetRect(new Rectangle2D.Double((rect.x +
527
                        (difL) + ((m_numUnit * i) + (m_hasleft * m_numUnit))),
528
                        (rect.y + (difUp)), (m_numUnit),
529
                        (rect.height - (difUp + difDown)) / 2), at);
530
            Rectangle2D.Double recderB = FLayoutUtilities.fromSheetRect(new Rectangle2D.Double((rect.x +
531
                        (difL) + ((m_numUnit * i) + (m_hasleft * m_numUnit))),
532
                        (rect.y + difUp) +
533
                        ((rect.height - (difUp + difDown)) / 2), (m_numUnit),
534
                        ((rect.height - (difUp + difDown)) / 2)), at);
535

    
536
            //                        Correcci?n cuando la altura en pixels del rect?ngulo es impar.
537
            rectotal.y = recder.y;
538
            recderB.height = rectotal.height - recder.height + 0.5;
539

    
540
            /**
541
             * if (i == (m_numinterval - 1)) { if (recder.getMaxX() !=
542
             * rectotal.getMaxX()) { recder.width = (recder.width +
543
             * recder.getMaxX()) - rectotal.getMaxX(); } if (recderB.getMaxX()
544
             * != rectotal.getMaxX()) { recderB.width = (recderB.width +
545
             * recderB.getMaxX()) - rectotal.getMaxX(); }} if
546
             * (recderB.getMaxY() != rectotal.getMaxY()) { recderB.height =
547
             * (recderB.height + recderB.getMaxY()) - rectotal.getMaxY(); }
548
             */
549
            if ((m_numleft % 2) == 0) {
550
                if ((i % 2) == 0) {
551
                    if ((type == BARRA1) || (type == BARRA2)) {
552
                        fillRect(g, recder);
553
                    } else if (type == BARRA3) {
554
                        g.drawRect((int) recder.x, (int) recder.y,
555
                            (int) recder.width, (int) recder.height);
556
                    }
557
                } else if (type == BARRA1) {
558
                    fillRect(g, recderB);
559
                }
560
            } else {
561
                if ((i % 2) != 0) {
562
                    if ((type == BARRA1) || (type == BARRA2)) {
563
                        fillRect(g, recder);
564
                    } else if (type == BARRA3) {
565
                        g.drawRect((int) recderB.x, (int) recderB.y,
566
                            (int) recderB.width, (int) recderB.height);
567
                    }
568
                } else if (type == BARRA1) {
569
                    fillRect(g, recderB);
570
                }
571
            }
572

    
573
            String interString = format(m_interval * i);
574
            Point2D.Double p = null;
575

    
576
            if (isAboveIntervals()) {
577
                p = new Point2D.Double(recder.x - difpos,
578
                        r.getMinY() + (r.getHeight() / DIFUP));
579
            } else {
580
                p = new Point2D.Double(recder.x - difpos,
581
                        ((r.getHeight() / 4) + r.getMaxY()) -
582
                        (r.getHeight() / DIFDOWN));
583
            }
584

    
585
            //Para dibujar el 0 centrado en su sitio.
586
            if (i == 0) {
587
                double dif0 = recder.x - (fm.stringWidth(interString) / 2);
588
                p = new Point2D.Double(dif0, p.getY());
589
            }
590

    
591
            drawInterval(g, interString, p);
592
        }
593

    
594
        //?ltimo n?mero a dibujar.
595
        String interString = format(m_interval * m_numinterval);
596

    
597
        Point2D.Double p = null;
598

    
599
        if (isAboveIntervals()) {
600
            p = new Point2D.Double(rectotal.getMaxX() - difpos,
601
                    r.getMinY() + (r.getHeight() / DIFUP));
602
        } else {
603
            p = new Point2D.Double(rectotal.getMaxX() - difpos,
604
                    ((r.getHeight() / 4) + r.getMaxY()) -
605
                    (r.getHeight() / DIFDOWN));
606
        }
607

    
608
        drawInterval(g, interString, p);
609

    
610
        //Izquierda del cero
611
        for (int i = 0; i < m_numleft; i++) {
612
            Rectangle2D.Double reciz = FLayoutUtilities.fromSheetRect(new Rectangle2D.Double((rect.x +
613
                        difL + ((m_numUnit / m_numleft) * i)),
614
                        (rect.y + difUp), (m_numUnit / numleft),
615
                        (rect.height - (difUp + difDown)) / 2), at);
616
            Rectangle2D.Double recizB = FLayoutUtilities.fromSheetRect(new Rectangle2D.Double((rect.x +
617
                        difL + ((m_numUnit / m_numleft) * i)),
618
                        (rect.y + difUp) +
619
                        ((rect.height - (difUp + difDown)) / 2),
620
                        (m_numUnit / numleft),
621
                        ((rect.height - (difUp + difDown)) / 2)), at);
622

    
623
            //Correcci?n cuando la altura en pixels del rectangulo es impar.
624
            reciz.y = rectotal.y;
625
            recizB.height = rectotal.height - reciz.height + 0.5;
626

    
627
            if ((i % 2) == 0) {
628
                if ((type == BARRA1) || (type == BARRA2)) {
629
                    fillRect(g, reciz);
630
                } else if (type == BARRA3) {
631
                    g.drawRect((int) reciz.x, (int) reciz.y, (int) reciz.width,
632
                        (int) reciz.height);
633
                }
634
            } else if (type == BARRA1) {
635
                fillRect(g, recizB);
636
            }
637
        }
638

    
639
        if (m_numleft > 0) {
640
            interString = format(m_interval);
641

    
642
            if (isAboveIntervals()) {
643
                p = new Point2D.Double(rectotal.x - difpos,
644
                        r.getMinY() + (r.getHeight() / DIFUP));
645
            } else {
646
                p = new Point2D.Double(rectotal.x - difpos,
647
                        ((r.getHeight() / 4) + r.getMaxY()) -
648
                        (r.getHeight() / DIFDOWN));
649
            }
650

    
651
            drawInterval(g, interString, p);
652
        }
653

    
654
        //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.
655
        if (m_numleft == 0) {
656
            Rectangle2D.Double recAux = FLayoutUtilities.fromSheetRect(new Rectangle2D.Double((rect.x +
657
                        difL + ((m_numUnit / 1) * 0)), (rect.y + difUp),
658
                        (m_numUnit / 1), (rect.height - (difUp + difDown)) / 2),
659
                    at);
660
            rectotal.x = rectotal.x + recAux.width;
661
            rectotal.width = rectotal.width - recAux.width;
662
        }
663

    
664
        //Se dibuja el rect?ngulo que bordea toda la escala gr?fica.
665
        g.drawRect((int) rectotal.x, (int) rectotal.y, (int) (rectotal.width),
666
            (int) rectotal.height);
667

    
668
        drawNameUnits(g, r);
669
        drawDescription(g, r);
670
    }
671

    
672
    /**
673
     * Inicializa las distancias de la barra de escala.
674
     */
675
    private void initDistances() {
676
        int numUp = 0;
677
        int numDown = 0;
678

    
679
        DIFDOWN = 30;
680
        DIFL = 40;
681
        DIFR = 40;
682
        DIFUP = 30;
683

    
684
        if (isAboveName()) {
685
            numUp++;
686
        } else {
687
            numDown++;
688
        }
689

    
690
        if (isAboveIntervals()) {
691
            numUp++;
692
        } else {
693
            numDown++;
694
        }
695

    
696
        if (isAboveDescription()) {
697
            numUp++;
698
        } else {
699
            numDown++;
700
        }
701

    
702
        if (numDown == 1) {
703
            DIFDOWN = 3;
704
        } else if (numDown == 2) {
705
            DIFDOWN = 2;
706
        } else if (numDown == 3) {
707
            DIFDOWN = 1.2;
708
        }
709

    
710
        if (numUp == 1) {
711
            DIFUP = 3;
712
        } else if (numUp == 2) {
713
            DIFUP = 2;
714
        } else if (numUp == 3) {
715
            DIFUP = 1.2;
716
        }
717
    }
718

    
719
    /**
720
     * Dibuja sobre el Graphics el nombre de la unidad de medida de la escala.
721
     *
722
     * @param g Graphics sobre el que se dibuja.
723
     * @param rec Rect?ngulo que ocupa la escala gr?fica.
724
     */
725
    private void drawNameUnits(Graphics g, Rectangle2D.Double rec) {
726
        //        Nombre de las unidades utilizadas.
727
        Point2D.Double p = null;
728
        FontMetrics fm = g.getFontMetrics();
729

    
730
        if (isShowNameUnits()) {
731
            if (isAboveName()) {
732
                p = new Point2D.Double(rec.getCenterX() -
733
                        (fm.stringWidth(m_nameUnit) / 2),
734
                        (rec.getMinY() + (rec.getHeight() / 3) +
735
                        (fm.getHeight() / 2)));
736
            } else {
737
                p = new Point2D.Double(rec.getCenterX() -
738
                        (fm.stringWidth(m_nameUnit) / 2),
739
                        (rec.getMaxY() - (rec.getHeight() / 9) +
740
                        (fm.getHeight() / 2)));
741
            }
742

    
743
            g.setColor(textcolor);
744
            g.drawString(m_nameUnit, (int) p.x, (int) p.y);
745
        }
746
    }
747

    
748
    /**
749
     * Dibuja sobre el Graphics la descripci?n que por defecto sera la escala.
750
     *
751
     * @param g Graphics sobre el que se dibuja.
752
     * @param rec Rect?ngulo que ocupa la escala gr?fica.
753
     */
754
    private void drawDescription(Graphics g, Rectangle2D.Double rec) {
755
        Point2D.Double p = null;
756
        FontMetrics fm = g.getFontMetrics();
757

    
758
        if (isShowDescription()) {
759
            if (isAboveDescription()) {
760
                p = new Point2D.Double(rec.getCenterX() -
761
                        (fm.stringWidth(getDescripcion()) / 2),
762
                        (rec.getMinY() + (rec.getHeight() / 9) +
763
                        (fm.getHeight() / 2)));
764
            } else {
765
                p = new Point2D.Double(rec.getCenterX() -
766
                        (fm.stringWidth(getDescripcion()) / 2),
767
                        (rec.getMaxY() - (rec.getHeight() / 3) +
768
                        (fm.getHeight() / 2)));
769
            }
770

    
771
            g.setColor(textcolor);
772
            g.drawString(getDescripcion(), (int) p.x, (int) p.y);
773
        }
774
    }
775

    
776
    /**
777
     * Rellena la fuente utilizada para dibujar los intervalos y la unidad de
778
     * medida utilizada.
779
     *
780
     * @param f fuente a utilizar.
781
     */
782
    public void setFont(Font f) {
783
        m_f = f;
784
    }
785

    
786
    /**
787
     * Devuelve la fuente con la que se est? dibujando sobre el graphics.
788
     *
789
     * @return fuente utilizada.
790
     */
791
    public Font getFont() {
792
        return new Font(m_f.getFontName(), m_f.getStyle(), 9);
793
    }
794

    
795
    /**
796
     * Devuelve si el intervalo es variable o si por el contrario es fijo.
797
     *
798
     * @return true si el intervalo es fijo.
799
     */
800
    public boolean isbIntervalSet() {
801
        return m_bIntervalSet;
802
    }
803

    
804
    /**
805
     * Especificar si el intervalo se debe mantener o es variable.
806
     *
807
     * @param b si se quiere mantener el intervalo especificado.
808
     */
809
    public void setbIntervalSet(boolean b) {
810
        m_bIntervalSet = b;
811
    }
812

    
813
    /**
814
     * Devuelve el porcentaje por el cual hay que multiplicar  el intervalo
815
     * para conseguir un intervalo redondeado,  de momento con una cifra
816
     * significativas(NUM=1).
817
     *
818
     * @param total intervalo.
819
     *
820
     * @return Porcentaje
821
     */
822
    private double getExact(double total) {
823
        int NUM = 1;
824
        double t = 0;
825
        double dif = 1;
826
        Double d = new Double(total);
827
        Long l = new Long(d.longValue());
828
        int num = l.toString().length();
829
        t = ((long) (total / Math.pow(10, num - NUM)) * Math.pow(10, num - NUM));
830
        dif = t / total;
831

    
832
        if (dif == 0) {
833
            return 1;
834
        }
835

    
836
        return dif;
837
    }
838

    
839
    /**
840
     * Rellena un rect?ngulo.
841
     *
842
     * @param g Graphics sobre el que dibujar.
843
     * @param r Rect?ngulo a rellenar.
844
     */
845
    private void fillRect(Graphics2D g, Rectangle2D.Double r) {
846
        g.fillRect((int) r.x, (int) r.y, (int) r.width, (int) r.height);
847
    }
848

    
849
    /**
850
     * Escribe sobre el Graphics y en la posici?n indicada el tama?o del
851
     * intervalo.
852
     *
853
     * @param g Graphics sobre el que dibujar.
854
     * @param inter Valor del intervalo.
855
     * @param p Punto donde dibujarlo.
856
     */
857
    private void drawInterval(Graphics2D g, String inter, Point2D.Double p) {
858
        //Double l = new Double(inter);
859
        g.setColor(textcolor);
860
        g.drawString(inter, (int) p.x, (int) p.y);
861
        g.setColor(barcolor);
862
    }
863

    
864
    /**
865
     * DOCUMENT ME!
866
     *
867
     * @return DOCUMENT ME!
868
     *
869
     * @throws SaveException
870
     *
871
     * @see com.iver.cit.gvsig.gui.layout.fframes.IFFrame#getXMLEntity()
872
     */
873
    public XMLEntity getXMLEntity() throws SaveException {
874
        XMLEntity xml = super.getXMLEntity();
875

    
876
        try {
877
            xml.putProperty("type", Layout.RECTANGLESCALEBAR);
878
            xml.putProperty("m_bIntervalSet", m_bIntervalSet);
879
            xml.putProperty("m_dif", m_dif);
880
            xml.putProperty("m_hasleft", m_hasleft);
881
            xml.putProperty("m_nameUnit", m_nameUnit);
882
            xml.putProperty("m_numUnit", m_numUnit);
883

    
884
            xml.putProperty("m_height", m_height);
885

    
886
            xml.putProperty("m_style", m_style);
887
            xml.putProperty("m_units", m_units);
888
            xml.putProperty("m_interval", m_interval);
889
            xml.putProperty("m_numinterval", m_numinterval);
890
            xml.putProperty("m_numleft", m_numleft);
891
            xml.putProperty("m_mapUnits", m_mapUnits);
892
            xml.putProperty("fontName", m_f.getFontName());
893
            xml.putProperty("fontStyle", m_f.getStyle());
894
            xml.putProperty("numDec", numDec);
895
            xml.putProperty("m_units", m_units);
896

    
897
            if (fframeview != null) {
898
                Layout layout = fframeview.getLayout();
899
                IFFrame[] fframes = layout.getAllFFrames();
900

    
901
                for (int i = 0; i < fframes.length; i++) {
902
                    if (fframeview.getName().equals(fframes[i].getName())) {
903
                        xml.putProperty("index", i);
904
                    }
905
                }
906
            }
907

    
908
            xml.putProperty("barcolor", StringUtilities.color2String(barcolor));
909
            xml.putProperty("textcolor", StringUtilities.color2String(textcolor));
910
            xml.putProperty("showNameUnits", showNameUnits);
911
            xml.putProperty("showDescription", showDescription);
912
            xml.putProperty("aboveName", aboveName);
913
            xml.putProperty("aboveIntervals", aboveIntervals);
914
            xml.putProperty("aboveDescription", aboveDescription);
915
            xml.putProperty("description", description);
916
        } catch (Exception e) {
917
            throw new SaveException(e, this.getClass().getName());
918
        }
919

    
920
        return xml;
921
    }
922

    
923
    /**
924
     * @see com.iver.cit.gvsig.gui.layout.fframes.IFFrame#setXMLEntity(com.iver.utiles.XMLEntity,
925
     *      com.iver.cit.gvsig.project.Project)
926
     */
927
    public void setXMLEntity03(XMLEntity xml, Layout l) {
928
        if (xml.getIntProperty("m_Selected") != 0) {
929
            this.setSelected(true);
930
        } else {
931
            this.setSelected(false);
932
        }
933

    
934
        this.m_bIntervalSet = xml.getBooleanProperty("m_bIntervalSet");
935
        this.m_dif = xml.getDoubleProperty("m_dif");
936
        this.m_hasleft = xml.getIntProperty("m_hasleft");
937
        this.m_nameUnit = xml.getStringProperty("m_nameUnit");
938
        this.m_numUnit = xml.getDoubleProperty("m_numUnit");
939

    
940
        this.m_height = xml.getDoubleProperty("m_height");
941

    
942
        this.m_style = xml.getIntProperty("m_style");
943
        this.m_interval = xml.getLongProperty("m_interval");
944
        this.m_numinterval = xml.getIntProperty("m_numinterval");
945
        this.m_numleft = xml.getIntProperty("m_numleft");
946
        this.m_mapUnits = xml.getIntProperty("m_mapUnits");
947
        this.m_f = new Font(xml.getStringProperty("fontName"),
948
                xml.getIntProperty("fontStyle"), 9);
949

    
950
        fframeview = (FFrameView) l.getFFrame(xml.getIntProperty("index"));
951

    
952
        if (xml.contains("description")) { //Comprobar que es de la versi?n que cambia el di?logo.
953
            this.barcolor = StringUtilities.string2Color(xml.getStringProperty(
954
                        "barcolor"));
955
            this.textcolor = StringUtilities.string2Color(xml.getStringProperty(
956
                        "textcolor"));
957
            this.showNameUnits = xml.getBooleanProperty("showNameUnits");
958
            this.showDescription = xml.getBooleanProperty("showDescription");
959
            this.aboveName = xml.getBooleanProperty("aboveName");
960
            this.aboveIntervals = xml.getBooleanProperty("aboveIntervals");
961
            this.aboveDescription = xml.getBooleanProperty("aboveDescription");
962
            this.description = xml.getStringProperty("description");
963
        }
964
    }
965

    
966
    /**
967
     * @see com.iver.cit.gvsig.gui.layout.fframes.IFFrame#setXMLEntity(com.iver.utiles.XMLEntity,
968
     *      com.iver.cit.gvsig.project.Project)
969
     */
970
    public void setXMLEntity(XMLEntity xml) {
971
        if (xml.getIntProperty("m_Selected") != 0) {
972
            this.setSelected(true);
973
        } else {
974
            this.setSelected(false);
975
        }
976

    
977
        this.m_bIntervalSet = xml.getBooleanProperty("m_bIntervalSet");
978
        this.m_dif = xml.getDoubleProperty("m_dif");
979
        this.m_hasleft = xml.getIntProperty("m_hasleft");
980
        this.m_nameUnit = xml.getStringProperty("m_nameUnit");
981
        this.m_numUnit = xml.getDoubleProperty("m_numUnit");
982

    
983
        this.m_height = xml.getDoubleProperty("m_height");
984

    
985
        this.m_style = xml.getIntProperty("m_style");
986
        this.m_interval = xml.getDoubleProperty("m_interval");
987
        this.m_numinterval = xml.getIntProperty("m_numinterval");
988
        this.m_numleft = xml.getIntProperty("m_numleft");
989
        this.m_mapUnits = xml.getIntProperty("m_mapUnits");
990
        this.m_f = new Font(xml.getStringProperty("fontName"),
991
                xml.getIntProperty("fontStyle"), 9);
992
        setRotation(xml.getDoubleProperty("m_rotation"));
993

    
994
        if (xml.contains("m_units")) { //Comprobaci?n por versi?n 0.5
995
            setUnits(xml.getIntProperty("m_units"));
996
        }
997

    
998
        if (xml.contains("index")) {
999
            dependenceIndex = xml.getIntProperty("index");
1000
        }
1001

    
1002
        if (xml.contains("description")) { //Comprobar que es de la versi?n que cambia el di?logo.
1003
            this.barcolor = StringUtilities.string2Color(xml.getStringProperty(
1004
                        "barcolor"));
1005
            this.textcolor = StringUtilities.string2Color(xml.getStringProperty(
1006
                        "textcolor"));
1007
            this.showNameUnits = xml.getBooleanProperty("showNameUnits");
1008
            this.showDescription = xml.getBooleanProperty("showDescription");
1009
            this.aboveName = xml.getBooleanProperty("aboveName");
1010
            this.aboveIntervals = xml.getBooleanProperty("aboveIntervals");
1011
            this.aboveDescription = xml.getBooleanProperty("aboveDescription");
1012
            this.description = xml.getStringProperty("description");
1013
        }
1014

    
1015
        if (xml.contains("numDec")) {
1016
            setNumDec(xml.getIntProperty("numDec"));
1017
        }
1018
    }
1019

    
1020
    /**
1021
     * @see com.iver.cit.gvsig.gui.layout.fframes.IFFrame#getNameFFrame()
1022
     */
1023
    public String getNameFFrame() {
1024
        return PluginServices.getText(this, "escala") + num;
1025
    }
1026

    
1027
    /**
1028
     * Inserta el color de la escala gr?fica.
1029
     *
1030
     * @param color Color de la escala gr?fica.
1031
     */
1032
    public void setBarColor(Color color) {
1033
        barcolor = color;
1034
    }
1035

    
1036
    /**
1037
     * Inserta el color del texto.
1038
     *
1039
     * @param color Color del texto.
1040
     */
1041
    public void setTextColor(Color color) {
1042
        textcolor = color;
1043
    }
1044

    
1045
    /**
1046
     * Devuelve el color de la escala gr?fica.
1047
     *
1048
     * @return Color de la escala gr?fica.
1049
     */
1050
    public Color getBarColor() {
1051
        return barcolor;
1052
    }
1053

    
1054
    /**
1055
     * Devuelve el color del texto.
1056
     *
1057
     * @return Color del texto.
1058
     */
1059
    public Color getTextColor() {
1060
        return textcolor;
1061
    }
1062

    
1063
    /**
1064
     * Devuelve true si se debe mostrar el nombre de las unidades de medida de
1065
     * la escala gr?fica.
1066
     *
1067
     * @return True si se muestra las unidades de medida.
1068
     */
1069
    public boolean isShowNameUnits() {
1070
        return showNameUnits;
1071
    }
1072

    
1073
    /**
1074
     * Inserta si se debe de mostrar el nombre de las unidades de medida o no.
1075
     *
1076
     * @param showNameUnits True si se muestra el nombre de las unidades de
1077
     *        medida.
1078
     */
1079
    public void setShowNameUnits(boolean showNameUnits) {
1080
        this.showNameUnits = showNameUnits;
1081
    }
1082

    
1083
    /**
1084
     * Devuelve true si se muestra la descripci?n a la parte de arriba de la
1085
     * escala gr?fica.
1086
     *
1087
     * @return True si se muestra arriba de la escala gr?fica.
1088
     */
1089
    public boolean isAboveDescription() {
1090
        return aboveDescription;
1091
    }
1092

    
1093
    /**
1094
     * Introduce true si se muestra arriba de la escala gr?fica la descripci?n.
1095
     *
1096
     * @param aboveDescription True si se muestra arriba la descripci?n.
1097
     */
1098
    public void setAboveDescription(boolean aboveDescription) {
1099
        this.aboveDescription = aboveDescription;
1100
    }
1101

    
1102
    /**
1103
     * Devuelve true si se muestran a la parte de arriba los valores de los
1104
     * intervalos.
1105
     *
1106
     * @return True si se muestran arriba de la escala gr?fica.
1107
     */
1108
    public boolean isAboveIntervals() {
1109
        return aboveIntervals;
1110
    }
1111

    
1112
    /**
1113
     * Inserta si se muestran los valores de los intervalos a la parte de
1114
     * arriba de la escala o debajo.
1115
     *
1116
     * @param aboveIntervals True si se muestran los valores de los intervalos
1117
     *        a la parte de arriba de la escala gr?fica.
1118
     */
1119
    public void setAboveIntervals(boolean aboveIntervals) {
1120
        this.aboveIntervals = aboveIntervals;
1121
    }
1122

    
1123
    /**
1124
     * Devuelve si se muestra a la parte de arriba de la escala gr?fica el
1125
     * nombre de las unidades de medida o debajo.
1126
     *
1127
     * @return True si se muestra a la parte de arriba de la escala gr?fica.
1128
     */
1129
    public boolean isAboveName() {
1130
        return aboveName;
1131
    }
1132

    
1133
    /**
1134
     * Inserta si el nombre se muestra a la parte de arriba de la escala
1135
     * gr?fica o a la parte de abajo.
1136
     *
1137
     * @param aboveName True si se muestra a la parte de arriba de la escala
1138
     *        gr?fica.
1139
     */
1140
    public void setAboveName(boolean aboveName) {
1141
        this.aboveName = aboveName;
1142
    }
1143

    
1144
    /**
1145
     * Devuelve si se debe mostrar la descripci?n o no.
1146
     *
1147
     * @return True si se muestra la descripci?n.
1148
     */
1149
    public boolean isShowDescription() {
1150
        return showDescription;
1151
    }
1152

    
1153
    /**
1154
     * Inserta si se muestra o no la descripci?n.
1155
     *
1156
     * @param showDescription True si se muestra la descripci?n.
1157
     */
1158
    public void setShowDescription(boolean showDescription) {
1159
        this.showDescription = showDescription;
1160
    }
1161

    
1162
    /**
1163
     * Devuelve la descripci?n de la escala.
1164
     *
1165
     * @return Descripci?n de la escala.
1166
     */
1167
    public String getDescripcion() {
1168
        return description;
1169
    }
1170

    
1171
    /**
1172
     * Inserta la descripci?n de la escala.
1173
     *
1174
     * @param descripcion Descripci?n de la escala.
1175
     */
1176
    public void setDescripcion(String descripcion) {
1177
        this.description = descripcion;
1178
    }
1179

    
1180
    /**
1181
     * @see com.iver.cit.gvsig.gui.layout.fframes.IFFrame#print(java.awt.Graphics2D,
1182
     *      java.awt.geom.AffineTransform)
1183
     */
1184
    public void print(Graphics2D g, AffineTransform at)
1185
        throws DriverException {
1186
        draw(g, at, null, null);
1187
    }
1188

    
1189
    /**
1190
     * Update the dependences that have this FFrame with the other FFrame.
1191
     *
1192
     * @param fframes Other FFrames.
1193
     */
1194
    public void initDependence(IFFrame[] fframes) {
1195
        if ((dependenceIndex != -1) &&
1196
                fframes[dependenceIndex] instanceof FFrameView) {
1197
            fframeview = (FFrameView) fframes[dependenceIndex];
1198
        }
1199
    }
1200

    
1201
    /**
1202
     * DOCUMENT ME!
1203
     *
1204
     * @param d DOCUMENT ME!
1205
     *
1206
     * @return DOCUMENT ME!
1207
     */
1208
    public String format(double d) {
1209
        NumberFormat nf = NumberFormat.getInstance();
1210

    
1211
        if ((d % (long) d) != 0) {
1212
            nf.setMaximumFractionDigits(getNumDec());
1213
        } else {
1214
            nf.setMaximumFractionDigits(0);
1215
        }
1216

    
1217
        //String s = String.valueOf(nf.format(d));
1218
        //s=s.replace('.','*');
1219
        //s = s.replace(',', '.');
1220
        //s=s.replace('*',',');
1221
        return nf.format(d); //(Double.valueOf(s).doubleValue());
1222
    }
1223

    
1224
    /**
1225
     * DOCUMENT ME!
1226
     *
1227
     * @return DOCUMENT ME!
1228
     */
1229
    public int getNumDec() {
1230
        return numDec;
1231
    }
1232

    
1233
    /**
1234
     * DOCUMENT ME!
1235
     *
1236
     * @param numDec DOCUMENT ME!
1237
     */
1238
    public void setNumDec(int numDec) {
1239
        this.numDec = numDec;
1240
    }
1241
}