source: josm/trunk/src/org/openstreetmap/josm/data/gpx/WayPoint.java @ 14068

Last change on this file since 14068 was 14068, checked in by Don-vip, 8 months ago

checkstyle/sonarqube

  • Property svn:eol-style set to native
File size: 6.7 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.gpx;
3
4import java.awt.Color;
5import java.util.ArrayList;
6import java.util.Date;
7import java.util.List;
8import java.util.Objects;
9
10import org.openstreetmap.josm.data.coor.EastNorth;
11import org.openstreetmap.josm.data.coor.ILatLon;
12import org.openstreetmap.josm.data.coor.LatLon;
13import org.openstreetmap.josm.data.osm.search.SearchCompiler.Match;
14import org.openstreetmap.josm.data.projection.Projecting;
15import org.openstreetmap.josm.tools.Logging;
16import org.openstreetmap.josm.tools.UncheckedParseException;
17import org.openstreetmap.josm.tools.date.DateUtils;
18import org.openstreetmap.josm.tools.template_engine.TemplateEngineDataProvider;
19
20/**
21 * A point in the GPX data
22 * @since 12167 implements ILatLon
23 */
24public class WayPoint extends WithAttributes implements Comparable<WayPoint>, TemplateEngineDataProvider, ILatLon {
25
26    /**
27     * The seconds (not milliseconds!) since 1970-01-01 00:00 UTC
28     */
29    public double time;
30    /**
31     * The color to draw the segment before this point in
32     * @see #drawLine
33     */
34    public Color customColoring;
35    /**
36     * <code>true</code> indicates that the line before this point should be drawn
37     */
38    public boolean drawLine;
39    /**
40     * The direction of the line before this point. Used as cache to speed up drawing. Should not be relied on.
41     */
42    public int dir;
43
44    /**
45     * Constructs a new {@code WayPoint} from an existing one.
46     * @param p existing waypoint
47     */
48    public WayPoint(WayPoint p) {
49        attr.putAll(p.attr);
50        lat = p.lat;
51        lon = p.lon;
52        east = p.east;
53        north = p.north;
54        eastNorthCacheKey = p.eastNorthCacheKey;
55        time = p.time;
56        customColoring = p.customColoring;
57        drawLine = p.drawLine;
58        dir = p.dir;
59    }
60
61    /**
62     * Constructs a new {@code WayPoint} from lat/lon coordinates.
63     * @param ll lat/lon coordinates
64     */
65    public WayPoint(LatLon ll) {
66        lat = ll.lat();
67        lon = ll.lon();
68    }
69
70    /*
71     * We "inline" lat/lon, rather than usinga LatLon internally => reduces memory overhead. Relevant
72     * because a lot of GPX waypoints are created when GPS tracks are downloaded from the OSM server.
73     */
74    private final double lat;
75    private final double lon;
76
77    /*
78     * internal cache of projected coordinates
79     */
80    private double east = Double.NaN;
81    private double north = Double.NaN;
82    private Object eastNorthCacheKey;
83
84    /**
85     * Invalidate the internal cache of east/north coordinates.
86     */
87    public void invalidateEastNorthCache() {
88        this.east = Double.NaN;
89        this.north = Double.NaN;
90    }
91
92    /**
93     * Returns the waypoint coordinates.
94     * @return the waypoint coordinates
95     */
96    public final LatLon getCoor() {
97        return new LatLon(lat, lon);
98    }
99
100    @Override
101    public double lon() {
102        return lon;
103    }
104
105    @Override
106    public double lat() {
107        return lat;
108    }
109
110    @Override
111    public final EastNorth getEastNorth(Projecting projecting) {
112        Object newCacheKey = projecting.getCacheKey();
113        if (Double.isNaN(east) || Double.isNaN(north) || !Objects.equals(newCacheKey, this.eastNorthCacheKey)) {
114            // projected coordinates haven't been calculated yet,
115            // so fill the cache of the projected waypoint coordinates
116            EastNorth en = projecting.latlon2eastNorth(this);
117            this.east = en.east();
118            this.north = en.north();
119            this.eastNorthCacheKey = newCacheKey;
120        }
121        return new EastNorth(east, north);
122    }
123
124    @Override
125    public String toString() {
126        return "WayPoint (" + (attr.containsKey(GPX_NAME) ? get(GPX_NAME) + ", " : "") + getCoor() + ", " + attr + ')';
127    }
128
129    /**
130     * Sets the {@link #time} field as well as the {@link #PT_TIME} attribute to the specified time
131     *
132     * @param time the time to set
133     * @since 9383
134     */
135    public void setTime(Date time) {
136        this.time = time.getTime() / 1000.;
137        this.attr.put(PT_TIME, DateUtils.fromDate(time));
138    }
139
140    /**
141     * Convert the time stamp of the waypoint into seconds from the epoch
142     */
143    public void setTime() {
144        setTimeFromAttribute();
145    }
146
147    /**
148     * Set the the time stamp of the waypoint into seconds from the epoch,
149     * @param time millisecond from the epoch
150     * @since 13210
151     */
152    public void setTime(long time) {
153        this.time = time / 1000.;
154    }
155
156    /**
157     * Convert the time stamp of the waypoint into seconds from the epoch
158     * @return The parsed time if successful, or {@code null}
159     * @since 9383
160     */
161    public Date setTimeFromAttribute() {
162        if (attr.containsKey(PT_TIME)) {
163            try {
164                final Object obj = get(PT_TIME);
165                final Date date = obj instanceof Date ? (Date) obj : DateUtils.fromString(obj.toString());
166                time = date.getTime() / 1000.;
167                return date;
168            } catch (UncheckedParseException e) {
169                Logging.warn(e);
170                time = 0;
171            }
172        }
173        return null;
174    }
175
176    @Override
177    public int compareTo(WayPoint w) {
178        return Double.compare(time, w.time);
179    }
180
181    /**
182     * Returns the waypoint time.
183     * @return the waypoint time
184     */
185    public Date getTime() {
186        return new Date((long) (time * 1000));
187    }
188
189    @Override
190    public Object getTemplateValue(String name, boolean special) {
191        if (!special)
192            return get(name);
193        else
194            return null;
195    }
196
197    @Override
198    public boolean evaluateCondition(Match condition) {
199        throw new UnsupportedOperationException();
200    }
201
202    @Override
203    public List<String> getTemplateKeys() {
204        return new ArrayList<>(attr.keySet());
205    }
206
207    @Override
208    public int hashCode() {
209        final int prime = 31;
210        int result = super.hashCode();
211        long temp = Double.doubleToLongBits(lat);
212        result = prime * result + (int) (temp ^ (temp >>> 32));
213        temp = Double.doubleToLongBits(lon);
214        result = prime * result + (int) (temp ^ (temp >>> 32));
215        temp = Double.doubleToLongBits(time);
216        result = prime * result + (int) (temp ^ (temp >>> 32));
217        return result;
218    }
219
220    @Override
221    public boolean equals(Object obj) {
222        if (this == obj)
223            return true;
224        if (obj == null || !super.equals(obj) || getClass() != obj.getClass())
225            return false;
226        WayPoint other = (WayPoint) obj;
227        return Double.doubleToLongBits(lat) == Double.doubleToLongBits(other.lat)
228            && Double.doubleToLongBits(lon) == Double.doubleToLongBits(other.lon)
229            && Double.doubleToLongBits(time) == Double.doubleToLongBits(other.time);
230    }
231}
Note: See TracBrowser for help on using the repository browser.