me.himanshusoni.gpxparser.GPXParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of swingset3-demos Show documentation
Show all versions of swingset3-demos Show documentation
Demonstrating the abilities of the Swing UI Toolkit swingset2 and swingx aka swingset3
The newest version!
package me.himanshusoni.gpxparser;
import me.himanshusoni.gpxparser.extension.DummyExtensionParser;
import me.himanshusoni.gpxparser.extension.IExtensionParser;
import me.himanshusoni.gpxparser.modal.*;
import me.himanshusoni.gpxparser.type.Fix;
import org.w3c.dom.*;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.InputStream;
import java.util.Date;
import java.util.Iterator;
import java.util.regex.Pattern;
/**
*
* This class defines methods for parsing and writing gpx files.
*
*
* Usage for parsing a gpx file into a {@link GPX} object:
*
* GPXParser p = new GPXParser();
* FileInputStream in = new FileInputStream("inFile.gpx");
* GPX gpx = p.parseGPX(in);
*
* Usage for writing a {@link GPX} object to a file:
*
* GPXParser p = new GPXParser();
* FileOutputStream out = new FileOutputStream("outFile.gpx");
* p.writeGPX(gpx, out);
* out.close();
*
*/
public class GPXParser extends BaseGPX {
// TFE, 20180109: use pattern for parsing to improve performance
private final static Pattern datevaluePattern = Pattern.compile("([0-9\\-T]+:[0-9]{2}:[0-9.+]+):([0-9]{2})");
/**
* Parses a stream containing GPX data
*
* @param in the input stream
* @return {@link GPX} object containing parsed data, or null if no gpx data
* was found in the seream
* @throws Exception when gpx file is invalid
*/
public GPX parseGPX(InputStream in) throws Exception {
// TFE, 20180217: add default parser if none set
if (this.extensionParsers.isEmpty()) {
this.extensionParsers.add(new DummyExtensionParser());
}
// TFE, 20190905: fix for issue #12
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(in);
Node firstChild = doc.getFirstChild();
if (firstChild != null && GPXConstants.NODE_GPX.equals(firstChild.getNodeName())) {
GPX gpx = new GPX();
NamedNodeMap attrs = firstChild.getAttributes();
for (int idx = 0; idx < attrs.getLength(); idx++) {
Node attr = attrs.item(idx);
if (GPXConstants.ATTR_VERSION.equals(attr.getNodeName())) {
gpx.setVersion(attr.getNodeValue());
} else if (GPXConstants.ATTR_CREATOR.equals(attr.getNodeName())) {
gpx.setCreator(attr.getNodeValue());
// TFE, 20180201: support multiple xmlns attributes
// TFE, 20200726: treat xsi as xmlns attribute
} else if (attr.getNodeName().startsWith(GPXConstants.ATTR_XMLNS) ||
attr.getNodeName().startsWith(GPXConstants.ATTR_XSI)) {
gpx.addXmlns(attr.getNodeName(), attr.getNodeValue());
}
}
NodeList nodes = firstChild.getChildNodes();
for (int idx = 0; idx < nodes.getLength(); idx++) {
Node currentNode = nodes.item(idx);
if (GPXConstants.NODE_METADATA.equals(currentNode.getNodeName())) {
Metadata m = this.parseMetadata(currentNode);
if (m != null) {
gpx.setMetadata(m);
}
} else if (GPXConstants.NODE_WPT.equals(currentNode.getNodeName())) {
Waypoint w = this.parseWaypoint(currentNode);
if (w != null) {
gpx.addWaypoint(w);
}
} else if (GPXConstants.NODE_RTE.equals(currentNode.getNodeName())) {
Route rte = this.parseRoute(currentNode);
if (rte != null) {
gpx.addRoute(rte);
}
} else if (GPXConstants.NODE_TRK.equals(currentNode.getNodeName())) {
Track trk = this.parseTrack(currentNode);
if (trk != null) {
gpx.addTrack(trk);
}
} else if (GPXConstants.NODE_EXTENSIONS.equals(currentNode.getNodeName())) {
for (IExtensionParser parser : this.extensionParsers) {
Object data = parser.parseExtensions(currentNode);
gpx.addExtensionData(parser.getId(), data);
}
}
}
return gpx;
} else {
throw new IllegalAccessException("Not a valid GPX file.");
}
}
private Metadata parseMetadata(Node node) throws DOMException {
if (node == null) {
return null;
}
Metadata m = new Metadata();
NodeList childNodes = node.getChildNodes();
if (childNodes != null) {
for (int idx = 0; idx < childNodes.getLength(); idx++) {
Node currentNode = childNodes.item(idx);
if (GPXConstants.NODE_NAME.equals(currentNode.getNodeName())) {
m.setName(this.getNodeValueAsString(currentNode));
} else if (GPXConstants.NODE_DESC.equals(currentNode.getNodeName())) {
m.setDesc(this.getNodeValueAsString(currentNode));
} else if (GPXConstants.NODE_AUTHOR.equals(currentNode.getNodeName())) {
Person author = this.parsePerson(currentNode);
if (author != null) {
m.setAuthor(author);
}
} else if (GPXConstants.NODE_COPYRIGHT.equals(currentNode.getNodeName())) {
Copyright copyright = this.parseCopyright(currentNode);
if (copyright != null) {
m.setCopyright(copyright);
}
} else if (GPXConstants.NODE_LINK.equals(currentNode.getNodeName())) {
Link link = this.parseLink(currentNode);
if (link != null) {
m.addLink(link);
}
} else if (GPXConstants.NODE_TIME.equals(currentNode.getNodeName())) {
m.setTime(this.getNodeValueAsDate(currentNode));
} else if (GPXConstants.NODE_KEYWORDS.equals(currentNode.getNodeName())) {
m.setKeywords(this.getNodeValueAsString(currentNode));
} else if (GPXConstants.NODE_BOUNDS.equals(currentNode.getNodeName())) {
Bounds bounds = this.parseBounds(currentNode);
if (bounds != null) {
m.setBounds(bounds);
}
} else if (GPXConstants.NODE_EXTENSIONS.equals(currentNode.getNodeName())) {
for (IExtensionParser parser : this.extensionParsers) {
Object data = parser.parseExtensions(currentNode);
m.addExtensionData(parser.getId(), data);
}
}
}
}
return m;
}
private Person parsePerson(Node node) {
if (node == null) {
return null;
}
Person p = new Person();
NodeList childNodes = node.getChildNodes();
if (childNodes != null) {
for (int idx = 0; idx < childNodes.getLength(); idx++) {
Node currentNode = childNodes.item(idx);
if (GPXConstants.NODE_NAME.equals(currentNode.getNodeName())) {
p.setName(this.getNodeValueAsString(currentNode));
} else if (GPXConstants.NODE_EMAIL.equals(currentNode.getNodeName())) {
Email email = this.parseEmail(currentNode);
if (email != null) {
p.setEmail(email);
}
} else if (GPXConstants.NODE_LINK.equals(currentNode.getNodeName())) {
Link link = this.parseLink(currentNode);
if (link != null) {
p.setLink(link);
}
}
}
}
return p;
}
private Copyright parseCopyright(Node node) {
if (node == null) {
return null;
}
Copyright c = new Copyright(null);
NamedNodeMap attrs = node.getAttributes();
for (int idx = 0; idx < attrs.getLength(); idx++) {
Node attr = attrs.item(idx);
if (GPXConstants.ATTR_AUTHOR.equals(attr.getNodeName())) {
c.setAuthor(attr.getNodeValue());
}
}
NodeList childNodes = node.getChildNodes();
if (childNodes != null) {
for (int idx = 0; idx < childNodes.getLength(); idx++) {
Node currentNode = childNodes.item(idx);
if (GPXConstants.NODE_YEAR.equals(currentNode.getNodeName())) {
c.setYear(this.getNodeValueAsString(currentNode));
} else if (GPXConstants.NODE_LICENSE.equals(currentNode.getNodeName())) {
c.setLicense(this.getNodeValueAsString(currentNode));
}
}
}
return c;
}
private Link parseLink(Node node) {
if (node == null) {
return null;
}
Link l = new Link(null);
NamedNodeMap attrs = node.getAttributes();
for (int idx = 0; idx < attrs.getLength(); idx++) {
Node attr = attrs.item(idx);
if (GPXConstants.ATTR_HREF.equals(attr.getNodeName())) {
l.setHref(attr.getNodeValue());
}
}
NodeList childNodes = node.getChildNodes();
if (childNodes != null) {
for (int idx = 0; idx < childNodes.getLength(); idx++) {
Node currentNode = childNodes.item(idx);
if (GPXConstants.NODE_TEXT.equals(currentNode.getNodeName())) {
l.setText(this.getNodeValueAsString(currentNode));
} else if (GPXConstants.NODE_TYPE.equals(currentNode.getNodeName())) {
l.setType(this.getNodeValueAsString(currentNode));
}
}
}
return l;
}
private Bounds parseBounds(Node node) {
if (node == null) {
return null;
}
Bounds b = new Bounds(0, 0, 0, 0);
NamedNodeMap attrs = node.getAttributes();
for (int idx = 0; idx < attrs.getLength(); idx++) {
Node attr = attrs.item(idx);
if (GPXConstants.ATTR_MINLAT.equals(attr.getNodeName())) {
b.setMinLat(Double.parseDouble(attr.getNodeValue()));
} else if (GPXConstants.ATTR_MINLON.equals(attr.getNodeName())) {
b.setMinLon(Double.parseDouble(attr.getNodeValue()));
} else if (GPXConstants.ATTR_MAXLAT.equals(attr.getNodeName())) {
b.setMaxLat(Double.parseDouble(attr.getNodeValue()));
} else if (GPXConstants.ATTR_MAXLON.equals(attr.getNodeName())) {
b.setMaxLon(Double.parseDouble(attr.getNodeValue()));
}
}
return b;
}
private Email parseEmail(Node node) {
if (node == null) {
return null;
}
Email e = new Email(null, null);
NamedNodeMap attrs = node.getAttributes();
for (int idx = 0; idx < attrs.getLength(); idx++) {
Node attr = attrs.item(idx);
if (GPXConstants.ATTR_ID.equals(attr.getNodeName())) {
e.setId(attr.getNodeValue());
} else if (GPXConstants.ATTR_DOMAIN.equals(attr.getNodeName())) {
e.setDomain(attr.getNodeValue());
}
}
return e;
}
private Waypoint parseWaypoint(Node node) throws Exception {
if (node == null) {
return null;
}
Waypoint w = new Waypoint(0, 0);
NamedNodeMap attrs = node.getAttributes();
// check for lat attribute
Node latNode = attrs.getNamedItem(GPXConstants.ATTR_LAT);
if (latNode != null) {
double latVal;
latVal = Double.parseDouble(latNode.getNodeValue());
w.setLatitude(latVal);
} else {
throw new Exception("no lat value in waypoint data.");
}
// check for lon attribute
Node lonNode = attrs.getNamedItem(GPXConstants.ATTR_LON);
if (lonNode != null) {
double lonVal = Double.parseDouble(lonNode.getNodeValue());
w.setLongitude(lonVal);
} else {
throw new Exception("no lon value in waypoint data.");
}
NodeList childNodes = node.getChildNodes();
if (childNodes != null) {
for (int idx = 0; idx < childNodes.getLength(); idx++) {
Node currentNode = childNodes.item(idx);
if (GPXConstants.NODE_ELE.equals(currentNode.getNodeName())) {
w.setElevation(this.getNodeValueAsDouble(currentNode));
} else if (GPXConstants.NODE_TIME.equals(currentNode.getNodeName())) {
w.setTime(this.getNodeValueAsDate(currentNode));
} else if (GPXConstants.NODE_MAGVAR.equals(currentNode.getNodeName())) {
w.setMagneticVariation(this.getNodeValueAsDouble(currentNode));
} else if (GPXConstants.NODE_GEOIDHEIGHT.equals(currentNode.getNodeName())) {
w.setGeoIdHeight(this.getNodeValueAsDouble(currentNode));
} else if (GPXConstants.NODE_NAME.equals(currentNode.getNodeName())) {
w.setName(this.getNodeValueAsString(currentNode));
} else if (GPXConstants.NODE_CMT.equals(currentNode.getNodeName())) {
w.setComment(this.getNodeValueAsString(currentNode));
} else if (GPXConstants.NODE_DESC.equals(currentNode.getNodeName())) {
w.setDescription(this.getNodeValueAsString(currentNode));
} else if (GPXConstants.NODE_SRC.equals(currentNode.getNodeName())) {
w.setSrc(this.getNodeValueAsString(currentNode));
} else if (GPXConstants.NODE_LINK.equals(currentNode.getNodeName())) {
Link link = this.parseLink(currentNode);
if (link != null) {
w.addLink(link);
}
} else if (GPXConstants.NODE_SYM.equals(currentNode.getNodeName())) {
w.setSym(this.getNodeValueAsString(currentNode));
} else if (GPXConstants.NODE_TYPE.equals(currentNode.getNodeName())) {
w.setType(this.getNodeValueAsString(currentNode));
} else if (GPXConstants.NODE_FIX.equals(currentNode.getNodeName())) {
w.setFix(this.getNodeValueAsFixType(currentNode));
} else if (GPXConstants.NODE_SAT.equals(currentNode.getNodeName())) {
w.setSat(this.getNodeValueAsInteger(currentNode));
} else if (GPXConstants.NODE_HDOP.equals(currentNode.getNodeName())) {
w.setHdop(this.getNodeValueAsDouble(currentNode));
} else if (GPXConstants.NODE_VDOP.equals(currentNode.getNodeName())) {
w.setVdop(this.getNodeValueAsDouble(currentNode));
} else if (GPXConstants.NODE_PDOP.equals(currentNode.getNodeName())) {
w.setPdop(this.getNodeValueAsDouble(currentNode));
} else if (GPXConstants.NODE_AGEOFGPSDATA.equals(currentNode.getNodeName())) {
w.setAgeOfGPSData(this.getNodeValueAsDouble(currentNode));
} else if (GPXConstants.NODE_DGPSID.equals(currentNode.getNodeName())) {
w.setdGpsStationId(this.getNodeValueAsInteger(currentNode));
} else if (GPXConstants.NODE_EXTENSIONS.equals(currentNode.getNodeName())) {
for (IExtensionParser parser : this.extensionParsers) {
Object data = parser.parseExtensions(currentNode);
w.addExtensionData(parser.getId(), data);
}
}
}
}
return w;
}
private Route parseRoute(Node node) throws Exception {
if (node == null) {
return null;
}
Route rte = new Route();
NodeList nodes = node.getChildNodes();
if (nodes != null) {
for (int idx = 0; idx < nodes.getLength(); idx++) {
Node currentNode = nodes.item(idx);
if (GPXConstants.NODE_NAME.equals(currentNode.getNodeName())) {
rte.setName(this.getNodeValueAsString(currentNode));
} else if (GPXConstants.NODE_CMT.equals(currentNode.getNodeName())) {
rte.setComment(this.getNodeValueAsString(currentNode));
} else if (GPXConstants.NODE_DESC.equals(currentNode.getNodeName())) {
rte.setDescription(this.getNodeValueAsString(currentNode));
} else if (GPXConstants.NODE_SRC.equals(currentNode.getNodeName())) {
rte.setSrc(this.getNodeValueAsString(currentNode));
} else if (GPXConstants.NODE_LINK.equals(currentNode.getNodeName())) {
Link link = this.parseLink(currentNode);
if (link != null) {
rte.addLink(link);
}
} else if (GPXConstants.NODE_NUMBER.equals(currentNode.getNodeName())) {
rte.setNumber(this.getNodeValueAsInteger(currentNode));
} else if (GPXConstants.NODE_TYPE.equals(currentNode.getNodeName())) {
rte.setType(this.getNodeValueAsString(currentNode));
} else if (GPXConstants.NODE_EXTENSIONS.equals(currentNode.getNodeName())) {
Iterator it = this.extensionParsers.iterator();
while (it.hasNext()) {
while (it.hasNext()) {
IExtensionParser parser = it.next();
Object data = parser.parseExtensions(currentNode);
rte.addExtensionData(parser.getId(), data);
}
}
} else if (GPXConstants.NODE_RTEPT.equals(currentNode.getNodeName())) {
Waypoint wp = this.parseWaypoint(currentNode);
if (wp != null) {
rte.addRoutePoint(wp);
}
}
}
}
return rte;
}
private Track parseTrack(Node node) throws Exception {
if (node == null) {
return null;
}
Track trk = new Track();
NodeList nodes = node.getChildNodes();
if (nodes != null) {
for (int idx = 0; idx < nodes.getLength(); idx++) {
Node currentNode = nodes.item(idx);
if (GPXConstants.NODE_NAME.equals(currentNode.getNodeName())) {
trk.setName(this.getNodeValueAsString(currentNode));
} else if (GPXConstants.NODE_CMT.equals(currentNode.getNodeName())) {
trk.setComment(this.getNodeValueAsString(currentNode));
} else if (GPXConstants.NODE_DESC.equals(currentNode.getNodeName())) {
trk.setDescription(this.getNodeValueAsString(currentNode));
} else if (GPXConstants.NODE_SRC.equals(currentNode.getNodeName())) {
trk.setSrc(this.getNodeValueAsString(currentNode));
} else if (GPXConstants.NODE_LINK.equals(currentNode.getNodeName())) {
Link link = this.parseLink(currentNode);
if (link != null) {
trk.addLink(link);
}
} else if (GPXConstants.NODE_NUMBER.equals(currentNode.getNodeName())) {
trk.setNumber(this.getNodeValueAsInteger(currentNode));
} else if (GPXConstants.NODE_TYPE.equals(currentNode.getNodeName())) {
trk.setType(this.getNodeValueAsString(currentNode));
} else if (GPXConstants.NODE_EXTENSIONS.equals(currentNode.getNodeName())) {
Iterator it = this.extensionParsers.iterator();
while (it.hasNext()) {
while (it.hasNext()) {
IExtensionParser parser = it.next();
Object data = parser.parseExtensions(currentNode);
trk.addExtensionData(parser.getId(), data);
}
}
} else if (GPXConstants.NODE_TRKSEG.equals(currentNode.getNodeName())) {
TrackSegment trackSeg = this.parseTrackSegment(currentNode);
if (trackSeg != null) {
trk.addTrackSegment(trackSeg);
}
}
}
}
return trk;
}
private TrackSegment parseTrackSegment(Node node) throws Exception {
if (node == null) {
return null;
}
TrackSegment ts = new TrackSegment();
NodeList childNodes = node.getChildNodes();
if (childNodes != null) {
for (int idx = 0; idx < childNodes.getLength(); idx++) {
Node currentNode = childNodes.item(idx);
if (GPXConstants.NODE_TRKPT.equals(currentNode.getNodeName())) {
Waypoint w = this.parseWaypoint(currentNode);
if (w != null) {
ts.addWaypoint(w);
}
} else if (GPXConstants.NODE_EXTENSIONS.equals(currentNode.getNodeName())) {
Iterator it = this.extensionParsers.iterator();
while (it.hasNext()) {
while (it.hasNext()) {
IExtensionParser parser = it.next();
Object data = parser.parseExtensions(currentNode);
ts.addExtensionData(parser.getId(), data);
}
}
}
}
}
return ts;
}
private Date getNodeValueAsDate(Node node) throws DOMException {
Date val = null;
try {
// TFE, 20180109: use pre-compiled pattern instead of String.replaceAll
// val = xmlDateFormat.parse(node.getFirstChild().getNodeValue()
// .replaceAll("([0-9\\-T]+:[0-9]{2}:[0-9.+]+):([0-9]{2})", "$1$2"));
// TFE, 20180223: allow for errors with missing "Z" at the end of the string...
String nodeValue = node.getFirstChild().getNodeValue();
if (!nodeValue.endsWith("Z")) {
nodeValue += "Z";
}
// TFE, 20181105: add support for milli seconds during read
final String parseValue = datevaluePattern.matcher(nodeValue).replaceAll("$1$2");
if (parseValue.length() == xmlDateFormatWithMilli_length) {
val = xmlDateFormatWithMilli.parse(parseValue);
} else {
val = xmlDateFormat.parse(parseValue);
}
} catch (Exception e) {
e.printStackTrace();
}
return val;
}
private Double getNodeValueAsDouble(Node node) {
return Double.parseDouble(node.getFirstChild().getNodeValue());
}
private Fix getNodeValueAsFixType(Node node) {
return Fix.returnType(node.getFirstChild().getNodeValue());
}
private Integer getNodeValueAsInteger(Node node) {
return Integer.parseInt(node.getFirstChild().getNodeValue());
}
private String getNodeValueAsString(Node node) {
if (node == null) {
return null;
}
Node child = node.getFirstChild();
if (child == null) {
return null;
}
return child.getNodeValue();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy