001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data.vector;
003
004import java.util.List;
005
006import org.openstreetmap.gui.jmapviewer.interfaces.ICoordinate;
007import org.openstreetmap.josm.data.coor.EastNorth;
008import org.openstreetmap.josm.data.coor.LatLon;
009import org.openstreetmap.josm.data.osm.BBox;
010import org.openstreetmap.josm.data.osm.INode;
011import org.openstreetmap.josm.data.osm.IPrimitive;
012import org.openstreetmap.josm.data.osm.IWay;
013import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
014import org.openstreetmap.josm.data.osm.UniqueIdGenerator;
015import org.openstreetmap.josm.data.osm.visitor.PrimitiveVisitor;
016import org.openstreetmap.josm.data.projection.ProjectionRegistry;
017import org.openstreetmap.josm.tools.Utils;
018
019/**
020 * The "Node" type of a vector layer
021 *
022 * @since 17862
023 */
024public class VectorNode extends VectorPrimitive implements INode {
025    private static final UniqueIdGenerator ID_GENERATOR = new UniqueIdGenerator();
026    private double lon = Double.NaN;
027    private double lat = Double.NaN;
028
029    /**
030     * Create a new vector node
031     * @param layer The layer for the vector node
032     */
033    public VectorNode(String layer) {
034        super(layer);
035    }
036
037    @Override
038    public double lon() {
039        return this.lon;
040    }
041
042    @Override
043    public double lat() {
044        return this.lat;
045    }
046
047    @Override
048    public UniqueIdGenerator getIdGenerator() {
049        return ID_GENERATOR;
050    }
051
052    @Override
053    public LatLon getCoor() {
054        return new LatLon(this.lat, this.lon);
055    }
056
057    @Override
058    public void setCoor(LatLon coordinates) {
059        this.lat = coordinates.lat();
060        this.lon = coordinates.lon();
061    }
062
063    /**
064     * Set the coordinates of this node
065     *
066     * @param coordinates The coordinates to set
067     * @see #setCoor(LatLon)
068     */
069    public void setCoor(ICoordinate coordinates) {
070        this.lat = coordinates.getLat();
071        this.lon = coordinates.getLon();
072    }
073
074    @Override
075    public void setEastNorth(EastNorth eastNorth) {
076        final LatLon ll = ProjectionRegistry.getProjection().eastNorth2latlon(eastNorth);
077        this.lat = ll.lat();
078        this.lon = ll.lon();
079    }
080
081    @Override
082    public boolean isReferredByWays(int n) {
083        // Count only referrers that are members of the same dataset (primitive can have some fake references, for example
084        // when way is cloned
085        List<? extends IPrimitive> referrers = super.getReferrers();
086        if (Utils.isEmpty(referrers))
087            return false;
088        if (referrers instanceof IPrimitive)
089            return n <= 1 && referrers instanceof IWay && ((IPrimitive) referrers).getDataSet() == getDataSet();
090        else {
091            int counter = 0;
092            for (IPrimitive o : referrers) {
093                if (getDataSet() == o.getDataSet() && o instanceof IWay && ++counter >= n)
094                    return true;
095            }
096            return false;
097        }
098    }
099
100    @Override
101    public void accept(PrimitiveVisitor visitor) {
102        visitor.visit(this);
103    }
104
105    @Override
106    public BBox getBBox() {
107        return new BBox(this.lon, this.lat).toImmutable();
108    }
109
110    @Override
111    public OsmPrimitiveType getType() {
112        return OsmPrimitiveType.NODE;
113    }
114}