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