001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data.osm;
003
004import java.util.List;
005
006/**
007 * IWay captures the common functions of {@link Way} and {@link WayData}.
008 * @param <N> type of OSM node
009 * @since 4098
010 */
011public interface IWay<N extends INode> extends IPrimitive {
012
013    /**
014     * Replies the number of nodes in this way.
015     *
016     * @return the number of nodes in this way.
017     */
018    int getNodesCount();
019
020    /**
021     * Replies the real number of nodes in this way (full number of nodes minus one if this way is closed)
022     *
023     * @return the real number of nodes in this way.
024     *
025     * @see #getNodesCount()
026     * @see #isClosed()
027     * @since 5847
028     * @since 13564 (IWay)
029     */
030    default int getRealNodesCount() {
031        int count = getNodesCount();
032        return isClosed() ? count-1 : count;
033    }
034
035    /**
036     * Replies the node at position <code>index</code>.
037     *
038     * @param index the position
039     * @return  the node at position <code>index</code>
040     * @throws ArrayIndexOutOfBoundsException if <code>index</code> &lt; 0
041     * or <code>index</code> &gt;= {@link #getNodesCount()}
042     * @since 1862
043     * @since 13717 (IWay)
044     */
045    N getNode(int index);
046
047    /**
048     * Returns the list of nodes in this way.
049     * @return the list of nodes in this way
050     * @since 1862
051     * @since 13717 (IWay)
052     */
053    List<N> getNodes();
054
055    /**
056     * Returns the list of node ids in this way.
057     * @return the list of node ids in this way
058     * @since 13717
059     */
060    List<Long> getNodeIds();
061
062    /**
063     * Returns id of the node at given index.
064     * @param idx node index
065     * @return id of the node at given index
066     */
067    long getNodeId(int idx);
068
069    /**
070     * Set new list of nodes to way. This method is preferred to multiple calls to addNode/removeNode
071     * and similar methods because nodes are internally saved as array which means lower memory overhead
072     * but also slower modifying operations.
073     * @param nodes New way nodes. Can be null, in that case all way nodes are removed
074     */
075    void setNodes(List<N> nodes);
076
077    /**
078     * Determines if this way is closed.
079     * @return {@code true} if this way is closed, {@code false} otherwise
080     */
081    boolean isClosed();
082
083    @Override
084    default int compareTo(IPrimitive o) {
085        if (o instanceof IRelation)
086            return 1;
087        return o instanceof IWay ? Long.compare(getUniqueId(), o.getUniqueId()) : -1;
088    }
089
090    @Override
091    default String getDisplayName(NameFormatter formatter) {
092        return formatter.format(this);
093    }
094
095    /**
096     * Returns the first node of this way.
097     * The result equals {@link #getNode getNode}{@code (0)}.
098     * @return the first node of this way
099     * @since 13922
100     */
101    N firstNode();
102
103    /**
104     * Returns the last node of this way.
105     * The result equals <code>{@link #getNode getNode}({@link #getNodesCount getNodesCount} - 1)</code>.
106     * @return the last node of this way
107     * @since 13922
108     */
109    N lastNode();
110
111    /**
112     * Replies true if the given node is the first or the last one of this way, false otherwise.
113     * @param n The node to test
114     * @return true if the {@code n} is the first or the last node, false otherwise.
115     * @since 13922
116     */
117    boolean isFirstLastNode(INode n);
118
119    /**
120     * Replies true if the given node is an inner node of this way, false otherwise.
121     * @param n The node to test
122     * @return true if the {@code n} is an inner node, false otherwise.
123     * @since 13922
124     */
125    boolean isInnerNode(INode n);
126}