]> gitweb.fperrin.net Git - GpsPrune.git/blob - tim/prune/load/xml/KmlHandler.java
787dd0bd1cfc8d1df08cdd3caeb74c471a497bcb
[GpsPrune.git] / tim / prune / load / xml / KmlHandler.java
1 package tim.prune.load.xml;
2
3 import java.util.ArrayList;
4 import org.xml.sax.Attributes;
5 import org.xml.sax.SAXException;
6
7 import tim.prune.data.Field;
8
9
10 /**
11  * Class for handling specifics of parsing Kml files
12  */
13 public class KmlHandler extends XmlHandler
14 {
15         private boolean _insidePlacemark = false;
16         private boolean _insideName = false;
17         private boolean _insideCoordinates = false;
18         private String _name = null;
19         private StringBuffer _coordinates = null;
20         private ArrayList<String[]> _pointList = new ArrayList<String[]>();
21
22
23         /**
24          * Receive the start of a tag
25          * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
26          */
27         public void startElement(String uri, String localName, String qName,
28                         Attributes attributes) throws SAXException
29         {
30                 String tagName = localName;
31                 if (tagName == null || tagName.equals("")) {tagName = qName;}
32                 if (tagName.equalsIgnoreCase("Placemark")) _insidePlacemark = true;
33                 else if (tagName.equalsIgnoreCase("coordinates")) {_insideCoordinates = true; _coordinates = null;}
34                 else if (tagName.equalsIgnoreCase("name")) {_insideName = true; _name = null;}
35                 super.startElement(uri, localName, qName, attributes);
36         }
37
38
39         /**
40          * Process end tag
41          * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
42          */
43         public void endElement(String uri, String localName, String qName)
44         throws SAXException
45         {
46                 String tagName = localName;
47                 if (tagName == null || tagName.equals("")) {tagName = qName;}
48                 if (tagName.equalsIgnoreCase("Placemark"))
49                 {
50                         processPlacemark();
51                         _insidePlacemark = false;
52                 }
53                 else if (tagName.equalsIgnoreCase("coordinates")) _insideCoordinates = false;
54                 else if (tagName.equalsIgnoreCase("name")) _insideName = false;
55                 super.endElement(uri, localName, qName);
56         }
57
58
59         /**
60          * Process character text (inside tags or between them)
61          * @see org.xml.sax.ContentHandler#characters(char[], int, int)
62          */
63         public void characters(char[] ch, int start, int length)
64                         throws SAXException
65         {
66                 if (_insidePlacemark && (_insideName || _insideCoordinates))
67                 {
68                         String value = new String(ch, start, length);
69                         if (_insideName) {_name = value;}
70                         else if (_insideCoordinates)
71                         {
72                                 if (_coordinates == null)
73                                 {
74                                         _coordinates = new StringBuffer();
75                                 }
76                                 _coordinates.append(value);
77                         }
78                 }
79                 super.characters(ch, start, length);
80         }
81
82
83         /**
84          * Process a placemark entry, either a single waypoint or a whole track
85          */
86         private void processPlacemark()
87         {
88                 if (_coordinates == null) return;
89                 String allCoords = _coordinates.toString().trim();
90                 String[] coordArray = allCoords.split("[ \n]");
91                 int numPoints = coordArray.length;
92                 if (numPoints == 1)
93                 {
94                         // Add single waypoint to list
95                         _pointList.add(makeStringArray(allCoords, _name));
96                 }
97                 else if (numPoints > 1)
98                 {
99                         // Add each of the unnamed track points to list
100                         boolean firstPoint = true;
101                         for (int p=0; p<numPoints; p++)
102                         {
103                                 if (coordArray[p] != null && coordArray[p].trim().length()>3)
104                                 {
105                                         String[] pointArray = makeStringArray(coordArray[p], null);
106                                         if (firstPoint) {pointArray[4] = "1";} // start of segment flag
107                                         firstPoint = false;
108                                         _pointList.add(pointArray);
109                                 }
110                         }
111                 }
112         }
113
114
115         /**
116          * Construct the String array for the given coordinates and name
117          * @param inCoordinates coordinate string in Kml format
118          * @param inName name of waypoint, or null if track point
119          * @return String array for point
120          */
121         private static String[] makeStringArray(String inCoordinates, String inName)
122         {
123                 String[] result = new String[5];
124                 String[] values = inCoordinates.split(",");
125                 if (values.length == 3) {System.arraycopy(values, 0, result, 0, 3);}
126                 result[3] = inName;
127                 return result;
128         }
129
130
131         /**
132          * @see tim.prune.load.xml.XmlHandler#getFieldArray()
133          */
134         public Field[] getFieldArray()
135         {
136                 final Field[] fields = {Field.LONGITUDE, Field.LATITUDE, Field.ALTITUDE, Field.WAYPT_NAME, Field.NEW_SEGMENT};
137                 return fields;
138         }
139
140
141         /**
142          * Return the parsed information as a 2d array
143          * @see tim.prune.load.xml.XmlHandler#getDataArray()
144          */
145         public String[][] getDataArray()
146         {
147                 int numPoints = _pointList.size();
148                 // construct data array
149                 String[][] result = new String[numPoints][];
150                 for (int i=0; i<numPoints; i++)
151                 {
152                         result[i] = _pointList.get(i);
153                 }
154                 return result;
155         }
156
157 }