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;
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 */
037public 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    /**
052     * Constructs a new {@code NTV2GridShift}.
053     */
054    public NTV2GridShift() {
055    }
056
057    public NTV2GridShift(LatLon p) {
058        setLatDegrees(p.lat());
059        setLonPositiveEastDegrees(p.lon());
060    }
061
062    /**
063     * Data access function for latitude value
064     * @return latitude in seconds
065     */
066    public double getLatSeconds() {
067        return lat;
068    }
069
070    /**
071     * Data access function for latitude value
072     * @return latitude in degree
073     */
074    public double getLatDegrees() {
075        return lat / 3600.0;
076    }
077
078    /**
079     * Data access function for latitude shift value
080     * @return latitude shift in seconds
081     */
082    public double getLatShiftSeconds() {
083        return latShift;
084    }
085
086    /**
087     * Data access function for latitude shift value
088     * @return latitude shift in degree
089     */
090    public double getLatShiftDegrees() {
091        return latShift / 3600.0;
092    }
093
094    /**
095     * Data access function for already shifted latitude value
096     * @return shifted latitude in seconds
097     */
098    public double getShiftedLatSeconds() {
099        return lat + latShift;
100    }
101
102    /**
103     * Data access function for already shifted latitude value
104     * @return shifted latitude in degree
105     */
106    public double getShiftedLatDegrees() {
107        return (lat + latShift) / 3600.0;
108    }
109
110    /**
111     * Checks whether latitude accuracy is available or not
112     * @return <code>true</code> if latitude accuracy is available
113     */
114    public boolean isLatAccuracyAvailable() {
115        return latAccuracyAvailable;
116    }
117
118    /**
119     * Data access function for latitude accuracy
120     * @return latitude accuracy in seconds
121     */
122    public double getLatAccuracySeconds() {
123        if (!latAccuracyAvailable)
124            throw new IllegalStateException("Latitude Accuracy not available");
125        return latAccuracy;
126    }
127
128    /**
129     * Data access function for latitude accuracy
130     * @return latitude accuracy in degree
131     */
132    public double getLatAccuracyDegrees() {
133        if (!latAccuracyAvailable)
134            throw new IllegalStateException("Latitude Accuracy not available");
135        return latAccuracy / 3600.0;
136    }
137
138    /**
139     * Data access function for latitude accuracy
140     * @return latitude accuracy in meter
141     */
142    public double getLatAccuracyMetres() {
143        if (!latAccuracyAvailable)
144            throw new IllegalStateException("Latitude Accuracy not available");
145        return latAccuracy * METRE_PER_SECOND;
146    }
147
148    /**
149     * Data access function for longitude value, positive values in west direction
150     * @return longitude in seconds
151     */
152    public double getLonPositiveWestSeconds() {
153        return lon;
154    }
155
156    /**
157     * Data access function for longitude value, positive values in east direction
158     * @return longitude in degree
159     */
160    public double getLonPositiveEastDegrees() {
161        return lon / -3600.0;
162    }
163
164    /**
165     * Data access function for longitude shift value, positive values in west direction
166     * @return longitude shift in seconds
167     */
168    public double getLonShiftPositiveWestSeconds() {
169        return lonShift;
170    }
171
172    /**
173     * Data access function for longitude shift value, positive values in east direction
174     * @return longitude shift in degree
175     */
176    public double getLonShiftPositiveEastDegrees() {
177        return lonShift / -3600.0;
178    }
179
180    /**
181     * Data access function for shifted longitude value, positive values in west direction
182     * @return shifted longitude in seconds
183     */
184    public double getShiftedLonPositiveWestSeconds() {
185        return lon + lonShift;
186    }
187
188    /**
189     * Data access function for shifted longitude value, positive values in east direction
190     * @return shifted longitude in degree
191     */
192    public double getShiftedLonPositiveEastDegrees() {
193        return (lon + lonShift) / -3600.0;
194    }
195
196    /**
197     * Checks whether longitude accuracy is available or not
198     * @return <code>true</code> if longitude accuracy is available
199     */
200    public boolean isLonAccuracyAvailable() {
201        return lonAccuracyAvailable;
202    }
203
204    /**
205     * Data access function for longitude accuracy
206     * @return longitude accuracy in seconds
207     */
208    public double getLonAccuracySeconds() {
209        if (!lonAccuracyAvailable)
210            throw new IllegalStateException("Longitude Accuracy not available");
211        return lonAccuracy;
212    }
213
214    /**
215     * Data access function for longitude accuracy
216     * @return longitude accuracy in degree
217     */
218    public double getLonAccuracyDegrees() {
219        if (!lonAccuracyAvailable)
220            throw new IllegalStateException("Longitude Accuracy not available");
221        return lonAccuracy / 3600.0;
222    }
223
224    /**
225     * Data access function for longitude accuracy
226     * @return longitude accuracy in meter
227     */
228    public double getLonAccuracyMetres() {
229        if (!lonAccuracyAvailable)
230            throw new IllegalStateException("Longitude Accuracy not available");
231        return lonAccuracy * METRE_PER_SECOND * Math.cos(RADIANS_PER_SECOND * lat);
232    }
233
234    /**
235     * Data store function for latitude
236     * @param d latitude value in seconds
237     */
238    public final void setLatSeconds(double d) {
239        lat = d;
240    }
241
242    /**
243     * Data store function for latitude
244     * @param d latitude value in degree
245     */
246    public final void setLatDegrees(double d) {
247        lat = d * 3600.0;
248    }
249
250    /**
251     * Data store function for latitude accuracy availability
252     * @param b availability of latitude accuracy
253     */
254    public final void setLatAccuracyAvailable(boolean b) {
255        latAccuracyAvailable = b;
256    }
257
258    /**
259     * Data store function for latitude accuracy
260     * @param d latitude accuracy in seconds
261     */
262    public final void setLatAccuracySeconds(double d) {
263        latAccuracy = d;
264    }
265
266    /**
267     * Data store function for latitude shift
268     * @param d latitude shift in seconds
269     */
270    public final void setLatShiftSeconds(double d) {
271        latShift = d;
272    }
273
274    /**
275     * Data store function for longitude
276     * @param d latitude value in seconds, west direction is positive
277     */
278    public final void setLonPositiveWestSeconds(double d) {
279        lon = d;
280    }
281
282    /**
283     * Data store function for longitude
284     * @param d latitude value in degree, est direction is positive
285     */
286    public final void setLonPositiveEastDegrees(double d) {
287        lon = d * -3600.0;
288    }
289
290    /**
291     * Data store function for longitude accuracy availability
292     * @param b availability of longitude accuracy
293     */
294    public final void setLonAccuracyAvailable(boolean b) {
295        lonAccuracyAvailable = b;
296    }
297
298    /**
299     * Data store function for longitude accuracy
300     * @param d longitude accuracy in seconds
301     */
302    public final void setLonAccuracySeconds(double d) {
303        lonAccuracy = d;
304    }
305
306    /**
307     * Data store function for longitude shift value
308     * @param d longitude shift in seconds, west direction is positive
309     */
310    public final void setLonShiftPositiveWestSeconds(double d) {
311        lonShift = d;
312    }
313
314    /**
315     * Get the name of the sub grid
316     * @return name of the sub grid
317     */
318    public String getSubGridName() {
319        return subGridName;
320    }
321
322    /**
323     * Set the name of the sub grid
324     * @param string name of the sub grid
325     */
326    public void setSubGridName(String string) {
327        subGridName = string;
328    }
329
330    /**
331     * Make this object a copy of the supplied GridShift
332     * @param gs grid to copy data from
333     */
334    public void copy(NTV2GridShift gs) {
335        this.lon = gs.lon;
336        this.lat = gs.lat;
337        this.lonShift = gs.lonShift;
338        this.latShift = gs.latShift;
339        this.lonAccuracy = gs.lonAccuracy;
340        this.latAccuracy = gs.latAccuracy;
341        this.latAccuracyAvailable = gs.latAccuracyAvailable;
342        this.lonAccuracyAvailable = gs.lonAccuracyAvailable;
343        this.subGridName = gs.subGridName;
344    }
345
346}