Index: trunk/src/org/openstreetmap/josm/actions/ExtensionFileFilter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/ExtensionFileFilter.java	(revision 15246)
+++ trunk/src/org/openstreetmap/josm/actions/ExtensionFileFilter.java	(revision 15247)
@@ -27,4 +27,5 @@
 import org.openstreetmap.josm.gui.io.importexport.OsmChangeImporter;
 import org.openstreetmap.josm.gui.io.importexport.OsmImporter;
+import org.openstreetmap.josm.gui.io.importexport.RtkLibImporter;
 import org.openstreetmap.josm.gui.io.importexport.WMSLayerImporter;
 import org.openstreetmap.josm.gui.widgets.AbstractFileChooser;
@@ -65,4 +66,5 @@
                 GpxImporter.class,
                 NMEAImporter.class,
+                RtkLibImporter.class,
                 NoteImporter.class,
                 JpgImporter.class,
Index: trunk/src/org/openstreetmap/josm/data/gpx/GpxConstants.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/GpxConstants.java	(revision 15246)
+++ trunk/src/org/openstreetmap/josm/data/gpx/GpxConstants.java	(revision 15247)
@@ -165,3 +165,38 @@
     Collection<String> FIX_VALUES = Collections.unmodifiableList(
             Arrays.asList("none", "2d", "3d", "dgps", "pps", "rtk", "float rtk", "estimated", "manual", "simulated"));
+
+    /**
+     * The flag which indicates the solution quality.<ul>
+     * <li>1 : Fixed, solution by carrier‐based relative positioning and the integer ambiguity is properly resolved.</li>
+     * <li>2 : Float, solution by carrier‐based relative positioning but the integer ambiguity is not resolved.</li>
+     * <li>3 : Reserved</li>
+     * <li>4 : DGPS, solution by code‐based DGPS solutions or single point positioning with SBAS corrections</li>
+     * <li>5 : Single, solution by single point positioning</li></ul>
+     * @since 15247
+     */
+    String RTKLIB_Q = "Q";
+    /** N (north) component of the standard deviations in m. */
+    String RTKLIB_SDN = "sdn";
+    /** E (east) component of the standard deviations in m. */
+    String RTKLIB_SDE = "sde";
+    /** U (up) component of the standard deviations in m. */
+    String RTKLIB_SDU = "sdu";
+    /**
+     * The absolute value of sdne means square root of the absolute value of NE component of the estimated covariance matrix.
+     * The sign represents the sign of the covariance. */
+    String RTKLIB_SDNE = "sdne";
+    /**
+     * The absolute value of sdeu means square root of the absolute value of EU component of the estimated covariance matrix.
+     * The sign represents the sign of the covariance. */
+    String RTKLIB_SDEU = "sdeu";
+    /**
+     * The absolute value of sdun means square root of the absolute value of UN component of the estimated covariance matrix.
+     * The sign represents the sign of the covariance. */
+    String RTKLIB_SDUN = "sdun";
+    /** The time difference between the observation data epochs of the rover receiver and the base station in second. */
+    String RTKLIB_AGE = "age";
+    /**
+     * The ratio factor of ʺratio‐testʺ for standard integer ambiguity validation strategy.
+     * The value means the ratio of the squared sum of the residuals with the second best integer vector to with the best integer vector. */
+    String RTKLIB_RATIO = "ration";
 }
