source: josm/trunk/src/org/openstreetmap/josm/data/osm/Node.java@ 3348

Last change on this file since 3348 was 3348, checked in by jttt, 14 years ago

Thread safe Dataset and OsmPrimitive, read/write lock for dataset

  • Property svn:eol-style set to native
File size: 6.4 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.data.osm;
3
4import org.openstreetmap.josm.Main;
5import org.openstreetmap.josm.data.coor.CachedLatLon;
6import org.openstreetmap.josm.data.coor.EastNorth;
7import org.openstreetmap.josm.data.coor.LatLon;
8import org.openstreetmap.josm.data.osm.visitor.Visitor;
9
10/**
11 * One node data, consisting of one world coordinate waypoint.
12 *
13 * @author imi
14 */
15public final class Node extends OsmPrimitive {
16
17 private CachedLatLon coor;
18
19 public final void setCoor(LatLon coor) {
20 if(coor != null){
21 if (getDataSet() != null) {
22 boolean locked = writeLock();
23 try {
24 getDataSet().fireNodeMoved(this, coor);
25 } finally {
26 writeUnlock(locked);
27 }
28 } else {
29 setCoorInternal(coor);
30 }
31 }
32 }
33
34 public final LatLon getCoor() {
35 return coor;
36 }
37
38 public final void setEastNorth(EastNorth eastNorth) {
39 if(eastNorth != null) {
40 setCoor(Main.proj.eastNorth2latlon(eastNorth));
41 }
42 }
43
44 public final EastNorth getEastNorth() {
45 return coor != null ? coor.getEastNorth() : null;
46 }
47
48 /**
49 * To be used only by Dataset.reindexNode
50 */
51 protected void setCoorInternal(LatLon coor) {
52 if(this.coor == null) {
53 this.coor = new CachedLatLon(coor);
54 } else {
55 this.coor.setCoor(coor);
56 }
57 }
58
59 protected Node(long id, boolean allowNegative) {
60 super(id, allowNegative);
61 }
62
63 /**
64 * Create a new local node.
65 *
66 */
67 public Node() {
68 this(0, false);
69 }
70
71 /**
72 * Create an incomplete Node object
73 */
74 public Node(long id) {
75 super(id, false);
76 }
77
78 /**
79 * Create new node
80 * @param id
81 * @param version
82 */
83 public Node(long id, int version) {
84 super(id, version, false);
85 }
86
87 /**
88 *
89 * @param clone
90 * @param clearId If true, set version to 0 and id to new unique value
91 */
92 public Node(Node clone, boolean clearId) {
93 super(clone.getUniqueId(), true /* allow negative IDs */);
94 cloneFrom(clone);
95 if (clearId) {
96 clearOsmId();
97 }
98 }
99
100 /**
101 * Create an identical clone of the argument (including the id)
102 */
103 public Node(Node clone) {
104 this(clone, false);
105 }
106
107 public Node(LatLon latlon) {
108 super(0, false);
109 setCoor(latlon);
110 }
111
112 public Node(EastNorth eastNorth) {
113 super(0, false);
114 setEastNorth(eastNorth);
115 }
116
117 @Override public void visit(Visitor visitor) {
118 visitor.visit(this);
119 }
120
121 @Override public void cloneFrom(OsmPrimitive osm) {
122 boolean locked = writeLock();
123 try {
124 super.cloneFrom(osm);
125 setCoor(((Node)osm).coor);
126 } finally {
127 writeUnlock(locked);
128 }
129 }
130
131 /**
132 * Merges the technical and semantical attributes from <code>other</code> onto this.
133 *
134 * Both this and other must be new, or both must be assigned an OSM ID. If both this and <code>other</code>
135 * have an assigend OSM id, the IDs have to be the same.
136 *
137 * @param other the other primitive. Must not be null.
138 * @throws IllegalArgumentException thrown if other is null.
139 * @throws DataIntegrityProblemException thrown if either this is new and other is not, or other is new and this is not
140 * @throws DataIntegrityProblemException thrown if other is new and other.getId() != this.getId()
141 */
142 @Override
143 public void mergeFrom(OsmPrimitive other) {
144 boolean locked = writeLock();
145 try {
146 super.mergeFrom(other);
147 if (!other.isIncomplete()) {
148 setCoor(new LatLon(((Node)other).coor));
149 }
150 } finally {
151 writeUnlock(locked);
152 }
153 }
154
155 @Override public void load(PrimitiveData data) {
156 boolean locked = writeLock();
157 try {
158 super.load(data);
159 setCoor(((NodeData)data).getCoor());
160 } finally {
161 writeUnlock(locked);
162 }
163 }
164
165 @Override public NodeData save() {
166 NodeData data = new NodeData();
167 saveCommonAttributes(data);
168 if (!isIncomplete()) {
169 data.setCoor(getCoor());
170 }
171 return data;
172 }
173
174 @Override public String toString() {
175 String coorDesc = coor == null?"":"lat="+coor.lat()+",lon="+coor.lon();
176 return "{Node id=" + getUniqueId() + " version=" + getVersion() + " " + getFlagsAsString() + " " + coorDesc+"}";
177 }
178
179 @Override
180 public boolean hasEqualSemanticAttributes(OsmPrimitive other) {
181 if (other == null || ! (other instanceof Node) )
182 return false;
183 if (! super.hasEqualSemanticAttributes(other))
184 return false;
185 Node n = (Node)other;
186 if (coor == null && n.coor == null)
187 return true;
188 else if (coor != null && n.coor != null)
189 return coor.equalsEpsilon(n.coor);
190 else
191 return false;
192 }
193
194 public int compareTo(OsmPrimitive o) {
195 return o instanceof Node ? Long.valueOf(getUniqueId()).compareTo(o.getUniqueId()) : 1;
196 }
197
198 @Override
199 public String getDisplayName(NameFormatter formatter) {
200 return formatter.format(this);
201 }
202
203 public OsmPrimitiveType getType() {
204 return OsmPrimitiveType.NODE;
205 }
206
207 @Override
208 public BBox getBBox() {
209 return new BBox(this);
210 }
211
212 @Override
213 public void updatePosition() {
214 // TODO: replace CachedLatLon with simple doubles and update precalculated EastNorth value here
215 }
216
217 public boolean isConnectionNode() {
218 return (OsmPrimitive.getFilteredList(getReferrers(), Way.class)).size() > 1;
219 }
220
221 public String get3892DebugInfo() {
222 StringBuilder builder = new StringBuilder();
223 builder.append("Unexpected error. Please report it to http://josm.openstreetmap.de/ticket/3892\n");
224 builder.append(toString());
225 builder.append("\n");
226 if (coor == null) {
227 builder.append("Coor is null\n");
228 } else {
229 builder.append(String.format("EastNorth: %s\n", coor.getEastNorth()));
230 builder.append(coor.getProjection());
231 builder.append("\n");
232 }
233
234 return builder.toString();
235 }
236}
Note: See TracBrowser for help on using the repository browser.