jenetics / jpx Goto Github PK
View Code? Open in Web Editor NEWJPX - Java GPX library
License: Apache License 2.0
JPX - Java GPX library
License: Apache License 2.0
I try to write the GPX file with the local time (Asia/Taipei), but it always write the UTC time to the file. Following is my code:
GPX.Builder gpx_builder = GPX.builder();
gpx_builder.addTrack(track -> track
.addSegment(segment -> segment
.addPoint(p -> p.lat(latitude).lon(longitude).time(timestamp, ZoneId.of("Asia/Taipei")))));
final GPX gpx = gpx_builder.build();
GPX.write(gpx, out_file);
for example:
with timestamp 1517553382053, I expect
<time>2018-02-02T14:36:22.053+08:00</time>
in the GPX file
but it always show <time>2018-02-02T06:36:22.053+08:00</time>
in the GPX file
Is this an issue?
In the XMLReader class, there is an issue with the general element handling logic and how extensions documents are processed. There is no problem if whitespace/indentation is used between elements but if there is not indentation present there is an error.
When a parent element processes a new child element (START_ELEMENT case), it spawns a new reader which processes the child element. Once that child process is done reading the stream, the parent then advances to the next parseable XML stream entity.
When an extensions metadata element is encountered, the entire extensions stream is processed including its end element, leaving the code that parses to the next parseable XML stream entity missing that end tag processing, leading to stuck loop reading, where the parent is looking for its missing end element.
Take this as an example, with and without a space after
<?xml
version="1.0" encoding="UTF-8" standalone="yes"?><wpt lat="48.2081743" lon="16.3738189"><name>Wien</name><ele>171.0</ele><extensions><foo>asdf</foo><foo>asdf</foo></extensions></wpt></gpx>
Simple parsing flow with no whitespace after the extensions element
START: gpx
START: wpt
START: name
CHARACTERS: null
END: name
START: ele
CHARACTERS: null
END: ele
START: extensions
END: gpx
END: gpx
Simple parsing flow with with the whitespace after the extensions element
START: gpx
START: name
CHARACTERS: null
END: name
START: ele
CHARACTERS: null
END: ele
START: extensions
END: wpt
END: gpx
The unit test GPXTest.readWriteRandomNonIndentedGPX() has a typo in that it always uses indentation as well. It should not have GPX.writer(" ").write(gpx, bout);
`
Loading a GPX with the following metadata
<metadata>
<time>2019-07-14T10:23:24+02:00
</time>
</metadata>
<trk>
causes the exception:
Caused by: java.lang.IllegalArgumentException: Can't parse time: 2019-07-14T10:23:24+02:00
'
at io.jenetics.jpx.ZonedDateTimeFormat.lambda$parse$4(ZonedDateTimeFormat.java:134)
at java.util.Optional.orElseThrow(Optional.java:290)
at io.jenetics.jpx.ZonedDateTimeFormat.parse(ZonedDateTimeFormat.java:132)
at io.jenetics.jpx.XMLReader$1.read(XMLReader.java:142)
If you remove the line break so the closing tag is in the same line it loads:
<metadata>
<time>2019-07-14T10:23:24+02:00</time>
</metadata>
<trk>
Sometimes the way-points, delivered by the GPX device, are not that reliable. E.g. one way-point is some km away from its neighbors. It should be easily possible to filter out such outliers.
final GPX gpx = GPX.read("file")
.filterTrackPoints(Filters.outlierFilter());
The toString
method of the WayPoint
class
@Override
public String toString() {
return format(
"[lat=%s, lon=%s, ele=%s]",
_latitude, _latitude, _elevation
);
}
Instead of the longitude value, the latitude is printed twice.
It should be possible to store GPS data into a relational (JDBC) database.
It should be possible to create a ISO 6709 conform string representation of a GPS Point
. It should be possible to define a patterns string like in the Java DateTimeFormatter.ofPattern(String, Locale)
final LocationFormatter formatter = LocationFormatter.ofPattern(...);
abstract class LocationFormatter {
abstract String format(Latitude lat, Longitude lon, Length ele);
}
Symbol | Meaning |
---|---|
' | escape for text |
'' | single quote |
[ | optional section start |
] | optional section end |
+ | forces adding '+' sign for positive values |
Symbol | Meaning |
---|---|
D | degree part of latitude |
M | minute part of latitude |
S | second part of latitude |
X | hemisphere (N or S) |
Examples
DD°MM''SS.SSS"X
+DD°MM''SS.SSS"
+DD.D
+D.DDD
D.DD
+DDMM.M
+DDMMSS.SSS
Symbol | Meaning |
---|---|
d | degree part of longitude |
m | minute part of longitude |
s | second part of longitude |
x | east longitude or west longitude (E or W) |
Examples
dd°mm''ss.sss"x
+dd°mm''ss.sss"
+dd.d
+d.ddd
d.dd
+ddmm.m
+ddmmss.sss
Symbol | Meaning |
---|---|
E | elevation in meters |
' | escape for text |
'' | single quote |
Examples
E.EE'm'
E'm'
[ E.EE'm']
It would be nice to have some (simple) algorithm which detects possible positioning errors. This would be helpful for correcting the GPS-Track taken during a bicycle by a standard GPS tracker. The algorithm should also work on a pure waypoint track, without native GPS errors.
See:
Some of the files contain "Java Genetic Algorithm Library" in the copyright header. Replace this with "Java GPX Library".
The exceptions, thrown in the case of a parsing error, should be fit with the already thrown exception. In the case of an un-parsable value (e.g. 'asf' for the elevation), an IllegalArgumentException
is thrown. This exception is neither documented, nor a good fit into the existing exception strategy.
Use java.io.InvalidObjectException
for not-parsable values.
The following code will throw an NPE:
@Test
public void extensions() throws ParserConfigurationException {
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
final DocumentBuilder db = dbf.newDocumentBuilder();
final Document doc = db.newDocument();
GPX gpx = GPX.builder()
.extensions(doc)
.build();
}
java.lang.NullPointerException
at io.jenetics.jpx.XML.checkExtensions(XML.java:281)
at io.jenetics.jpx.GPX$Builder.extensions(GPX.java:759)
at io.jenetics.jpx.GPXTest.extensions(GPXTest.java:75)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:583)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:719)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:989)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:648)
at org.testng.TestRunner.run(TestRunner.java:505)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:73)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)
An IllegalArgumentException
should be thrown instead.
It is not possible to read existing GPX files with invalid points; e.g. latitude or longitude values are not in the valid range.
<trkpt lat="-37050536.000000000" lon="0.000475423">
<ele>0.000000</ele>
<time>2025-12-17T05:10:27Z</time>
<speed>56528.671875</speed>
<name>TP000003</name>
</trkpt>
With a lenient mode it should be possible to read such files, removing the invalid points.
Hi, thanks for a great project.
A reference to the maven is would be handy on the readme,
For gradle it is:
// https://mvnrepository.com/artifact/io.jenetics/jpx
compile group: 'io.jenetics', name: 'jpx', version: '1.3.0'
Cheers
The library should be able to read GPX 1.0 files.
When creating a Copyright
object with a null
license URL string an NPE is thrown.
java.lang.NullPointerException
at java.net.URI$Parser.parse(URI.java:3042)
at java.net.URI.<init>(URI.java:588)
at io.jenetics.jpx.Copyright.of(Copyright.java:175)
...
Fix alerts, recognized by LGTM.
As a preparation step for Java 9 and JPMS (Jigsaw), all Jenetics modules should define a stable module name in the MANIFEST.MF
file by adding a Automatic-Module-Name
entry.
Automatic-Module-Name: io.jenetics.jpx
See:
The LocationFormatter
object should also be able to parse its created location strings.
This is a follow up from #70.
Location LocationFormatter.parse(CharSequence text);
It seems that #51 was not fully fixed. The following file causes an exception in jpx 1.4:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Generated by Christian Pesch's RouteConverter. See http://www.routeconverter.com -->
<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="RouteConverter 2.26-SNAPSHOT-59">
<trk>
<name>09-OKT-18 15:12:08</name>
<trkseg>
<trkpt lat="48.7065017" lon="11.3178901">
<ele>374.6</ele>
<time>2018-10-09T11:57:05.000Z</time>
<name>Position 1</name>
</trkpt>
</trkseg>
</trk>
</gpx>
javax.xml.stream.XMLStreamException: Event type START_ELEMENT specified did not match with current parser event COMMENT
The reason is the comment. After removing it the exception disappears.
Of course, such comments are valid syntax and should work.
The order of the links should not influence the equality of the Metadata
, Route
or Track
object.
Missing lat
and lon
values of WayPoint
s will just throw a NPE.
java.lang.NullPointerException
at io.jenetics.jpx.WayPoint.lambda$reader$0(WayPoint.java:1322)
at io.jenetics.jpx.XMLReaderImpl.read(XMLReader.java:356)
at io.jenetics.jpx.XMLReaderImpl.read(XMLReader.java:336)
at io.jenetics.jpx.GPX.read(GPX.java:734)
at io.jenetics.jpx.GPXTest.emptyElements(GPXTest.java:73)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:86)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:643)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:820)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1128)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:129)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:112)
at org.testng.TestRunner.privateRun(TestRunner.java:782)
at org.testng.TestRunner.run(TestRunner.java:632)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:366)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:361)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:319)
at org.testng.SuiteRunner.run(SuiteRunner.java:268)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1244)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1169)
at org.testng.TestNG.run(TestNG.java:1064)
at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:127)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Instead of a NPE, an IOE (or a sub-class from it) with a proper error message should be thrown.
Creating a new Maven project using jpx 1.2.3, the class TrackSegment is not visible:
io.jenetics.jpx.GPX gpx = io.jenetics.jpx.GPX.read("tracks.gpx").toBuilder().build();
And any other pieces of code involving TrackSegment:
GPX gpx = GPX.read(input); io.jenetics.jpx.Track t = gpx.getTracks().get(0); io.jenetics.jpx.TrackSegment s = t.getSegments().get(0);
Those lines work with version 1.2.2 .
If you make a bike tour, it is also interesting to calculate the traveled altitude difference. The difference in altitude can't be simply added up since the GPS altitude is not very reliable.
For playing a little bit with gpx files in an OSM context, I used version 1.4.0 of jpx.
In my test driven context there are some test methods to read a couple of my own Garmin eTrex 10 and Oregon files. They are only stored on the handheld device with the export functions of the Garmin firmware. I chose a couple of files I recorded over the last years with different versions.
Until the update to jpx 1.5.0 every test was green.
Now I got the following Exception:
java.io.IOException: javax.xml.stream.XMLStreamException: Unexpected element <trkpt>. at io.jenetics.jpx.GPX$Reader.read(GPX.java:1143) at io.jenetics.jpx.GPX$Reader.read(GPX.java:1160) at io.jenetics.jpx.GPX$Reader.read(GPX.java:1174) at io.jenetics.jpx.GPX$Reader.read(GPX.java:1187) at io.jenetics.jpx.GPX.read(GPX.java:2054)
A snippet from the simple test case:
Assertions.assertTrue(Files.exists(Paths.get("src/test/resources/Track_19-JUN-18 182748.gpx")));
try {
GPX.read("src/test/resources/Track_19-JUN-18 182748.gpx")
.tracks()
.flatMap(Track::segments)
.flatMap(TrackSegment::points)
.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
Nothing special I think.
Empty XML elements of optional properties should be handled without exception. The following GPX file will trigger an NFE.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="Jenetics TSP">
<wpt lat="48.259124" lon="13.047988">
<ele/>
<name>Braunau am Inn</name>
</wpt>
</gpx>
java.lang.NumberFormatException: empty String
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1842)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at io.jenetics.jpx.Length.parse(Length.java:201)
at io.jenetics.jpx.WayPoint.lambda$reader$0(WayPoint.java:1302)
at io.jenetics.jpx.XMLReaderImpl.read(XMLReader.java:356)
at io.jenetics.jpx.XMLReaderImpl.read(XMLReader.java:336)
at io.jenetics.jpx.GPX.read(GPX.java:734)
at io.jenetics.jpx.GPXTest.loadEmptyGPX(GPXTest.java:71)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:86)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:643)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:820)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1128)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:129)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:112)
at org.testng.TestRunner.privateRun(TestRunner.java:782)
at org.testng.TestRunner.run(TestRunner.java:632)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:366)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:361)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:319)
at org.testng.SuiteRunner.run(SuiteRunner.java:268)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1244)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1169)
at org.testng.TestNG.run(TestNG.java:1064)
at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:127)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Empty, optional elements should be ignored instead.
Add factory methods which allows the creation of GPX
objects from a GPX-XML string.
final String gps = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<gpx version=\"1.1\" creator=\"JPX - Java GPX library\" xmlns=\"http://www.topografix.com/GPX/1/1\">\n" +
" <trk>\n" +
" <trkseg>\n" +
" <trkpt lat=\"48.2081743\" lon=\"16.3738189\">\n" +
" <ele>160.0</ele>\n" +
" </trkpt>\n" +
" <trkpt lat=\"48.2081743\" lon=\"16.3738189\">\n" +
" <ele>161.0</ele>\n" +
" </trkpt>\n" +
" <trkpt lat=\"48.2081743\" lon=\"16.3738189\">\n" +
" <ele>162.0</ele>\n" +
" </trkpt>\n" +
" </trkseg>\n" +
" </trk>\n" +
"</gpx>";
final GPX gpx = GPX.fromString(gps);
Many thanks for this nice library.
When the GPX object is created, I want it as a string. I read javadoc, but I was unable to use GPX.Writer with method toString. Can you put a snippet ?
Additional question : for writing the GPX object to a file, I use GPX.write. I have no line breaks in the file. What is the correct way ?
For some GPX files, the Bounds
metadata is missing. Add a collector, which allows to collect the boundaries of a given WayPoint
stream.
static Collector<WayPoint, ?, Bounds> toBounds();
final Bounds bounds = gpx.tracks()
.flatMap(Track::segments)
.flatMap(TrackSegment::points)
.collect(toBounds());
The GPX definition allows to create empty objects like
final GPX gpx = GPX.builder()
.metadata(md -> {})
.addTrack(track -> {})
.addTrack(track -> track
.addSegment(segment -> {})
.addSegment(segment -> segment
.addPoint(wp -> wp.ele(12).lat(21).lon(23))))
.build();
GPX.write(gpx, System.out, " ");
This leads to empty elements in the serialized GPX file.
<?xml version="1.0" encoding="UTF-8"?>
<gpx version="1.1" creator="JPX - https://jenetics.github.io/jpx" xmlns="http://www.topografix.com/GPX/1/1">
<metadata></metadata>
<trk></trk>
<trk>
<trkseg></trkseg>
<trkseg>
<trkpt lat="21.0" lon="23.0">
<ele>12.0</ele>
</trkpt>
</trkseg>
</trk>
</gpx>
The files are valid, but empty elements doesn't add additional information. The library should omit empty objects when writing them into a file.
When I try to parse files like the one in test.gpx.zip, the following exception occurs:
java.io.IOException: javax.xml.stream.XMLStreamException
: Unexpected element <extensions>.
at io.jenetics.jpx.GPX.read(GPX.java:1190)
at io.jenetics.jpx.GPX.read(GPX.java:1204)
at [...].main(Main.java:37)
Caused by: javax.xml.stream.XMLStreamException: Unexpected element <extensions>.
at io.jenetics.jpx.ElemReader.read(XMLReader.java:529)
at io.jenetics.jpx.ListReader.read(XMLReader.java:435)
at io.jenetics.jpx.ListReader.read(XMLReader.java:421)
at io.jenetics.jpx.ElemReader.throwUnexpectedElement(XMLReader.java:596)
at io.jenetics.jpx.ElemReader.read(XMLReader.java:540)
at io.jenetics.jpx.GPX.read(GPX.java:1185)
... 4 more
According to specification, the tag <extensions> is valid in both <trk> and <trkpt> (which are the failing cases in this test), among other places.
Add additional tests for geoid distance calculations.
Add some basic way-point filter methods.
Both are popular units for altitudes and distances, respectively.
It's be great if they'd have first-class support.
(Maybe even more so than inch, yards and statute miles...)
I have a class in my Android app which is writing a GPX file out of the location stream from the device location sensor. And there is a counterpart class which is reading the GPX file and creates a location stream out of it.
public final void onLocationChanged(final Location pLocation)
{
final WayPoint.Builder wayPointBuilder = WayPoint.builder();
wayPointBuilder.time(pLocation.getTime());
wayPointBuilder.ele(pLocation.getAltitude());
wayPointBuilder.speed(pLocation.getSpeed());
wayPointBuilder.pdop((double) pLocation.getAccuracy());
wayPointBuilder.course(pLocation.getBearing());
wayPointBuilder.lat(pLocation.getLatitude());
wayPointBuilder.lon(pLocation.getLongitude());
mSegmentBuilder.addPoint(wayPointBuilder.build());
}
But there is a problem. The course data is not written into the GPX file which looks like a bug.
Anything i can contribute ?
I was sent a GPX that could not be loaded by JPX 1.5.0. It throws the following exception.
java.io.IOException: javax.xml.stream.XMLStreamException: Unexpected element .
at io.jenetics.jpx.GPX$Reader.read(GPX.java:1143)
at io.jenetics.jpx.GPX.read(GPX.java:1974)
Analysis showed that the format was ok, but with try-and-error I found that adding a single line break makes the file load without exception. Of course, XML should ignore any whitespace and line breaks around the tags.
Error can be reproduced with this GPX (no line breaks included):
<?xml version="1.0" encoding="UTF-8" standalone="no" ?><gpx xmlns="http://www.topografix.com/GPX/1/1" xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3" xmlns:wptx1="http://www.garmin.com/xmlschemas/WaypointExtension/v1" xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1" creator="Oregon 450" version="1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www8.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/WaypointExtension/v1 http://www8.garmin.com/xmlschemas/WaypointExtensionv1.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd"><metadata><link href="http://www.garmin.com"><text>Garmin International</text></link><time>2014-09-28T12:15:24Z</time></metadata><trk><name>28-SEP-14 14:15:22</name>
<extensions><gpxx:TrackExtension><gpxx:DisplayColor>Black</gpxx:DisplayColor></gpxx:TrackExtension></extensions><trkseg><trkpt lat="46.7155065201" lon="12.3633751553"><ele>1999.20</ele><time>2014-09-28T09:00:29Z</time></trkpt><trkpt lat="46.7155107111" lon="12.3633777536"><ele>1999.20</ele><time>2014-09-28T09:00:30Z</time></trkpt><trkpt lat="46.7155086156" lon="12.3633698747"><ele>1999.20</ele><time>2014-09-28T09:00:51Z</time></trkpt><trkpt lat="46.7155669536" lon="12.3635026440"><ele>1999.20</ele><time>2014-09-28T09:01:11Z</time></trkpt><trkpt lat="46.7155936919" lon="12.3635734711"><ele>1999.20</ele><time>2014-09-28T09:01:20Z</time></trkpt><trkpt lat="46.7158015631" lon="12.3637087550"><ele>2000.16</ele><time>2014-09-28T09:01:34Z</time></trkpt><trkpt lat="46.7157668620" lon="12.3638706096"><ele>2002.08</ele><time>2014-09-28T09:01:50Z</time></trkpt></trkseg></trk></gpx>
Adding a single line break after the closing tag </extensions>
will make it load.
The GPX reader doesn't handle commented elements correctly.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="Jenetics TSP">
<wpt lat="48.2081743" lon="16.3738189">
<ele>171.0</ele>
<!--
<name>Wien</name>
-->
</wpt>
</gpx>
The comment way-point name is read as well.
Trying to create a new WayPoint
with
WayPoint.builder().build();
creates a NPE:
java.lang.NullPointerException
at java.util.Objects.requireNonNull(Objects.java:203)
at io.jenetics.jpx.WayPoint.<init>(WayPoint.java:158)
at io.jenetics.jpx.WayPoint.<init>(WayPoint.java:67)
at io.jenetics.jpx.WayPoint$Builder.build(WayPoint.java:952)
It is not allowed to create an empty WayPoint
, but the NPE is not very clear in this case. It would be better to throw a IllegalStateException
(or something similar) with a proper error message.
Thanks for the lib but could you upload the library to some repo?
E.g.: https://mvnrepository.com/
Background: Would like to use it via gradle and maybe some other maven guys could also make better use of it instead of compiling the .jar themself.
It would be a great benefit if common gpx-extensions like:
http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd
http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd
would be supported. Or at least to get the raw xml of unknown sub-tags.
Sample file attached:
Using Serialization Proxy Pattern.
The library looks really nice but I haven't been able to use it with Android Studio 3.2.1. During testing libraries missing from the android jdk implementation seem to lead to runtime errors. Is there any work been done to remedy android support at this time?
Hello,
when trying to write a GPX file I get an error.
I found a fix to simply add the encoding "UTF-8" when creating the XMLStreamWriter in the GPX.java class, starting from line 1075:
try {
final XMLStreamWriter writer = indent != null
? new IndentingXMLWriter(
factory.createXMLStreamWriter(output, "UTF-8"), indent)
: factory.createXMLStreamWriter(output, "UTF-8");
writer.writeStartDocument("UTF-8", "1.0");
gpx.write(writer);
writer.writeEndDocument();
The error message i got before adding the encoding:
java.io.IOException: javax.xml.stream.XMLStreamException: Underlying stream encoding 'Cp1252' and input paramter for writeStartDocument() method 'UTF-8' do not match.
at io.jenetics.jpx.GPX.write(GPX.java:1085)
at io.jenetics.jpx.GPX.write(GPX.java:1021)
at io.jenetics.jpx.GPX.write(GPX.java:1039)
at io.jenetics.jpx.GPX.write(GPX.java:1053)
at org.sonnenwagen.spark.gps.GPXhandler.updateOrSetNewWayPoint(GPXhandler.java:56)
at org.sonnenwagen.spark.gps.GPXhandler.main(GPXhandler.java:31)
Caused by: javax.xml.stream.XMLStreamException: Underlying stream encoding 'Cp1252' and input paramter for writeStartDocument() method 'UTF-8' do not match.
at com.sun.xml.internal.stream.writers.XMLStreamWriterImpl.writeStartDocument(Unknown Source)
at io.jenetics.jpx.GPX.write(GPX.java:1081)
... 5 more
Best regards
While indeed Person reflects "personType" from official schema, it doesn't fit in Metadata which handles "personType" as "author".
<gpx creator="Creator" version="1.1">
<metadata>
<name>Name of GPX</name>
<author>
<name>Name of Author/Person</name>
<link href="http://author.net">
<text>Link of Author/Person</text>
</link>
</author>
<link href="http://company.net">
<text>Link of GPX</text>
</link>
</metadata>
</gpx>
Reason:
"author" tag is omitted making author's children be treated as "metadata".
Solution:
I think its enough to change: Person:187 and Person:199 from "person" to "author".
I tried reading the RT file in this zip http://users.telenet.be/meirenwi/Achterbroek%20naar%20De%20Maatjes%20-%2013%20km%20RT.zip, and I had to remove the bounds element to make it load. With this element I got a NPE. I believe the schema at http://www.topografix.com/GPX/1/0/gpx.xsd indicates the bounds element is legal.
Improve equals
and hashCode
methods and add additional tests.
Add Point.getInstant
default method.
/**
* Creation/modification instant of the given point.
*
* @return creation/modification instant for the point
*/
public default Optional<Instant> getInstant() {
return getTime().map(t -> t.toOffsetDateTime().toInstant());
}
Update the XMLReader
/XMLWriter
classes to the implementation as in the Jenetics project.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.