Index: trunk/src/org/openstreetmap/josm/gui/io/importexport/RtkLibImporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/io/importexport/RtkLibImporter.java	(revision 15247)
+++ trunk/src/org/openstreetmap/josm/gui/io/importexport/RtkLibImporter.java	(revision 15247)
@@ -0,0 +1,114 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.io.importexport;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.swing.JOptionPane;
+import javax.swing.SwingUtilities;
+
+import org.openstreetmap.josm.actions.ExtensionFileFilter;
+import org.openstreetmap.josm.gui.HelpAwareOptionPane;
+import org.openstreetmap.josm.gui.MainApplication;
+import org.openstreetmap.josm.gui.Notification;
+import org.openstreetmap.josm.gui.io.importexport.GpxImporter.GpxImporterData;
+import org.openstreetmap.josm.gui.layer.GpxLayer;
+import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.gui.util.GuiHelper;
+import org.openstreetmap.josm.io.Compression;
+import org.openstreetmap.josm.io.rtklib.RtkLibPosReader;
+import org.openstreetmap.josm.spi.preferences.Config;
+import org.xml.sax.SAXException;
+
+/**
+ * File importer allowing to import RTKLib files (*.pos files).
+ * @since 15247
+ */
+public class RtkLibImporter extends FileImporter {
+
+    /**
+     * The RtkLib file filter (*.pos files).
+     */
+    public static final ExtensionFileFilter FILE_FILTER = ExtensionFileFilter.newFilterWithArchiveExtensions(
+            "pos", "pos", tr("RTKLib Positioning Solution Files"), false);
+
+    /**
+     * Constructs a new {@code RtkLibImporter}.
+     */
+    public RtkLibImporter() {
+        super(FILE_FILTER);
+    }
+
+    @Override
+    public void importData(File file, ProgressMonitor progressMonitor) throws IOException {
+        final String fn = file.getName();
+        try (InputStream fis = Compression.getUncompressedFileInputStream(file)) {
+            final RtkLibPosReader r = buildAndParse(fis);
+            if (r.getNumberOfCoordinates() > 0) {
+                r.getGpxData().storageFile = file;
+                final GpxLayer gpxLayer = new GpxLayer(r.getGpxData(), fn, true);
+                final File fileFinal = file;
+
+                GuiHelper.runInEDT(() -> {
+                    MainApplication.getLayerManager().addLayer(gpxLayer);
+                    if (Config.getPref().getBoolean("marker.makeautomarkers", true)) {
+                        MarkerLayer ml = new MarkerLayer(r.getGpxData(), tr("Markers from {0}", fn), fileFinal, gpxLayer);
+                        if (!ml.data.isEmpty()) {
+                            MainApplication.getLayerManager().addLayer(ml);
+                        }
+                    }
+                });
+            }
+            showRtkLibInfobox(r.getNumberOfCoordinates() > 0, r);
+        }
+    }
+
+    private static void showRtkLibInfobox(boolean success, RtkLibPosReader r) {
+        final StringBuilder msg = new StringBuilder(160).append("<html>")
+           .append(tr("Coordinates imported: {0}", r.getNumberOfCoordinates()))
+           .append("</html>");
+        if (success) {
+            SwingUtilities.invokeLater(() -> new Notification(
+                    "<h3>" + tr("RTKLib import success:") + "</h3>" + msg.toString())
+                    .setIcon(JOptionPane.INFORMATION_MESSAGE)
+                    .show());
+        } else {
+            HelpAwareOptionPane.showMessageDialogInEDT(
+                    MainApplication.getMainFrame(),
+                    msg.toString(),
+                    tr("RTKLib import failure!"),
+                    JOptionPane.ERROR_MESSAGE, null);
+        }
+    }
+
+    /**
+     * Replies the new GPX and marker layers corresponding to the specified RTKLib file.
+     * @param is input stream to RTKLib data
+     * @param associatedFile RTKLib file
+     * @param gpxLayerName The GPX layer name
+     * @param markerLayerName The marker layer name
+     * @return the new GPX and marker layers corresponding to the specified RTKLib file
+     * @throws IOException if an I/O error occurs
+     */
+    public static GpxImporterData loadLayers(InputStream is, final File associatedFile,
+            final String gpxLayerName, String markerLayerName) throws IOException {
+        final RtkLibPosReader r = buildAndParse(is);
+        final boolean parsedProperly = r.getNumberOfCoordinates() > 0;
+        r.getGpxData().storageFile = associatedFile;
+        return GpxImporter.loadLayers(r.getGpxData(), parsedProperly, gpxLayerName, markerLayerName);
+    }
+
+    static RtkLibPosReader buildAndParse(InputStream fis) throws IOException {
+        final RtkLibPosReader r = new RtkLibPosReader(fis);
+        try {
+            r.parse(true);
+        } catch (SAXException e) {
+            throw new IOException(e);
+        }
+        return r;
+    }
+}
Index: trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java	(revision 15246)
+++ trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java	(revision 15247)
@@ -79,4 +79,5 @@
 import org.openstreetmap.josm.gui.io.importexport.JpgImporter;
 import org.openstreetmap.josm.gui.io.importexport.NMEAImporter;
+import org.openstreetmap.josm.gui.io.importexport.RtkLibImporter;
 import org.openstreetmap.josm.gui.layer.GpxLayer;
 import org.openstreetmap.josm.gui.layer.Layer;
