1 package fr.ifremer.dali.ui.swing.util.map.layer;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 import fr.ifremer.dali.dto.DaliBeans;
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.geotools.geometry.jts.ReferencedEnvelope;
30 import org.geotools.map.DirectLayer;
31 import org.geotools.map.MapContent;
32 import org.geotools.map.MapViewport;
33 import org.geotools.renderer.lite.RendererUtilities;
34
35 import java.awt.BasicStroke;
36 import java.awt.Color;
37 import java.awt.FontMetrics;
38 import java.awt.Graphics2D;
39 import java.awt.geom.Rectangle2D;
40
41
42
43
44
45
46 public class ScaleLayer extends DirectLayer {
47
48 private static final Log log = LogFactory.getLog(ScaleLayer.class);
49
50 private static final int MARGIN = 10;
51 private static final int SCALE_HEIGHT = 10;
52 private static final int SCALE_WIDTH_MAX = 200;
53
54 private static final int METERS_BY_MILES = 1852;
55
56 private int mileScaleWidth;
57 private int meterScaleWidth;
58
59 private String mileLabelScaleUp;
60 private String meterLabelScaleUp;
61
62 public ScaleLayer() {
63 setTitle("scaleLayer");
64 }
65
66 @Override
67 public void draw(Graphics2D graphics, MapContent map, MapViewport viewport) {
68 if (viewport == null) {
69 viewport = map.getViewport();
70 }
71 if (viewport == null || viewport.getScreenArea() == null) {
72 return;
73 }
74
75 int viewWidth = graphics.getClipBounds().width;
76 int viewHeight = graphics.getClipBounds().height;
77
78 ReferencedEnvelope displayArea = viewport.getBounds();
79
80 ReferencedEnvelope roundDisplayArea = new ReferencedEnvelope(
81 DaliBeans.roundDouble(displayArea.getMinX(), 4),
82 DaliBeans.roundDouble(displayArea.getMaxX(), 4),
83 DaliBeans.roundDouble(displayArea.getMinY(), 4),
84 DaliBeans.roundDouble(displayArea.getMaxY(), 4),
85 displayArea.getCoordinateReferenceSystem());
86
87 double dpi = 2.54 / 100;
88
89 try {
90 double meterPerPixel = RendererUtilities.calculateScale(roundDisplayArea, viewWidth, viewHeight, dpi);
91 double maxWidthMeter = SCALE_WIDTH_MAX * meterPerPixel;
92 {
93
94 double maxWidthMiles = maxWidthMeter / METERS_BY_MILES;
95 int nbDigit = (int) Math.floor(Math.log10(maxWidthMiles));
96 int firstDigit = (int) Math.floor(maxWidthMiles / Math.pow(10, nbDigit));
97 int useFirstDigit;
98 if (firstDigit >= 5) {
99 useFirstDigit = 5;
100 } else if (firstDigit >= 2) {
101 useFirstDigit = 2;
102 } else {
103 useFirstDigit = 1;
104 }
105 long scaleInMiles = useFirstDigit * (long) Math.pow(10, nbDigit);
106 mileScaleWidth = (int) Math.round(scaleInMiles * METERS_BY_MILES / meterPerPixel);
107 mileLabelScaleUp = String.format("%,d " + "milles", scaleInMiles);
108 }
109 {
110
111 int nbDigit = (int) Math.floor(Math.log10(maxWidthMeter));
112 int firstDigit = (int) Math.floor(maxWidthMeter / Math.pow(10, nbDigit));
113 int useFirstDigit;
114 if (firstDigit >= 5) {
115 useFirstDigit = 5;
116 } else if (firstDigit >= 2) {
117 useFirstDigit = 2;
118 } else {
119 useFirstDigit = 1;
120 }
121 long scaleInMeter = useFirstDigit * (long) Math.pow(10, nbDigit);
122 meterScaleWidth = (int) Math.round(scaleInMeter / meterPerPixel);
123 meterLabelScaleUp = String.format("%,d " + "meters", scaleInMeter);
124 }
125
126 } catch (Exception e) {
127 if (log.isErrorEnabled()) {
128 log.error("error", e);
129 }
130 }
131
132 graphics.setColor(Color.BLACK);
133 graphics.setStroke(new BasicStroke());
134 FontMetrics fm = graphics.getFontMetrics();
135
136 {
137
138 Rectangle2D textArea = fm.getStringBounds(mileLabelScaleUp, graphics);
139 int labelLeft = viewWidth - MARGIN * 2 - mileScaleWidth - (int) textArea.getWidth();
140 graphics.drawString(mileLabelScaleUp, labelLeft, viewHeight - MARGIN);
141 int scalesEndX = viewWidth - MARGIN;
142 int scaleStartX = scalesEndX - mileScaleWidth;
143 int scalesEndY = viewHeight - MARGIN;
144 int scaleStartY = scalesEndY - SCALE_HEIGHT;
145
146 graphics.drawLine(scaleStartX, scaleStartY, scaleStartX, scalesEndY);
147 graphics.drawLine(scaleStartX, scalesEndY, scalesEndX, scalesEndY);
148 graphics.drawLine(scalesEndX, scalesEndY, scalesEndX, scaleStartY);
149 }
150
151 {
152
153 Rectangle2D textArea = fm.getStringBounds(meterLabelScaleUp, graphics);
154 int offsetHeight = (int) (textArea.getHeight());
155 int labelLeft = viewWidth - MARGIN * 2 - meterScaleWidth - (int) textArea.getWidth();
156 graphics.drawString(meterLabelScaleUp, labelLeft, viewHeight - MARGIN - offsetHeight);
157 int scalesEndX = viewWidth - MARGIN;
158 int scaleStartX = scalesEndX - meterScaleWidth;
159 int scalesEndY = viewHeight - MARGIN - offsetHeight;
160 int scaleStartY = scalesEndY - SCALE_HEIGHT;
161
162 graphics.drawLine(scaleStartX, scaleStartY, scaleStartX, scalesEndY);
163 graphics.drawLine(scaleStartX, scalesEndY, scalesEndX, scalesEndY);
164 graphics.drawLine(scalesEndX, scalesEndY, scalesEndX, scaleStartY);
165 }
166
167
168 }
169
170 @Override
171 public ReferencedEnvelope getBounds() {
172 return null;
173 }
174 }