]> gitweb.fperrin.net Git - GpsPrune.git/blob - tim/prune/load/xml/GpxHandler.java
ec52f8b5b4b81c54cadb5976a0ed4633d528f494
[GpsPrune.git] / tim / prune / load / xml / GpxHandler.java
1 package tim.prune.load.xml;
2
3 import java.util.ArrayList;
4
5 import org.xml.sax.Attributes;
6 import org.xml.sax.SAXException;
7
8 import tim.prune.data.Field;
9 import tim.prune.load.TrackNameList;
10
11
12 /**
13  * Class for handling specifics of parsing Gpx files
14  */
15 public class GpxHandler extends XmlHandler
16 {
17         private boolean _insidePoint = false;
18         private boolean _insideWaypoint = false;
19         private boolean _startSegment = true;
20         private boolean _isTrackPoint = false;
21         private int _trackNum = -1;
22         private GpxTag _name = new GpxTag(), _trackName = new GpxTag();
23         private String _latitude = null, _longitude = null;
24         private GpxTag _elevation = new GpxTag(), _time = new GpxTag();
25         private GpxTag _type = new GpxTag(), _link = new GpxTag();
26         private GpxTag _currentTag = null;
27         private ArrayList<String[]> _pointList = new ArrayList<String[]>();
28         private ArrayList<String> _linkList = new ArrayList<String>();
29         private TrackNameList _trackNameList = new TrackNameList();
30
31
32         /**
33          * Receive the start of a tag
34          * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
35          */
36         public void startElement(String uri, String localName, String qName,
37                 Attributes attributes) throws SAXException
38         {
39                 // Read the parameters for waypoints and track points
40                 String tag = qName.toLowerCase();
41                 if (tag.equals("wpt") || tag.equals("trkpt") || tag.equals("rtept"))
42                 {
43                         _insidePoint = true;
44                         _insideWaypoint = tag.equals("wpt");
45                         _isTrackPoint = tag.equals("trkpt");
46                         final int numAttributes = attributes.getLength();
47                         for (int i=0; i<numAttributes; i++)
48                         {
49                                 String att = attributes.getQName(i).toLowerCase();
50                                 if (att.equals("lat")) {_latitude = attributes.getValue(i);}
51                                 else if (att.equals("lon")) {_longitude = attributes.getValue(i);}
52                         }
53                         _elevation.setValue(null);
54                         _name.setValue(null);
55                         _time.setValue(null);
56                         _type.setValue(null);
57                         _link.setValue(null);
58                 }
59                 else if (tag.equals("ele")) {
60                         _currentTag = _elevation;
61                 }
62                 else if (tag.equals("name")) {
63                         _currentTag = (_insidePoint?_name:_trackName);
64                 }
65                 else if (tag.equals("time")) {
66                         _currentTag = _time;
67                 }
68                 else if (tag.equals("type")) {
69                         _currentTag = _type;
70                 }
71                 else if (tag.equals("link")) {
72                         _link.setValue(attributes.getValue("href"));
73                 }
74                 else if (tag.equals("trkseg")) {
75                         _startSegment = true;
76                 }
77                 else if (tag.equals("trk"))
78                 {
79                         _trackNum++;
80                         _trackName.setValue(null);
81                 }
82                 super.startElement(uri, localName, qName, attributes);
83         }
84
85
86         /**
87          * Process end tag
88          * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
89          */
90         public void endElement(String uri, String localName, String qName)
91                 throws SAXException
92         {
93                 String tag = qName.toLowerCase();
94                 if (tag.equals("wpt") || tag.equals("trkpt") || tag.equals("rtept"))
95                 {
96                         processPoint();
97                         _insidePoint = false;
98                 }
99                 else {
100                         _currentTag = null;
101                 }
102                 super.endElement(uri, localName, qName);
103         }
104
105
106         /**
107          * Process character text (inside tags or between them)
108          * @see org.xml.sax.ContentHandler#characters(char[], int, int)
109          */
110         public void characters(char[] ch, int start, int length)
111                 throws SAXException
112         {
113                 String value = new String(ch, start, length);
114                 if (_currentTag != null) {
115                         _currentTag.setValue(checkCharacters(_currentTag.getValue(), value));
116                 }
117                 super.characters(ch, start, length);
118         }
119
120
121         /**
122          * Check to concatenate partially-received values, if necessary
123          * @param inVariable variable containing characters received until now
124          * @param inValue new value received
125          * @return concatenation
126          */
127         private static String checkCharacters(String inVariable, String inValue)
128         {
129                 if (inVariable == null) {return inValue;}
130                 return inVariable + inValue;
131         }
132
133
134         /**
135          * Process a point, either a waypoint or track point
136          */
137         private void processPoint()
138         {
139                 // Put the values into a String array matching the order in getFieldArray()
140                 String[] values = new String[7];
141                 values[0] = _latitude;
142                 values[1] = _longitude;
143                 values[2] = _elevation.getValue();
144                 if (_insideWaypoint) {values[3] = _name.getValue();}
145                 values[4] = _time.getValue();
146                 if (_startSegment && !_insideWaypoint) {
147                         values[5] = "1";
148                         _startSegment = false;
149                 }
150                 values[6] = _type.getValue();
151                 _pointList.add(values);
152                 _trackNameList.addPoint(_trackNum, _trackName.getValue(), _isTrackPoint);
153                 _linkList.add(_link.getValue());
154         }
155
156
157         /**
158          * @see tim.prune.load.xml.XmlHandler#getFieldArray()
159          */
160         public Field[] getFieldArray()
161         {
162                 final Field[] fields = {Field.LATITUDE, Field.LONGITUDE, Field.ALTITUDE,
163                         Field.WAYPT_NAME, Field.TIMESTAMP, Field.NEW_SEGMENT, Field.WAYPT_TYPE};
164                 return fields;
165         }
166
167
168         /**
169          * Return the parsed information as a 2d array
170          * @see tim.prune.load.xml.XmlHandler#getDataArray()
171          */
172         public String[][] getDataArray()
173         {
174                 int numPoints = _pointList.size();
175                 // construct data array
176                 String[][] result = new String[numPoints][];
177                 for (int i=0; i<numPoints; i++)
178                 {
179                         result[i] = _pointList.get(i);
180                 }
181                 return result;
182         }
183
184         /**
185          * @return array of links, or null if none
186          */
187         public String[] getLinkArray()
188         {
189                 int numPoints = _linkList.size();
190                 boolean hasLink = false;
191                 String[] result = new String[numPoints];
192                 for (int i=0; i<numPoints; i++)
193                 {
194                         result[i] = _linkList.get(i);
195                         if (result[i] != null) {hasLink = true;}
196                 }
197                 if (!hasLink) {result = null;}
198                 return result;
199         }
200
201         /**
202          * @return track name list
203          */
204         public TrackNameList getTrackNameList() {
205                 return _trackNameList;
206         }
207 }