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