001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data.coor;
003
004import java.util.Objects;
005
006import org.openstreetmap.josm.Main;
007import org.openstreetmap.josm.data.projection.Projection;
008
009/**
010 * LatLon class that maintains a cache of projected EastNorth coordinates.
011 *
012 * This class is convenient to use, but has relatively high memory costs.
013 * It keeps a pointer to the last known projection in order to detect projection changes.
014 *
015 * Node and WayPoint have another, optimized, cache for projected coordinates.
016 */
017public class CachedLatLon extends LatLon {
018
019    private static final long serialVersionUID = 1L;
020
021    private EastNorth eastNorth;
022    private transient Projection proj;
023
024    /**
025     * Constructs a new {@code CachedLatLon}.
026     * @param lat latitude
027     * @param lon longitude
028     */
029    public CachedLatLon(double lat, double lon) {
030        super(lat, lon);
031    }
032
033    /**
034     * Constructs a new {@code CachedLatLon}.
035     * @param coor lat/lon
036     */
037    public CachedLatLon(LatLon coor) {
038        super(coor.lat(), coor.lon());
039        proj = null;
040    }
041
042    /**
043     * Constructs a new {@code CachedLatLon}.
044     * @param eastNorth easting/northing
045     */
046    public CachedLatLon(EastNorth eastNorth) {
047        super(Main.getProjection().eastNorth2latlon(eastNorth));
048        proj = Main.getProjection();
049        this.eastNorth = eastNorth;
050    }
051
052    /**
053     * Replies the projected east/north coordinates.
054     *
055     * @return the internally cached east/north coordinates. null, if the globally defined projection is null
056     */
057    public final EastNorth getEastNorth() {
058        if (!Objects.equals(proj, Main.getProjection())) {
059            proj = Main.getProjection();
060            eastNorth = proj.latlon2eastNorth(this);
061        }
062        return eastNorth;
063    }
064
065    @Override
066    public int hashCode() {
067        return Objects.hash(x, y, eastNorth);
068    }
069
070    @Override
071    public boolean equals(Object obj) {
072        if (!super.equals(obj))
073            return false;
074        CachedLatLon other = (CachedLatLon) obj;
075        return Objects.equals(eastNorth, other.eastNorth);
076    }
077
078    @Override
079    public String toString() {
080        return "CachedLatLon[lat="+lat()+",lon="+lon()+']';
081    }
082}