001 /*
002 * Java GPX Library (jpx-3.1.0).
003 * Copyright (c) 2016-2023 Franz Wilhelmstötter
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 *
017 * Author:
018 * Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
019 */
020 package io.jenetics.jpx;
021
022 import static java.lang.String.format;
023
024 import java.io.DataInput;
025 import java.io.DataOutput;
026 import java.io.IOException;
027 import java.io.InvalidObjectException;
028 import java.io.ObjectInputStream;
029 import java.io.Serial;
030 import java.io.Serializable;
031
032 /**
033 * The longitude of the point. Decimal degrees, WGS84 datum, which must be within
034 * the range of {@code [-180..180]}.
035 *
036 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
037 * @version 2.0
038 * @since 1.0
039 */
040 public final class Longitude extends Number implements Serializable {
041
042 @Serial
043 private static final long serialVersionUID = 2L;
044
045 /**
046 * A constant holding the maximum value a {@code Latitude} value can have,
047 * -180 inclusively.
048 *
049 * @since 2.0
050 */
051 public static final double MIN_DEGREES = -180;
052
053 /**
054 * A constant holding the maximum value a {@code Latitude} value can have,
055 * -180 inclusively.
056 *
057 * @since 2.0
058 */
059 public static final Longitude MIN_VALUE = ofDegrees(MIN_DEGREES);
060
061 /**
062 * A constant holding the maximum value a {@code Latitude} value can have,
063 * 180 inclusively.
064 *
065 * @since 2.0
066 */
067 public static final double MAX_DEGREES = 180;
068
069 /**
070 * A constant holding the maximum value a {@code Latitude} value can have,
071 * 180 inclusively.
072 *
073 * @since 2.0
074 */
075 public static final Longitude MAX_VALUE = ofDegrees(MAX_DEGREES);
076
077 private final double _value;
078
079 /**
080 * Create a new (decimal degrees) {@code Longitude} value.
081 *
082 * @param value the longitude value in decimal degrees
083 * @throws IllegalArgumentException if the given value is not within the
084 * range of {@code [-180..180]}
085 */
086 private Longitude(final double value) {
087 if (value < MIN_DEGREES || value > MAX_DEGREES) {
088 throw new IllegalArgumentException(format(
089 "%f is not in range [-180, 180).", value
090 ));
091 }
092
093 _value = value;
094 }
095
096 /**
097 * Return the longitude value in decimal degrees.
098 *
099 * @return the longitude value in decimal degrees
100 */
101 @Override
102 public double doubleValue() {
103 return _value;
104 }
105
106 /**
107 * Return the longitude value in radians.
108 *
109 * @return the longitude value in radians
110 */
111 public double toRadians() {
112 return Math.toRadians(_value);
113 }
114
115 /**
116 * Return the longitude in decimal degree.
117 *
118 * @return the longitude in decimal degree
119 */
120 public double toDegrees() {
121 return _value;
122 }
123
124 @Override
125 public int intValue() {
126 return (int)doubleValue();
127 }
128
129 @Override
130 public long longValue() {
131 return (long)doubleValue();
132 }
133
134 @Override
135 public float floatValue() {
136 return (float)doubleValue();
137 }
138
139 @Override
140 public int hashCode() {
141 return Double.hashCode(_value);
142 }
143
144 @Override
145 public boolean equals(final Object obj) {
146 return obj == this ||
147 obj instanceof Longitude lng &&
148 Double.compare(lng._value, _value) == 0;
149 }
150
151 @Override
152 public String toString() {
153 return Double.toString(_value);
154 }
155
156
157 /* *************************************************************************
158 * Static object creation methods
159 * ************************************************************************/
160
161 /**
162 * Create a new (decimal degrees) {@code Longitude} object.
163 *
164 * @param degrees the longitude value in decimal degrees
165 * @return a new (decimal degrees) {@code Longitude} object
166 * @throws IllegalArgumentException if the given value is not within the
167 * range of {@code [-180..180)}
168 */
169 public static Longitude ofDegrees(final double degrees) {
170 return new Longitude(degrees);
171 }
172
173 /**
174 * Create a new {@code Longitude} value for the given {@code radians}.
175 *
176 * @param radians the longitude value in radians
177 * @return a new {@code Longitude} value for the given {@code radians}
178 * @throws IllegalArgumentException if the given radians is not within the
179 * range of {@code [-2*Pi..2*Pi]}
180 */
181 public static Longitude ofRadians(final double radians) {
182 return new Longitude(Math.toDegrees(radians));
183 }
184
185 static Longitude parse(final String value) {
186 final String lon = Strings.trim(value);
187 return lon != null
188 ? Longitude.ofDegrees(Double.parseDouble(lon))
189 : null;
190 }
191
192 /* *************************************************************************
193 * Java object serialization
194 * ************************************************************************/
195
196 @Serial
197 private Object writeReplace() {
198 return new SerialProxy(SerialProxy.LONGITUDE, this);
199 }
200
201 @Serial
202 private void readObject(final ObjectInputStream stream)
203 throws InvalidObjectException
204 {
205 throw new InvalidObjectException("Serialization proxy required.");
206 }
207
208 void write(final DataOutput out) throws IOException {
209 out.writeDouble(_value);
210 }
211
212 static Longitude read(final DataInput in) throws IOException {
213 return new Longitude(in.readDouble());
214 }
215
216 }
|