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

Last change on this file since 92 was 86, checked in by imi, 19 years ago
  • added conflicts and resolve conflict dialog

This is one of those "changed everything" checkpoint.

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