001 // License: GPL. For details, see LICENSE file.
002 package org.openstreetmap.josm.data.osm.history;
003
004 import static org.openstreetmap.josm.tools.I18n.tr;
005
006 import java.util.ArrayList;
007 import java.util.Collections;
008 import java.util.Date;
009 import java.util.List;
010
011 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
012 import org.openstreetmap.josm.data.osm.User;
013 import org.openstreetmap.josm.data.osm.Way;
014 import org.openstreetmap.josm.tools.CheckParameterUtil;
015
016 /**
017 * Represents an immutable OSM way in the context of a historical view on
018 * OSM data.
019 *
020 */
021 public class HistoryWay extends HistoryOsmPrimitive {
022
023 private ArrayList<Long> nodeIds = new ArrayList<Long>();
024
025 /**
026 * Constructs a new {@code HistoryWay}.
027 *
028 * @param id the id (> 0 required)
029 * @param version the version (> 0 required)
030 * @param visible whether the node is still visible
031 * @param user the user (! null required)
032 * @param changesetId the changeset id (> 0 required if {@code checkHistoricParams} is true)
033 * @param timestamp the timestamp (! null required if {@code checkHistoricParams} is true)
034 * @throws IllegalArgumentException if preconditions are violated
035 */
036 public HistoryWay(long id, long version, boolean visible, User user, long changesetId, Date timestamp) throws IllegalArgumentException {
037 super(id, version, visible, user, changesetId, timestamp);
038 }
039
040 /**
041 * Constructs a new {@code HistoryWay} with a configurable checking of historic parameters.
042 * This is needed to build virtual HistoryWays for modified ways, which do not have a timestamp and a changeset id.
043 *
044 * @param id the id (> 0 required)
045 * @param version the version (> 0 required)
046 * @param visible whether the node is still visible
047 * @param user the user (! null required)
048 * @param changesetId the changeset id (> 0 required if {@code checkHistoricParams} is true)
049 * @param timestamp the timestamp (! null required if {@code checkHistoricParams} is true)
050 * @param checkHistoricParams if true, checks values of {@code changesetId} and {@code timestamp}
051 * @throws IllegalArgumentException if preconditions are violated
052 * @since 5440
053 */
054 public HistoryWay(long id, long version, boolean visible, User user, long changesetId, Date timestamp, boolean checkHistoricParams) throws IllegalArgumentException {
055 super(id, version, visible, user, changesetId, timestamp, checkHistoricParams);
056 }
057
058 /**
059 * Constructs a new {@code HistoryWay} with a given list of node ids.
060 *
061 * @param id the id (> 0 required)
062 * @param version the version (> 0 required)
063 * @param visible whether the node is still visible
064 * @param user the user (! null required)
065 * @param changesetId the changeset id (> 0 required if {@code checkHistoricParams} is true)
066 * @param timestamp the timestamp (! null required if {@code checkHistoricParams} is true)
067 * @param nodeIdList the node ids (! null required)
068 * @throws IllegalArgumentException if preconditions are violated
069 */
070 public HistoryWay(long id, long version, boolean visible, User user, long changesetId, Date timestamp, ArrayList<Long> nodeIdList) throws IllegalArgumentException {
071 this(id, version, visible, user, changesetId, timestamp);
072 CheckParameterUtil.ensureParameterNotNull(nodeIdList, "nodeIdList");
073 this.nodeIds.addAll(nodeIdList);
074 }
075
076 /**
077 * Constructs a new {@code HistoryWay} from an existing {@link Way}.
078 * @param w the way
079 */
080 public HistoryWay(Way w) {
081 super(w);
082 }
083
084 /**
085 * replies the number of nodes in this way
086 * @return the number of nodes
087 */
088 public int getNumNodes() {
089 return nodeIds.size();
090 }
091
092 /**
093 * replies the idx-th node id in the list of node ids of this way
094 *
095 * @param idx the index
096 * @return the idx-th node id
097 * @exception IndexOutOfBoundsException thrown, if idx <0 || idx >= {#see {@link #getNumNodes()}
098 */
099 public long getNodeId(int idx) throws IndexOutOfBoundsException {
100 if (idx < 0 || idx >= nodeIds.size())
101 throw new IndexOutOfBoundsException(tr("Parameter {0} not in range 0..{1}. Got ''{2}''.", "idx", nodeIds.size(),idx));
102 return nodeIds.get(idx);
103 }
104
105 /**
106 * replies an immutable list of the ways node ids
107 *
108 * @return the ways node ids
109 */
110 public List<Long> getNodes() {
111 return Collections.unmodifiableList(nodeIds);
112 }
113
114 /**
115 * replies the ways type, i.e. {@link OsmPrimitiveType#WAY}
116 *
117 * @return the ways type
118 */
119 @Override
120 public OsmPrimitiveType getType() {
121 return OsmPrimitiveType.WAY;
122 }
123
124 /**
125 * adds a node id to the list nodes of this way
126 *
127 * @param ref the node id to add
128 */
129 public void addNode(long ref) {
130 nodeIds.add(ref);
131 }
132
133 /**
134 * Replies true if this way is closed.
135 *
136 * @return true if this way is closed.
137 */
138 public boolean isClosed() {
139 return getNumNodes() >= 3 && nodeIds.get(0) == nodeIds.get(nodeIds.size()-1);
140 }
141
142 @Override
143 public String getDisplayName(HistoryNameFormatter formatter) {
144 return formatter.format(this);
145 }
146 }