Last active
July 13, 2017 09:58
-
-
Save kamituel/6465125 to your computer and use it in GitHub Desktop.
Parsing GPX files (Android compatible).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package pl.kamituel.gpx; | |
import java.io.IOException; | |
import java.io.InputStream; | |
public class GpxParser { | |
private InputStream mIs = null; | |
private StringBuilder mStringBuilder = new StringBuilder(); | |
public GpxParser (InputStream is) { | |
mIs = is; | |
} | |
public TrkPt nextTrkPt () throws IOException { | |
mStringBuilder.delete(0, mStringBuilder.length()); | |
int c; | |
while ( (c = mIs.read()) != -1 ) { | |
mStringBuilder.append((char)c); | |
TrkPt trkpt = new TrkPt(); | |
if (trkpt.parse(mStringBuilder)) { | |
return trkpt; | |
} | |
} | |
return null; | |
} | |
public TrkPtInputStream getTrkPtStream () { | |
return new TrkPtInputStream(this); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package pl.kamituel.gpx; | |
import java.io.IOException; | |
import java.util.Vector; | |
/** | |
* Created by kls on 6/18/13. | |
*/ | |
public class GpxSmooth { | |
public static Iterable<TrkPt> compressGpx (GpxParser gpx, Double threshold) throws IOException { | |
Vector<TrkPt> res = new Vector<TrkPt>(); | |
TrkPt pN = null; | |
TrkPt pN_1 = null; | |
TrkPt pN_2 = null; | |
while ((pN = gpx.nextTrkPt()) != null) { | |
if (threshold != null && pN_1 != null && pN_2 != null) { | |
if (distanceFromTheLine(pN, pN_2, pN_1) > threshold) { | |
res.add(pN); | |
} | |
} else { | |
res.add(pN); | |
} | |
pN_2 = pN_1; | |
pN_1 = pN; | |
} | |
return res; | |
} | |
public static double distanceFromTheLine(TrkPt p1, TrkPt p2, TrkPt x) { | |
double A = p1.getLon() - p2.getLon(); | |
double B = p2.getLat() - p1.getLat(); | |
double C = p1.getLat() * (p2.getLon() - p1.getLon()) - p1.getLon() * (p2.getLat() - p1.getLat()); | |
return (A * x.getLat() + B * x.getLon() + C) / Math.sqrt(A*A + B*B); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package pl.kamituel.gpx; | |
import java.security.InvalidParameterException; | |
public class TrkPt { | |
private final static String START_TAG = "<trkpt "; | |
private final static String START_ANY_TAG = "<"; | |
private final static String END_TAG_EMPTY = "/>"; | |
private final static String END_TAG_FULL = "</trkpt>"; | |
private final static String ATTR_LAT = "lat=\""; | |
private final static String ATTR_LON = "lon=\""; | |
private final static String ELEM_ELE = "<ele>"; | |
private double mLat = 0.0; | |
private double mLon = 0.0; | |
private double mEle = Double.MIN_VALUE; | |
public TrkPt () { | |
} | |
private boolean parse (String s) { | |
int lat = s.indexOf(ATTR_LAT); | |
int lon = s.indexOf(ATTR_LON); | |
int ele = s.indexOf(ELEM_ELE); | |
if (lat < 0 || lon < 0) { | |
//throw new InvalidParameterException("trkpt without lat or lon attribute"); | |
return false; | |
} | |
int endLat = s.indexOf("\"", lat + ATTR_LAT.length()); | |
int endLon = s.indexOf("\"", lon + ATTR_LON.length()); | |
mLat = Double.parseDouble(s.substring(lat+ATTR_LAT.length(), endLat)); | |
mLon = Double.parseDouble(s.substring(lon+ATTR_LON.length(), endLon)); | |
if (ele > 0) { | |
mEle = Double.parseDouble(s.substring(ele + ELEM_ELE.length(), s.indexOf("<", ele + ELEM_ELE.length()))); | |
} | |
//System.out.println("lat " + (lat+ATTR_LAT.length()) + " endLat " + endLat); | |
return true; | |
} | |
public boolean parse (StringBuilder s) { | |
int startTag = s.indexOf(START_TAG); | |
if (startTag < 0) return false; | |
int nextTag = s.indexOf(START_ANY_TAG, startTag); | |
int endTagEmpty = s.indexOf(END_TAG_EMPTY, startTag); | |
int endTagFull = s.indexOf(END_TAG_FULL, startTag); | |
if (endTagEmpty + END_TAG_EMPTY.length() == s.length()) { | |
// It's like <trkpt .../>EOF | |
//System.out.println("matches 0 " + s.substring(startTag, endTagEmpty + END_TAG_EMPTY.length())); | |
return parse(s.substring(startTag, endTagEmpty + END_TAG_EMPTY.length())); | |
} else if (nextTag > 0 && endTagEmpty > 0 && nextTag < endTagEmpty) { | |
// It's like <trkpt ...><... | |
if (nextTag == endTagFull) { | |
// It's like <trkpt ...></trkpt> | |
return parse(s.substring(startTag, endTagFull + END_TAG_FULL.length())); | |
} else if (endTagFull > 0) { | |
// It's like <trkpt ...>...</trkpt> | |
//System.out.println("matches 2 " + s.substring(startTag, endTagFull + END_TAG_FULL.length())); | |
return parse(s.substring(startTag, endTagFull + END_TAG_FULL.length())); | |
} else { | |
return false; | |
} | |
} else if (nextTag > 0 && endTagFull > 0) { | |
//System.out.println("matches 3 " + s.substring(startTag, endTagFull + END_TAG_FULL.length())); | |
return parse(s.substring(startTag, endTagFull + END_TAG_FULL.length())); | |
} else { | |
//System.out.println("no match " + s.toString()); | |
return false; | |
} | |
} | |
public double getLat() { | |
return mLat; | |
} | |
public double getLon() { | |
return mLon; | |
} | |
public double getEle () { | |
return mEle; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package pl.kamituel.gpx; | |
import java.io.IOException; | |
import java.io.InputStream; | |
/** | |
* Created by kls on 6/19/13. | |
*/ | |
public class TrkPtInputStream extends InputStream { | |
private GpxParser mParser; | |
private StringBuilder mBuffer = new StringBuilder(); | |
public TrkPtInputStream(GpxParser parser) { | |
mParser = parser; | |
} | |
@Override | |
public int read() throws IOException { | |
if (mBuffer.length() == 0) { | |
TrkPt point = mParser.nextTrkPt(); | |
if (point == null) { | |
return -1; | |
} | |
mBuffer.append(point.getLat() + "," + point.getLon() + "\n"); | |
} | |
int res = mBuffer.charAt(0); | |
mBuffer.deleteCharAt(0); | |
return res; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Should it be useful to anybody, I made a library for this: https://github.com/ticofab/android-gpx-parser .