source: josm/src/org/openstreetmap/josm/io/OsmReaderOld.java@ 58

Last change on this file since 58 was 58, checked in by imi, 20 years ago
  • implemented 0.3 API
  • enabled upload of ways
  • switched to MinML (GPX still uses JDOM)
  • changed assumed server precision to 10-12 (was 10-13)
File size: 7.4 KB
Line 
1package org.openstreetmap.josm.io;
2
3import java.io.IOException;
4import java.io.Reader;
5import java.util.Collection;
6import java.util.HashMap;
7import java.util.StringTokenizer;
8
9import org.jdom.Element;
10import org.jdom.JDOMException;
11import org.jdom.input.SAXBuilder;
12import org.openstreetmap.josm.data.GeoPoint;
13import org.openstreetmap.josm.data.osm.DataSet;
14import org.openstreetmap.josm.data.osm.Key;
15import org.openstreetmap.josm.data.osm.LineSegment;
16import org.openstreetmap.josm.data.osm.Node;
17import org.openstreetmap.josm.data.osm.OsmPrimitive;
18import org.openstreetmap.josm.data.osm.Track;
19import org.openstreetmap.josm.data.osm.visitor.AddVisitor;
20
21/**
22 * Reads the old osm 0.2 format.
23 *
24 * @author imi
25 */
26public class OsmReaderOld {
27
28 /**
29 * The data source from this reader.
30 */
31 public Reader source;
32
33 /**
34 * Construct a parser from a specific data source.
35 * @param source The data source, as example a FileReader to read from a file.
36 */
37 public OsmReaderOld(Reader source) {
38 this.source = source;
39 }
40
41 /**
42 * Read the input stream and return a DataSet from the stream.
43 */
44 public DataSet parse() throws JDOMException, IOException {
45 try {
46 final SAXBuilder builder = new SAXBuilder();
47 Element root = builder.build(source).getRootElement();
48 return parseDataSet(root);
49 } catch (NumberFormatException nfe) {
50 throw new JDOMException("NumberFormatException. Probably a tag is missing.", nfe);
51 } catch (NullPointerException npe) {
52 throw new JDOMException("NullPointerException. Probably a tag name mismatch.", npe);
53 } catch (ClassCastException cce) {
54 throw new JDOMException("ClassCastException. Probably a tag does not contain the correct type.", cce);
55 }
56 }
57
58
59 /**
60 * Read one node.
61 * @param e The element to parse
62 * @return The Waypoint read from the element
63 * @throws JDOMException In case of a parsing error.
64 */
65 private Node parseNode(Element e) throws JDOMException {
66 Node data = new Node();
67 data.coor = new GeoPoint(
68 Double.parseDouble(e.getAttributeValue("lat")),
69 Double.parseDouble(e.getAttributeValue("lon")));
70 if (Double.isNaN(data.coor.lat) ||
71 data.coor.lat < -90 || data.coor.lat > 90 ||
72 data.coor.lon < -180 || data.coor.lon > 180)
73 throw new JDOMException("Illegal lat or lon value: "+data.coor.lat+"/"+data.coor.lon);
74 parseCommon(data, e);
75 return data;
76 }
77
78 /**
79 * Parse any (yet unknown) object and return it.
80 */
81 private OsmPrimitive parseObject(Element e, DataSet data) throws JDOMException {
82 if (e.getName().equals("node"))
83 return parseNode(e);
84 else if (e.getName().equals("segment"))
85 return parseLineSegment(e, data);
86 else if (e.getName().equals("track"))
87 return parseTrack(e, data);
88 else if (e.getName().equals("property")) {
89 parseProperty(e, data);
90 return null;
91 }
92 throw new JDOMException("unknown tag: "+e.getName());
93 }
94
95 /**
96 * Read a data set from the element.
97 * @param e The element to parse
98 * @return The DataSet read from the element
99 * @throws JDOMException In case of a parsing error.
100 */
101 private DataSet parseDataSet(Element e) throws JDOMException {
102 DataSet data = new DataSet();
103 AddVisitor visitor = new AddVisitor(data);
104 for (Object o : e.getChildren()) {
105 Element child = (Element)o;
106 OsmPrimitive osm = parseObject(child, data);
107 if (osm != null)
108 osm.visit(visitor);
109 }
110
111 // clear all negative ids (new to this file)
112 for (OsmPrimitive osm : data.allPrimitives())
113 if (osm.id < 0)
114 osm.id = 0;
115
116 return data;
117 }
118
119 /**
120 * Parse and return an line segment. The node information of the "from" and
121 * "to" attributes must already be in the dataset.
122 * @param e The line segment element to parse.
123 * @param data The dataset to obtain the node information from.
124 * @return The parsed line segment.
125 * @throws JDOMException In case of parsing errors.
126 */
127 private LineSegment parseLineSegment(Element e, DataSet data) throws JDOMException {
128 long startId = Long.parseLong(e.getAttributeValue("from"));
129 long endId = Long.parseLong(e.getAttributeValue("to"));
130
131 Node start = null, end = null;
132 for (Node n : data.nodes) {
133 if (n.id == startId)
134 start = n;
135 if (n.id == endId)
136 end = n;
137 }
138 if (start == null || end == null)
139 throw new JDOMException("The 'from' or 'to' object has not been transfered before.");
140 LineSegment ls = new LineSegment(start, end);
141 parseCommon(ls, e);
142 return ls;
143 }
144
145 /**
146 * Parse and read a track from the element.
147 *
148 * @param e The element that contain the track.
149 * @param data The DataSet to get segment information from.
150 * @return The parsed track.
151 * @throws JDOMException In case of a parsing error.
152 */
153 private Track parseTrack(Element e, DataSet data) throws JDOMException {
154 Track track = new Track();
155 parseCommon(track, e);
156 for (Object o : e.getChildren("segment")) {
157 Element child = (Element)o;
158 long id = Long.parseLong(child.getAttributeValue("uid"));
159 LineSegment ls = findLineSegment(data.lineSegments, id);
160 track.segments.add(ls);
161 }
162 return track;
163 }
164
165 /**
166 * Parse the common part (properties and uid) of the element.
167 * @param data To store the data in.
168 * @param e The element to extract the common information.
169 * @throws JDOMException In case of a parsing error
170 */
171 private void parseCommon(OsmPrimitive data, Element e) {
172 String suid = e.getAttributeValue("uid");
173 if (suid != null)
174 data.id = Long.parseLong(suid);
175
176 String propStr = e.getAttributeValue("tags");
177 if (propStr != null && !propStr.equals("")) {
178 data.keys = new HashMap<Key, String>();
179 StringTokenizer st = new StringTokenizer(propStr, ";");
180 while (st.hasMoreTokens()) {
181 String next = st.nextToken();
182 if (next.trim().equals(""))
183 continue;
184 int equalPos = next.indexOf('=');
185 if (equalPos == -1)
186 data.keys.put(Key.get(next), "");
187 else {
188 String keyStr = next.substring(0, equalPos);
189 data.keys.put(Key.get(keyStr), next.substring(equalPos+1));
190 }
191 }
192 }
193
194 String action = e.getAttributeValue("action");
195 if ("delete".equals(action))
196 data.setDeleted(true);
197 else if ("modify".equals(action))
198 data.modified = data.modifiedProperties = true;
199 else if ("modify/property".equals(action))
200 data.modifiedProperties = true;
201 else if ("modify/object".equals(action))
202 data.modified = true;
203 }
204
205 /**
206 * Parse a property tag and assign the property to a previous found object.
207 */
208 private void parseProperty(Element e, DataSet data) throws JDOMException {
209 long id = Long.parseLong(e.getAttributeValue("uid"));
210 OsmPrimitive osm = findObject(data, id);
211 Key key = Key.get(e.getAttributeValue("key"));
212 String value = e.getAttributeValue("value");
213 if (value != null) {
214 if (osm.keys == null)
215 osm.keys = new HashMap<Key, String>();
216 osm.keys.put(key, value);
217 }
218 }
219
220 /**
221 * Search for an object in the dataset by comparing the id.
222 */
223 private OsmPrimitive findObject(DataSet data, long id) throws JDOMException {
224 for (OsmPrimitive osm : data.nodes)
225 if (osm.id == id)
226 return osm;
227 for (OsmPrimitive osm : data.lineSegments)
228 if (osm.id == id)
229 return osm;
230 for (OsmPrimitive osm : data.tracks)
231 if (osm.id == id)
232 return osm;
233 throw new JDOMException("Unknown object reference: "+id);
234 }
235
236 /**
237 * Search for a segment in a collection by comparing the id.
238 */
239 private LineSegment findLineSegment(Collection<LineSegment> segments, long id) throws JDOMException {
240 for (LineSegment ls : segments)
241 if (ls.id == id)
242 return ls;
243 throw new JDOMException("Unknown line segment reference: "+id);
244 }
245}
Note: See TracBrowser for help on using the repository browser.