@@ -267,5 +268,6 @@
             ExtensionFileFilter gpxFilter = GpxImporter.getFileFilter();
             AbstractFileChooser fc = new FileChooserManager(true, null).createFileChooser(false, null,
-                    Arrays.asList(gpxFilter, NMEAImporter.FILE_FILTER), gpxFilter, JFileChooser.FILES_ONLY).openFileChooser();
+                    Arrays.asList(gpxFilter, NMEAImporter.FILE_FILTER, RtkLibImporter.FILE_FILTER), gpxFilter, JFileChooser.FILES_ONLY)
+                    .openFileChooser();
             if (fc == null)
                 return;
Index: trunk/src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java	(revision 15246)
+++ trunk/src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java	(revision 15247)
@@ -126,4 +126,5 @@
     /** Colors (without custom alpha channel, if given) for HDOP painting. **/
     private ColorScale hdopScale;
+    private ColorScale qualityScale;
     private ColorScale dateScale;
     private ColorScale directionScale;
@@ -177,4 +178,13 @@
     private static Color[] heatMapLutColorJosmRed2Blue = createColorFromResource("red2blue");
 
+    private static Color[] rtkLibQualityColors = new Color[] {
+        Color.GREEN, // Fixed, solution by carrier‐based relative positioning and the integer ambiguity is properly resolved.
+        Color.ORANGE, // Float, solution by carrier‐based relative positioning but the integer ambiguity is not resolved.
+        Color.PINK, // Reserved
+        Color.BLUE, // DGPS, solution by code‐based DGPS solutions or single point positioning with SBAS corrections
+        Color.RED, // Single, solution by single point positioning
+        Color.CYAN // PPP
+    };
+
     // user defined heatmap color
     private Color[] heatMapLutColor = createColorLut(0, Color.BLACK, Color.WHITE);
@@ -188,4 +198,5 @@
         /** Colors (without custom alpha channel, if given) for HDOP painting. **/
         hdopScale = ColorScale.createHSBScale(256).makeReversed().addTitle(tr("HDOP"));
+        qualityScale = ColorScale.createFixedScale(rtkLibQualityColors).addTitle(tr("Quality"));
         dateScale = ColorScale.createHSBScale(256).addTitle(tr("Time"));
         directionScale = ColorScale.createCyclicScale(256).setIntervalCount(4).addTitle(tr("Direction"));
@@ -228,5 +239,9 @@
          * Color using a heatmap instead of normal lines
          */
-        HEATMAP;
+        HEATMAP,
+        /**
+         * Color by quality (RTKLib)
+         */
+        QUALITY;
 
         static ColorMode fromIndex(final int index) {
@@ -343,4 +358,5 @@
         dateScale.setNoDataColor(neutralColor);
         hdopScale.setNoDataColor(neutralColor);
+        qualityScale.setNoDataColor(neutralColor);
         directionScale.setNoDataColor(neutralColor);
 
@@ -557,4 +573,5 @@
             velocityScale.setRange(0, colorTracksTune);
             hdopScale.setRange(0, hdoprange);
+            qualityScale.setRange(1, rtkLibQualityColors.length);
         }
         double now = System.currentTimeMillis()/1000.0;
