Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.app / org.gvsig.app.mainplugin / src / main / java / org / gvsig / app / project / documents / view / toolListeners / StatusBarListener.java @ 40558

History | View | Annotate | Download (11.8 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
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 3
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
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.app.project.documents.view.toolListeners;
25

    
26
import java.awt.Image;
27
import java.awt.geom.Point2D;
28
import java.text.NumberFormat;
29

    
30
import org.cresques.cts.IProjection;
31
import org.gvsig.andami.PluginServices;
32
import org.gvsig.andami.ui.mdiFrame.MainFrame;
33
import org.gvsig.fmap.mapcontext.MapContext;
34
import org.gvsig.fmap.mapcontrol.MapControl;
35
import org.gvsig.fmap.mapcontrol.tools.BehaviorException;
36
import org.gvsig.fmap.mapcontrol.tools.Events.PointEvent;
37
import org.gvsig.fmap.mapcontrol.tools.Listeners.PointListener;
38

    
39

    
40

    
41
/**
42
 * <p>Listener that displays at the status bar of the application's main frame, the value of the point coordinates of the mouse's
43
 *  cursor on the associated <code>MapControl</code>, just as is received a <code>PointEvent</code> event.</p>
44
 *
45
 * <p>Calculates the coordinates equivalent to the point according this rules:
46
 *  <ul>
47
 *   <li>uses <i><code>formatDegrees(p.get{X or Y}()</code></i> if the associated <code>MapControl</code> object isn't projected.</li>
48
 *   <li>uses <i><code>formatDegrees({MapControl's projection}.toGeo(p.get{X or Y}())</code></i> if the associated
49
 *    <code>MapControl</code> object is projected and its <code>ViewPort</code>'s distance units are in degrees.</li>
50
 *   <li>uses <i><code>{NumberFormat according to {@link #setFractionDigits(Point2D) #setFractionDigits(Point2D)}}.format((p.get{X or Y}()/MapContext.CHANGEM[mapControl.getViewPort().getDistanceUnits()])*MapContext.CHANGEM[mapControl.getViewPort().getMapUnits()])</code></i>
51
 *    otherwise.</li>
52
 *  </ul>
53
 * </p>
54
 *
55
 * <p>The <u>prefix</u> of the coordinate expressions will be:
56
 *  <ul>
57
 *   <li>Longitude "<i>Long =</i>" and latitude "<i>Lat =</i>", if the associated <i>MapControl</i> object isn't projected, or the current distance unit
58
 *    of the <code>MapControl</code>'s view port is in degrees.</li>
59
 *   <li>X "<i>X =</i>" and Y "<i>Y =</i>", otherwise.</li>
60
 *  </ul>
61
 * </p>
62
 *
63
 * <p>And the <u>sufix</u> value:
64
 *  <ul>
65
 *   <li>If the associated <i>MapControl</i> object isn't projected, or the current distance unit
66
 *    of the <code>MapControl</code>'s view port is in degrees(expected latitude or longitude), according this pattern:<br>
67
 *    <code><b><i>S?G? M' S''</i></b></code>, having:<br>
68
 *    <ul>
69
 *     <li><i>S?</i> : optionally, if the value is negative, sets a "-" symbol.</li>
70
 *     <li><i>G</i> : equivalent grades.</li>
71
 *     <li><i>M</i> : equivalent minutes.</li>
72
 *     <li><i>S</i> : equivalent seconds.</li>
73
 *    </ul>
74
 *   </li>
75
 *   <li>Otherwise a decimal number according this rules:
76
 *    <ul>
77
 *     <li><i>8 decimals</i>, if is using any of the following geographic coordinate systems:
78
 *      <ul>
79
 *       <li><i>EPSG:4230 (known as <a href="http://en.wikipedia.org/wiki/ED50">ED50</a>)</i>.</li>
80
 *       <li><i>EPSG:4326 (known as <a href="http://en.wikipedia.org/wiki/WGS84">WGS84</a>)</i>.</li>
81
 *      </ul>
82
 *     <li><i>2 decimals</i>, otherwise.</li>
83
 *    </ul>
84
 *   </li>
85
 *  </ul>
86
 * </p>
87
 *
88
 * @author Vicente Caballero Navarro
89
 */
90
public class StatusBarListener implements PointListener {
91
        /**
92
         * Reference to the <code>MapControl</code> object that uses.
93
         */
94
        private MapControl mapControl = null;
95

    
96
        /**
97
         * Format of the coordinates. Is used to set the number of decimals.
98
         */
99
        private NumberFormat nf = null;
100

    
101
        /**
102
         * <p>Creates a new <code>StatusBarListener</code> object.</p>
103
         *
104
         * @param mc the <code>MapControl</code> where will be applied the changes
105
         */
106
        public StatusBarListener(MapControl mc) {
107
                mapControl = mc;
108
                nf = NumberFormat.getInstance();
109
                nf.setMaximumFractionDigits(2);
110
        }
111

    
112
        /*
113
         * (non-Javadoc)
114
         * @see com.iver.cit.gvsig.fmap.tools.Listeners.ToolListener#getImageCursor()
115
         */
116
        public Image getImageCursor() {
117
                return null;
118
        }
119

    
120
        /*
121
         * (non-Javadoc)
122
         * @see com.iver.cit.gvsig.fmap.tools.Listeners.ToolListener#cancelDrawing()
123
         */
124
        public boolean cancelDrawing() {
125
                return false;
126
        }
127

    
128
        /*
129
         * 050211, jmorell: M?todo modificado para mejorar la manera de mostrar las
130
         * coordenadas geod?sicas en la barra de estado. Muestra Lat y Lon y aumenta
131
         * el n?mero de decimales para cuando trabajemos en coordenadas geod?sicas.
132
         *
133
         * (non-Javadoc)
134
         * @see com.iver.cit.gvsig.fmap.tools.Listeners.PointListener#point(com.iver.cit.gvsig.fmap.tools.Events.PointEvent)
135
         */
136
        public void point(PointEvent event) throws BehaviorException {
137
                String[] axisText = new String[2];
138
                axisText[0] = "X = ";
139
                axisText[1] = "Y = ";
140
                Point2D p = mapControl.getMapContext().getViewPort().toMapPoint(event.getPoint());
141
                setFractionDigits(p);
142
                axisText = setCoorDisplayText(axisText);
143
                MainFrame mF = PluginServices.getMainFrame();
144

    
145
                if (mF != null){
146

    
147
                        mF.getStatusBar().setMessage("units",
148
                            PluginServices.getText(this, MapContext.getDistanceNames()[mapControl.getMapContext().getViewPort().getDistanceUnits()]));
149

    
150
                        // FJP: No se debe llamar a setControlValue desde aqu?, porque
151
            // cambia la escala, y con ella el viewPort (adem?s, de
152
            // la vista que no es).
153
            // mF.getStatusBar().setControlValue("scale",String.valueOf(mapControl.getMapContext().getScaleView()));
154
            // Fin
155
                        mF.getStatusBar().setMessage("projection", mapControl.getViewPort().getProjection().getAbrev());
156

    
157
                        String[] coords=getCoords(p);
158
                        mF.getStatusBar().setMessage("x", axisText[0] + coords[0]);
159
                        mF.getStatusBar().setMessage("y", axisText[1] + coords[1]);
160
                }
161
        }
162

    
163
        /**
164
         * <p>Sets the number of decimals of the coordinates that will be displayed, according the current projection
165
         *  of the associated <code>MapControl</code>:
166
         *  <ul>
167
         *   <li><i>8 decimals</i>, if is using geographical coordinates:
168
         *    <ul>
169
         *     <li><i>EPSG:4230 (known as <a href="http://en.wikipedia.org/wiki/ED50">ED50</a>)</i>.</li>
170
         *     <li><i>EPSG:4326 (known as <a href="http://en.wikipedia.org/wiki/WGS84">WGS84</a>)</i>.</li>
171
         *    </ul>
172
         *   <li><i>2 decimals</i>, otherwise.</li>
173
         *  </ul>
174
         * </p>
175
         *
176
         * @param p unused parameter
177
         *
178
         * @version 050211
179
         * @author jmorell.
180
         */
181
        public void setFractionDigits(Point2D p) {
182
                IProjection iProj = mapControl.getMapContext().getProjection();
183
                if (!iProj.isProjected()) {
184
                        nf.setMaximumFractionDigits(8);
185
                } else {
186
                        nf.setMaximumFractionDigits(2);
187
                }
188
        }
189

    
190
        /**
191
         * <p>Gets the name of the coordinates:
192
         *  <ul>
193
         *   <li><i>Longitude</i> and <i>Latitude</i>, if the associated <i>MapControl</i> object isn't projected, or the current distance unit
194
         *    of the <code>MapControl</code>'s view port is in degrees.</li>
195
         *   <li><i>X</i> and <i>Y</i>, otherwise.</li>
196
         *  </ul>
197
         * </p>
198
         *
199
         * @param p array of at least two <code>String</code>, where text will be stored and returned
200
         *
201
         * @return text describing the coordinate value:
202
         *  <ul>
203
         *   <li>If isn't projected:
204
         *    <ul>
205
         *     <li><code>String[0]</code> : "Long = "</li>
206
         *     <li><code>String[1]</code> : "Lat = "</li>
207
         *    </ul>
208
         *   </li>
209
         *   <li>Otherwise:
210
         *    <ul>
211
         *     <li><code>String[0]</code> : "X = "</li>
212
         *     <li><code>String[1]</code> : "Y = "</li>
213
         *    </ul>
214
         *   </li>
215
         *  </ul>
216
         *
217
         * @version 050211
218
         * @author jmorell
219
         */
220
        public String[] setCoorDisplayText(String[] axisText) {
221
                IProjection iProj = mapControl.getMapContext().getProjection();
222
                if (!iProj.isProjected() || MapContext.getDistanceNames()[mapControl.getMapContext().getViewPort().getDistanceUnits()].equals("Grados")) {
223
                        axisText[0] = "Lon = ";
224
                        axisText[1] = "Lat = ";
225
                } else {
226
                        axisText[0] = "X = ";
227
                        axisText[1] = "Y = ";
228
                }
229
                return axisText;
230
        }
231

    
232
        /**
233
         * <p>Converts a decimal value (expected latitude or longitude) in degrees, and formats it according this pattern:<br>
234
         *  <code><b><i>S?G? M' S''</i></b></code>, having:<br>
235
         *  <ul>
236
         *   <li><i>S?</i> : optionally, if the value is negative, sets a "-" symbol.</li>
237
         *   <li><i>G</i> : equivalent grades.</li>
238
         *   <li><i>M</i> : equivalent minutes.</li>
239
         *   <li><i>S</i> : equivalent seconds.</li>
240
         *  </ul>
241
         * </p>
242
         *
243
         * @param d the latitude or longitude value to convert
244
         *
245
         * @return value formatted in degrees
246
         */
247
        private String formatDegrees(double d) {
248
                String signo = d<0 ? "-" : "";
249
                d = Math.abs(d);
250
                long grado = 0;
251
                double minuto = 0;
252
                double segundo = 0;
253

    
254
                grado = (long)(d);
255
                minuto = (d - grado) * 60;
256
                segundo = (minuto - (long) minuto)*60;
257
//                System.out.println("Grados: " + grado);
258
//                System.out.println("Minutos: " + minuto);
259
//                System.out.println("Segundos: " + segundo);
260
                return signo+grado+"? "+(long) minuto+"' "+(long)segundo+"''";
261
        }
262

    
263
        /**
264
         * <p>Returns the coordinates equivalent to <code>p</code>:
265
         *  <ul>
266
         *   <li>Uses <i><code>formatDegrees(p.get{X or Y}()</code></i> if the associated <code>MapControl</code> object isn't projected.</li>
267
         *   <li>Uses <i><code>formatDegrees({MapControl's projection}.toGeo(p.get{X or Y}())</code></i> if the associated
268
         *    <code>MapControl</code> object is projected and its <code>ViewPort</code>'s distance units are in degrees.</li>
269
         *   <li>Uses <i><code>{NumberFormat according to {@link #setFractionDigits(Point2D) #setFractionDigits(Point2D)}}.format((p.get{X or Y}()/MapContext.CHANGEM[mapControl.getViewPort().getDistanceUnits()])*MapContext.CHANGEM[mapControl.getViewPort().getMapUnits()])</code></i>
270
         *    otherwise.</li>
271
         *  </ul>
272
         * </p>
273
         *
274
         * @param p point 2D to convert in text coordinates according the projection of the associated <code>MapControl</code> and the
275
         *  distance units of its <code>ViewPort</code>.
276
         *
277
         * @return coordinates equivalent to <code>p</code>, according to the algorithm explained up
278
         */
279
        public String[] getCoords(Point2D p) {
280
                String[] coords=new String[2];
281
                IProjection iProj = mapControl.getMapContext().getProjection();
282
                if (!iProj.isProjected()) {
283
                        coords[0]=String.valueOf(formatDegrees(p.getX()));
284
                        coords[1]=String.valueOf(formatDegrees(p.getY()));
285
                } else {
286
                        double[] trans2Meter=MapContext.getDistanceTrans2Meter();
287
                        if (PluginServices.getText(this,MapContext.getDistanceNames()[mapControl.getViewPort().getDistanceUnits()]).equals(PluginServices.getText(this,"Grados"))) {
288
                                Point2D pgeo=iProj.toGeo(p);
289
                                coords[0]=String.valueOf(formatDegrees(pgeo.getX()));
290
                                coords[1]=String.valueOf(formatDegrees(pgeo.getY()));
291
                        }else {
292
                                if (PluginServices.getText(this,MapContext.getDistanceNames()[mapControl.getViewPort().getMapUnits()]).equals(PluginServices.getText(this,"Grados"))) {
293
                                        mapControl.getViewPort().setMapUnits(1);
294
                                }
295

    
296
                                coords[0]=String.valueOf(nf.format((p.getX()/trans2Meter[mapControl.getViewPort().getDistanceUnits()])*trans2Meter[mapControl.getViewPort().getMapUnits()]));
297
                                coords[1]=String.valueOf(nf.format((p.getY()/trans2Meter[mapControl.getViewPort().getDistanceUnits()])*trans2Meter[mapControl.getViewPort().getMapUnits()]));
298
                        }
299
                }
300
                return coords;
301
        }
302

    
303
        /*
304
         * (non-Javadoc)
305
         * @see com.iver.cit.gvsig.fmap.tools.Listeners.PointListener#pointDoubleClick(com.iver.cit.gvsig.fmap.tools.Events.PointEvent)
306
         */
307
        public void pointDoubleClick(PointEvent event) throws BehaviorException {
308
                // TODO Auto-generated method stub
309
        }
310
}