1 | package org.openstreetmap.josm.io;
|
---|
2 |
|
---|
3 | import java.io.IOException;
|
---|
4 | import java.io.Reader;
|
---|
5 | import java.util.Collection;
|
---|
6 | import java.util.LinkedList;
|
---|
7 | import java.util.List;
|
---|
8 |
|
---|
9 | import org.jdom.Element;
|
---|
10 | import org.jdom.JDOMException;
|
---|
11 | import org.jdom.Namespace;
|
---|
12 | import org.jdom.input.SAXBuilder;
|
---|
13 | import org.openstreetmap.josm.data.GeoPoint;
|
---|
14 |
|
---|
15 | /**
|
---|
16 | * Read raw gps data from a gpx file. Only way points with their waies segments
|
---|
17 | * and waypoints are imported.
|
---|
18 | * @author imi
|
---|
19 | */
|
---|
20 | public class RawGpsReader {
|
---|
21 |
|
---|
22 | /**
|
---|
23 | * The data source from this reader.
|
---|
24 | */
|
---|
25 | public Reader source;
|
---|
26 |
|
---|
27 | /**
|
---|
28 | * Construct a gps reader from an input reader source.
|
---|
29 | * @param source The source to read the raw gps data from. The data must be
|
---|
30 | * in GPX format.
|
---|
31 | */
|
---|
32 | public RawGpsReader(Reader source) {
|
---|
33 | this.source = source;
|
---|
34 | }
|
---|
35 |
|
---|
36 | /**
|
---|
37 | * The gpx namespace.
|
---|
38 | */
|
---|
39 | private Namespace GPX = Namespace.getNamespace("http://www.topografix.com/GPX/1/0");
|
---|
40 |
|
---|
41 | /**
|
---|
42 | * Parse and return the read data
|
---|
43 | */
|
---|
44 | public Collection<Collection<GeoPoint>> parse() throws JDOMException, IOException {
|
---|
45 | final SAXBuilder builder = new SAXBuilder();
|
---|
46 | builder.setValidation(false);
|
---|
47 | Element root = builder.build(source).getRootElement();
|
---|
48 | return parseData(root);
|
---|
49 | }
|
---|
50 |
|
---|
51 | /**
|
---|
52 | * Parse and return the whole data thing.
|
---|
53 | * @param root
|
---|
54 | * @return
|
---|
55 | */
|
---|
56 | @SuppressWarnings("unchecked")
|
---|
57 | private Collection<Collection<GeoPoint>> parseData(Element root) throws JDOMException {
|
---|
58 | Collection<Collection<GeoPoint>> data = new LinkedList<Collection<GeoPoint>>();
|
---|
59 |
|
---|
60 | // workaround for bug where the server adds /gpx.asd to the namespace
|
---|
61 | GPX = Namespace.getNamespace(root.getNamespaceURI());
|
---|
62 |
|
---|
63 | for (Object o : root.getChildren("wpt", GPX)) {
|
---|
64 | Collection<GeoPoint> line = new LinkedList<GeoPoint>();
|
---|
65 | line.add(new GeoPoint(parseDouble((Element)o, LatLon.lat), parseDouble((Element)o, LatLon.lon)));
|
---|
66 | data.add(line);
|
---|
67 | }
|
---|
68 | for (Object o : root.getChildren("rte", GPX)) {
|
---|
69 | Collection<GeoPoint> line = parseLine(((Element)o).getChildren("rtept", GPX));
|
---|
70 | if (!line.isEmpty())
|
---|
71 | data.add(line);
|
---|
72 | }
|
---|
73 | for (Object o : root.getChildren("trk", GPX)) {
|
---|
74 | for (Object seg : ((Element)o).getChildren("trkseg", GPX)) {
|
---|
75 | Collection<GeoPoint> line = parseLine(((Element)seg).getChildren("trkpt", GPX));
|
---|
76 | if (!line.isEmpty())
|
---|
77 | data.add(line);
|
---|
78 | }
|
---|
79 | }
|
---|
80 | return data;
|
---|
81 | }
|
---|
82 |
|
---|
83 | enum LatLon {lat, lon}
|
---|
84 | /**
|
---|
85 | * Return a parsed float value from the element behind the object o.
|
---|
86 | * @param o An object of dynamic type org.jdom.Element (will be casted).
|
---|
87 | * @param attr The name of the attribute.
|
---|
88 | * @throws JDOMException If the absolute of the value is out of bound.
|
---|
89 | */
|
---|
90 | private double parseDouble(Element e, LatLon attr) throws JDOMException {
|
---|
91 | double d = Double.parseDouble(e.getAttributeValue(attr.toString()));
|
---|
92 | if (Math.abs(d) > (attr == LatLon.lat ? 90 : 180))
|
---|
93 | throw new JDOMException("Data error: "+attr+" value '"+d+"' is out of bound.");
|
---|
94 | return d;
|
---|
95 | }
|
---|
96 |
|
---|
97 | /**
|
---|
98 | * Parse the list of waypoint - elements and return a collection with the
|
---|
99 | * points read.
|
---|
100 | */
|
---|
101 | private Collection<GeoPoint> parseLine(List<Element> wpt) throws JDOMException {
|
---|
102 | Collection<GeoPoint> data = new LinkedList<GeoPoint>();
|
---|
103 | for (Element e : wpt)
|
---|
104 | data.add(new GeoPoint(parseDouble(e, LatLon.lat), parseDouble(e, LatLon.lon)));
|
---|
105 | return data;
|
---|
106 | }
|
---|
107 | }
|
---|