Changeset 4464 in osm for applications/editors/josm/core_0.5/src/org/openstreetmap/josm/io/OsmReader.java
- Timestamp:
- 2007-09-05T23:55:17+02:00 (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/core_0.5/src/org/openstreetmap/josm/io/OsmReader.java
r4437 r4464 21 21 import org.openstreetmap.josm.data.osm.DataSet; 22 22 import org.openstreetmap.josm.data.osm.DataSource; 23 import org.openstreetmap.josm.data.osm.Relation; 24 import org.openstreetmap.josm.data.osm.RelationMember; 23 25 import org.openstreetmap.josm.data.osm.Node; 24 26 import org.openstreetmap.josm.data.osm.OsmPrimitive; 25 import org.openstreetmap.josm.data.osm.Segment;26 27 import org.openstreetmap.josm.data.osm.User; 27 28 import org.openstreetmap.josm.data.osm.Way; … … 41 42 * all nodes are read and stored. Other information than nodes are stored in a raw list 42 43 * 43 * The second phase reads from the raw list all segments and create Segment objects. 44 * 45 * The third phase read all ways out of the remaining objects in the raw list. 44 * The second phase read all ways out of the remaining objects in the raw list. 46 45 * 47 46 * @author Imi … … 88 87 89 88 /** 90 * Data structure for the remaining segment objects 91 * Maps the raw attributes to key/value pairs. 92 */ 93 private Map<OsmPrimitiveData, long[]> segs = new HashMap<OsmPrimitiveData, long[]>(); 89 * Used as a temporary storage for relation members, before they 90 * are resolved into pointers to real objects. 91 */ 92 private static class RelationMemberData { 93 public String type; 94 public long id; 95 public RelationMember relationMember; 96 } 94 97 95 98 /** … … 97 100 */ 98 101 private Map<OsmPrimitiveData, Collection<Long>> ways = new HashMap<OsmPrimitiveData, Collection<Long>>(); 102 103 /** 104 * Data structure for relation objects 105 */ 106 private Map<OsmPrimitiveData, Collection<RelationMemberData>> relations = new HashMap<OsmPrimitiveData, Collection<RelationMemberData>>(); 99 107 100 108 /** … … 129 137 ds.dataSources.add(src); 130 138 } 139 140 // ---- PARSING NODES AND WAYS ---- 141 131 142 } else if (qName.equals("node")) { 132 143 current = new Node(new LatLon(getDouble(atts, "lat"), getDouble(atts, "lon"))); 133 144 readCommon(atts, current); 134 145 nodes.put(current.id, (Node)current); 135 } else if (qName.equals("segment")) {136 current = new OsmPrimitiveData();137 readCommon(atts, current);138 segs.put((OsmPrimitiveData)current, new long[]{getLong(atts, "from"), getLong(atts, "to")});139 146 } else if (qName.equals("way")) { 140 147 current = new OsmPrimitiveData(); 141 148 readCommon(atts, current); 142 149 ways.put((OsmPrimitiveData)current, new LinkedList<Long>()); 143 } else if (qName.equals(" seg")) {150 } else if (qName.equals("nd")) { 144 151 Collection<Long> list = ways.get(current); 145 152 if (list == null) 146 throw new SAXException(tr("Found < seg> tag on non-way."));147 long id = getLong(atts, " id");153 throw new SAXException(tr("Found <nd> element in non-way.")); 154 long id = getLong(atts, "ref"); 148 155 if (id == 0) 149 throw new SAXException(tr(" Incomplete segment with id=0"));156 throw new SAXException(tr("<nd> has zero ref")); 150 157 list.add(id); 151 } else if (qName.equals("tag")) 158 159 // ---- PARSING ENTITIES ---- 160 161 } else if (qName.equals("relation")) { 162 current = new OsmPrimitiveData(); 163 readCommon(atts, current); 164 relations.put((OsmPrimitiveData)current, new LinkedList<RelationMemberData>()); 165 } else if (qName.equals("member")) { 166 Collection<RelationMemberData> list = relations.get(current); 167 if (list == null) 168 throw new SAXException(tr("Found <member> tag on non-relation.")); 169 RelationMemberData emd = new RelationMemberData(); 170 emd.relationMember = new RelationMember(); 171 emd.id = getLong(atts, "ref"); 172 emd.type=atts.getValue("type"); 173 emd.relationMember.role = atts.getValue("role"); 174 175 if (emd.id == 0) 176 throw new SAXException(tr("Incomplete <member> specification with ref=0")); 177 178 list.add(emd); 179 180 // ---- PARSING TAGS (applicable to all objects) ---- 181 182 } else if (qName.equals("tag")) { 152 183 current.put(atts.getValue("k"), atts.getValue("v")); 184 } 153 185 } catch (NumberFormatException x) { 154 186 x.printStackTrace(); // SAXException does not chain correctly … … 170 202 public OsmReader() { 171 203 // first add the main server version 172 allowedVersions.add(Main.pref.get("osm-server.version", "0. 4"));204 allowedVersions.add(Main.pref.get("osm-server.version", "0.5")); 173 205 // now also add all compatible versions 174 206 String[] additionalVersions = 175 Main.pref.get("osm-server.additional-versions", "0.3").split("/,/"); 207 Main.pref.get("osm-server.additional-versions", "").split("/,/"); 208 if (additionalVersions.length == 1 && additionalVersions[0].length() == 0) 209 additionalVersions = new String[] {}; 176 210 allowedVersions.addAll(Arrays.asList(additionalVersions)); 177 211 } … … 221 255 throw new SAXException(tr("Missing required attribute \"{0}\".",value)); 222 256 return Long.parseLong(s); 223 }224 225 private void createSegments() {226 for (Entry<OsmPrimitiveData, long[]> e : segs.entrySet()) {227 Node from = findNode(e.getValue()[0]);228 Node to = findNode(e.getValue()[1]);229 if (from == null || to == null)230 continue; //TODO: implement support for incomplete nodes.231 Segment s = new Segment(from, to);232 e.getKey().copyTo(s);233 segments.put(s.id, s);234 adder.visit(s);235 }236 257 } 237 258 … … 250 271 } 251 272 252 private Segment findSegment(long id) {253 Segment s = segments.get(id);254 if (s != null)255 return s;256 for (Segment seg : references.segments)257 if (seg.id == id)258 return seg;259 // TODO: This has to be changed to support multiple layers.260 for (Segment seg : Main.ds.segments)261 if (seg.id == id)262 return new Segment(seg);263 return null;264 }265 266 273 private void createWays() { 267 274 for (Entry<OsmPrimitiveData, Collection<Long>> e : ways.entrySet()) { 268 275 Way w = new Way(); 276 boolean failed = false; 269 277 for (long id : e.getValue()) { 270 Segment s= findSegment(id);271 if ( s== null) {272 s = new Segment(id); // incomplete line segment273 adder.visit(s);278 Node n = findNode(id); 279 if (n == null) { 280 failed = true; 281 break; 274 282 } 275 w. segments.add(s);283 w.nodes.add(n); 276 284 } 285 if (failed) continue; 277 286 e.getKey().copyTo(w); 278 287 adder.visit(w); … … 281 290 282 291 /** 283 * All read segments after phase 2. 284 */ 285 private Map<Long, Segment> segments = new HashMap<Long, Segment>(); 292 * Return the Way object with the given id, or null if it doesn't 293 * exist yet. This method only looks at ways stored in the data set. 294 * 295 * @param id 296 * @return way object or null 297 */ 298 private Way findWay(long id) { 299 for (Way wy : ds.ways) 300 if (wy.id == id) 301 return wy; 302 for (Way wy : Main.ds.ways) 303 if (wy.id == id) 304 return wy; 305 return null; 306 } 307 308 /** 309 * Return the Relation object with the given id, or null if it doesn't 310 * exist yet. This method only looks at relations stored in the data set. 311 * 312 * @param id 313 * @return relation object or null 314 */ 315 private Relation findRelation(long id) { 316 for (Relation e : ds.relations) 317 if (e.id == id) 318 return e; 319 for (Relation e : Main.ds.relations) 320 if (e.id == id) 321 return e; 322 return null; 323 } 324 325 /** 326 * Create relations. This is slightly different than n/s/w because 327 * unlike other objects, relations may reference other relations; it 328 * is not guaranteed that a referenced relation will have been created 329 * before it is referenced. So we have to create all relations first, 330 * and populate them later. 331 */ 332 private void createRelations() { 333 334 // pass 1 - create all relations 335 for (Entry<OsmPrimitiveData, Collection<RelationMemberData>> e : relations.entrySet()) { 336 Relation en = new Relation(); 337 e.getKey().copyTo(en); 338 adder.visit(en); 339 } 340 341 // pass 2 - sort out members 342 for (Entry<OsmPrimitiveData, Collection<RelationMemberData>> e : relations.entrySet()) { 343 Relation en = findRelation(e.getKey().id); 344 if (en == null) throw new Error("Failed to create relation " + e.getKey().id); 345 346 for (RelationMemberData emd : e.getValue()) { 347 RelationMember em = emd.relationMember; 348 if (emd.type.equals("node")) { 349 em.member = findNode(emd.id); 350 if (em.member == null) { 351 em.member = new Node(emd.id); 352 adder.visit((Node)em.member); 353 } 354 } else if (emd.type.equals("way")) { 355 em.member = findWay(emd.id); 356 if (em.member == null) { 357 em.member = new Way(emd.id); 358 adder.visit((Way)em.member); 359 } 360 } else if (emd.type.equals("relation")) { 361 em.member = findRelation(emd.id); 362 if (em.member == null) { 363 em.member = new Relation(emd.id); 364 adder.visit((Relation)em.member); 365 } 366 } else { 367 // this is an error. 368 } 369 en.members.add(em); 370 } 371 } 372 } 286 373 287 374 /** … … 295 382 osm.references = ref == null ? new DataSet() : ref; 296 383 297 // phase 1: Parse nodes and read in raw segments andways384 // phase 1: Parse nodes and read in raw ways 298 385 osm.new Parser().parse(new InputStreamReader(source, "UTF-8")); 299 386 if (pleaseWaitDlg != null) { … … 305 392 306 393 try { 307 osm.createSegments();308 394 osm.createWays(); 395 osm.createRelations(); 309 396 } catch (NumberFormatException e) { 310 397 e.printStackTrace();
Note:
See TracChangeset
for help on using the changeset viewer.