1 | package org.openstreetmap.josm.io;
|
---|
2 |
|
---|
3 | import static org.openstreetmap.josm.tools.I18n.tr;
|
---|
4 |
|
---|
5 | import java.io.IOException;
|
---|
6 | import java.io.InputStream;
|
---|
7 | import java.io.InputStreamReader;
|
---|
8 | import java.util.Collection;
|
---|
9 | import java.util.LinkedList;
|
---|
10 |
|
---|
11 | import org.openstreetmap.josm.data.coor.LatLon;
|
---|
12 | import org.openstreetmap.josm.gui.layer.RawGpsLayer.GpsPoint;
|
---|
13 | import org.xml.sax.Attributes;
|
---|
14 | import org.xml.sax.SAXException;
|
---|
15 |
|
---|
16 | import uk.co.wilson.xml.MinML2;
|
---|
17 |
|
---|
18 | /**
|
---|
19 | * Read raw gps data from a gpx file. Only way points with their ways segments
|
---|
20 | * and waypoints are imported.
|
---|
21 | * @author imi
|
---|
22 | */
|
---|
23 | public class RawGpsReader {
|
---|
24 |
|
---|
25 | private static class Parser extends MinML2 {
|
---|
26 | /**
|
---|
27 | * Current track to be read. The last entry is the current trkpt.
|
---|
28 | * If in wpt-mode, it contain only one GpsPoint.
|
---|
29 | */
|
---|
30 | private Collection<GpsPoint> current = new LinkedList<GpsPoint>();
|
---|
31 | public Collection<Collection<GpsPoint>> data = new LinkedList<Collection<GpsPoint>>();
|
---|
32 | private LatLon currentLatLon;
|
---|
33 | private String currentTime;
|
---|
34 |
|
---|
35 | @Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
|
---|
36 | if (qName.equals("wpt") || qName.equals("trkpt")) {
|
---|
37 | try {
|
---|
38 | double lat = Double.parseDouble(atts.getValue("lat"));
|
---|
39 | double lon = Double.parseDouble(atts.getValue("lon"));
|
---|
40 | if (Math.abs(lat) > 90)
|
---|
41 | throw new SAXException(tr("Data error: lat value '{0}' is out of bound.", lat));
|
---|
42 | if (Math.abs(lon) > 180)
|
---|
43 | throw new SAXException(tr("Data error: lon value '{0}' is out of bound.", lon));
|
---|
44 | currentLatLon = new LatLon(lat, lon);
|
---|
45 | } catch (NumberFormatException e) {
|
---|
46 | e.printStackTrace();
|
---|
47 | throw new SAXException(e);
|
---|
48 | }
|
---|
49 | } else if (qName.equals("time")) {
|
---|
50 | currentTime = "";
|
---|
51 | }
|
---|
52 | }
|
---|
53 |
|
---|
54 | @Override public void characters(char[] ch, int start, int length) {
|
---|
55 | if (currentTime != null && currentTime.equals(""))
|
---|
56 | currentTime = new String(ch, start, length);
|
---|
57 | }
|
---|
58 |
|
---|
59 | @Override public void endElement(String namespaceURI, String localName, String qName) {
|
---|
60 | if (qName.equals("wpt") || qName.equals("trkpt")) {
|
---|
61 | current.add(new GpsPoint(currentLatLon, currentTime));
|
---|
62 | } else if (qName.equals("trkseg") || qName.equals("trk") || qName.equals("gpx"))
|
---|
63 | newTrack();
|
---|
64 | }
|
---|
65 |
|
---|
66 | private void newTrack() {
|
---|
67 | if (!current.isEmpty()) {
|
---|
68 | data.add(current);
|
---|
69 | current = new LinkedList<GpsPoint>();
|
---|
70 | }
|
---|
71 | }
|
---|
72 | }
|
---|
73 |
|
---|
74 | /**
|
---|
75 | * Parse and return the read data
|
---|
76 | */
|
---|
77 | public static Collection<Collection<GpsPoint>> parse(InputStream source) throws SAXException, IOException {
|
---|
78 | Parser parser = new Parser();
|
---|
79 | parser.parse(new InputStreamReader(source, "UTF-8"));
|
---|
80 | return parser.data;
|
---|
81 | }
|
---|
82 | }
|
---|