Changeset 101 in josm for src/org/openstreetmap/josm/io/OsmReader.java
- Timestamp:
- 2006-05-03T22:21:02+02:00 (20 years ago)
- File:
-
- 1 edited
-
src/org/openstreetmap/josm/io/OsmReader.java (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/org/openstreetmap/josm/io/OsmReader.java
r91 r101 6 6 import java.text.ParseException; 7 7 import java.text.SimpleDateFormat; 8 import java.util.Collection; 8 9 import java.util.HashMap; 10 import java.util.LinkedList; 9 11 import java.util.Map; 12 import java.util.Map.Entry; 13 14 import javax.swing.BoundedRangeModel; 15 import javax.swing.JLabel; 10 16 11 17 import org.openstreetmap.josm.data.coor.LatLon; … … 16 22 import org.openstreetmap.josm.data.osm.Way; 17 23 import org.openstreetmap.josm.data.osm.visitor.AddVisitor; 24 import org.openstreetmap.josm.data.osm.visitor.Visitor; 18 25 import org.xml.sax.Attributes; 19 26 import org.xml.sax.SAXException; … … 24 31 * Parser for the Osm Api. Read from an input stream and construct a dataset out of it. 25 32 * 33 * Reading process takes place in three phases. During the first phase (including xml parse), 34 * all nodes are read and stored. Other information than nodes are stored in a raw list 35 * 36 * The second phase reads from the raw list all segments and create Segment objects. 37 * 38 * The third phase read all ways out of the remaining objects in the raw list. 39 * 26 40 * @author Imi 27 41 */ 28 public class OsmReader extends MinML2{42 public class OsmReader { 29 43 30 44 /** … … 37 51 */ 38 52 private AddVisitor adder = new AddVisitor(ds); 53 54 /** 55 * All read nodes after phase 1. 56 */ 57 private Map<Long, Node> nodes = new HashMap<Long, Node>(); 39 58 40 /**41 * The current processed primitive.42 */43 private OsmPrimitive current; 44 45 /**46 * All read nodes so far.47 */48 private Map<Long, Node> nodes = new HashMap<Long, Node>();49 /**50 * All read segents so far.51 */ 52 private Map<Long, Segment> segments = new HashMap<Long, Segment>();59 private static class OsmPrimitiveData extends OsmPrimitive { 60 @Override public void visit(Visitor visitor) {} 61 public int compareTo(OsmPrimitive o) {return 0;} 62 63 public void copyTo(OsmPrimitive osm) { 64 osm.id = id; 65 osm.keys = keys; 66 osm.modified = modified; 67 osm.selected = selected; 68 osm.deleted = deleted; 69 osm.timestamp = timestamp; 70 } 71 } 53 72 54 73 /** 55 * Parse the given input source and return the dataset. 56 */ 57 public static DataSet parseDataSet(Reader source) throws SAXException, IOException { 58 OsmReader osm = new OsmReader(source); 59 60 // clear all negative ids (new to this file) 61 for (OsmPrimitive o : osm.ds.allPrimitives()) 62 if (o.id < 0) 63 o.id = 0; 64 65 return osm.ds; 66 } 67 68 private OsmReader(Reader source) throws SAXException, IOException { 69 parse(source); 70 } 71 72 @Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { 73 try { 74 if (qName.equals("osm")) { 75 if (atts == null) 76 throw new SAXException("Unknown version."); 77 if (!"0.3".equals(atts.getValue("version"))) 78 throw new SAXException("Unknown version "+atts.getValue("version")); 79 } else if (qName.equals("node")) { 80 Node n = new Node(new LatLon(getDouble(atts, "lat"), getDouble(atts, "lon"))); 81 current = n; 82 readCommon(atts); 83 current.id = getLong(atts, "id"); 84 nodes.put(n.id, n); 85 } else if (qName.equals("segment")) { 86 Node from = nodes.get(getLong(atts, "from")); 87 Node to = nodes.get(getLong(atts, "to")); 88 if (from == null || to == null) 89 throw new SAXException("Segment "+atts.getValue("id")+" is missing its nodes."); 90 current = new Segment(from, to); 91 readCommon(atts); 92 segments.put(current.id, (Segment)current); 93 } else if (qName.equals("way")) { 94 current = new Way(); 95 readCommon(atts); 96 } else if (qName.equals("seg")) { 97 if (current instanceof Way) { 74 * Data structure for the remaining segment objects 75 * Maps the raw attributes to key/value pairs. 76 */ 77 private Map<OsmPrimitiveData, long[]> segs = new HashMap<OsmPrimitiveData, long[]>(); 78 /** 79 * Data structure for the remaining way objects 80 */ 81 private Map<OsmPrimitiveData, Collection<Long>> ways = new HashMap<OsmPrimitiveData, Collection<Long>>(); 82 83 84 private class Parser extends MinML2 { 85 /** 86 * The current osm primitive to be read. 87 */ 88 private OsmPrimitive current; 89 90 @Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { 91 try { 92 if (qName.equals("osm")) { 93 if (atts == null) 94 throw new SAXException("Unknown version."); 95 if (!"0.3".equals(atts.getValue("version"))) 96 throw new SAXException("Unknown version "+atts.getValue("version")); 97 } else if (qName.equals("node")) { 98 current = new Node(new LatLon(getDouble(atts, "lat"), getDouble(atts, "lon"))); 99 readCommon(atts, current); 100 nodes.put(current.id, (Node)current); 101 } else if (qName.equals("segment")) { 102 current = new OsmPrimitiveData(); 103 readCommon(atts, current); 104 segs.put((OsmPrimitiveData)current, new long[]{getLong(atts, "from"), getLong(atts, "to")}); 105 } else if (qName.equals("way")) { 106 current = new OsmPrimitiveData(); 107 readCommon(atts, current); 108 ways.put((OsmPrimitiveData)current, new LinkedList<Long>()); 109 } else if (qName.equals("seg")) { 110 Collection<Long> list = ways.get(current); 111 if (list == null) 112 throw new SAXException("Found <seg> tag on non-way."); 98 113 long id = getLong(atts, "id"); 99 114 if (id == 0) 100 115 throw new SAXException("Incomplete segment with id=0"); 101 Segment ls = segments.get(id); 102 if (ls == null) { 103 ls = new Segment(id); // incomplete segment 104 segments.put(id, ls); 105 adder.visit(ls); 106 } 107 ((Way)current).segments.add(ls); 108 } 109 } else if (qName.equals("tag")) 110 current.put(atts.getValue("k"), atts.getValue("v")); 111 } catch (NumberFormatException x) { 112 x.printStackTrace(); // SAXException does not chain correctly 113 throw new SAXException(x.getMessage(), x); 114 } catch (NullPointerException x) { 115 x.printStackTrace(); // SAXException does not chain correctly 116 throw new SAXException("NullPointerException. Possible some missing tags.", x); 117 } 118 } 119 120 121 @Override public void endElement(String namespaceURI, String localName, String qName) { 122 if (qName.equals("node") || qName.equals("segment") || qName.equals("way") || qName.equals("area")) { 123 current.visit(adder); 116 list.add(id); 117 } else if (qName.equals("tag")) 118 current.put(atts.getValue("k"), atts.getValue("v")); 119 } catch (NumberFormatException x) { 120 x.printStackTrace(); // SAXException does not chain correctly 121 throw new SAXException(x.getMessage(), x); 122 } catch (NullPointerException x) { 123 x.printStackTrace(); // SAXException does not chain correctly 124 throw new SAXException("NullPointerException. Possible some missing tags.", x); 125 } 126 } 127 128 private double getDouble(Attributes atts, String value) { 129 return Double.parseDouble(atts.getValue(value)); 124 130 } 125 131 } … … 128 134 * Read out the common attributes from atts and put them into this.current. 129 135 */ 130 privatevoid readCommon(Attributes atts) throws SAXException {136 void readCommon(Attributes atts, OsmPrimitive current) throws SAXException { 131 137 current.id = getLong(atts, "id"); 132 138 if (current.id == 0) 133 139 throw new SAXException("Illegal object with id=0"); 134 140 135 141 String time = atts.getValue("timestamp"); 136 142 if (time != null && time.length() != 0) { 137 143 try { 138 144 DateFormat df = new SimpleDateFormat("y-M-d H:m:s"); 139 current.timestamp = df.parse(time);140 } catch (ParseException e) {141 e.printStackTrace();142 throw new SAXException("Couldn't read time format '"+time+"'.");143 }144 } 145 145 current.timestamp = df.parse(time); 146 } catch (ParseException e) { 147 e.printStackTrace(); 148 throw new SAXException("Couldn't read time format '"+time+"'."); 149 } 150 } 151 146 152 String action = atts.getValue("action"); 147 153 if (action == null) … … 152 158 current.modified = true; 153 159 } 154 155 private double getDouble(Attributes atts, String value) { 156 return Double.parseDouble(atts.getValue(value)); 157 } 158 private long getLong(Attributes atts, String value) { 159 return Long.parseLong(atts.getValue(value)); 160 private long getLong(Attributes atts, String value) throws SAXException { 161 String s = atts.getValue(value); 162 if (s == null) 163 throw new SAXException("Missing required attirbute '"+value+"'"); 164 return Long.parseLong(s); 165 } 166 167 private void createSegments() { 168 for (Entry<OsmPrimitiveData, long[]> e : segs.entrySet()) { 169 Node from = nodes.get(e.getValue()[0]); 170 Node to = nodes.get(e.getValue()[1]); 171 if (from == null || to == null) 172 continue; //TODO: implement support for incomplete nodes. 173 Segment s = new Segment(from, to); 174 e.getKey().copyTo(s); 175 segments.put(s.id, s); 176 adder.visit(s); 177 } 178 } 179 180 private void createWays() { 181 for (Entry<OsmPrimitiveData, Collection<Long>> e : ways.entrySet()) { 182 Way w = new Way(); 183 for (long id : e.getValue()) { 184 Segment s = segments.get(id); 185 if (s == null) 186 s = new Segment(id); // incomplete line segment 187 w.segments.add(s); 188 } 189 e.getKey().copyTo(w); 190 adder.visit(w); 191 } 192 } 193 194 /** 195 * All read segments after phase 2. 196 */ 197 private Map<Long, Segment> segments = new HashMap<Long, Segment>(); 198 199 /** 200 * Parse the given input source and return the dataset. 201 */ 202 public static DataSet parseDataSet(Reader source, JLabel currentAction, BoundedRangeModel progress) throws SAXException, IOException { 203 OsmReader osm = new OsmReader(); 204 205 // phase 1: Parse nodes and read in raw segments and ways 206 osm.new Parser().parse(source); 207 if (progress != null) 208 progress.setValue(0); 209 if (currentAction != null) 210 currentAction.setText("Preparing data..."); 211 for (Node n : osm.nodes.values()) 212 osm.adder.visit(n); 213 214 try { 215 osm.createSegments(); 216 osm.createWays(); 217 } catch (NumberFormatException e) { 218 e.printStackTrace(); 219 throw new SAXException("Illformed Node id"); 220 } 221 222 // clear all negative ids (new to this file) 223 for (OsmPrimitive o : osm.ds.allPrimitives()) 224 if (o.id < 0) 225 o.id = 0; 226 227 return osm.ds; 160 228 } 161 229 }
Note:
See TracChangeset
for help on using the changeset viewer.
