001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data.osm;
003
004import org.openstreetmap.josm.data.coor.EastNorth;
005import org.openstreetmap.josm.data.coor.LatLon;
006import org.openstreetmap.josm.data.osm.visitor.PrimitiveVisitor;
007import org.openstreetmap.josm.data.projection.Projections;
008
009public class NodeData extends PrimitiveData implements INode {
010
011    /*
012     * we "inline" lat/lon coordinates instead of using a LatLon => reduces memory footprint
013     */
014    private double lat = Double.NaN;
015    private double lon = Double.NaN;
016
017    /**
018     * Constructs a new {@code NodeData}.
019     */
020    public NodeData() {
021        // contents can be set later with setters
022    }
023
024    /**
025     * Constructs a new {@code NodeData}.
026     * @param data node data to copy
027     */
028    public NodeData(NodeData data) {
029        super(data);
030        setCoor(data.getCoor());
031    }
032
033    private boolean isLatLonKnown() {
034        return !Double.isNaN(lat) && !Double.isNaN(lon);
035    }
036
037    @Override
038    public LatLon getCoor() {
039        return isLatLonKnown() ? new LatLon(lat, lon) : null;
040    }
041
042    @Override
043    public final void setCoor(LatLon coor) {
044        if (coor == null) {
045            this.lat = Double.NaN;
046            this.lon = Double.NaN;
047        } else {
048            this.lat = coor.lat();
049            this.lon = coor.lon();
050        }
051    }
052
053    @Override
054    public EastNorth getEastNorth() {
055        // No internal caching of projected coordinates needed. In contrast to getEastNorth()
056        // on Node, this method is rarely used. Caching would be overkill.
057        return Projections.project(getCoor());
058    }
059
060    @Override
061    public void setEastNorth(EastNorth eastNorth) {
062        setCoor(Projections.inverseProject(eastNorth));
063    }
064
065    @Override
066    public NodeData makeCopy() {
067        return new NodeData(this);
068    }
069
070    @Override
071    public String toString() {
072        return super.toString() + " NODE " + getCoor();
073    }
074
075    @Override
076    public OsmPrimitiveType getType() {
077        return OsmPrimitiveType.NODE;
078    }
079
080    @Override
081    public void accept(PrimitiveVisitor visitor) {
082        visitor.visit(this);
083    }
084}