@@ -586,6 +603,7 @@
 
                 if (colored == ColorMode.HDOP) {
-                    Float hdop = (Float) trkPnt.get(GpxConstants.PT_HDOP);
-                    color = hdopScale.getColor(hdop);
+                    color = hdopScale.getColor((Float) trkPnt.get(GpxConstants.PT_HDOP));
+                } else if (colored == ColorMode.QUALITY) {
+                    color = qualityScale.getColor((Integer) trkPnt.get(GpxConstants.RTKLIB_Q));
                 }
                 if (oldWp != null) { // other coloring modes need segment for calcuation
@@ -1506,4 +1524,6 @@
         if (colored == ColorMode.HDOP) {
             hdopScale.drawColorBar(g, w-30, 50, 20, 100, 1.0);
+        } else if (colored == ColorMode.QUALITY) {
+            qualityScale.drawColorBar(g, w-30, 50, 20, 100, 1.0);
         } else if (colored == ColorMode.VELOCITY) {
             SystemOfMeasurement som = SystemOfMeasurement.getSystemOfMeasurement();
Index: trunk/src/org/openstreetmap/josm/gui/preferences/display/GPXSettingsPanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/display/GPXSettingsPanel.java	(revision 15246)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/display/GPXSettingsPanel.java	(revision 15247)
@@ -65,4 +65,5 @@
     private final JRadioButton colorTypeDirection = new JRadioButton(tr("Direction (red = west, yellow = north, green = east, blue = south)"));
     private final JRadioButton colorTypeDilution = new JRadioButton(tr("Dilution of Position (red = high, green = low, if available)"));
+    private final JRadioButton colorTypeQuality = new JRadioButton(tr("Quality (RTKLib only, if available)"));
     private final JRadioButton colorTypeTime = new JRadioButton(tr("Track date"));
     private final JRadioButton colorTypeHeatMap = new JRadioButton(tr("Heat Map (dark = few, bright = many)"));
@@ -249,4 +250,5 @@
         colorGroup.add(colorTypeDirection);
         colorGroup.add(colorTypeDilution);
+        colorGroup.add(colorTypeQuality);
         colorGroup.add(colorTypeTime);
         colorGroup.add(colorTypeHeatMap);
@@ -257,4 +259,6 @@
         colorTypeDilution.setToolTipText(
                 tr("Colors points and track segments by dilution of position (HDOP). Your capture device needs to log that information."));
+        colorTypeQuality.setToolTipText(
+                tr("Colors points and track segments by RTKLib quality flag (Q). Your capture device needs to log that information."));
         colorTypeTime.setToolTipText(tr("Colors points and track segments by its timestamp."));
         colorTypeHeatMap.setToolTipText(tr("Collected points and track segments for a position and displayed as heat map."));
@@ -277,4 +281,5 @@
         add(colorTypeDirection, GBC.eol().insets(40, 0, 0, 0));
         add(colorTypeDilution, GBC.eol().insets(40, 0, 0, 0));
+        add(colorTypeQuality, GBC.eol().insets(40, 0, 0, 0));
         add(colorTypeTime, GBC.eol().insets(40, 0, 0, 0));
         add(colorTypeHeatMap, GBC.std().insets(40, 0, 0, 0));
@@ -341,4 +346,5 @@
         ExpertToggleAction.addVisibilitySwitcher(colorTypeDirection);
         ExpertToggleAction.addVisibilitySwitcher(colorTypeDilution);
+        ExpertToggleAction.addVisibilitySwitcher(colorTypeQuality);
         ExpertToggleAction.addVisibilitySwitcher(colorTypeHeatMapLowerLimit);
         ExpertToggleAction.addVisibilitySwitcher(colorTypeHeatMapLowerLimitLabel);
@@ -445,4 +451,5 @@
             case 4: colorTypeTime.setSelected(true); break;
             case 5: colorTypeHeatMap.setSelected(true); break;
+            case 6: colorTypeQuality.setSelected(true); break;
             default: Logging.warn("Unknown color type: " + colorType);
             }
@@ -525,4 +532,6 @@
         } else if (colorTypeHeatMap.isSelected()) {
             Config.getPref().putInt("draw.rawgps.colors"+layerNameDot, 5);
+        } else if (colorTypeQuality.isSelected()) {
+            Config.getPref().putInt("draw.rawgps.colors"+layerNameDot, 6);
         } else {
             Config.getPref().putInt("draw.rawgps.colors"+layerNameDot, 0);
Index: trunk/src/org/openstreetmap/josm/io/OsmServerLocationReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmServerLocationReader.java	(revision 15246)
+++ trunk/src/org/openstreetmap/josm/io/OsmServerLocationReader.java	(revision 15247)
@@ -62,5 +62,7 @@
         TASKING_MANAGER("https?://.*/api/v\\p{Digit}+/project/\\p{Digit}+/tasks_as_gpx?.*"),
 
+        /** External GPX script */
         EXTERNAL_GPX_SCRIPT("https?://.*exportgpx.*"),
+        /** External GPX file */
         EXTERNAL_GPX_FILE  ("https?://.*/(.*\\.gpx)");
 
@@ -116,4 +118,13 @@
     public OsmServerLocationReader(String url) {
         this.url = url;
+    }
+
+    /**
+     * Returns the URL to fetch
+     * @return the URL to fetch
+     * @since 15247
+     */
+    public final String getUrl() {
+        return url;
     }
 
Index: trunk/src/org/openstreetmap/josm/io/nmea/NmeaReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/nmea/NmeaReader.java	(revision 15246)
+++ trunk/src/org/openstreetmap/josm/io/nmea/NmeaReader.java	(revision 15247)
@@ -213,4 +213,8 @@
     }
 
