Statistics
| Revision:

svn-gvsig-desktop / branches / v10 / extensions / extArcims / src / es / prodevelop / cit / gvsig / arcims / gui / panels / LayerScaleDrawPanel.java @ 20976

History | View | Annotate | Download (16.4 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
        maxScaleX = getWidth() - 20;
200

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

    
213
        drawTitle(g2d);
214

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

    
218
        int size = layerInfo.size();
219

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
295
        // ------------------------------------------------------
296
        rulerItem ruIt;
297

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
441
        // ------------------------------------------
442
    }
443

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

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

    
470
        return ri;
471
    }
472

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

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

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

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

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

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

    
514
    private class rulerItem {
515
        private int scale;
516

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

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

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

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

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

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

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