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    public NodeData() {}
018
019    public NodeData(NodeData data) {
020        super(data);
021        setCoor(data.getCoor());
022    }
023
024    private boolean isLatLonKnown() {
025        return !Double.isNaN(lat) && !Double.isNaN(lon);
026    }
027
028    @Override
029    public LatLon getCoor() {
030        return isLatLonKnown() ? new LatLon(lat,lon) : null;
031    }
032
033    @Override
034    public void setCoor(LatLon coor) {
035        if (coor == null) {
036            this.lat = Double.NaN;
037            this.lon = Double.NaN;
038        } else {
039            this.lat = coor.lat();
040            this.lon = coor.lon();
041        }
042    }
043
044    @Override
045    public EastNorth getEastNorth() {
046        /*
047         * No internal caching of projected coordinates needed. In contrast to getEastNorth()
048         * on Node, this method is rarely used. Caching would be overkill.
049         */
050        return Projections.project(getCoor());
051    }
052
053    @Override
054    public void setEastNorth(EastNorth eastNorth) {
055        LatLon ll = Projections.inverseProject(eastNorth);
056        setCoor(ll);
057    }
058
059    @Override
060    public NodeData makeCopy() {
061        return new NodeData(this);
062    }
063
064    @Override
065    public String toString() {
066        return super.toString() + " NODE " + getCoor();
067    }
068
069    @Override
070    public OsmPrimitiveType getType() {
071        return OsmPrimitiveType.NODE;
072    }
073
074    @Override
075    public void accept(PrimitiveVisitor visitor) {
076        visitor.visit(this);
077    }
078
079}