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 */
020package org.openstreetmap.josm.data.projection.datum;
021
022import java.io.Serializable;
023
024import org.openstreetmap.josm.data.coor.LatLon;
025import org.openstreetmap.josm.data.projection.Ellipsoid;
026
027/**
028 * A value object for storing Longitude and Latitude of a point, the
029 * Lon and Lat shift values to get from one datum to another, and the
030 * Lon and Lat accuracy of the shift values.
031 * <p>All values are stored as Positive West Seconds, but accessors
032 * are also provided for Positive East Degrees.
033 *
034 * @author Peter Yuill
035 * Modifified for JOSM :
036 * - add a constructor for JOSM LatLon (Pieren)
037 */
038public class NTV2GridShift implements Serializable {
039
040    private static final long serialVersionUID = 1L;
041
042    private static final double METRE_PER_SECOND = 2.0 * Math.PI * Ellipsoid.WGS84.a / 3600.0 / 360.0;
043    private static final double RADIANS_PER_SECOND = 2.0 * Math.PI / 3600.0 / 360.0;
044    private double lon;
045    private double lat;
046    private double lonShift;
047    private double latShift;
048    private double lonAccuracy;
049    private double latAccuracy;
050    private boolean latAccuracyAvailable;
051    private boolean lonAccuracyAvailable;
052    private String subGridName;
053
054    /**
055     * Constructs a new {@code NTV2GridShift}.
056     */
057    public NTV2GridShift() {
058        // contents can be set later with setters
059    }
060
061    /**
062     * Constructs a new {@code NTV2GridShift} from a {@code LatLon}.
063     * @param p lat/lon
064     */
065    public NTV2GridShift(LatLon p) {
066        setLatDegrees(p.lat());
067        setLonPositiveEastDegrees(p.lon());
068    }
069
070    /**
071     * Data access function for latitude value
072     * @return latitude in seconds
073     */
074    public double getLatSeconds() {
075        return lat;
076    }
077
078    /**
079     * Data access function for latitude value
080     * @return latitude in degree
081     */
082    public double getLatDegrees() {
083        return lat / 3600.0;
084    }
085
086    /**
087     * Data access function for latitude shift value
088     * @return latitude shift in seconds
089     */
090    public double getLatShiftSeconds() {
091        return latShift;
092    }
093
094    /**
095     * Data access function for latitude shift value
096     * @return latitude shift in degree
097     */
098    public double getLatShiftDegrees() {
099        return latShift / 3600.0;
100    }
101
102    /**
103     * Data access function for already shifted latitude value
104     * @return shifted latitude in seconds
105     */
106    public double getShiftedLatSeconds() {
107        return lat + latShift;
108    }
109
110    /**
111     * Data access function for already shifted latitude value
112     * @return shifted latitude in degree
113     */
114    public double getShiftedLatDegrees() {
115        return (lat + latShift) / 3600.0;
116    }
117
118    /**
119     * Checks whether latitude accuracy is available or not
120     * @return <code>true</code> if latitude accuracy is available
121     */
122    public boolean isLatAccuracyAvailable() {
123        return latAccuracyAvailable;
124    }
125
126    /**
127     * Data access function for latitude accuracy
128     * @return latitude accuracy in seconds
129     */
130    public double getLatAccuracySeconds() {
131        if (!latAccuracyAvailable)
132            throw new IllegalStateException("Latitude Accuracy not available");
133        return latAccuracy;
134    }
135
136    /**
137     * Data access function for latitude accuracy
138     * @return latitude accuracy in degree
139     */
140    public double getLatAccuracyDegrees() {
141        if (!latAccuracyAvailable)
142            throw new IllegalStateException("Latitude Accuracy not available");
143        return latAccuracy / 3600.0;
144    }
145
146    /**
147     * Data access function for latitude accuracy
148     * @return latitude accuracy in meter
149     */
150    public double getLatAccuracyMetres() {
151        if (!latAccuracyAvailable)
152            throw new IllegalStateException("Latitude Accuracy not available");
153        return latAccuracy * METRE_PER_SECOND;
154    }
155
156    /**
157     * Data access function for longitude value, positive values in west direction
158     * @return longitude in seconds
159     */
160    public double getLonPositiveWestSeconds() {
161        return lon;
162    }
163
164    /**
165     * Data access function for longitude value, positive values in east direction
166     * @return longitude in degree
167     */
168    public double getLonPositiveEastDegrees() {
169        return lon / -3600.0;
170    }
171
172    /**
173     * Data access function for longitude shift value, positive values in west direction
174     * @return longitude shift in seconds
175     */
176    public double getLonShiftPositiveWestSeconds() {
177        return lonShift;
178    }
179
180    /**
181     * Data access function for longitude shift value, positive values in east direction
182     * @return longitude shift in degree
183     */
184    public double getLonShiftPositiveEastDegrees() {
185        return lonShift / -3600.0;
186    }
187
188    /**
189     * Data access function for shifted longitude value, positive values in west direction
190     * @return shifted longitude in seconds
191     */
192    public double getShiftedLonPositiveWestSeconds() {
193        return lon + lonShift;
194    }
195
196    /**
197     * Data access function for shifted longitude value, positive values in east direction
198     * @return shifted longitude in degree
199     */
200    public double getShiftedLonPositiveEastDegrees() {
201        return (lon + lonShift) / -3600.0;
202    }
203
204    /**
205     * Checks whether longitude accuracy is available or not
206     * @return <code>true</code> if longitude accuracy is available
207     */
208    public boolean isLonAccuracyAvailable() {
209        return lonAccuracyAvailable;
210    }
211
212    /**
213     * Data access function for longitude accuracy
214     * @return longitude accuracy in seconds
215     */
216    public double getLonAccuracySeconds() {
217        if (!lonAccuracyAvailable)
218            throw new IllegalStateException("Longitude Accuracy not available");
219        return lonAccuracy;
220    }
221
222    /**
223     * Data access function for longitude accuracy
224     * @return longitude accuracy in degree
225     */
226    public double getLonAccuracyDegrees() {
227        if (!lonAccuracyAvailable)
228            throw new IllegalStateException("Longitude Accuracy not available");
229        return lonAccuracy / 3600.0;
230    }
231
232    /**
233     * Data access function for longitude accuracy
234     * @return longitude accuracy in meter
235     */
236    public double getLonAccuracyMetres() {
237        if (!lonAccuracyAvailable)
238            throw new IllegalStateException("Longitude Accuracy not available");
239        return lonAccuracy * METRE_PER_SECOND * Math.cos(RADIANS_PER_SECOND * lat);
240    }
241
242    /**
243     * Data store function for latitude
244     * @param d latitude value in seconds
245     */
246    public final void setLatSeconds(double d) {
247        lat = d;
248    }
249
250    /**
251     * Data store function for latitude
252     * @param d latitude value in degree
253     */
254    public final void setLatDegrees(double d) {
255        lat = d * 3600.0;
256    }
257
258    /**
259     * Data store function for latitude accuracy availability
260     * @param b availability of latitude accuracy
261     */
262    public final void setLatAccuracyAvailable(boolean b) {
263        latAccuracyAvailable = b;
264    }
265
266    /**
267     * Data store function for latitude accuracy
268     * @param d latitude accuracy in seconds
269     */
270    public final void setLatAccuracySeconds(double d) {
271        latAccuracy = d;
272    }
273
274    /**
275     * Data store function for latitude shift
276     * @param d latitude shift in seconds
277     */
278    public final void setLatShiftSeconds(double d) {
279        latShift = d;
280    }
281
282    /**
283     * Data store function for longitude
284     * @param d latitude value in seconds, west direction is positive
285     */
286    public final void setLonPositiveWestSeconds(double d) {
287        lon = d;
288    }
289
290    /**
291     * Data store function for longitude
292     * @param d latitude value in degree, est direction is positive
293     */
294    public final void setLonPositiveEastDegrees(double d) {
295        lon = d * -3600.0;
296    }
297
298    /**
299     * Data store function for longitude accuracy availability
300     * @param b availability of longitude accuracy
301     */
302    public final void setLonAccuracyAvailable(boolean b) {
303        lonAccuracyAvailable = b;
304    }
305
306    /**
307     * Data store function for longitude accuracy
308     * @param d longitude accuracy in seconds
309     */
310    public final void setLonAccuracySeconds(double d) {
311        lonAccuracy = d;
312    }
313
314    /**
315     * Data store function for longitude shift value
316     * @param d longitude shift in seconds, west direction is positive
317     */
318    public final void setLonShiftPositiveWestSeconds(double d) {
319        lonShift = d;
320    }
321
322    /**
323     * Get the name of the sub grid
324     * @return name of the sub grid
325     */
326    public String getSubGridName() {
327        return subGridName;
328    }
329
330    /**
331     * Set the name of the sub grid
332     * @param string name of the sub grid
333     */
334    public void setSubGridName(String string) {
335        subGridName = string;
336    }
337}