source: josm/trunk/test/unit/org/openstreetmap/josm/io/GpxWriterTest.java@ 16009

Last change on this file since 16009 was 15560, checked in by GerdP, 4 years ago

fix #18389: GPX track with color black is invisible (Patch by Bjoeni)
Show popup that track is not visible because color matches backgroud color. This shows a popup only if

  • background color of all tracks in the file equals background color and
  • no imagery layer is currently visible

"I noticed that Garmin actually uses gpxx:TrackExtension instead of gpxx:TrackExtensions, so the abbreviations don't work and files are sometimes not written according to the standard."

  • Property svn:eol-style set to native
File size: 14.3 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.io;
3
4import static org.junit.Assert.assertEquals;
5
6import java.awt.Color;
7import java.io.ByteArrayOutputStream;
8import java.io.IOException;
9import java.nio.charset.StandardCharsets;
10import java.time.LocalDate;
11import java.time.Month;
12import java.time.ZoneOffset;
13import java.util.Arrays;
14import java.util.Date;
15import java.util.HashMap;
16import java.util.function.Consumer;
17
18import org.junit.Rule;
19import org.junit.Test;
20import org.openstreetmap.josm.data.coor.LatLon;
21import org.openstreetmap.josm.data.gpx.GpxConstants;
22import org.openstreetmap.josm.data.gpx.GpxData;
23import org.openstreetmap.josm.data.gpx.GpxData.XMLNamespace;
24import org.openstreetmap.josm.data.gpx.GpxExtensionCollection;
25import org.openstreetmap.josm.data.gpx.GpxTrack;
26import org.openstreetmap.josm.data.gpx.GpxTrackSegment;
27import org.openstreetmap.josm.data.gpx.WayPoint;
28import org.openstreetmap.josm.testutils.JOSMTestRules;
29
30import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
31
32/**
33 * Tests the {@link GpxWriter}.
34 */
35public class GpxWriterTest {
36
37 /**
38 * Setup rule
39 */
40 @Rule
41 @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
42 public JOSMTestRules test = new JOSMTestRules();
43
44 private static void testSingleWaypoint(Consumer<WayPoint> consumer, String atts) throws IOException {
45 GpxData gpx = new GpxData();
46 WayPoint waypoint = new WayPoint(LatLon.ZERO);
47 consumer.accept(waypoint);
48 gpx.addWaypoint(waypoint);
49 ByteArrayOutputStream baos = new ByteArrayOutputStream();
50 try (GpxWriter writer = new GpxWriter(baos)) {
51 writer.write(gpx);
52 }
53 assertEquals(String.format("<?xml version='1.0' encoding='UTF-8'?>%n" +
54 "<gpx version=\"1.1\" creator=\"JOSM GPX export\" xmlns=\"http://www.topografix.com/GPX/1/1\"%n" +
55 " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"%n" +
56 " xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\">%n" +
57 " <metadata>%n" +
58 " <bounds minlat=\"0.0\" minlon=\"0.0\" maxlat=\"0.0\" maxlon=\"0.0\"/>%n" +
59 " </metadata>%n" +
60 " <wpt lat=\"0.0\" lon=\"0.0\">%n" +
61 atts +
62 " </wpt>%n" +
63 "</gpx>"), baos.toString(StandardCharsets.UTF_8.name()));
64 }
65
66 /**
67 * Non-regression test for ticket <a href="https://josm.openstreetmap.de/ticket/16550">#16550</a>
68 * @throws IOException never
69 */
70 @Test
71 public void testTicket16550() throws IOException {
72 // Checks that time stored as date is correctly written into XML timestamp
73 testSingleWaypoint(
74 w -> w.put(GpxConstants.PT_TIME, Date.from(LocalDate.of(2018, Month.AUGUST, 2).atStartOfDay(ZoneOffset.UTC).toInstant())),
75 " <time>2018-08-02T00:00:00Z</time>%n");
76 }
77
78 /**
79 * Non-regression test for ticket <a href="https://josm.openstreetmap.de/ticket/16725">#16725</a>
80 * @throws IOException never
81 */
82 @Test
83 public void testTicket16725() throws IOException {
84 // Checks that sat, hdop, pdop, vdop are correctly exported
85 testSingleWaypoint(
86 w -> {
87 w.put(GpxConstants.PT_SAT, 16);
88 w.put(GpxConstants.PT_HDOP, 0.7);
89 w.put(GpxConstants.PT_VDOP, 0.9);
90 w.put(GpxConstants.PT_PDOP, 1.2);
91 },
92 " <sat>16</sat>%n" +
93 " <hdop>0.7</hdop>%n" +
94 " <vdop>0.9</vdop>%n" +
95 " <pdop>1.2</pdop>%n");
96 }
97
98 /**
99 * Tests if extensions are written correctly.
100 * @throws IOException in case of I/O error
101 */
102 @Test
103 public void testExtensions() throws IOException {
104 GpxData data = new GpxData();
105 // only namespace, no location printed
106 data.getNamespaces().add(new XMLNamespace("test", "http://example.com/testURI"));
107 // printed
108 data.getNamespaces().add(new XMLNamespace("knownprefix", "http://example.com/URI", "http://example.com/location.xsd"));
109 // NOT printed
110 data.getNamespaces().add(new XMLNamespace("notpresent", "http://example.com/notpresent", "http://example.com/notpresent.xsd"));
111
112 GpxExtensionCollection exts = data.getExtensions();
113 data.fromServer = true; //printed
114 data.getLayerPrefs().put("foo", "bar"); //printed depending on writer config
115 exts.add("knownprefix", "foo", "bar"); //printed
116 exts.add("unknownprefix", "foo", "bar"); //NOT printed
117
118 WayPoint wpt = new WayPoint(LatLon.ZERO);
119 wpt.getExtensions().add("test", "foo", "extension of a waypoint"); //printed
120
121 GpxTrackSegment seg = new GpxTrackSegment(Arrays.asList(wpt));
122 seg.getExtensions().add("test", "foo", "extension of a segment"); //printed
123
124 GpxTrack trk = new GpxTrack(Arrays.asList(seg), new HashMap<>());
125
126 trk.setColor(Color.RED); //printed depending on writer configuration
127
128 data.addTrack(trk);
129
130 ByteArrayOutputStream baos = new ByteArrayOutputStream();
131 GpxWriter writer = new GpxWriter(baos);
132
133 // CHECKSTYLE.OFF: LineLength
134
135 writer.write(data);
136 assertEquals("<?xml version='1.0' encoding='UTF-8'?>\n" +
137 "<gpx version=\"1.1\" creator=\"JOSM GPX export\" xmlns=\"http://www.topografix.com/GPX/1/1\"\n" +
138 " xmlns:knownprefix=\"http://example.com/URI\"\n" +
139 " xmlns:josm=\"http://josm.openstreetmap.de/gpx-extensions-1.1\"\n" +
140 " xmlns:gpxd=\"http://josm.openstreetmap.de/gpx-drawing-extensions-1.0\"\n" +
141 " xmlns:test=\"http://example.com/testURI\"\n" +
142 " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
143 " xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://example.com/URI http://example.com/location.xsd http://josm.openstreetmap.de/gpx-extensions-1.1 http://josm.openstreetmap.de/gpx-extensions-1.1.xsd http://josm.openstreetmap.de/gpx-drawing-extensions-1.0 http://josm.openstreetmap.de/gpx-drawing-extensions-1.0.xsd\">\n" +
144 " <metadata>\n" +
145 " <bounds minlat=\"0.0\" minlon=\"0.0\" maxlat=\"0.0\" maxlon=\"0.0\"/>\n" +
146 " <extensions>\n" +
147 " <knownprefix:foo>bar</knownprefix:foo>\n" +
148 " <josm:from-server>true</josm:from-server>\n" +
149 " <josm:layerPreferences>\n" +
150 " <josm:entry key=\"foo\" value=\"bar\"/>\n" +
151 " </josm:layerPreferences>\n" +
152 " </extensions>\n" +
153 " </metadata>\n" +
154 " <trk>\n" +
155 " <extensions>\n" +
156 " <gpxd:color>#FF0000</gpxd:color>\n" +
157 " </extensions>\n" +
158 " <trkseg>\n" +
159 " <extensions>\n" +
160 " <test:foo>extension of a segment</test:foo>\n" +
161 " </extensions>\n" +
162 " <trkpt lat=\"0.0\" lon=\"0.0\">\n" +
163 " <extensions>\n" +
164 " <test:foo>extension of a waypoint</test:foo>\n" +
165 " </extensions>\n" +
166 " </trkpt>\n" +
167 " </trkseg>\n" +
168 " </trk>\n" +
169 "</gpx>", baos.toString());
170
171 baos.reset();
172 writer.write(data, GpxConstants.ColorFormat.GPXX, true);
173 assertEquals("<?xml version='1.0' encoding='UTF-8'?>\n" +
174 "<gpx version=\"1.1\" creator=\"JOSM GPX export\" xmlns=\"http://www.topografix.com/GPX/1/1\"\n" +
175 " xmlns:knownprefix=\"http://example.com/URI\"\n" +
176 " xmlns:josm=\"http://josm.openstreetmap.de/gpx-extensions-1.1\"\n" +
177 " xmlns:gpxx=\"http://www.garmin.com/xmlschemas/GpxExtensions/v3\"\n" +
178 " xmlns:test=\"http://example.com/testURI\"\n" +
179 " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
180 " xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://example.com/URI http://example.com/location.xsd http://josm.openstreetmap.de/gpx-extensions-1.1 http://josm.openstreetmap.de/gpx-extensions-1.1.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd\">\n" +
181 " <metadata>\n" +
182 " <bounds minlat=\"0.0\" minlon=\"0.0\" maxlat=\"0.0\" maxlon=\"0.0\"/>\n" +
183 " <extensions>\n" +
184 " <knownprefix:foo>bar</knownprefix:foo>\n" +
185 " <josm:from-server>true</josm:from-server>\n" +
186 " <josm:layerPreferences>\n" +
187 " <josm:entry key=\"foo\" value=\"bar\"/>\n" +
188 " </josm:layerPreferences>\n" +
189 " </extensions>\n" +
190 " </metadata>\n" +
191 " <trk>\n" +
192 " <extensions>\n" +
193 " <gpxx:TrackExtension>\n" +
194 " <gpxx:DisplayColor>Red</gpxx:DisplayColor>\n" +
195 " </gpxx:TrackExtension>\n" +
196 " </extensions>\n" +
197 " <trkseg>\n" +
198 " <extensions>\n" +
199 " <test:foo>extension of a segment</test:foo>\n" +
200 " </extensions>\n" +
201 " <trkpt lat=\"0.0\" lon=\"0.0\">\n" +
202 " <extensions>\n" +
203 " <test:foo>extension of a waypoint</test:foo>\n" +
204 " </extensions>\n" +
205 " </trkpt>\n" +
206 " </trkseg>\n" +
207 " </trk>\n" +
208 "</gpx>", baos.toString());
209
210 baos.reset();
211 writer.write(data, null, false);
212 assertEquals("<?xml version='1.0' encoding='UTF-8'?>\n" +
213 "<gpx version=\"1.1\" creator=\"JOSM GPX export\" xmlns=\"http://www.topografix.com/GPX/1/1\"\n" +
214 " xmlns:knownprefix=\"http://example.com/URI\"\n" +
215 " xmlns:josm=\"http://josm.openstreetmap.de/gpx-extensions-1.1\"\n" +
216 " xmlns:test=\"http://example.com/testURI\"\n" +
217 " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
218 " xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://example.com/URI http://example.com/location.xsd http://josm.openstreetmap.de/gpx-extensions-1.1 http://josm.openstreetmap.de/gpx-extensions-1.1.xsd\">\n" +
219 " <metadata>\n" +
220 " <bounds minlat=\"0.0\" minlon=\"0.0\" maxlat=\"0.0\" maxlon=\"0.0\"/>\n" +
221 " <extensions>\n" +
222 " <knownprefix:foo>bar</knownprefix:foo>\n" +
223 " <josm:from-server>true</josm:from-server>\n" +
224 " </extensions>\n" +
225 " </metadata>\n" +
226 " <trk>\n" +
227 " <trkseg>\n" +
228 " <extensions>\n" +
229 " <test:foo>extension of a segment</test:foo>\n" +
230 " </extensions>\n" +
231 " <trkpt lat=\"0.0\" lon=\"0.0\">\n" +
232 " <extensions>\n" +
233 " <test:foo>extension of a waypoint</test:foo>\n" +
234 " </extensions>\n" +
235 " </trkpt>\n" +
236 " </trkseg>\n" +
237 " </trk>\n" +
238 "</gpx>", baos.toString());
239
240 baos.reset();
241 writer.write(data, GpxConstants.ColorFormat.GPXX, true);
242 // checked again to make sure that extensions are shown again after
243 // being hidden, even if they don't actually have to be converted
244 // (GPXD -> convertColor() -> GPXX -> hide() -> null -> show() -> GPXX)
245 assertEquals("<?xml version='1.0' encoding='UTF-8'?>\n" +
246 "<gpx version=\"1.1\" creator=\"JOSM GPX export\" xmlns=\"http://www.topografix.com/GPX/1/1\"\n" +
247 " xmlns:knownprefix=\"http://example.com/URI\"\n" +
248 " xmlns:josm=\"http://josm.openstreetmap.de/gpx-extensions-1.1\"\n" +
249 " xmlns:gpxx=\"http://www.garmin.com/xmlschemas/GpxExtensions/v3\"\n" +
250 " xmlns:test=\"http://example.com/testURI\"\n" +
251 " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
252 " xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://example.com/URI http://example.com/location.xsd http://josm.openstreetmap.de/gpx-extensions-1.1 http://josm.openstreetmap.de/gpx-extensions-1.1.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd\">\n" +
253 " <metadata>\n" +
254 " <bounds minlat=\"0.0\" minlon=\"0.0\" maxlat=\"0.0\" maxlon=\"0.0\"/>\n" +
255 " <extensions>\n" +
256 " <knownprefix:foo>bar</knownprefix:foo>\n" +
257 " <josm:from-server>true</josm:from-server>\n" +
258 " <josm:layerPreferences>\n" +
259 " <josm:entry key=\"foo\" value=\"bar\"/>\n" +
260 " </josm:layerPreferences>\n" +
261 " </extensions>\n" +
262 " </metadata>\n" +
263 " <trk>\n" +
264 " <extensions>\n" +
265 " <gpxx:TrackExtension>\n" +
266 " <gpxx:DisplayColor>Red</gpxx:DisplayColor>\n" +
267 " </gpxx:TrackExtension>\n" +
268 " </extensions>\n" +
269 " <trkseg>\n" +
270 " <extensions>\n" +
271 " <test:foo>extension of a segment</test:foo>\n" +
272 " </extensions>\n" +
273 " <trkpt lat=\"0.0\" lon=\"0.0\">\n" +
274 " <extensions>\n" +
275 " <test:foo>extension of a waypoint</test:foo>\n" +
276 " </extensions>\n" +
277 " </trkpt>\n" +
278 " </trkseg>\n" +
279 " </trk>\n" +
280 "</gpx>", baos.toString());
281
282 // CHECKSTYLE.ON: LineLength
283
284 writer.close();
285 }
286}
Note: See TracBrowser for help on using the repository browser.