+    /**
+     * Returns the number of coordinates that have been successfuly read.
+     * @return the number of coordinates that have been successfuly read
+     */
     public int getNumberOfCoordinates() {
         return ps.success;
Index: trunk/src/org/openstreetmap/josm/io/rtklib/RtkLibPosReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/rtklib/RtkLibPosReader.java	(revision 15247)
+++ trunk/src/org/openstreetmap/josm/io/rtklib/RtkLibPosReader.java	(revision 15247)
@@ -0,0 +1,124 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.io.rtklib;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Locale;
+import java.util.Objects;
+
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.gpx.GpxConstants;
+import org.openstreetmap.josm.data.gpx.GpxData;
+import org.openstreetmap.josm.data.gpx.ImmutableGpxTrack;
+import org.openstreetmap.josm.data.gpx.WayPoint;
+import org.openstreetmap.josm.io.IGpxReader;
+import org.openstreetmap.josm.tools.Logging;
+import org.xml.sax.SAXException;
+
+/**
+ * Reads a RTKLib Positioning Solution file.
+ * <p>
+ * See <a href="https://github.com/tomojitakasu/RTKLIB/blob/rtklib_2.4.3/doc/manual_2.4.2.pdf">RTKLIB Manual</a>.
+ * @since 15247
+ */
+public class RtkLibPosReader implements IGpxReader {
+
+    private static final int IDX_DATE = 0;
+    private static final int IDX_TIME = 1;
+    private static final int IDX_LAT = 2;
+    private static final int IDX_LON = 3;
+    private static final int IDX_HEIGHT = 4;
+    private static final int IDX_Q = 5;
+    private static final int IDX_NS = 6;
+    private static final int IDX_SDN = 7;
+    private static final int IDX_SDE = 8;
+    private static final int IDX_SDU = 9;
+    private static final int IDX_SDNE = 10;
+    private static final int IDX_SDEU = 11;
+    private static final int IDX_SDUN = 12;
+    private static final int IDX_AGE = 13;
+    private static final int IDX_RATIO = 14;
+
+    private final SimpleDateFormat dateTimeFmt = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS", Locale.ENGLISH); // 2019/06/08 08:23:15.000
+
+    private final InputStream source;
+    private GpxData data;
+    private int success; // number of successfully parsed lines
+
+    /**
+     * Constructs a new {@code RtkLibPosReader}
+     * @param source RTKLib .pos file input stream
+     * @throws IOException if an I/O error occurs
+     */
+    public RtkLibPosReader(InputStream source) throws IOException {
+        this.source = Objects.requireNonNull(source);
+    }
+
+    @Override
+    public boolean parse(boolean tryToFinish) throws SAXException, IOException {
+        data = new GpxData();
+        Collection<Collection<WayPoint>> currentTrack = new ArrayList<>();
+        Collection<WayPoint> waypoints = new ArrayList<>();
+        try (BufferedReader rd = new BufferedReader(new InputStreamReader(source, StandardCharsets.UTF_8))) {
+            String line = null;
+            do {
+                line = rd.readLine();
+                if (line != null) {
+                    if (line.startsWith("% ref pos   :")) {
+                        // TODO add marker
+                    } else if (!line.startsWith("%")) {
+                        try {
+                            String[] fields = line.split("[ ]+");
+                            WayPoint currentwp = new WayPoint(new LatLon(
+                                    Double.parseDouble(fields[IDX_LAT]),
+                                    Double.parseDouble(fields[IDX_LON])));
+                            currentwp.put(GpxConstants.PT_ELE, fields[IDX_HEIGHT]);
+                            currentwp.setTime(dateTimeFmt.parse(fields[IDX_DATE]+" "+fields[IDX_TIME]));
+                            currentwp.put(GpxConstants.RTKLIB_Q, Integer.parseInt(fields[IDX_Q]));
+                            currentwp.put(GpxConstants.PT_SAT, fields[IDX_NS]);
+                            currentwp.put(GpxConstants.RTKLIB_SDN, fields[IDX_SDN]);
+                            currentwp.put(GpxConstants.RTKLIB_SDE, fields[IDX_SDE]);
+                            currentwp.put(GpxConstants.RTKLIB_SDE, fields[IDX_SDU]);
+                            currentwp.put(GpxConstants.RTKLIB_SDNE, fields[IDX_SDNE]);
+                            currentwp.put(GpxConstants.RTKLIB_SDEU, fields[IDX_SDEU]);
+                            currentwp.put(GpxConstants.RTKLIB_SDUN, fields[IDX_SDUN]);
+                            currentwp.put(GpxConstants.RTKLIB_AGE, fields[IDX_AGE]);
+                            currentwp.put(GpxConstants.RTKLIB_RATIO, fields[IDX_RATIO]);
+                            double sdn = Double.parseDouble(fields[IDX_SDN]);
+                            double sde = Double.parseDouble(fields[IDX_SDN]);
+                            currentwp.put(GpxConstants.PT_HDOP, (float) Math.sqrt(sdn*sdn + sde*sde));
+                            waypoints.add(currentwp);
+                            success++;
+                        } catch (ParseException | IllegalArgumentException e) {
+                            Logging.error(e);
+                        }
+                    }
+                }
+            } while (line != null);
+        }
+        currentTrack.add(waypoints);
+        data.tracks.add(new ImmutableGpxTrack(currentTrack, Collections.<String, Object>emptyMap()));
+        return true;
+    }
+
+    @Override
+    public GpxData getGpxData() {
+        return data;
+    }
+
+    /**
+     * Returns the number of coordinates that have been successfuly read.
+     * @return the number of coordinates that have been successfuly read
+     */
+    public int getNumberOfCoordinates() {
+        return success;
+    }
+}
Index: trunk/src/org/openstreetmap/josm/io/rtklib/package-info.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/rtklib/package-info.java	(revision 15247)
+++ trunk/src/org/openstreetmap/josm/io/rtklib/package-info.java	(revision 15247)
@@ -0,0 +1,9 @@
+// License: GPL. For details, see LICENSE file.
+
+/**
+ * Provides the classes for reading RTKLib Positioning Solution files.
+ * <p>
+ * See <a href="https://github.com/tomojitakasu/RTKLIB/blob/rtklib_2.4.3/doc/manual_2.4.2.pdf">RTKLIB Manual</a>.
+ * @since 15247
+ */
+package org.openstreetmap.josm.io.rtklib;
Index: trunk/src/org/openstreetmap/josm/io/session/GpxTracksSessionImporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/session/GpxTracksSessionImporter.java	(revision 15246)
+++ trunk/src/org/openstreetmap/josm/io/session/GpxTracksSessionImporter.java	(revision 15247)
@@ -15,4 +15,5 @@
 import org.openstreetmap.josm.gui.io.importexport.GpxImporter;
 import org.openstreetmap.josm.gui.io.importexport.NMEAImporter;
+import org.openstreetmap.josm.gui.io.importexport.RtkLibImporter;
 import org.openstreetmap.josm.gui.layer.GpxLayer;
 import org.openstreetmap.josm.gui.layer.Layer;
@@ -48,4 +49,6 @@
                 if (NMEAImporter.FILE_FILTER.acceptName(fileStr)) {
                     importData = NMEAImporter.loadLayers(in, support.getFile(fileStr), support.getLayerName(), null);
+                } else if (RtkLibImporter.FILE_FILTER.acceptName(fileStr)) {
+                    importData = RtkLibImporter.loadLayers(in, support.getFile(fileStr), support.getLayerName(), null);
                 } else {
                     importData = GpxImporter.loadLayers(in, support.getFile(fileStr), support.getLayerName(), null, progressMonitor);
Index: trunk/src/org/openstreetmap/josm/tools/ColorScale.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/ColorScale.java	(revision 15246)
+++ trunk/src/org/openstreetmap/josm/tools/ColorScale.java	(revision 15247)
@@ -22,4 +22,18 @@
     private ColorScale() {
 
+    }
+
+    /**
+     * Gets a fixed color range.
+     * @param colors the fixed colors list
+     * @return The scale
+     * @since 15247
+     */
+    public static ColorScale createFixedScale(Color[] colors) {
+        ColorScale sc = new ColorScale();
+        sc.colors = Utils.copyArray(colors);
+        sc.setRange(0, colors.length - 1);
+        sc.addBounds();
+        return sc;
     }
 
