All Downloads are FREE. Search and download functionalities are using the official Maven repository.

me.himanshusoni.gpxparser.GPXParser Maven / Gradle / Ivy

Go to download

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