File: GpxCacher.java

package info (click to toggle)
gpsprune 10-1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 2,220 kB
  • ctags: 3,013
  • sloc: java: 22,662; sh: 23; makefile: 16; python: 15
file content (198 lines) | stat: -rw-r--r-- 5,213 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
package tim.prune.save;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import tim.prune.data.DataPoint;
import tim.prune.data.SourceInfo;

/**
 * Class to read in a GPX file and cache all the point strings
 */
public class GpxCacher extends DefaultHandler
{
	private SourceInfo _sourceInfo = null;
	private String _headerString = null;
	private String[] _strings = null;
	private int _pointNum = 0;
	private boolean _insidePoint = false;
	private StringBuilder _builder = null;


	/**
	 * Constructor
	 * @param inSourceInfo source information
	 */
	public GpxCacher(SourceInfo inInfo)
	{
		_sourceInfo = inInfo;
		_strings = new String[inInfo.getNumPoints()];
		_pointNum = 0;
		// Should be a gpx file, but might be raw, zipped or gzipped
		File gpxFile = inInfo.getFile();
		String fileName = gpxFile.getName().toLowerCase();
		if (gpxFile.exists() && gpxFile.canRead())
		{
			try {
				SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
				if (fileName.endsWith(".gpx") || fileName.endsWith(".xml")) {
					saxParser.parse(inInfo.getFile(), this);
				}
				else if (fileName.endsWith(".zip")) {
					saxParser.parse(getZipInputStream(inInfo.getFile()), this);
				}
				else if (fileName.endsWith(".gz")) {
					saxParser.parse(new GZIPInputStream(new FileInputStream(inInfo.getFile())), this);
				}
				else {
					System.out.println("GpxCacher unrecognised file type: " + inInfo.getFile().getName());
				}
			} catch (Exception e) {
				// TODO: Handle errors here with a list of warnings?
				e.printStackTrace();
			}
		}
		_builder = null;
	}


	/**
	 * Receive the start of a tag
	 */
	public void startElement(String inUri, String inLocalName, String inTagName,
		Attributes inAttributes) throws SAXException
	{
		if (inTagName.equalsIgnoreCase("gpx"))
		{
			// store initial gpx tag
			_builder = new StringBuilder(60);
			appendTag(_builder, inTagName, inAttributes);
			_headerString = _builder.toString();
		}
		else
		{
			if (inTagName.equalsIgnoreCase("wpt") || inTagName.equalsIgnoreCase("trkpt")
				|| inTagName.equalsIgnoreCase("rtept"))
			{
				_insidePoint = true;
				_builder = new StringBuilder(60);
			}
			if (_insidePoint) {
				appendTag(_builder, inTagName, inAttributes);
			}
		}
		super.startElement(inUri, inLocalName, inTagName, inAttributes);
	}

	/**
	 * Receive characters between tags (inside or outside)
	 */
	public void characters(char[] inChars, int inStart, int inLength)
		throws SAXException
	{
		if (_insidePoint) {
			_builder.append(new String(inChars, inStart, inLength));
		}
		super.characters(inChars, inStart, inLength);
	}

	/**
	 * Receive end of xml tag
	 */
	public void endElement(String inUri, String inLocalName, String inTagName)
		throws SAXException
	{
		if (_insidePoint) {
			_builder.append("</").append(inTagName).append('>');
		}
		if (inTagName.equalsIgnoreCase("wpt") || inTagName.equalsIgnoreCase("trkpt")
			|| inTagName.equalsIgnoreCase("rtept"))
		{
			_strings[_pointNum] = _builder.toString();
			_pointNum++;
			_insidePoint = false;
		}
		super.endElement(inUri, inLocalName, inTagName);
	}


	/**
	 * Append the current tag to the supplied StringBuilder
	 * @param inBuilder Stringbuilder object to append tag to
	 * @param inTagName name of tag
	 * @param inAttributes attributes of tag
	 */
	private static void appendTag(StringBuilder inBuilder, String inTagName, Attributes inAttributes)
	{
		inBuilder.append('<').append(inTagName);
		int numAtts = inAttributes.getLength();
		for (int i=0; i<numAtts; i++) {
			inBuilder.append(' ').append(inAttributes.getQName(i)).append("=\"")
				.append(inAttributes.getValue(i)).append('"');
		}
		inBuilder.append('>');
	}


	/**
	 * @return the header string from the GPX tag
	 */
	public String getHeaderString()
	{
		return _headerString;
	}

	/**
	 * Get the source string for the given point
	 * @param inPoint point to retrieve
	 * @return string if found, otherwise null
	 */
	public String getSourceString(DataPoint inPoint)
	{
		int index = _sourceInfo.getIndex(inPoint);
		if (index >= 0) {
			return _strings[index];
		}
		return null;
	}

	/**
	 * Get an inputstream of a GPX file inside a zip
	 * @param inFile File object describing zip file
	 * @return input stream for Xml parser
	 */
	private static InputStream getZipInputStream(File inFile)
	{
		try
		{
			ZipInputStream zis = new ZipInputStream(new FileInputStream(inFile));
			while (zis.available() > 0)
			{
				ZipEntry entry = zis.getNextEntry();
				String entryName = entry.toString();
				if (entryName != null && entryName.length() > 4)
				{
					String suffix = entryName.substring(entryName.length()-4).toLowerCase();
					if (suffix.equals(".gpx") || suffix.equals(".xml")) {
						// First matching file so must be gpx
						return zis;
					}
				}
			}
		}
		catch (Exception e) {} // ignore errors
		// not found - error!
		return null;
	}
}