Ticket #21932: 21932-v0.1.patch

File 21932-v0.1.patch, 29.7 KB (added by Bjoeni, 3 years ago)
  • src/org/openstreetmap/josm/io/GpxReader.java

    ### Eclipse Workspace Patch 1.0
    #P josm-2-21932
     
    304304            case EXT:
    305305                if (states.lastElement() == State.TRK) {
    306306                    currentTrackExtensionCollection.openChild(namespaceURI, qName, atts);
     307                } else if (states.lastElement() == State.WPT) {
     308                    currentWayPoint.getExtensions().openChild(namespaceURI, qName, atts);
    307309                } else {
    308310                    currentExtensionCollection.openChild(namespaceURI, qName, atts);
    309311                }
     
    548550                    String acc = accumulator.toString().trim();
    549551                    if (states.lastElement() == State.TRK) {
    550552                        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);
    551555                    } else {
    552556                        currentExtensionCollection.closeChild(qName, acc);
    553557                    }
  • 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

     
    2323import org.openstreetmap.josm.data.gpx.GpxConstants;
    2424import org.openstreetmap.josm.data.gpx.GpxData;
    2525import org.openstreetmap.josm.data.gpx.GpxTrack;
     26import org.openstreetmap.josm.data.gpx.IWithAttributes;
    2627import org.openstreetmap.josm.data.gpx.WayPoint;
    2728import org.openstreetmap.josm.io.IGpxReader;
    2829import org.openstreetmap.josm.io.IllegalDataException;
     
    439440                    accu = e[VTG.COURSE.position];
    440441                    if (!accu.isEmpty() && currentwp != null) {
    441442                        Double.parseDouble(accu);
    442                         currentwp.put("course", accu);
     443                        putExt(currentwp, "course", accu);
    443444                    }
    444445                }
    445446                // SPEED
     
    448449                    accu = e[VTG.SPEED_KMH.position];
    449450                    if (!accu.isEmpty() && currentwp != null) {
    450451                        double speed = Double.parseDouble(accu);
    451                         currentwp.put("speed", Double.toString(speed)); // speed in km/h
     452                        putExt(currentwp, "speed", Double.toString(speed)); // speed in km/h
    452453                    }
    453454                }
    454455            } else if (isSentence(e[0], Sentence.GSA)) {
     
    494495                currentwp.setInstant(instant);
    495496                // speed
    496497                accu = e[RMC.SPEED.position];
    497                 if (!accu.isEmpty() && !currentwp.attr.containsKey("speed")) {
     498                if (!accu.isEmpty() && !hasExt(currentwp, "speed")) {
    498499                    double speed = Double.parseDouble(accu);
    499500                    speed *= 0.514444444 * 3.6; // to km/h
    500                     currentwp.put("speed", Double.toString(speed));
     501                    putExt(currentwp, "speed", Double.toString(speed));
    501502                }
    502503                // course
    503504                accu = e[RMC.COURSE.position];
    504                 if (!accu.isEmpty() && !currentwp.attr.containsKey("course")) {
     505                if (!accu.isEmpty() && !hasExt(currentwp, "course")) {
    505506                    Double.parseDouble(accu);
    506                     currentwp.put("course", accu);
     507                    putExt(currentwp, "course", accu);
    507508                }
    508509
    509510                // TODO fix?
     
    562563        }
    563564    }
    564565
     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
    565576    private static LatLon parseLatLon(String ns, String ew, String dlat, String dlon) {
    566577        String widthNorth = dlat.trim();
    567578        String lengthEast = dlon.trim();
  • test/unit/org/openstreetmap/josm/io/rtklib/RtkLibPosReaderTest.java

     
    6161        assertEquals(Instant.parse("2019-06-08T08:23:12.600Z"), wayPoints.get(2).getInstant());
    6262
    6363        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)));
    6565        assertEquals("92.3955", wp0.get(GpxConstants.PT_ELE));
    6666        assertEquals("2", wp0.get(GpxConstants.PT_SAT));
    6767        assertEquals("1.8191757", wp0.get(GpxConstants.PT_HDOP).toString().trim());
    6868
    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));
    7575    }
    7676
     77    private String getRtk(WayPoint wp, String flag) {
     78        return wp.getExtensions().get("rtklib", flag).getValue();
     79    }
     80
    7781    /**
    7882     * Tests reading another RTKLib pos file with different date format.
    7983     * @throws Exception if any error occurs
  • src/org/openstreetmap/josm/io/GpxWriter.java

     
    99import java.io.PrintWriter;
    1010import java.nio.charset.StandardCharsets;
    1111import java.time.Instant;
    12 import java.util.ArrayList;
    1312import java.util.Collection;
    1413import java.util.Date;
    1514import java.util.List;
    1615import java.util.Map;
    1716import java.util.Objects;
     17import java.util.function.Function;
    1818import java.util.stream.Collectors;
     19import java.util.stream.Stream;
    1920
    2021import javax.xml.XMLConstants;
    2122
     
    126127        data.put(META_TIME, (metaTime != null ? metaTime : Instant.now()).toString(), false);
    127128        data.endUpdate();
    128129
    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 = all
    138                 .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)
    140141                .distinct()
    141                 .map(p -> data.getNamespaces()
     142                .map(prefix -> data.getNamespaces()
    142143                        .stream()
    143                         .filter(s -> s.getPrefix().equals(p))
     144                        .filter(namespace -> namespace.getPrefix().equals(prefix))
    144145                        .findAny()
    145                         .orElse(GpxExtension.findNamespace(p)))
     146                        .orElse(GpxExtension.findNamespace(prefix)))
    146147                .filter(Objects::nonNull)
    147148                .collect(Collectors.toList());
    148149
    149         validprefixes = namespaces.stream().map(n -> n.getPrefix()).collect(Collectors.toList());
     150        validprefixes = namespaces.stream()
     151                .map(XMLNamespace::getPrefix)
     152                .collect(Collectors.toList());
    150153
    151154        data.creator = JOSM_CREATOR_NAME;
    152155        out.println("<?xml version='1.0' encoding='UTF-8'?>");
  • src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java

     
    922922        addDoubleIfPresent(wpt, n, gpxPrefix, GpxConstants.PT_AGEOFDGPSDATA, "gps:ageofdgpsdata");
    923923        addIntegerIfPresent(wpt, n, gpxPrefix, GpxConstants.PT_DGPSID, "gps:dgpsid");
    924924
     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
    925932        return wpt;
    926933    }
    927934
  • 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

     
    3535     */
    3636    @Override
    3737    public Object get(String key) {
    38         return attr.get(key);
     38        return getAttributes().get(key);
    3939    }
    4040
    4141    /**
     
    4848     */
    4949    @Override
    5050    public String getString(String key) {
    51         Object value = attr.get(key);
     51        Object value = getAttributes().get(key);
    5252        return (value instanceof String) ? (String) value : null;
    5353    }
    5454
     
    6464    @SuppressWarnings("unchecked")
    6565    @Override
    6666    public <T> Collection<T> getCollection(String key) {
    67         Object value = attr.get(key);
     67        Object value = getAttributes().get(key);
    6868        return (value instanceof Collection) ? (Collection<T>) value : null;
    6969    }
    7070
     
    7777     */
    7878    @Override
    7979    public void put(String key, Object value) {
    80         attr.put(key, value);
     80        getAttributes().put(key, value);
    8181    }
    8282
    8383    @Override
     
    100100
    101101    @Override
    102102    public int hashCode() {
    103         return Objects.hash(attr, exts);
     103        return Objects.hash(getAttributes(), exts);
    104104    }
    105105
    106106    @Override
     
    112112        if (getClass() != obj.getClass())
    113113            return false;
    114114        WithAttributes other = (WithAttributes) obj;
    115         if (attr == null) {
    116             if (other.attr != null)
     115        if (getAttributes() == null) {
     116            if (other.getAttributes() != null)
    117117                return false;
    118         } else if (!attr.equals(other.attr))
     118        } else if (!getAttributes().equals(other.getAttributes()))
    119119            return false;
    120120        if (exts == null) {
    121121            if (other.exts != null)
  • test/unit/org/openstreetmap/josm/io/nmea/NmeaReaderTest.java

     
    163163    }
    164164
    165165    private static double readSpeed(String nmeaLine) throws IOException, SAXException {
    166         return Double.parseDouble(readWayPoint(nmeaLine).getString("speed"));
     166        return Double.parseDouble(readWayPoint(nmeaLine).getExtensions().get("nmea", "speed").getValue());
    167167    }
    168168
    169169    /**
  • src/org/openstreetmap/josm/data/gpx/GpxConstants.java

     
    128128    String XML_XSD_EXTENSIONS_DRAWING = Config.getUrls().getXMLBase() + "/gpx-drawing-extensions-1.0.xsd";
    129129
    130130    /**
     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    /**
    131149     * Namespace for Garmin GPX extensions
    132150     */
    133151    String XML_URI_EXTENSIONS_GARMIN = "http://www.garmin.com/xmlschemas/GpxExtensions/v3";
  • src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java

     
    4040import org.openstreetmap.josm.data.gpx.GpxData;
    4141import org.openstreetmap.josm.data.gpx.GpxData.GpxDataChangeEvent;
    4242import org.openstreetmap.josm.data.gpx.GpxData.GpxDataChangeListener;
     43import org.openstreetmap.josm.data.gpx.GpxExtension;
    4344import org.openstreetmap.josm.data.gpx.Line;
    4445import org.openstreetmap.josm.data.gpx.WayPoint;
    4546import org.openstreetmap.josm.data.preferences.NamedColorProperty;
     
    633634                if (colored == ColorMode.HDOP) {
    634635                    color = hdopScale.getColor((Float) trkPnt.get(GpxConstants.PT_HDOP));
    635636                } 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                    }
    637647                } else if (colored == ColorMode.FIX) {
    638648                    Object fixval = trkPnt.get(GpxConstants.PT_FIX);
    639649                    if (fixval != null) {
  • test/unit/org/openstreetmap/josm/data/gpx/GpxExtensionTest.java

     
    3838        col.add("josm", "from-server", "true");
    3939        EqualsVerifier.forClass(GpxExtension.class).usingGetClass()
    4040        .suppress(Warning.NONFINAL_FIELDS)
    41         .withIgnoredFields("qualifiedName", "parent")
     41        .withIgnoredFields("parent")
    4242        .withPrefabValues(GpxExtensionCollection.class, new GpxExtensionCollection(), col)
    4343        .verify();
    4444    }
  • src/org/openstreetmap/josm/io/rtklib/RtkLibPosReader.java

     
    1515import org.openstreetmap.josm.data.gpx.GpxConstants;
    1616import org.openstreetmap.josm.data.gpx.GpxData;
    1717import org.openstreetmap.josm.data.gpx.GpxTrack;
     18import org.openstreetmap.josm.data.gpx.IWithAttributes;
    1819import org.openstreetmap.josm.data.gpx.WayPoint;
    1920import org.openstreetmap.josm.io.IGpxReader;
    2021import org.openstreetmap.josm.tools.Logging;
     
    7778                                    Double.parseDouble(fields[IDX_LAT]),
    7879                                    Double.parseDouble(fields[IDX_LON])));
    7980                            currentwp.put(GpxConstants.PT_ELE, fields[IDX_HEIGHT]);
     81                            currentwp.put(GpxConstants.PT_SAT, fields[IDX_NS]);
    8082                            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
    9194                            double sdn = Double.parseDouble(fields[IDX_SDN]);
    9295                            double sde = Double.parseDouble(fields[IDX_SDE]);
    9396                            currentwp.put(GpxConstants.PT_HDOP, (float) Math.sqrt(sdn*sdn + sde*sde));
     
    105108        return true;
    106109    }
    107110
     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
    108117    @Override
    109118    public GpxData getGpxData() {
    110119        return data;
  • src/org/openstreetmap/josm/data/gpx/GpxExtension.java

     
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.data.gpx;
    33
     4import java.util.HashMap;
     5import java.util.Map;
    46import java.util.Objects;
    57import java.util.Optional;
    68
     
    1315 * @since 15496
    1416 */
    1517public class GpxExtension extends WithAttributes {
    16     private final String qualifiedName, prefix, key;
     18    private final String prefix, key;
    1719    private IWithAttributes parent;
    1820    private String value;
    1921    private boolean visible = true;
     
    2830        this.prefix = Optional.ofNullable(prefix).orElse("");
    2931        this.key = key;
    3032        this.value = value;
    31         this.qualifiedName = (this.prefix.isEmpty() ? "" : this.prefix + ":") + key;
     33        this.attr = null;
    3234    }
    3335
    3436    /**
     
    4042     * @param atts the attributes
    4143     */
    4244    public GpxExtension(String namespaceURI, String qName, Attributes atts) {
    43         qualifiedName = qName;
    4445        int dot = qName.indexOf(':');
    4546        String p = findPrefix(namespaceURI);
    4647        if (p == null) {
     
    5455        }
    5556        key = qName.substring(dot + 1);
    5657        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));
    5859        }
    5960    }
    6061
    6162    /**
    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.
    6364     * @param namespaceURI namespace URI
    6465     * @return the prefix
    6566     */
     
    7374        if (XML_URI_EXTENSIONS_JOSM.equals(namespaceURI))
    7475            return "josm";
    7576
     77        if (XML_URI_EXTENSIONS_RTKLIB.equals(namespaceURI))
     78            return "rtklib";
     79
     80        if (XML_URI_EXTENSIONS_NMEA.equals(namespaceURI))
     81            return "nmea";
     82
    7683        return null;
    7784    }
    7885
     
    8996            return new XMLNamespace("gpxd", XML_URI_EXTENSIONS_DRAWING, XML_XSD_EXTENSIONS_DRAWING);
    9097        case "josm":
    9198            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);
    92103        }
    93104        return null;
    94105    }
     
    98109     * @return the qualified name of the XML element
    99110     */
    100111    public String getQualifiedName() {
    101         return qualifiedName;
     112        return (this.prefix.isEmpty() ? "" : this.prefix + ":") + key;
    102113    }
    103114
    104115    /**
     
    169180     */
    170181    public void remove() {
    171182        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.");
    173184
    174185        parent.getExtensions().remove(this);
    175186        if (parent instanceof GpxExtension) {
     
    232243     */
    233244    public void setParent(IWithAttributes parent) {
    234245        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");
    236247
    237248        this.parent = parent;
    238249    }
    239250
     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
    240259    @Override
     260    public Map<String, Object> getAttributes() {
     261        if (attr == null) {
     262            attr = new HashMap<>();
     263        }
     264        return attr;
     265    }
     266
     267    @Override
    241268    public int hashCode() {
    242269        return Objects.hash(prefix, key, value, attr, visible, super.hashCode());
    243270    }