001    /*
002     * Copyright (c) 2003 Objectix Pty Ltd  All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or
005     * modify it under the terms of the GNU Lesser General Public
006     * License as published by the Free Software Foundation.
007     *
008     * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
009     * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
010     * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
011     * DISCLAIMED.  IN NO EVENT SHALL OBJECTIX PTY LTD BE LIABLE FOR ANY
012     * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
013     * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
014     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
015     * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
016     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
017     * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
018     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
019     */
020    package org.openstreetmap.josm.data.projection.datum;
021    
022    import java.io.Serializable;
023    
024    import org.openstreetmap.josm.data.coor.LatLon;
025    
026    /**
027     * A value object for storing Longitude and Latitude of a point, the
028     * Lon and Lat shift values to get from one datum to another, and the
029     * Lon and Lat accuracy of the shift values.
030     * <p>All values are stored as Positive West Seconds, but accessors
031     * are also provided for Positive East Degrees.
032     *
033     * @author Peter Yuill
034     * Modifified for JOSM :
035     * - add a constructor for JOSM LatLon (Pieren)
036     */
037    public class NTV2GridShift implements Serializable {
038    
039        private static final double METRE_PER_SECOND = 2.0 * Math.PI * 6378137.0 / 3600.0 / 360.0;
040        private static final double RADIANS_PER_SECOND = 2.0 * Math.PI / 3600.0 / 360.0;
041        private double lon;
042        private double lat;
043        private double lonShift;
044        private double latShift;
045        private double lonAccuracy;
046        private double latAccuracy;
047        boolean latAccuracyAvailable;
048        boolean lonAccuracyAvailable;
049        private String subGridName;
050    
051        public NTV2GridShift() {
052        }
053    
054        public NTV2GridShift(LatLon p) {
055            setLatDegrees(p.lat());
056            setLonPositiveEastDegrees(p.lon());
057        }
058    
059        /**
060         * @return
061         */
062        public double getLatSeconds() {
063            return lat;
064        }
065    
066        /**
067         * @return
068         */
069        public double getLatDegrees() {
070            return lat / 3600.0;
071        }
072    
073        /**
074         * @return
075         */
076        public double getLatShiftSeconds() {
077            return latShift;
078        }
079    
080        /**
081         * @return
082         */
083        public double getLatShiftDegrees() {
084            return latShift / 3600.0;
085        }
086    
087        /**
088         * @return
089         */
090        public double getShiftedLatSeconds() {
091            return lat + latShift;
092        }
093    
094        /**
095         * @return
096         */
097        public double getShiftedLatDegrees() {
098            return (lat + latShift) / 3600.0;
099        }
100    
101        /**
102         * @return
103         */
104        public boolean isLatAccuracyAvailable() {
105            return latAccuracyAvailable;
106        }
107    
108        /**
109         * @return
110         */
111        public double getLatAccuracySeconds() {
112            if (!latAccuracyAvailable)
113                throw new IllegalStateException("Latitude Accuracy not available");
114            return latAccuracy;
115        }
116    
117        /**
118         * @return
119         */
120        public double getLatAccuracyDegrees() {
121            if (!latAccuracyAvailable)
122                throw new IllegalStateException("Latitude Accuracy not available");
123            return latAccuracy / 3600.0;
124        }
125    
126        /**
127         * @return
128         */
129        public double getLatAccuracyMetres() {
130            if (!latAccuracyAvailable)
131                throw new IllegalStateException("Latitude Accuracy not available");
132            return latAccuracy * METRE_PER_SECOND;
133        }
134    
135        /**
136         * @return
137         */
138        public double getLonPositiveWestSeconds() {
139            return lon;
140        }
141    
142        /**
143         * @return
144         */
145        public double getLonPositiveEastDegrees() {
146            return lon / -3600.0;
147        }
148    
149        /**
150         * @return
151         */
152        public double getLonShiftPositiveWestSeconds() {
153            return lonShift;
154        }
155    
156        /**
157         * @return
158         */
159        public double getLonShiftPositiveEastDegrees() {
160            return lonShift / -3600.0;
161        }
162    
163        /**
164         * @return
165         */
166        public double getShiftedLonPositiveWestSeconds() {
167            return lon + lonShift;
168        }
169    
170        /**
171         * @return
172         */
173        public double getShiftedLonPositiveEastDegrees() {
174            return (lon + lonShift) / -3600.0;
175        }
176    
177        /**
178         * @return
179         */
180        public boolean isLonAccuracyAvailable() {
181            return lonAccuracyAvailable;
182        }
183    
184        /**
185         * @return
186         */
187        public double getLonAccuracySeconds() {
188            if (!lonAccuracyAvailable)
189                throw new IllegalStateException("Longitude Accuracy not available");
190            return lonAccuracy;
191        }
192    
193        /**
194         * @return
195         */
196        public double getLonAccuracyDegrees() {
197            if (!lonAccuracyAvailable)
198                throw new IllegalStateException("Longitude Accuracy not available");
199            return lonAccuracy / 3600.0;
200        }
201    
202        /**
203         * @return
204         */
205        public double getLonAccuracyMetres() {
206            if (!lonAccuracyAvailable)
207                throw new IllegalStateException("Longitude Accuracy not available");
208            return lonAccuracy * METRE_PER_SECOND * Math.cos(RADIANS_PER_SECOND * lat);
209        }
210    
211        /**
212         * @param d
213         */
214        public void setLatSeconds(double d) {
215            lat = d;
216        }
217    
218        /**
219         * @param d
220         */
221        public void setLatDegrees(double d) {
222            lat = d * 3600.0;
223        }
224    
225        /**
226         * @param b
227         */
228        public void setLatAccuracyAvailable(boolean b) {
229            latAccuracyAvailable = b;
230        }
231    
232        /**
233         * @param d
234         */
235        public void setLatAccuracySeconds(double d) {
236            latAccuracy = d;
237        }
238    
239        /**
240         * @param d
241         */
242        public void setLatShiftSeconds(double d) {
243            latShift = d;
244        }
245    
246        /**
247         * @param d
248         */
249        public void setLonPositiveWestSeconds(double d) {
250            lon = d;
251        }
252    
253        /**
254         * @param d
255         */
256        public void setLonPositiveEastDegrees(double d) {
257            lon = d * -3600.0;
258        }
259    
260        /**
261         * @param b
262         */
263        public void setLonAccuracyAvailable(boolean b) {
264            lonAccuracyAvailable = b;
265        }
266    
267        /**
268         * @param d
269         */
270        public void setLonAccuracySeconds(double d) {
271            lonAccuracy = d;
272        }
273    
274        /**
275         * @param d
276         */
277        public void setLonShiftPositiveWestSeconds(double d) {
278            lonShift = d;
279        }
280    
281        /**
282         * @return
283         */
284        public String getSubGridName() {
285            return subGridName;
286        }
287    
288        /**
289         * @param string
290         */
291        public void setSubGridName(String string) {
292            subGridName = string;
293        }
294    
295        /**
296         * Make this object a copy of the supplied GridShift
297         * @param gs
298         */
299        public void copy(NTV2GridShift gs) {
300            this.lon = gs.lon;
301            this.lat = gs.lat;
302            this.lonShift = gs.lonShift;
303            this.latShift = gs.latShift;
304            this.lonAccuracy = gs.lonAccuracy;
305            this.latAccuracy = gs.latAccuracy;
306            this.latAccuracyAvailable = gs.latAccuracyAvailable;
307            this.lonAccuracyAvailable = gs.lonAccuracyAvailable;
308            this.subGridName = gs.subGridName;
309        }
310    
311    }