source: josm/src/org/openstreetmap/josm/io/OsmReader.java@ 82

Last change on this file since 82 was 82, checked in by imi, 18 years ago

fixed bug when import timestamp after locale (now after fixed pattern)

File size: 5.1 KB
Line 
1package org.openstreetmap.josm.io;
2
3import java.io.IOException;
4import java.io.Reader;
5import java.text.DateFormat;
6import java.text.ParseException;
7import java.text.SimpleDateFormat;
8import java.util.HashMap;
9import java.util.Map;
10
11import org.openstreetmap.josm.data.coor.LatLon;
12import org.openstreetmap.josm.data.osm.DataSet;
13import org.openstreetmap.josm.data.osm.LineSegment;
14import org.openstreetmap.josm.data.osm.Node;
15import org.openstreetmap.josm.data.osm.OsmPrimitive;
16import org.openstreetmap.josm.data.osm.Way;
17import org.openstreetmap.josm.data.osm.visitor.AddVisitor;
18import org.xml.sax.Attributes;
19import org.xml.sax.SAXException;
20
21import uk.co.wilson.xml.MinML2;
22
23/**
24 * Parser for the Osm Api. Read from an input stream and construct a dataset out of it.
25 *
26 * @author Imi
27 */
28public class OsmReader extends MinML2 {
29
30 /**
31 * The dataset to add parsed objects to.
32 */
33 private DataSet ds = new DataSet();
34
35 /**
36 * The visitor to use to add the data to the set.
37 */
38 private AddVisitor adder = new AddVisitor(ds);
39
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, LineSegment> lineSegments = new HashMap<Long, LineSegment>();
53
54 /**
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
73 public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
74 try {
75 if (qName.equals("osm")) {
76 if (atts == null)
77 throw new SAXException("Unknown version.");
78 if (!"0.3".equals(atts.getValue("version")))
79 throw new SAXException("Unknown version "+atts.getValue("version"));
80 } else if (qName.equals("node")) {
81 Node n = new Node(new LatLon(getDouble(atts, "lat"), getDouble(atts, "lon")));
82 current = n;
83 readCommon(atts);
84 current.id = getLong(atts, "id");
85 nodes.put(n.id, n);
86 } else if (qName.equals("segment")) {
87 Node from = nodes.get(getLong(atts, "from"));
88 Node to = nodes.get(getLong(atts, "to"));
89 if (from == null || to == null)
90 throw new SAXException("Segment "+atts.getValue("id")+" is missing its nodes.");
91 current = new LineSegment(from, to);
92 readCommon(atts);
93 lineSegments.put(current.id, (LineSegment)current);
94 } else if (qName.equals("way")) {
95 current = new Way();
96 readCommon(atts);
97 } else if (qName.equals("seg")) {
98 if (current instanceof Way) {
99 long id = getLong(atts, "id");
100 if (id == 0)
101 throw new SAXException("Incomplete line segment with id=0");
102 LineSegment ls = lineSegments.get(id);
103 if (ls == null) {
104 ls = new LineSegment(id); // incomplete line segment
105 lineSegments.put(id, ls);
106 adder.visit(ls);
107 }
108 ((Way)current).segments.add(ls);
109 }
110 } else if (qName.equals("tag"))
111 current.put(atts.getValue("k"), atts.getValue("v"));
112 } catch (NumberFormatException x) {
113 x.printStackTrace(); // SAXException does not chain correctly
114 throw new SAXException(x.getMessage(), x);
115 } catch (NullPointerException x) {
116 throw new SAXException("NullPointerException. Possible some missing tags.", x);
117 }
118 }
119
120
121 @Override
122 public void endElement(String namespaceURI, String localName, String qName) {
123 if (qName.equals("node") || qName.equals("segment") || qName.equals("way") || qName.equals("area")) {
124 current.visit(adder);
125 }
126 }
127
128 /**
129 * Read out the common attributes from atts and put them into this.current.
130 */
131 private void readCommon(Attributes atts) throws SAXException {
132 current.id = getLong(atts, "id");
133 if (current.id == 0)
134 throw new SAXException("Illegal object with id=0");
135
136 String time = atts.getValue("timestamp");
137 if (time != null && time.length() != 0) {
138 try {
139 DateFormat df = new SimpleDateFormat("y-M-d H:m:s");
140 current.lastModified = df.parse(time);
141 } catch (ParseException e) {
142 e.printStackTrace();
143 throw new SAXException("Couldn't read time format '"+time+"'.");
144 }
145 }
146
147 String action = atts.getValue("action");
148 if ("delete".equals(action))
149 current.setDeleted(true);
150 else if ("modify".equals(action)) {
151 current.modified = true;
152 current.modifiedProperties = true;
153 } else if ("modify/object".equals(action))
154 current.modified = true;
155 else if ("modify/property".equals(action))
156 current.modifiedProperties = true;
157 }
158
159 private double getDouble(Attributes atts, String value) {
160 return Double.parseDouble(atts.getValue(value));
161 }
162 private long getLong(Attributes atts, String value) {
163 return Long.parseLong(atts.getValue(value));
164 }
165}
Note: See TracBrowser for help on using the repository browser.