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