Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / extensions / org.gvsig.image.extension / src / main / java / org / gvsig / arcims / image / gui / panels / LayerScaleDrawPanel.java @ 32321

History | View | Annotate | Download (14 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

    
23
/*
24
 * AUTHORS (In addition to CIT):
25
 * 2010 Prodevelop S.L. main development
26
 * http://www.prodevelop.es
27
 */
28

    
29
package org.gvsig.arcims.image.gui.panels;
30

    
31
import java.awt.BasicStroke;
32
import java.awt.Color;
33
import java.awt.Font;
34
import java.awt.Graphics;
35
import java.awt.Graphics2D;
36
import java.awt.Stroke;
37
import java.awt.geom.AffineTransform;
38
import java.util.Vector;
39

    
40
import javax.swing.JLabel;
41
import javax.swing.JPanel;
42

    
43
import org.gvsig.andami.PluginServices;
44
import org.gvsig.arcims.image.fmap.layers.LayerScaleData;
45
import org.gvsig.arcims.image.gui.dialogs.LayerScaleDialog;
46

    
47
/**
48
 * This is the 'canvas' where layer scale limits status is painted.
49
 * 
50
 * @author jldominguez
51
 * 
52
 */
53
public class LayerScaleDrawPanel extends JPanel {
54
        private static final long serialVersionUID = 0;
55
        private LayerScaleDialog parentDialog;
56
        private Vector layerLabelsVector = new Vector();
57
        private Vector layerInfo = new Vector();
58
        private float currentScale;
59
        private int dpi = 96;
60
        private String fontName = "Dialog";
61
        private rulerItem[] rulerItems;
62

    
63
        // ----------------------------------------------------------------------------
64
        private double minScale = 500.0;
65
        private double maxScale = 10000000.0;
66
        private int minScaleX = 93; // 88; // +- 8 for less than and more than
67
        private int maxScaleX = 762;
68
        private int margin = 8;
69
        private int rowHeight = 12;
70
        private int rowSep = 15;
71
        private int parentDialogMinLimitForNormalTitle = 485;
72
        private int parentDialogMinLimitForShortTitle = 350;
73
        private Color carrilColor = new Color(219, 219, 219);
74
        private Color scaleLineColor = new Color(199, 106, 191);
75

    
76
        // ----------------------------------------------------------------------------
77
        private double logDist = Math.log(maxScale) - Math.log(minScale);
78
        private String title = "";
79
        private double medScale;
80
        private JLabel updateLabel;
81

    
82
        /**
83
         * @param info
84
         *            this vector contains the layers' scale info
85
         */
86
        public LayerScaleDrawPanel(Vector info, LayerScaleDialog dlg, JLabel ulabel) {
87
                super();
88
                parentDialog = dlg;
89
                updateLabel = ulabel;
90

    
91
                LayerScaleData theInfo;
92
                LayerLabel ll;
93
                currentScale = (float) 1.0;
94
                setBackground(Color.WHITE);
95
                setLayout(null);
96

    
97
                // layerInfo = invertedVector(info);
98
                layerInfo = copyVector(info, true);
99

    
100
                int size = info.size();
101

    
102
                for (int i = 0; i < size; i++) {
103
                        theInfo = (LayerScaleData) layerInfo.get(i);
104
                        ll = new LayerLabel(theInfo.getName(), theInfo.getId());
105

    
106
                        ll.setBounds(5, indexDomainToYDomain(i), getLabelsWidth(),
107
                                        rowHeight);
108
                        // ll.setBounds(5, indexDomainToYDomain((size - 1) - i),
109
                        // getLabelsWidth(), rowHeight);
110

    
111
                        layerLabelsVector.add(ll);
112
                        add(ll);
113
                }
114

    
115
                layerInfo = copyVector(layerInfo, true);
116

    
117
                rulerItems = getRulerItems();
118
                medScale = Math.sqrt(maxScale * minScale);
119
                medScale = Math.sqrt(medScale * minScale);
120
        }
121

    
122
        /**
123
         * 
124
         * @param info
125
         */
126
        public void resetInfo(Vector info) {
127
                layerLabelsVector.removeAllElements();
128
                removeAll();
129

    
130
                layerInfo = info;
131

    
132
                LayerScaleData theInfo;
133
                LayerLabel ll;
134
                int size = info.size();
135

    
136
                for (int i = 0; i < size; i++) {
137
                        theInfo = (LayerScaleData) layerInfo.get(i);
138
                        ll = new LayerLabel(theInfo.getName(), theInfo.getId());
139
                        ll.setBounds(5, indexDomainToYDomain((size - 1) - i),
140
                                        getLabelsWidth(), rowHeight);
141
                        layerLabelsVector.add(ll);
142
                        add(ll);
143
                }
144
        }
145

    
146
        /**
147
         * 
148
         * @param v
149
         * @param inverted
150
         * @return
151
         */
152
        private Vector copyVector(Vector v, boolean inverted) {
153
                Vector res = new Vector();
154

    
155
                if (inverted) {
156
                        for (int i = (v.size() - 1); i >= 0; i--)
157
                                res.add(v.get(i));
158
                } else {
159
                        for (int i = 0; i < v.size(); i++)
160
                                res.add(v.get(i));
161
                }
162

    
163
                return res;
164
        }
165

    
166
        /**
167
         * Sets current scale (it is represented as a vertical line)
168
         * 
169
         * @param s
170
         */
171
        public void setCurrentScale(double s) {
172
                currentScale = (float) s;
173
                updateLabel.setText(PluginServices.getText(this, "Escala")
174
                                + "  1 : "
175
                                + LayerScaleDialog
176
                                                .getFormattedInteger(Math.round(currentScale)));
177
        }
178

    
179
        /**
180
         * 
181
         * @param s
182
         */
183
        public void setCurrentScale(float s) {
184
                currentScale = s;
185
                updateLabel.setText(PluginServices.getText(this, "Escala")
186
                                + "  1 : "
187
                                + LayerScaleDialog
188
                                                .getFormattedInteger(Math.round(currentScale)));
189
        }
190

    
191
        /**
192
         * 
193
         * @return
194
         */
195
        public float getCurrentScale() {
196
                return currentScale;
197
        }
198

    
199
        private int getLabelsWidth() {
200
                return minScaleX - margin - 5;
201
        }
202

    
203
        public void paint(Graphics g) {
204
                super.paint(g);
205

    
206
                Graphics2D g2d = (Graphics2D) g;
207

    
208
                maxScaleX = getWidth() - 20;
209

    
210
                if (getParentWidth() < parentDialogMinLimitForNormalTitle) {
211
                        if (getParentWidth() < parentDialogMinLimitForShortTitle) {
212
                                setEmptyTitle();
213
                        } else {
214
                                setShortTitle();
215
                        }
216
                } else {
217
                        setNormalTitle();
218
                }
219

    
220
                drawTitle(g2d);
221

    
222
                g2d.setStroke(new BasicStroke(1));
223
                g2d.setFont(new Font(fontName, Font.PLAIN, 12));
224

    
225
                int size = layerInfo.size();
226

    
227
                for (int i = 0; i < size; i++) {
228
                        LayerScaleData info = (LayerScaleData) layerInfo.get(i);
229

    
230
                        int x_min;
231
                        int y_min;
232
                        int w;
233
                        int x_max = this.scaleDomainToXDomain(Math.pow(10.0, 9.0));
234

    
235
                        x_min = scaleDomainToXDomain(info.getMinSc());
236
                        w = scaleDomainToXDomain(info.getMaxSc()) - x_min;
237
                        // y_min = indexDomainToYDomain(i);
238

    
239
                        y_min = indexDomainToYDomain((size - 1) - i);
240

    
241
                        g2d.setColor(carrilColor);
242
                        g2d.fillRect((minScaleX - margin), y_min, x_max
243
                                        - (minScaleX - margin), rowHeight);
244

    
245
                        g2d.setColor(info.getColor(currentScale));
246
                        g2d.fillRect(x_min, y_min, w, rowHeight);
247

    
248
                        g2d.setColor(Color.BLACK);
249
                }
250

    
251
                drawRuler(g2d, size);
252
                drawCurrentScale(g2d, size);
253

    
254
                int x = Math.min(getWidth() - 136,
255
                                ((getParentWidth() - parentDialogMinLimitForNormalTitle) / 2)
256
                                                + (parentDialogMinLimitForNormalTitle - 136));
257
                drawLegend(g2d, x, 10);
258
        }
259

    
260
        private void setEmptyTitle() {
261
                title = "";
262
        }
263

    
264
        private void setNormalTitle() {
265
                title = PluginServices.getText(this, "scale_limits_status");
266
        }
267

    
268
        private void setShortTitle() {
269
                title = PluginServices.getText(this, "scale_limits");
270
        }
271

    
272
        private void drawTitle(Graphics2D g) {
273
                g.setColor(Color.GRAY);
274
                g.setFont(new Font(fontName, Font.BOLD, 20));
275
                g.drawString(title, 20, 55);
276
        }
277

    
278
        private void drawRuler(Graphics2D g, int i) {
279
                g.setColor(Color.DARK_GRAY);
280

    
281
                int x_min = this.scaleDomainToXDomain(minScale - 1.0);
282
                int x_max = this.scaleDomainToXDomain(maxScale + 1.0);
283
                int y = this.indexDomainToYDomain(0) - 10;
284
                int offsetFromTagsToRuler = 8;
285

    
286
                g.drawLine(x_min, y, x_max, y);
287

    
288
                // arrows
289
                int[] xp = { x_min - 2, x_min + 5, x_min + 5 };
290
                int[] yp = { y, y - 3, y + 3 };
291
                g.fillPolygon(xp, yp, 3);
292

    
293
                int[] x2p = { x_max + 2, x_max - 5, x_max - 5 };
294
                g.fillPolygon(x2p, yp, 3);
295

    
296
                // ---------------- scale label -------------------------
297
                g.setFont(new Font(fontName, Font.BOLD, 12));
298
                g.drawString(PluginServices.getText(this, "the_scale"), 20, y - 44);
299
                g.drawString("(DPI = " + dpi + ")", 20, (y + 12) - 44);
300
                g.setFont(new Font(fontName, Font.PLAIN, 12));
301

    
302
                // ------------------------------------------------------
303
                rulerItem ruIt;
304

    
305
                g.drawString("1:", scaleDomainToXDomain(minScale) - 30, y
306
                                - offsetFromTagsToRuler);
307

    
308
                AffineTransform oldt = g.getTransform();
309
                AffineTransform newt;
310
                AffineTransform rott;
311
                AffineTransform trat;
312
                double angulo = -65.0;
313

    
314
                for (int ind = 0; ind < rulerItems.length; ind++) {
315
                        ruIt = this.rulerItems[ind];
316
                        g.drawLine(ruIt.getScaleInXDomain(), y - 3, ruIt
317
                                        .getScaleInXDomain(), y + 3);
318

    
319
                        int strx = ruIt.getScaleInXDomain();
320
                        int stry = y - offsetFromTagsToRuler;
321
                        trat = AffineTransform.getTranslateInstance(1.0 * strx, 1.0 * stry);
322
                        rott = AffineTransform
323
                                        .getRotateInstance((angulo * 3.1415926) / 180.0);
324
                        newt = (AffineTransform) oldt.clone();
325
                        newt.concatenate(trat);
326
                        newt.concatenate(rott);
327
                        g.setTransform(newt);
328
                        g.drawString(ruIt.getTag(), 0, 0);
329
                        g.setTransform(oldt);
330
                }
331
        }
332

    
333
        private int indexDomainToYDomain(int i) {
334
                return Math.round((float) (158.0 + (rowSep * i)));
335
        }
336

    
337
        private int scaleDomainToXDomain(double d) {
338
                if (d < minScale) {
339
                        return minScaleX - margin;
340
                }
341

    
342
                if (d > maxScale) {
343
                        return maxScaleX + margin;
344
                }
345

    
346
                double dist = Math.log(d) - Math.log(minScale);
347

    
348
                return Math
349
                                .round((float) ((1.0 * minScaleX) + ((dist * (maxScaleX - minScaleX)) / logDist)));
350
        }
351

    
352
        private void drawCurrentScale(Graphics2D g, int i) {
353
                int footLength = 90;
354
                int x = this.scaleDomainToXDomain(currentScale);
355
                int y_min = indexDomainToYDomain(0) - 10;
356
                int y_max = indexDomainToYDomain(layerInfo.size()) + 18;
357

    
358
                Stroke old = g.getStroke();
359
                g.setStroke(new BasicStroke(1));
360
                g.setColor(scaleLineColor);
361
                g.drawLine(x, y_min, x, y_max);
362

    
363
                // little square
364
                int[] xp = { x - 1, x + 2, x + 2, x - 1 };
365
                int[] yp = { y_min - 1, y_min - 1, y_min + 2, y_min + 2 };
366
                g.fillPolygon(xp, yp, 4);
367

    
368
                if (currentScale > medScale) { // label to the left
369
                        g.drawLine(x, y_max, x - footLength, y_max);
370
                        g.setColor(LayerScaleData.darker(scaleLineColor));
371
                        g.setFont(new Font(fontName, Font.BOLD, 12));
372
                        g.drawString(PluginServices.getText(this, "current_scale"), x
373
                                        - footLength, y_max - 4);
374
                } else { // label to the right
375
                        g.drawLine(x, y_max, x + 10, y_max);
376
                        g.setColor(LayerScaleData.darker(scaleLineColor));
377
                        g.setFont(new Font(fontName, Font.BOLD, 12));
378
                        g.drawString(PluginServices.getText(this, "current_scale"), x + 15,
379
                                        y_max + 4);
380
                }
381

    
382
                g.setFont(new Font(fontName, Font.PLAIN, 12));
383
                g.setStroke(old);
384
        }
385

    
386
        private void drawLegend(Graphics2D g, int orx, int ory) {
387
                // width = 2 * margin + 2 * sampleW + labelW = 126
388
                // height = 2 * margin + 4 * rowSep = 76
389
                int sampleW = 25;
390
                int margin = 8;
391
                int labelW = 60;
392

    
393
                // -----------------------------------------
394
                int correction = -2;
395
                int smpx = orx + margin + labelW;
396
                int smpy = ory + margin + (2 * rowSep) + (rowSep - rowHeight);
397
                int auxx;
398
                int auxy;
399

    
400
                g.setFont(new Font(fontName, Font.PLAIN, 12));
401

    
402
                auxx = orx + margin;
403
                auxy = ory + (2 * rowSep) + margin;
404
                g.setColor(Color.GRAY);
405
                g.drawString(PluginServices.getText(this, "type"), auxx, auxy
406
                                + correction);
407

    
408
                auxy = auxy + rowSep;
409
                g.setColor(Color.BLACK);
410
                g.drawString(PluginServices.getText(this, "vectorial"), auxx, auxy);
411

    
412
                auxy = auxy + rowSep;
413
                g.drawString(PluginServices.getText(this, "raster"), auxx, auxy);
414

    
415
                auxx = orx + margin + labelW;
416
                auxy = ory + rowSep + margin;
417
                g.setColor(Color.GRAY);
418
                g.drawString(PluginServices.getText(this, "visible"), auxx, auxy
419
                                + correction);
420

    
421
                auxy = auxy + rowSep;
422
                g.setFont(new Font(fontName, Font.PLAIN, 10));
423
                g.setColor(Color.BLACK);
424
                g.drawString(PluginServices.getText(this, "YES"), auxx, auxy
425
                                + correction);
426

    
427
                auxx = auxx + sampleW;
428
                g.drawString(PluginServices.getText(this, "NO"), auxx, auxy
429
                                + correction);
430

    
431
                // --------- samples ---------------------
432
                g.setColor(LayerScaleData.featYesColor);
433
                g.fillRect(smpx, smpy, sampleW, rowHeight);
434

    
435
                g.setColor(LayerScaleData.featNoColor);
436
                g.fillRect(smpx + sampleW, smpy, sampleW, rowHeight);
437

    
438
                g.setColor(LayerScaleData.imagYesColor);
439
                g.fillRect(smpx, smpy + rowSep, sampleW, rowHeight);
440

    
441
                g.setColor(LayerScaleData.imagNoColor);
442
                g.fillRect(smpx + sampleW, smpy + rowSep, sampleW, rowHeight);
443

    
444
                g.setColor(Color.BLACK);
445
                g.drawRect(orx, ory, (2 * margin) + (2 * sampleW) + labelW,
446
                                (2 * margin) + (4 * rowSep));
447

    
448
                // ------------------------------------------
449
        }
450

    
451
        // public void setLayerInfo(Vector v) {
452
        // layerInfo = invertedVector(v);
453
        // }
454
        public void setDpi(int dpi) {
455
                this.dpi = dpi;
456
        }
457

    
458
        /**
459
         * 
460
         * @return Scale items shown on ruler
461
         */
462
        private rulerItem[] getRulerItems() {
463
                rulerItem[] ri = new rulerItem[12];
464
                ri[0] = new rulerItem(500);
465
                ri[1] = new rulerItem(2000);
466
                ri[2] = new rulerItem(5000);
467
                ri[3] = new rulerItem(10000);
468
                ri[4] = new rulerItem(25000);
469
                ri[5] = new rulerItem(50000);
470
                ri[6] = new rulerItem(100000);
471
                ri[7] = new rulerItem(250000);
472
                ri[8] = new rulerItem(500000);
473
                ri[9] = new rulerItem(1000000);
474
                ri[10] = new rulerItem(5000000);
475
                ri[11] = new rulerItem(10000000); // must be the same as 'private double
476
                                                                                        // maxScale'
477

    
478
                return ri;
479
        }
480

    
481
        private int getParentWidth() {
482
                if (parentDialog == null) {
483
                        return parentDialogMinLimitForNormalTitle;
484
                } else {
485
                        return parentDialog.getWidth();
486
                }
487
        }
488

    
489
        /**
490
         * Utility class used to allow tool tips.
491
         * 
492
         * @author jldominguez
493
         * 
494
         */
495
        public class LayerLabel extends JLabel {
496
                private static final long serialVersionUID = 0;
497
                private String theName = "";
498
                private String theId = "";
499

    
500
                public LayerLabel(String name, String id) {
501
                        theName = name;
502
                        theId = id;
503
                        setToolTipText(toolTipString());
504
                        setText(toString());
505
                        setFont(new Font(fontName, Font.BOLD, 12));
506
                }
507

    
508
                public String toString() {
509
                        if (theName.length() < 19) {
510
                                return theName;
511
                        }
512

    
513
                        return theName.substring(0, 16) + "...";
514
                }
515

    
516
                public String toolTipString() {
517
                        return "[" + theId + "] " + theName;
518
                }
519
        }
520

    
521
        private class rulerItem {
522
                private int scale;
523

    
524
                public rulerItem(int sc) {
525
                        scale = sc;
526
                }
527

    
528
                public String getTag() {
529
                        return intToAbbrev(scale);
530
                }
531

    
532
                public int getScale() {
533
                        return scale;
534
                }
535

    
536
                public int getScaleInXDomain() {
537
                        return scaleDomainToXDomain(1.0 * scale);
538
                }
539

    
540
                public int xAxisOffset() {
541
                        return (getTag().length() * 4) + 3;
542
                }
543

    
544
                private String intToAbbrev(int n) {
545
                        if (n >= 1000000) {
546
                                return String.valueOf(n / 1000000) + " M";
547
                        }
548

    
549
                        return String.valueOf(n);
550
                }
551
        }
552
}