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.format;
021
022 import static java.lang.String.format;
023 import static java.util.Objects.requireNonNull;
024
025 import java.util.Objects;
026 import java.util.Optional;
027
028 import io.jenetics.jpx.Latitude;
029 import io.jenetics.jpx.Length;
030 import io.jenetics.jpx.Longitude;
031 import io.jenetics.jpx.Point;
032 import io.jenetics.jpx.WayPoint;
033
034 /**
035 * Aggregation of the three location components: latitude, longitude and
036 * elevation.
037 *
038 * @see Point
039 *
040 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
041 * @version 2.2
042 * @since 1.4
043 */
044 public final class Location {
045 private final Latitude _latitude;
046 private final Longitude _longitude;
047 private final Length _elevation;
048
049 private Location(
050 final Latitude latitude,
051 final Longitude longitude,
052 final Length elevation
053 ) {
054 _latitude = latitude;
055 _longitude = longitude;
056 _elevation = elevation;
057 }
058
059 /**
060 * Return the <em>latitude</em> of {@code this} location.
061 *
062 * @return the <em>latitude</em> of {@code this} location, or
063 * {@link Optional#empty()} if not available
064 */
065 public Optional<Latitude> latitude() {
066 return Optional.ofNullable(_latitude);
067 }
068
069 /**
070 * Return the <em>longitude</em> of {@code this} location.
071 *
072 * @return the <em>longitude</em> of {@code this} location, or
073 * {@link Optional#empty()} if not available
074 */
075 public Optional<Longitude> longitude() {
076 return Optional.ofNullable(_longitude);
077 }
078
079 /**
080 * Return the <em>elevation</em> of {@code this} location.
081 *
082 * @return the <em>elevation</em> of {@code this} location, or
083 * {@link Optional#empty()} if not available
084 */
085 public Optional<Length> elevation() {
086 return Optional.ofNullable(_elevation);
087 }
088
089 /**
090 * Return a new {@link Point} from {@code this} location. If the
091 * {@link #latitude()} or the {@link #longitude()} is not given,
092 * {@link Optional#empty()} is returned
093 *
094 * @return a new {@link Point} if the latitude and longitude is given,
095 * {@link Optional#empty()} otherwise
096 */
097 public Optional<Point> toPoint() {
098 return latitude().flatMap(lat ->
099 longitude().map(lon ->
100 WayPoint.of(lat, lon, _elevation, null)
101 )
102 );
103 }
104
105 @Override
106 public int hashCode(){
107 return Objects.hash(_latitude, _longitude, _elevation);
108 }
109
110 @Override
111 public boolean equals(final Object other) {
112 return other == this ||
113 other instanceof Location loc &&
114 Objects.equals(_latitude, loc._latitude) &&
115 Objects.equals(_longitude, loc._longitude) &&
116 Objects.equals(_elevation, loc._elevation);
117 }
118
119 @Override
120 public String toString() {
121 return format(
122 "[lat=%s, lon=%s, ele=%s]",
123 _latitude, _longitude, _elevation
124 );
125 }
126
127 /**
128 * Create a new location form the given GPS point.
129 *
130 * @param point the GPS point
131 * @return a new location form the given GPS point
132 * @throws NullPointerException if the given {@code point} is {@code null}
133 */
134 public static Location of(final Point point) {
135 requireNonNull(point);
136 return of(
137 point.getLatitude(),
138 point.getLongitude(),
139 point.getElevation().orElse(null)
140 );
141 }
142
143 /**
144 * Create a new <em>location</em> object from the given {@code latitude},
145 * {@code longitude} and {@code elevation}.
146 *
147 * @param latitude the latitude of the location, maybe {@code null}
148 * @param longitude the longitude of the location, maybe {@code null}
149 * @param elevation the elevation if the location, maybe {@code null}
150 * @return a new location object from the given input data
151 */
152 public static Location of(
153 final Latitude latitude,
154 final Longitude longitude,
155 final Length elevation
156 ) {
157 return new Location(latitude, longitude, elevation);
158 }
159
160 /**
161 * Create a new <em>location</em> object from the given {@code latitude}
162 * and {@code longitude}.
163 *
164 * @param latitude the latitude of the location, maybe {@code null}
165 * @param longitude the longitude of the location, maybe {@code null}
166 * @return a new location object from the given input data
167 */
168 public static Location of(final Latitude latitude, final Longitude longitude) {
169 return new Location(latitude, longitude, null);
170 }
171
172 /**
173 * Create a new <em>location</em> object from the given {@code latitude}.
174 *
175 * @param latitude the latitude of the location, maybe {@code null}
176 * @return a new location object from the given input data
177 */
178 public static Location of(final Latitude latitude) {
179 return new Location(latitude, null, null);
180 }
181
182 /**
183 * Create a new <em>location</em> object from the given {@code longitude}.
184 *
185 * @param longitude the longitude of the location, maybe {@code null}
186 * @return a new location object from the given input data
187 */
188 public static Location of(final Longitude longitude) {
189 return new Location(null, longitude, null);
190 }
191
192 /**
193 * Create a new <em>location</em> object from the given {@code elevation}.
194 *
195 * @param elevation the elevation of the location, maybe {@code null}
196 * @return a new location object from the given input data
197 */
198 public static Location of(final Length elevation) {
199 return new Location(null, null, elevation);
200 }
201
202 }
|