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 * Determines if this way is empty, i.e. it has no nodes. 022 * @return {@code true} if this way is empty, i.e. it has no nodes 023 * @since 16119 024 */ 025 default boolean isEmpty() { 026 return getNodesCount() == 0; 027 } 028 029 /** 030 * Replies the real number of nodes in this way (full number of nodes minus one if this way is closed) 031 * 032 * @return the real number of nodes in this way. 033 * 034 * @see #getNodesCount() 035 * @see #isClosed() 036 * @since 5847 037 * @since 13564 (IWay) 038 */ 039 default int getRealNodesCount() { 040 int count = getNodesCount(); 041 return isClosed() ? count-1 : count; 042 } 043 044 /** 045 * Replies the node at position <code>index</code>. 046 * 047 * @param index the position 048 * @return the node at position <code>index</code> 049 * @throws ArrayIndexOutOfBoundsException if <code>index</code> < 0 050 * or <code>index</code> >= {@link #getNodesCount()} 051 * @since 1862 052 * @since 13717 (IWay) 053 */ 054 N getNode(int index); 055 056 /** 057 * Returns the list of nodes in this way. 058 * @return the list of nodes in this way 059 * @since 1862 060 * @since 13717 (IWay) 061 */ 062 List<N> getNodes(); 063 064 /** 065 * Returns the list of node ids in this way. 066 * @return the list of node ids in this way 067 * @since 13717 068 */ 069 List<Long> getNodeIds(); 070 071 /** 072 * Returns id of the node at given index. 073 * @param idx node index 074 * @return id of the node at given index 075 */ 076 long getNodeId(int idx); 077 078 /** 079 * Set new list of nodes to way. This method is preferred to multiple calls to addNode/removeNode 080 * and similar methods because nodes are internally saved as array which means lower memory overhead 081 * but also slower modifying operations. 082 * @param nodes New way nodes. Can be null, in that case all way nodes are removed 083 */ 084 void setNodes(List<N> nodes); 085 086 /** 087 * Determines if this way is closed. 088 * @return {@code true} if this way is closed, {@code false} otherwise 089 */ 090 boolean isClosed(); 091 092 @Override 093 default int compareTo(IPrimitive o) { 094 if (o instanceof IRelation) 095 return 1; 096 return o instanceof IWay ? Long.compare(getUniqueId(), o.getUniqueId()) : -1; 097 } 098 099 @Override 100 default String getDisplayName(NameFormatter formatter) { 101 return formatter.format(this); 102 } 103 104 /** 105 * Returns the first node of this way. 106 * The result equals {@link #getNode getNode}{@code (0)}. 107 * @return the first node of this way 108 * @since 13922 109 */ 110 N firstNode(); 111 112 /** 113 * Returns the last node of this way. 114 * The result equals <code>{@link #getNode getNode}({@link #getNodesCount getNodesCount} - 1)</code>. 115 * @return the last node of this way 116 * @since 13922 117 */ 118 N lastNode(); 119 120 /** 121 * Replies true if the given node is the first or the last one of this way, false otherwise. 122 * @param n The node to test 123 * @return true if the {@code n} is the first or the last node, false otherwise. 124 * @since 13922 125 */ 126 boolean isFirstLastNode(INode n); 127 128 /** 129 * Replies true if the given node is an inner node of this way, false otherwise. 130 * @param n The node to test 131 * @return true if the {@code n} is an inner node, false otherwise. 132 * @since 13922 133 */ 134 boolean isInnerNode(INode n); 135 136 /** 137 * Replies true if this way has incomplete nodes, false otherwise. 138 * @return true if this way has incomplete nodes, false otherwise. 139 * @since 18019 140 */ 141 default boolean hasIncompleteNodes() { 142 return false; 143 } 144}