Ticket #21932: 21932-v0.1.patch
| File 21932-v0.1.patch, 29.7 KB (added by , 3 years ago) |
|---|
-
src/org/openstreetmap/josm/io/GpxReader.java
### Eclipse Workspace Patch 1.0 #P josm-2-21932
304 304 case EXT: 305 305 if (states.lastElement() == State.TRK) { 306 306 currentTrackExtensionCollection.openChild(namespaceURI, qName, atts); 307 } else if (states.lastElement() == State.WPT) { 308 currentWayPoint.getExtensions().openChild(namespaceURI, qName, atts); 307 309 } else { 308 310 currentExtensionCollection.openChild(namespaceURI, qName, atts); 309 311 } … … 548 550 String acc = accumulator.toString().trim(); 549 551 if (states.lastElement() == State.TRK) { 550 552 currentTrackExtensionCollection.closeChild(qName, acc); //a segment inside the track can have an extension too 553 } else if (states.lastElement() == State.WPT) { 554 currentWayPoint.getExtensions().closeChild(qName, acc); 551 555 } else { 552 556 currentExtensionCollection.closeChild(qName, acc); 553 557 } -
resources/data/gpx-nmea-extensions-1.0.xsd
1 <?xml version="1.0" encoding="UTF-8"?> 2 <schema targetNamespace="https://josm.openstreetmap.de/gpx-nmea-extensions-1.0" 3 elementFormDefault="qualified" 4 xmlns="http://www.w3.org/2001/XMLSchema" 5 xmlns:xsd="http://www.w3.org/2001/XMLSchema" 6 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 7 xmlns:nmea="https://josm.openstreetmap.de/gpx-nmea-extensions-1.0" 8 xsi:schemaLocation="https://josm.openstreetmap.de/gpx-nmea-extensions-1.0 https://josm.openstreetmap.de/gpx-nmea-extensions-1.0.xsd"> 9 10 <xsd:annotation> 11 <xsd:documentation> 12 This schema defines NMEA extensions for the GPX 1.1 schema (http://www.topografix.com/GPX/1/1/gpx.xsd). 13 Elements in this schema should be used as child elements of the "extensions" element defined by the GPX schema. 14 </xsd:documentation> 15 </xsd:annotation> 16 17 <!-- Elements --> 18 19 <xsd:element name="speed" type="xsd:decimal"> 20 <xsd:annotation> 21 <xsd:documentation> 22 The speed at the given waypoint in km/h. 23 </xsd:documentation> 24 </xsd:annotation> 25 </xsd:element> 26 27 <xsd:element name="course" type="xsd:decimal"> 28 <xsd:annotation> 29 <xsd:documentation> 30 The course in radians. 31 </xsd:documentation> 32 </xsd:annotation> 33 </xsd:element> 34 </schema> 35 No newline at end of file -
src/org/openstreetmap/josm/io/nmea/NmeaReader.java
23 23 import org.openstreetmap.josm.data.gpx.GpxConstants; 24 24 import org.openstreetmap.josm.data.gpx.GpxData; 25 25 import org.openstreetmap.josm.data.gpx.GpxTrack; 26 import org.openstreetmap.josm.data.gpx.IWithAttributes; 26 27 import org.openstreetmap.josm.data.gpx.WayPoint; 27 28 import org.openstreetmap.josm.io.IGpxReader; 28 29 import org.openstreetmap.josm.io.IllegalDataException; … … 439 440 accu = e[VTG.COURSE.position]; 440 441 if (!accu.isEmpty() && currentwp != null) { 441 442 Double.parseDouble(accu); 442 currentwp.put("course", accu);443 putExt(currentwp, "course", accu); 443 444 } 444 445 } 445 446 // SPEED … … 448 449 accu = e[VTG.SPEED_KMH.position]; 449 450 if (!accu.isEmpty() && currentwp != null) { 450 451 double speed = Double.parseDouble(accu); 451 currentwp.put("speed", Double.toString(speed)); // speed in km/h452 putExt(currentwp, "speed", Double.toString(speed)); // speed in km/h 452 453 } 453 454 } 454 455 } else if (isSentence(e[0], Sentence.GSA)) { … … 494 495 currentwp.setInstant(instant); 495 496 // speed 496 497 accu = e[RMC.SPEED.position]; 497 if (!accu.isEmpty() && ! currentwp.attr.containsKey("speed")) {498 if (!accu.isEmpty() && !hasExt(currentwp, "speed")) { 498 499 double speed = Double.parseDouble(accu); 499 500 speed *= 0.514444444 * 3.6; // to km/h 500 currentwp.put("speed", Double.toString(speed));501 putExt(currentwp, "speed", Double.toString(speed)); 501 502 } 502 503 // course 503 504 accu = e[RMC.COURSE.position]; 504 if (!accu.isEmpty() && ! currentwp.attr.containsKey("course")) {505 if (!accu.isEmpty() && !hasExt(currentwp, "course")) { 505 506 Double.parseDouble(accu); 506 currentwp.put("course", accu);507 putExt(currentwp, "course", accu); 507 508 } 508 509 509 510 // TODO fix? … … 562 563 } 563 564 } 564 565 566 private void putExt(IWithAttributes wp, String flag, String field) { 567 if (wp != null && field != null) { 568 wp.getExtensions().addOrUpdate("nmea", flag, field); 569 } 570 } 571 572 private boolean hasExt(IWithAttributes wp, String flag) { 573 return wp.hasExtensions() && wp.getExtensions().get("nmea", flag) != null; 574 } 575 565 576 private static LatLon parseLatLon(String ns, String ew, String dlat, String dlon) { 566 577 String widthNorth = dlat.trim(); 567 578 String lengthEast = dlon.trim(); -
test/unit/org/openstreetmap/josm/io/rtklib/RtkLibPosReaderTest.java
61 61 assertEquals(Instant.parse("2019-06-08T08:23:12.600Z"), wayPoints.get(2).getInstant()); 62 62 63 63 assertEquals(new LatLon(46.948881673, -1.484757046), wp0.getCoor()); 64 assertEquals(5, wp0.get(GpxConstants.RTKLIB_Q));64 assertEquals(5, Integer.parseInt(getRtk(wp0, GpxConstants.RTKLIB_Q))); 65 65 assertEquals("92.3955", wp0.get(GpxConstants.PT_ELE)); 66 66 assertEquals("2", wp0.get(GpxConstants.PT_SAT)); 67 67 assertEquals("1.8191757", wp0.get(GpxConstants.PT_HDOP).toString().trim()); 68 68 69 assertEquals("1.5620", wp0.get(GpxConstants.RTKLIB_SDN));70 assertEquals("0.9325", wp0.get(GpxConstants.RTKLIB_SDE));71 assertEquals("0.8167", wp0.get(GpxConstants.RTKLIB_SDU));72 assertEquals("-0.7246", wp0.get(GpxConstants.RTKLIB_SDNE));73 assertEquals("0.7583", wp0.get(GpxConstants.RTKLIB_SDEU));74 assertEquals("0.6573", wp0.get(GpxConstants.RTKLIB_SDUN));69 assertEquals("1.5620", getRtk(wp0, GpxConstants.RTKLIB_SDN)); 70 assertEquals("0.9325", getRtk(wp0, GpxConstants.RTKLIB_SDE)); 71 assertEquals("0.8167", getRtk(wp0, GpxConstants.RTKLIB_SDU)); 72 assertEquals("-0.7246", getRtk(wp0, GpxConstants.RTKLIB_SDNE)); 73 assertEquals("0.7583", getRtk(wp0, GpxConstants.RTKLIB_SDEU)); 74 assertEquals("0.6573", getRtk(wp0, GpxConstants.RTKLIB_SDUN)); 75 75 } 76 76 77 private String getRtk(WayPoint wp, String flag) { 78 return wp.getExtensions().get("rtklib", flag).getValue(); 79 } 80 77 81 /** 78 82 * Tests reading another RTKLib pos file with different date format. 79 83 * @throws Exception if any error occurs -
src/org/openstreetmap/josm/io/GpxWriter.java
9 9 import java.io.PrintWriter; 10 10 import java.nio.charset.StandardCharsets; 11 11 import java.time.Instant; 12 import java.util.ArrayList;13 12 import java.util.Collection; 14 13 import java.util.Date; 15 14 import java.util.List; 16 15 import java.util.Map; 17 16 import java.util.Objects; 17 import java.util.function.Function; 18 18 import java.util.stream.Collectors; 19 import java.util.stream.Stream; 19 20 20 21 import javax.xml.XMLConstants; 21 22 … … 126 127 data.put(META_TIME, (metaTime != null ? metaTime : Instant.now()).toString(), false); 127 128 data.endUpdate(); 128 129 129 Collection<IWithAttributes> all = new ArrayList<>();130 131 all.add(data);132 all.addAll(data.getWaypoints());133 all.addAll(data.getRoutes());134 all.addAll(data.getTracks());135 all.addAll(data.getTrackSegmentsStream().collect(Collectors.toList()));136 137 List<XMLNamespace> namespaces = all138 . stream()139 .flatMap( w -> w.getExtensions().getPrefixesStream())130 // find all XMLNamespaces that occur in the GpxData 131 List<XMLNamespace> namespaces = Stream.of( 132 Stream.of(data), 133 data.getWaypoints().stream(), 134 data.getRoutes().stream(), 135 data.getTracks().stream(), 136 data.getTrackSegmentsStream(), 137 data.getTrackSegmentsStream().flatMap(segment -> segment.getWayPoints().stream())) 138 .flatMap(Function.identity()) 139 .map(IWithAttributes::getExtensions) 140 .flatMap(GpxExtensionCollection::getPrefixesStream) 140 141 .distinct() 141 .map(p -> data.getNamespaces()142 .map(prefix -> data.getNamespaces() 142 143 .stream() 143 .filter( s -> s.getPrefix().equals(p))144 .filter(namespace -> namespace.getPrefix().equals(prefix)) 144 145 .findAny() 145 .orElse(GpxExtension.findNamespace(p )))146 .orElse(GpxExtension.findNamespace(prefix))) 146 147 .filter(Objects::nonNull) 147 148 .collect(Collectors.toList()); 148 149 149 validprefixes = namespaces.stream().map(n -> n.getPrefix()).collect(Collectors.toList()); 150 validprefixes = namespaces.stream() 151 .map(XMLNamespace::getPrefix) 152 .collect(Collectors.toList()); 150 153 151 154 data.creator = JOSM_CREATOR_NAME; 152 155 out.println("<?xml version='1.0' encoding='UTF-8'?>"); -
src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
922 922 addDoubleIfPresent(wpt, n, gpxPrefix, GpxConstants.PT_AGEOFDGPSDATA, "gps:ageofdgpsdata"); 923 923 addIntegerIfPresent(wpt, n, gpxPrefix, GpxConstants.PT_DGPSID, "gps:dgpsid"); 924 924 925 // Extensions 926 n.getKeys().forEach((key, value) -> { 927 if (key.startsWith(gpxPrefix + "extension")) { 928 wpt.getExtensions().addFlat(key.substring(gpxPrefix.length()).split(":"), value); 929 } 930 }); 931 925 932 return wpt; 926 933 } 927 934 -
resources/data/gpx-rtklib-extensions-1.0.xsd
1 <?xml version="1.0" encoding="UTF-8"?> 2 <schema targetNamespace="https://josm.openstreetmap.de/gpx-rtlib-extensions-1.0" 3 elementFormDefault="qualified" 4 xmlns="http://www.w3.org/2001/XMLSchema" 5 xmlns:xsd="http://www.w3.org/2001/XMLSchema" 6 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 7 xmlns:rtklib="https://josm.openstreetmap.de/gpx-rtklib-extensions-1.0" 8 xsi:schemaLocation="https://josm.openstreetmap.de/gpx-rtklib-extensions-1.0 https://josm.openstreetmap.de/gpx-rtklib-extensions-1.0.xsd"> 9 10 <xsd:annotation> 11 <xsd:documentation> 12 This schema defines RTKLib extensions for the GPX 1.1 schema (http://www.topografix.com/GPX/1/1/gpx.xsd). 13 Elements in this schema should be used as child elements of the "extensions" element defined by the GPX schema. 14 </xsd:documentation> 15 </xsd:annotation> 16 17 <!-- Elements --> 18 19 <xsd:element name="Q" type="xsd:positiveInteger"> 20 <xsd:annotation> 21 <xsd:documentation> 22 The flag which indicates the solution quality. 23 1 : Fixed, solution by carrier-based relative positioning and the integer ambiguity is properly resolved. 24 2 : Float, solution by carrier-based relative positioning but the integer ambiguity is not resolved. 25 3 : Reserved 26 4 : DGPS, solution by code-based DGPS solutions or single point positioning with SBAS corrections 27 5 : Single, solution by single point positioning 28 </xsd:documentation> 29 </xsd:annotation> 30 </xsd:element> 31 32 <xsd:element name="sdn" type="xsd:decimal"> 33 <xsd:annotation> 34 <xsd:documentation> 35 N (north) component of the standard deviations in m. 36 </xsd:documentation> 37 </xsd:annotation> 38 </xsd:element> 39 40 <xsd:element name="sde" type="xsd:decimal"> 41 <xsd:annotation> 42 <xsd:documentation> 43 E (east) component of the standard deviations in m. 44 </xsd:documentation> 45 </xsd:annotation> 46 </xsd:element> 47 48 <xsd:element name="sdu" type="xsd:decimal"> 49 <xsd:annotation> 50 <xsd:documentation> 51 U (up) component of the standard deviations in m. 52 </xsd:documentation> 53 </xsd:annotation> 54 </xsd:element> 55 56 <xsd:element name="sdne" type="xsd:decimal"> 57 <xsd:annotation> 58 <xsd:documentation> 59 The absolute value of sdne means square root of the absolute value of NE component of the estimated covariance matrix. 60 The sign represents the sign of the covariance. 61 </xsd:documentation> 62 </xsd:annotation> 63 </xsd:element> 64 65 <xsd:element name="sdeu" type="xsd:decimal"> 66 <xsd:annotation> 67 <xsd:documentation> 68 The absolute value of sdeu means square root of the absolute value of EU component of the estimated covariance matrix. 69 The sign represents the sign of the covariance. 70 </xsd:documentation> 71 </xsd:annotation> 72 </xsd:element> 73 74 <xsd:element name="sdun" type="xsd:decimal"> 75 <xsd:annotation> 76 <xsd:documentation> 77 The absolute value of sdun means square root of the absolute value of UN component of the estimated covariance matrix. 78 The sign represents the sign of the covariance. 79 </xsd:documentation> 80 </xsd:annotation> 81 </xsd:element> 82 83 <xsd:element name="age" type="xsd:decimal"> 84 <xsd:annotation> 85 <xsd:documentation> 86 The time difference between the observation data epochs of the rover receiver and the base station in second. 87 </xsd:documentation> 88 </xsd:annotation> 89 </xsd:element> 90 91 <xsd:element name="ratio" type="xsd:decimal"> 92 <xsd:annotation> 93 <xsd:documentation> 94 The ratio factor of "ratio-test" for standard integer ambiguity validation strategy. 95 The value means the ratio of the squared sum of the residuals with the second best integer vector to with the best integer vector. 96 </xsd:documentation> 97 </xsd:annotation> 98 </xsd:element> 99 100 </schema> 101 No newline at end of file -
src/org/openstreetmap/josm/data/gpx/WithAttributes.java
35 35 */ 36 36 @Override 37 37 public Object get(String key) { 38 return attr.get(key);38 return getAttributes().get(key); 39 39 } 40 40 41 41 /** … … 48 48 */ 49 49 @Override 50 50 public String getString(String key) { 51 Object value = attr.get(key);51 Object value = getAttributes().get(key); 52 52 return (value instanceof String) ? (String) value : null; 53 53 } 54 54 … … 64 64 @SuppressWarnings("unchecked") 65 65 @Override 66 66 public <T> Collection<T> getCollection(String key) { 67 Object value = attr.get(key);67 Object value = getAttributes().get(key); 68 68 return (value instanceof Collection) ? (Collection<T>) value : null; 69 69 } 70 70 … … 77 77 */ 78 78 @Override 79 79 public void put(String key, Object value) { 80 attr.put(key, value);80 getAttributes().put(key, value); 81 81 } 82 82 83 83 @Override … … 100 100 101 101 @Override 102 102 public int hashCode() { 103 return Objects.hash( attr, exts);103 return Objects.hash(getAttributes(), exts); 104 104 } 105 105 106 106 @Override … … 112 112 if (getClass() != obj.getClass()) 113 113 return false; 114 114 WithAttributes other = (WithAttributes) obj; 115 if ( attr== null) {116 if (other. attr!= null)115 if (getAttributes() == null) { 116 if (other.getAttributes() != null) 117 117 return false; 118 } else if (! attr.equals(other.attr))118 } else if (!getAttributes().equals(other.getAttributes())) 119 119 return false; 120 120 if (exts == null) { 121 121 if (other.exts != null) -
test/unit/org/openstreetmap/josm/io/nmea/NmeaReaderTest.java
163 163 } 164 164 165 165 private static double readSpeed(String nmeaLine) throws IOException, SAXException { 166 return Double.parseDouble(readWayPoint(nmeaLine).get String("speed"));166 return Double.parseDouble(readWayPoint(nmeaLine).getExtensions().get("nmea", "speed").getValue()); 167 167 } 168 168 169 169 /** -
src/org/openstreetmap/josm/data/gpx/GpxConstants.java
128 128 String XML_XSD_EXTENSIONS_DRAWING = Config.getUrls().getXMLBase() + "/gpx-drawing-extensions-1.0.xsd"; 129 129 130 130 /** 131 * Namespace for the RTKLib GPX extensions 132 */ 133 String XML_URI_EXTENSIONS_RTKLIB = Config.getUrls().getXMLBase() + "/rtklib-extensions-1.0"; 134 /** 135 * Location of the XSD schema for the RTKLib GPX extensions 136 */ 137 String XML_XSD_EXTENSIONS_RTKLIB = Config.getUrls().getXMLBase() + "/rtklib-extensions-1.0.xsd"; 138 139 /** 140 * Namespace for the NMEA GPX extensions 141 */ 142 String XML_URI_EXTENSIONS_NMEA = Config.getUrls().getXMLBase() + "/nmea-extensions-1.0"; 143 /** 144 * Location of the XSD schema for the NMEA GPX extensions 145 */ 146 String XML_XSD_EXTENSIONS_NMEA = Config.getUrls().getXMLBase() + "/nmea-extensions-1.0.xsd"; 147 148 /** 131 149 * Namespace for Garmin GPX extensions 132 150 */ 133 151 String XML_URI_EXTENSIONS_GARMIN = "http://www.garmin.com/xmlschemas/GpxExtensions/v3"; -
src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java
40 40 import org.openstreetmap.josm.data.gpx.GpxData; 41 41 import org.openstreetmap.josm.data.gpx.GpxData.GpxDataChangeEvent; 42 42 import org.openstreetmap.josm.data.gpx.GpxData.GpxDataChangeListener; 43 import org.openstreetmap.josm.data.gpx.GpxExtension; 43 44 import org.openstreetmap.josm.data.gpx.Line; 44 45 import org.openstreetmap.josm.data.gpx.WayPoint; 45 46 import org.openstreetmap.josm.data.preferences.NamedColorProperty; … … 633 634 if (colored == ColorMode.HDOP) { 634 635 color = hdopScale.getColor((Float) trkPnt.get(GpxConstants.PT_HDOP)); 635 636 } else if (colored == ColorMode.QUALITY) { 636 color = qualityScale.getColor((Integer) trkPnt.get(GpxConstants.RTKLIB_Q)); 637 if (trkPnt.hasExtensions()) { 638 GpxExtension extQ = trkPnt.getExtensions().get("rtklib", GpxConstants.RTKLIB_Q); 639 if (extQ != null) { 640 try { 641 color = qualityScale.getColor(Integer.parseInt(extQ.getValue())); 642 } catch (NumberFormatException ex) { 643 Logging.warn(ex); 644 } 645 } 646 } 637 647 } else if (colored == ColorMode.FIX) { 638 648 Object fixval = trkPnt.get(GpxConstants.PT_FIX); 639 649 if (fixval != null) { -
test/unit/org/openstreetmap/josm/data/gpx/GpxExtensionTest.java
38 38 col.add("josm", "from-server", "true"); 39 39 EqualsVerifier.forClass(GpxExtension.class).usingGetClass() 40 40 .suppress(Warning.NONFINAL_FIELDS) 41 .withIgnoredFields(" qualifiedName", "parent")41 .withIgnoredFields("parent") 42 42 .withPrefabValues(GpxExtensionCollection.class, new GpxExtensionCollection(), col) 43 43 .verify(); 44 44 } -
src/org/openstreetmap/josm/io/rtklib/RtkLibPosReader.java
15 15 import org.openstreetmap.josm.data.gpx.GpxConstants; 16 16 import org.openstreetmap.josm.data.gpx.GpxData; 17 17 import org.openstreetmap.josm.data.gpx.GpxTrack; 18 import org.openstreetmap.josm.data.gpx.IWithAttributes; 18 19 import org.openstreetmap.josm.data.gpx.WayPoint; 19 20 import org.openstreetmap.josm.io.IGpxReader; 20 21 import org.openstreetmap.josm.tools.Logging; … … 77 78 Double.parseDouble(fields[IDX_LAT]), 78 79 Double.parseDouble(fields[IDX_LON]))); 79 80 currentwp.put(GpxConstants.PT_ELE, fields[IDX_HEIGHT]); 81 currentwp.put(GpxConstants.PT_SAT, fields[IDX_NS]); 80 82 currentwp.setInstant(DateUtils.parseInstant(fields[IDX_DATE]+" "+fields[IDX_TIME])); 81 currentwp.put(GpxConstants.RTKLIB_Q, Integer.parseInt(fields[IDX_Q])); 82 currentwp.put(GpxConstants.PT_SAT, fields[IDX_NS]); 83 currentwp.put(GpxConstants.RTKLIB_SDN, fields[IDX_SDN]); 84 currentwp.put(GpxConstants.RTKLIB_SDE, fields[IDX_SDE]); 85 currentwp.put(GpxConstants.RTKLIB_SDU, fields[IDX_SDU]); 86 currentwp.put(GpxConstants.RTKLIB_SDNE, fields[IDX_SDNE]); 87 currentwp.put(GpxConstants.RTKLIB_SDEU, fields[IDX_SDEU]); 88 currentwp.put(GpxConstants.RTKLIB_SDUN, fields[IDX_SDUN]); 89 currentwp.put(GpxConstants.RTKLIB_AGE, fields[IDX_AGE]); 90 currentwp.put(GpxConstants.RTKLIB_RATIO, fields[IDX_RATIO]); 83 84 putExt(currentwp, GpxConstants.RTKLIB_Q, fields[IDX_Q]); 85 putExt(currentwp, GpxConstants.RTKLIB_SDN, fields[IDX_SDN]); 86 putExt(currentwp, GpxConstants.RTKLIB_SDE, fields[IDX_SDE]); 87 putExt(currentwp, GpxConstants.RTKLIB_SDU, fields[IDX_SDU]); 88 putExt(currentwp, GpxConstants.RTKLIB_SDNE, fields[IDX_SDNE]); 89 putExt(currentwp, GpxConstants.RTKLIB_SDEU, fields[IDX_SDEU]); 90 putExt(currentwp, GpxConstants.RTKLIB_SDUN, fields[IDX_SDUN]); 91 putExt(currentwp, GpxConstants.RTKLIB_AGE, fields[IDX_AGE]); 92 putExt(currentwp, GpxConstants.RTKLIB_RATIO, fields[IDX_RATIO]); 93 91 94 double sdn = Double.parseDouble(fields[IDX_SDN]); 92 95 double sde = Double.parseDouble(fields[IDX_SDE]); 93 96 currentwp.put(GpxConstants.PT_HDOP, (float) Math.sqrt(sdn*sdn + sde*sde)); … … 105 108 return true; 106 109 } 107 110 111 private void putExt(IWithAttributes wp, String flag, String field) { 112 if (wp != null && field != null) { 113 wp.getExtensions().add("rtklib", flag, field); 114 } 115 } 116 108 117 @Override 109 118 public GpxData getGpxData() { 110 119 return data; -
src/org/openstreetmap/josm/data/gpx/GpxExtension.java
1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.data.gpx; 3 3 4 import java.util.HashMap; 5 import java.util.Map; 4 6 import java.util.Objects; 5 7 import java.util.Optional; 6 8 … … 13 15 * @since 15496 14 16 */ 15 17 public class GpxExtension extends WithAttributes { 16 private final String qualifiedName,prefix, key;18 private final String prefix, key; 17 19 private IWithAttributes parent; 18 20 private String value; 19 21 private boolean visible = true; … … 28 30 this.prefix = Optional.ofNullable(prefix).orElse(""); 29 31 this.key = key; 30 32 this.value = value; 31 this. qualifiedName = (this.prefix.isEmpty() ? "" : this.prefix + ":") + key;33 this.attr = null; 32 34 } 33 35 34 36 /** … … 40 42 * @param atts the attributes 41 43 */ 42 44 public GpxExtension(String namespaceURI, String qName, Attributes atts) { 43 qualifiedName = qName;44 45 int dot = qName.indexOf(':'); 45 46 String p = findPrefix(namespaceURI); 46 47 if (p == null) { … … 54 55 } 55 56 key = qName.substring(dot + 1); 56 57 for (int i = 0; i < atts.getLength(); i++) { 57 attr.put(atts.getLocalName(i), atts.getValue(i));58 getAttributes().put(atts.getLocalName(i), atts.getValue(i)); 58 59 } 59 60 } 60 61 61 62 /** 62 * Finds the default prefix used by JOSM for the given namespaceURI as the document is free specify another one.63 * Finds the default prefix used by JOSM for the given namespaceURI as the document is free to specify another one. 63 64 * @param namespaceURI namespace URI 64 65 * @return the prefix 65 66 */ … … 73 74 if (XML_URI_EXTENSIONS_JOSM.equals(namespaceURI)) 74 75 return "josm"; 75 76 77 if (XML_URI_EXTENSIONS_RTKLIB.equals(namespaceURI)) 78 return "rtklib"; 79 80 if (XML_URI_EXTENSIONS_NMEA.equals(namespaceURI)) 81 return "nmea"; 82 76 83 return null; 77 84 } 78 85 … … 89 96 return new XMLNamespace("gpxd", XML_URI_EXTENSIONS_DRAWING, XML_XSD_EXTENSIONS_DRAWING); 90 97 case "josm": 91 98 return new XMLNamespace("josm", XML_URI_EXTENSIONS_JOSM, XML_XSD_EXTENSIONS_JOSM); 99 case "rtklib": 100 return new XMLNamespace("rtklib", XML_URI_EXTENSIONS_RTKLIB, XML_XSD_EXTENSIONS_RTKLIB); 101 case "nmea": 102 return new XMLNamespace("nmea", XML_URI_EXTENSIONS_NMEA, XML_XSD_EXTENSIONS_NMEA); 92 103 } 93 104 return null; 94 105 } … … 98 109 * @return the qualified name of the XML element 99 110 */ 100 111 public String getQualifiedName() { 101 return qualifiedName;112 return (this.prefix.isEmpty() ? "" : this.prefix + ":") + key; 102 113 } 103 114 104 115 /** … … 169 180 */ 170 181 public void remove() { 171 182 if (parent == null) 172 throw new IllegalStateException("Extension " + qualifiedName+ " has no parent, can't remove it.");183 throw new IllegalStateException("Extension " + getQualifiedName() + " has no parent, can't remove it."); 173 184 174 185 parent.getExtensions().remove(this); 175 186 if (parent instanceof GpxExtension) { … … 232 243 */ 233 244 public void setParent(IWithAttributes parent) { 234 245 if (this.parent != null) 235 throw new IllegalStateException("Parent of extension " + qualifiedName+ " is already set");246 throw new IllegalStateException("Parent of extension " + getQualifiedName() + " is already set"); 236 247 237 248 this.parent = parent; 238 249 } 239 250 251 /** 252 * Returns if the element has attributes without instantiating the HashMap 253 * @return if the element has attributes 254 */ 255 public boolean hasAttributes() { 256 return attr != null && !attr.isEmpty(); 257 } 258 240 259 @Override 260 public Map<String, Object> getAttributes() { 261 if (attr == null) { 262 attr = new HashMap<>(); 263 } 264 return attr; 265 } 266 267 @Override 241 268 public int hashCode() { 242 269 return Objects.hash(prefix, key, value, attr, visible, super.hashCode()); 243 270 }
