Statistics
| Revision:

root / branches / v10 / extensions / extArcims / src / es / prodevelop / cit / gvsig / arcims / gui / panels / LayerScaleDrawPanel.java @ 11868

History | View | Annotate | Download (16.5 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2006 Prodevelop and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *   Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *   +34 963862235
28
 *   gvsig@gva.es
29
 *   www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   Prodevelop Integraci?n de Tecnolog?as SL
34
 *   Conde Salvatierra de ?lava , 34-10
35
 *   46004 Valencia
36
 *   Spain
37
 *
38
 *   +34 963 510 612
39
 *   +34 963 510 968
40
 *   gis@prodevelop.es
41
 *   http://www.prodevelop.es
42
 */
43
package es.prodevelop.cit.gvsig.arcims.gui.panels;
44

    
45
import com.iver.andami.PluginServices;
46

    
47
import es.prodevelop.cit.gvsig.arcims.fmap.layers.LayerScaleData;
48
import es.prodevelop.cit.gvsig.arcims.gui.dialogs.LayerScaleDialog;
49

    
50
import java.awt.BasicStroke;
51
import java.awt.Color;
52
import java.awt.Font;
53
import java.awt.FontMetrics;
54
import java.awt.Graphics;
55
import java.awt.Graphics2D;
56
import java.awt.Stroke;
57
import java.awt.geom.AffineTransform;
58

    
59
import java.util.Vector;
60

    
61
import javax.swing.JLabel;
62
import javax.swing.JPanel;
63

    
64

    
65
/**
66
 * This is the 'canvas' where layer scale limits status is
67
 * painted.
68
 *
69
 * @author jldominguez
70
 *
71
 */
72
public class LayerScaleDrawPanel extends JPanel {
73
    private static final long serialVersionUID = 0;
74
    private LayerScaleDialog parentDialog;
75
    private Vector layerLabelsVector = new Vector();
76
    private Vector layerInfo = new Vector();
77
    private float currentScale;
78
    private int dpi = 96;
79
    private String fontName = "Dialog";
80
    private rulerItem[] rulerItems;
81

    
82
    // ----------------------------------------------------------------------------
83
    private double minScale = 500.0;
84
    private double maxScale = 10000000.0;
85
    private int minScaleX = 93; //88; // +- 8 for less than and more than
86
    private int maxScaleX = 762;
87
    private int margin = 8;
88
    private int rowHeight = 12;
89
    private int rowSep = 15;
90
    private int parentDialogMinLimitForNormalTitle = 485;
91
    private int parentDialogMinLimitForShortTitle = 350;
92
    private Color carrilColor = new Color(219, 219, 219);
93
    private Color scaleLineColor = new Color(199, 106, 191);
94

    
95
    // ----------------------------------------------------------------------------
96
    private double logDist = Math.log(maxScale) - Math.log(minScale);
97
    private String title = "";
98
    private double medScale;
99
    private JLabel updateLabel;
100

    
101
    /**
102
     * @param info this vector contains the layers' scale info
103
     */
104
    public LayerScaleDrawPanel(Vector info, LayerScaleDialog dlg, JLabel ulabel) {
105
        super();
106
        parentDialog = dlg;
107
        updateLabel = ulabel;
108

    
109
        LayerScaleData theInfo;
110
        LayerLabel ll;
111
        currentScale = (float) 1.0;
112
        setBackground(Color.WHITE);
113
        setLayout(null);
114
        
115
        // layerInfo = invertedVector(info);
116
        layerInfo = copyVector(info, true);
117

    
118
        int size = info.size();
119

    
120
        for (int i = 0; i < size; i++) {
121
            theInfo = (LayerScaleData) layerInfo.get(i);
122
            ll = new LayerLabel(theInfo.getName(), theInfo.getId());
123
            
124
            ll.setBounds(5, indexDomainToYDomain(i), getLabelsWidth(), rowHeight);
125
            // ll.setBounds(5, indexDomainToYDomain((size - 1) - i), getLabelsWidth(), rowHeight);
126
            
127
            
128
            layerLabelsVector.add(ll);
129
            add(ll);
130
        }
131
        
132
        layerInfo = copyVector(layerInfo, true);
133

    
134
        rulerItems = getRulerItems();
135
        medScale = Math.sqrt(maxScale * minScale);
136
        medScale = Math.sqrt(medScale * minScale);
137
    }
138

    
139
    public void resetInfo(Vector info) {
140
        layerLabelsVector.removeAllElements();
141
        removeAll();
142

    
143
        layerInfo = info;
144

    
145
        LayerScaleData theInfo;
146
        LayerLabel ll;
147
        int size = info.size();
148

    
149
        for (int i = 0; i < size; i++) {
150
            theInfo = (LayerScaleData) layerInfo.get(i);
151
            ll = new LayerLabel(theInfo.getName(), theInfo.getId());
152
            ll.setBounds(5, indexDomainToYDomain((size - 1) - i), getLabelsWidth(), rowHeight);
153
            layerLabelsVector.add(ll);
154
            add(ll);
155
        }
156
    }
157

    
158
    private Vector copyVector(Vector v, boolean inverted) {
159
        Vector res = new Vector();
160

    
161
        if (inverted) {
162
            for (int i = (v.size() - 1); i >= 0; i--) res.add(v.get(i));
163
        } else {
164
            for (int i = 0; i < v.size(); i++) res.add(v.get(i));
165
        }
166

    
167
        return res;
168
    }
169

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

    
180
    public void setCurrentScale(float s) {
181
        currentScale = s;
182
        updateLabel.setText(PluginServices.getText(this, "Escala") + "  1 : " +
183
            LayerScaleDialog.getFormattedInteger(Math.round(currentScale)));
184
    }
185

    
186
    public float getCurrentScale() {
187
        return currentScale;
188
    }
189

    
190
    private int getLabelsWidth() {
191
        return minScaleX - margin - 5;
192
    }
193

    
194
    public void paint(Graphics g) {
195
        super.paint(g);
196

    
197
        Graphics2D g2d = (Graphics2D) g;
198

    
199
        System.err.println("WIDTH = " + getWidth());
200
        maxScaleX = getWidth() - 20;
201

    
202
        if (getParentWidth() < parentDialogMinLimitForNormalTitle) {
203
            if (getParentWidth() < parentDialogMinLimitForShortTitle) {
204
                setEmptyTitle();
205
            }
206
            else {
207
                setShortTitle();
208
            }
209
        }
210
        else {
211
            setNormalTitle();
212
        }
213

    
214
        drawTitle(g2d);
215

    
216
        g2d.setStroke(new BasicStroke(1));
217
        g2d.setFont(new Font(fontName, Font.PLAIN, 12));
218

    
219
        int size = layerInfo.size();
220

    
221
        for (int i = 0; i < size; i++) {
222
            LayerScaleData info = (LayerScaleData) layerInfo.get(i);
223

    
224
            int x_min;
225
            int y_min;
226
            int w;
227
            int x_max = this.scaleDomainToXDomain(Math.pow(10.0, 9.0));
228

    
229
            x_min = scaleDomainToXDomain(info.getMinSc());
230
            w = scaleDomainToXDomain(info.getMaxSc()) - x_min;
231
            // y_min = indexDomainToYDomain(i);
232
            
233
            y_min = indexDomainToYDomain((size - 1) - i);
234

    
235
            g2d.setColor(carrilColor);
236
            g2d.fillRect((minScaleX - margin), y_min,
237
                x_max - (minScaleX - margin), rowHeight);
238

    
239
            g2d.setColor(info.getColor(currentScale));
240
            g2d.fillRect(x_min, y_min, w, rowHeight);
241

    
242
            g2d.setColor(Color.BLACK);
243
        }
244

    
245
        drawRuler(g2d, size);
246
        drawCurrentScale(g2d, size);
247

    
248
        int x = Math.min(getWidth() - 136,
249
                ((getParentWidth() - parentDialogMinLimitForNormalTitle) / 2) +
250
                (parentDialogMinLimitForNormalTitle - 136));
251
        drawLegend(g2d, x, 10);
252
    }
253

    
254
    private void setEmptyTitle() {
255
        title = "";
256
    }
257

    
258
    private void setNormalTitle() {
259
        title = PluginServices.getText(this, "scale_limits_status");
260
    }
261

    
262
    private void setShortTitle() {
263
        title = PluginServices.getText(this, "scale_limits");
264
    }
265

    
266
    private void drawTitle(Graphics2D g) {
267
        g.setColor(Color.GRAY);
268
        g.setFont(new Font(fontName, Font.BOLD, 20));
269
        g.drawString(title, 20, 55);
270
    }
271

    
272
    private void drawRuler(Graphics2D g, int i) {
273
        g.setColor(Color.DARK_GRAY);
274

    
275
        int x_min = this.scaleDomainToXDomain(minScale - 1.0);
276
        int x_max = this.scaleDomainToXDomain(maxScale + 1.0);
277
        int y = this.indexDomainToYDomain(0) - 10;
278
        int offsetFromTagsToRuler = 8;
279

    
280
        g.drawLine(x_min, y, x_max, y);
281

    
282
        // arrows
283
        int[] xp = { x_min - 2, x_min + 5, x_min + 5 };
284
        int[] yp = { y, y - 3, y + 3 };
285
        g.fillPolygon(xp, yp, 3);
286

    
287
        int[] x2p = { x_max + 2, x_max - 5, x_max - 5 };
288
        g.fillPolygon(x2p, yp, 3);
289

    
290
        // ---------------- scale label -------------------------
291
        g.setFont(new Font(fontName, Font.BOLD, 12));
292
        g.drawString(PluginServices.getText(this, "the_scale"), 20, y - 44);
293
        g.drawString("(DPI = " + dpi + ")", 20, (y + 12) - 44);
294
        g.setFont(new Font(fontName, Font.PLAIN, 12));
295

    
296
        // ------------------------------------------------------
297
        rulerItem ruIt;
298

    
299
        g.drawString("1:", scaleDomainToXDomain(minScale) - 30,
300
            y - offsetFromTagsToRuler);
301

    
302
        AffineTransform oldt = g.getTransform();
303
        AffineTransform newt;
304
        AffineTransform rott;
305
        AffineTransform trat;
306
        double angulo = -65.0;
307

    
308
        for (int ind = 0; ind < rulerItems.length; ind++) {
309
            ruIt = this.rulerItems[ind];
310
            g.drawLine(ruIt.getScaleInXDomain(), y - 3,
311
                ruIt.getScaleInXDomain(), y + 3);
312

    
313
            int strx = ruIt.getScaleInXDomain();
314
            int stry = y - offsetFromTagsToRuler;
315
            trat = AffineTransform.getTranslateInstance(1.0 * strx, 1.0 * stry);
316
            rott = AffineTransform.getRotateInstance((angulo * 3.1415926) / 180.0);
317
            newt = (AffineTransform) oldt.clone();
318
            newt.concatenate(trat);
319
            newt.concatenate(rott);
320
            g.setTransform(newt);
321
            g.drawString(ruIt.getTag(), 0, 0);
322
            g.setTransform(oldt);
323
        }
324
    }
325

    
326
    private int indexDomainToYDomain(int i) {
327
        return Math.round((float) (158.0 + (rowSep * i)));
328
    }
329

    
330
    private int scaleDomainToXDomain(double d) {
331
        if (d < minScale) {
332
            return minScaleX - margin;
333
        }
334

    
335
        if (d > maxScale) {
336
            return maxScaleX + margin;
337
        }
338

    
339
        double dist = Math.log(d) - Math.log(minScale);
340

    
341
        return Math.round((float) ((1.0 * minScaleX) +
342
            ((dist * (maxScaleX - minScaleX)) / logDist)));
343
    }
344

    
345
    private void drawCurrentScale(Graphics2D g, int i) {
346
        int footLength = 90;
347
        int x = this.scaleDomainToXDomain(currentScale);
348
        int y_min = indexDomainToYDomain(0) - 10;
349
        int y_max = indexDomainToYDomain(layerInfo.size()) + 18;
350

    
351
        Stroke old = g.getStroke();
352
        g.setStroke(new BasicStroke(1));
353
        g.setColor(scaleLineColor);
354
        g.drawLine(x, y_min, x, y_max);
355

    
356
        // little square
357
        int[] xp = { x - 1, x + 2, x + 2, x - 1 };
358
        int[] yp = { y_min - 1, y_min - 1, y_min + 2, y_min + 2 };
359
        g.fillPolygon(xp, yp, 4);
360

    
361
        if (currentScale > medScale) { // label to the left
362
            g.drawLine(x, y_max, x - footLength, y_max);
363
            g.setColor(LayerScaleData.darker(scaleLineColor));
364
            g.setFont(new Font(fontName, Font.BOLD, 12));
365
            g.drawString(PluginServices.getText(this, "current_scale"),
366
                x - footLength, y_max - 4);
367
        }
368
        else { // label to the right
369
            g.drawLine(x, y_max, x + 10, 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 + 15,
373
                y_max + 4);
374
        }
375

    
376
        g.setFont(new Font(fontName, Font.PLAIN, 12));
377
        g.setStroke(old);
378
    }
379

    
380
    private void drawLegend(Graphics2D g, int orx, int ory) {
381
        // width = 2 * margin + 2 * sampleW + labelW = 126 
382
        // height = 2 * margin + 4 * rowSep = 76
383
        int sampleW = 25;
384
        int margin = 8;
385
        int labelW = 60;
386

    
387
        // -----------------------------------------
388
        int correction = -2;
389
        int smpx = orx + margin + labelW;
390
        int smpy = ory + margin + (2 * rowSep) + (rowSep - rowHeight);
391
        int auxx;
392
        int auxy;
393

    
394
        g.setFont(new Font(fontName, Font.PLAIN, 12));
395

    
396
        auxx = orx + margin;
397
        auxy = ory + (2 * rowSep) + margin;
398
        g.setColor(Color.GRAY);
399
        g.drawString(PluginServices.getText(this, "type"), auxx,
400
            auxy + correction);
401

    
402
        auxy = auxy + rowSep;
403
        g.setColor(Color.BLACK);
404
        g.drawString(PluginServices.getText(this, "vectorial"), auxx, auxy);
405

    
406
        auxy = auxy + rowSep;
407
        g.drawString(PluginServices.getText(this, "raster"), auxx, auxy);
408

    
409
        auxx = orx + margin + labelW;
410
        auxy = ory + rowSep + margin;
411
        g.setColor(Color.GRAY);
412
        g.drawString(PluginServices.getText(this, "visible"), auxx,
413
            auxy + correction);
414

    
415
        auxy = auxy + rowSep;
416
        g.setFont(new Font(fontName, Font.PLAIN, 10));
417
        g.setColor(Color.BLACK);
418
        g.drawString(PluginServices.getText(this, "YES"), auxx,
419
            auxy + correction);
420

    
421
        auxx = auxx + sampleW;
422
        g.drawString(PluginServices.getText(this, "NO"), auxx, auxy +
423
            correction);
424

    
425
        // --------- samples ---------------------
426
        g.setColor(LayerScaleData.featYesColor);
427
        g.fillRect(smpx, smpy, sampleW, rowHeight);
428

    
429
        g.setColor(LayerScaleData.featNoColor);
430
        g.fillRect(smpx + sampleW, smpy, sampleW, rowHeight);
431

    
432
        g.setColor(LayerScaleData.imagYesColor);
433
        g.fillRect(smpx, smpy + rowSep, sampleW, rowHeight);
434

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

    
438
        g.setColor(Color.BLACK);
439
        g.drawRect(orx, ory, (2 * margin) + (2 * sampleW) + labelW,
440
            (2 * margin) + (4 * rowSep));
441

    
442
        // ------------------------------------------
443
    }
444

    
445
    //        public void setLayerInfo(Vector v) {
446
    //                layerInfo = invertedVector(v);
447
    //        }
448
    public void setDpi(int dpi) {
449
        this.dpi = dpi;
450
    }
451

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

    
471
        return ri;
472
    }
473

    
474
    private int getParentWidth() {
475
        if (parentDialog == null) {
476
            return parentDialogMinLimitForNormalTitle;
477
        }
478
        else {
479
            return parentDialog.getWidth();
480
        }
481
    }
482

    
483
    /**
484
     * Utility class used to allow tool tips.
485
     *
486
     * @author jldominguez
487
     *
488
     */
489
    public class LayerLabel extends JLabel {
490
        private static final long serialVersionUID = 0;
491
        private String theName = "";
492
        private String theId = "";
493

    
494
        public LayerLabel(String name, String id) {
495
            theName = name;
496
            theId = id;
497
            setToolTipText(toolTipString());
498
            setText(toString());
499
            setFont(new Font(fontName, Font.BOLD, 12));
500
        }
501

    
502
        public String toString() {
503
            if (theName.length() < 19) {
504
                return theName;
505
            }
506

    
507
            return theName.substring(0, 16) + "...";
508
        }
509

    
510
        public String toolTipString() {
511
            return "[" + theId + "] " + theName;
512
        }
513
    }
514

    
515
    private class rulerItem {
516
        private int scale;
517

    
518
        public rulerItem(int sc) {
519
            scale = sc;
520
        }
521

    
522
        public String getTag() {
523
            return intToAbbrev(scale);
524
        }
525

    
526
        public int getScale() {
527
            return scale;
528
        }
529

    
530
        public int getScaleInXDomain() {
531
            return scaleDomainToXDomain(1.0 * scale);
532
        }
533

    
534
        public int xAxisOffset() {
535
            return (getTag().length() * 4) + 3;
536
        }
537

    
538
        private String intToAbbrev(int n) {
539
            if (n >= 1000000) {
540
                return String.valueOf(n / 1000000) + " M";
541
            }
542

    
543
            return String.valueOf(n);
544
        }
545
    }
546
}