Changeset 18078 in josm for trunk/src/org/openstreetmap


Ignore:
Timestamp:
2021-07-20T19:23:32+02:00 (3 years ago)
Author:
Don-vip
Message:

see #21144 - Images correlation: temporary editable support layer to interpolate location of non-geotagged images

Location:
trunk/src/org/openstreetmap/josm
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java

    r18008 r18078  
    3434import org.openstreetmap.josm.data.gpx.GpxConstants;
    3535import org.openstreetmap.josm.data.gpx.GpxData;
     36import org.openstreetmap.josm.data.gpx.GpxDataContainer;
    3637import org.openstreetmap.josm.data.gpx.GpxData.GpxDataChangeListener;
    3738import org.openstreetmap.josm.data.gpx.IGpxTrack;
     
    6768 * A layer that displays data from a Gpx file / the OSM gpx downloads.
    6869 */
    69 public class GpxLayer extends AbstractModifiableLayer implements ExpertModeChangeListener, JumpToMarkerLayer {
     70public class GpxLayer extends AbstractModifiableLayer implements GpxDataContainer, ExpertModeChangeListener, JumpToMarkerLayer {
    7071
    7172    /** GPX data */
     
    575576    }
    576577
     578    @Override
     579    public GpxData getGpxData() {
     580        return data;
     581    }
     582
    577583    /**
    578584     * Jump (move the viewport) to the next track segment.
  • trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java

    r17863 r18078  
    762762    public static GpxData toGpxData(DataSet data, File file) {
    763763        GpxData gpxData = new GpxData();
     764        fillGpxData(gpxData, data, file, GpxConstants.GPX_PREFIX);
     765        return gpxData;
     766    }
     767
     768    protected static void fillGpxData(GpxData gpxData, DataSet data, File file, String gpxPrefix) {
    764769        if (data.getGPXNamespaces() != null) {
    765770            gpxData.getNamespaces().addAll(data.getGPXNamespaces());
     
    767772        gpxData.storageFile = file;
    768773        Set<Node> doneNodes = new HashSet<>();
    769         waysToGpxData(data.getWays(), gpxData, doneNodes);
    770         nodesToGpxData(data.getNodes(), gpxData, doneNodes);
    771         return gpxData;
    772     }
    773 
    774     private static void waysToGpxData(Collection<Way> ways, GpxData gpxData, Set<Node> doneNodes) {
     774        waysToGpxData(data.getWays(), gpxData, doneNodes, gpxPrefix);
     775        nodesToGpxData(data.getNodes(), gpxData, doneNodes, gpxPrefix);
     776    }
     777
     778    private static void waysToGpxData(Collection<Way> ways, GpxData gpxData, Set<Node> doneNodes, String gpxPrefix) {
    775779        /* When the dataset has been obtained from a gpx layer and now is being converted back,
    776780         * the ways have negative ids. The first created way corresponds to the first gpx segment,
     
    791795            GpxExtensionCollection segExts = new GpxExtensionCollection();
    792796            for (Entry<String, String> e : w.getKeys().entrySet()) {
    793                 String k = e.getKey().startsWith(GpxConstants.GPX_PREFIX) ? e.getKey().substring(GpxConstants.GPX_PREFIX.length()) : e.getKey();
     797                String k = e.getKey().startsWith(gpxPrefix) ? e.getKey().substring(gpxPrefix.length()) : e.getKey();
    794798                String v = e.getValue();
    795799                if (GpxConstants.RTE_TRK_KEYS.contains(k)) {
     
    799803                            .stream()
    800804                            .filter(s -> s.getValue().equals(e.getKey()))
    801                             .map(s -> s.getKey().substring(GpxConstants.GPX_PREFIX.length()))
     805                            .map(s -> s.getKey().substring(gpxPrefix.length()))
    802806                            .findAny()
    803807                            .orElse(k);
     
    822826                    continue;
    823827                }
    824                 if (!n.isTagged() || containsOnlyGpxTags(n)) {
     828                if (!n.isTagged() || containsOnlyGpxTags(n, gpxPrefix)) {
    825829                    doneNodes.add(n);
    826830                }
    827                 trkseg.add(nodeToWayPoint(n));
     831                trkseg.add(nodeToWayPoint(n, Long.MIN_VALUE, gpxPrefix));
    828832            }
    829833            trk.add(new GpxTrackSegment(trkseg));
     
    835839    }
    836840
    837     private static boolean containsOnlyGpxTags(Tagged t) {
     841    private static boolean containsOnlyGpxTags(Tagged t, String gpxPrefix) {
    838842        return t.keys()
    839                 .allMatch(key -> GpxConstants.WPT_KEYS.contains(key) || key.startsWith(GpxConstants.GPX_PREFIX));
     843                .allMatch(key -> GpxConstants.WPT_KEYS.contains(key) || key.startsWith(gpxPrefix));
    840844    }
    841845
     
    843847     * Reads the Gpx key from the given {@link OsmPrimitive}, with or without &quot;gpx:&quot; prefix
    844848     * @param prim OSM primitive
     849     * @param gpxPrefix the GPX prefix
    845850     * @param key GPX key without prefix
    846851     * @return the value or <code>null</code> if not present
    847      * @since 15419
    848      */
    849     public static String gpxVal(OsmPrimitive prim, String key) {
    850         String val = prim.get(GpxConstants.GPX_PREFIX + key);
     852     */
     853    private static String gpxVal(OsmPrimitive prim, String gpxPrefix, String key) {
     854        String val = prim.get(gpxPrefix + key);
    851855        return val != null ? val : prim.get(key);
    852856    }
    853857
    854858    /**
    855      * Converts a node to a waypoint.
    856      * @param n the {@code Node} to convert
    857      * @return {@code WayPoint} object
    858      * @since 13210
    859      */
    860     public static WayPoint nodeToWayPoint(Node n) {
    861         return nodeToWayPoint(n, Long.MIN_VALUE);
    862     }
    863 
    864     /**
    865      * Converts a node to a waypoint.
     859     * Converts a node to a waypoint with default {@link GpxConstants#GPX_PREFIX} for tags.
    866860     * @param n the {@code Node} to convert
    867861     * @param time a timestamp value in milliseconds from the epoch.
     
    870864     */
    871865    public static WayPoint nodeToWayPoint(Node n, long time) {
     866        return nodeToWayPoint(n, time, GpxConstants.GPX_PREFIX);
     867    }
     868
     869    /**
     870     * Converts a node to a waypoint with a configurable GPX prefix for tags.
     871     * @param n the {@code Node} to convert
     872     * @param time a timestamp value in milliseconds from the epoch.
     873     * @param gpxPrefix the GPX prefix for tags
     874     * @return {@code WayPoint} object
     875     * @since 18078
     876     */
     877    public static WayPoint nodeToWayPoint(Node n, long time, String gpxPrefix) {
    872878        WayPoint wpt = new WayPoint(n.getCoor());
    873879
    874880        // Position info
    875881
    876         addDoubleIfPresent(wpt, n, GpxConstants.PT_ELE, null);
     882        addDoubleIfPresent(wpt, n, gpxPrefix, GpxConstants.PT_ELE, null);
    877883
    878884        try {
     
    880886            if (time > Long.MIN_VALUE) {
    881887                wpt.setTimeInMillis(time);
    882             } else if ((v = gpxVal(n, GpxConstants.PT_TIME)) != null) {
     888            } else if ((v = gpxVal(n, gpxPrefix, GpxConstants.PT_TIME)) != null) {
    883889                wpt.setInstant(DateUtils.parseInstant(v));
    884890            } else if (!n.isTimestampEmpty()) {
     
    889895        }
    890896
    891         addDoubleIfPresent(wpt, n, GpxConstants.PT_MAGVAR, null);
    892         addDoubleIfPresent(wpt, n, GpxConstants.PT_GEOIDHEIGHT, null);
     897        addDoubleIfPresent(wpt, n, gpxPrefix, GpxConstants.PT_MAGVAR, null);
     898        addDoubleIfPresent(wpt, n, gpxPrefix, GpxConstants.PT_GEOIDHEIGHT, null);
    893899
    894900        // Description info
    895901
    896         addStringIfPresent(wpt, n, GpxConstants.GPX_NAME, null, null);
    897         addStringIfPresent(wpt, n, GpxConstants.GPX_DESC, "description", null);
    898         addStringIfPresent(wpt, n, GpxConstants.GPX_CMT, "comment", null);
    899         addStringIfPresent(wpt, n, GpxConstants.GPX_SRC, "source", "source:position");
     902        addStringIfPresent(wpt, n, gpxPrefix, GpxConstants.GPX_NAME, null, null);
     903        addStringIfPresent(wpt, n, gpxPrefix, GpxConstants.GPX_DESC, "description", null);
     904        addStringIfPresent(wpt, n, gpxPrefix, GpxConstants.GPX_CMT, "comment", null);
     905        addStringIfPresent(wpt, n, gpxPrefix, GpxConstants.GPX_SRC, "source", "source:position");
    900906
    901907        Collection<GpxLink> links = Stream.of("link", "url", "website", "contact:website")
    902                 .map(key -> gpxVal(n, key))
     908                .map(key -> gpxVal(n, gpxPrefix, key))
    903909                .filter(Objects::nonNull)
    904910                .map(GpxLink::new)
     
    906912        wpt.put(GpxConstants.META_LINKS, links);
    907913
    908         addStringIfPresent(wpt, n, GpxConstants.PT_SYM, "wpt_symbol", null);
    909         addStringIfPresent(wpt, n, GpxConstants.PT_TYPE, null, null);
     914        addStringIfPresent(wpt, n, gpxPrefix, GpxConstants.PT_SYM, "wpt_symbol", null);
     915        addStringIfPresent(wpt, n, gpxPrefix, GpxConstants.PT_TYPE, null, null);
    910916
    911917        // Accuracy info
    912         addStringIfPresent(wpt, n, GpxConstants.PT_FIX, "gps:fix", null);
    913         addIntegerIfPresent(wpt, n, GpxConstants.PT_SAT, "gps:sat");
    914         addDoubleIfPresent(wpt, n, GpxConstants.PT_HDOP, "gps:hdop");
    915         addDoubleIfPresent(wpt, n, GpxConstants.PT_VDOP, "gps:vdop");
    916         addDoubleIfPresent(wpt, n, GpxConstants.PT_PDOP, "gps:pdop");
    917         addDoubleIfPresent(wpt, n, GpxConstants.PT_AGEOFDGPSDATA, "gps:ageofdgpsdata");
    918         addIntegerIfPresent(wpt, n, GpxConstants.PT_DGPSID, "gps:dgpsid");
     918        addStringIfPresent(wpt, n, gpxPrefix, GpxConstants.PT_FIX, "gps:fix", null);
     919        addIntegerIfPresent(wpt, n, gpxPrefix, GpxConstants.PT_SAT, "gps:sat");
     920        addDoubleIfPresent(wpt, n, gpxPrefix, GpxConstants.PT_HDOP, "gps:hdop");
     921        addDoubleIfPresent(wpt, n, gpxPrefix, GpxConstants.PT_VDOP, "gps:vdop");
     922        addDoubleIfPresent(wpt, n, gpxPrefix, GpxConstants.PT_PDOP, "gps:pdop");
     923        addDoubleIfPresent(wpt, n, gpxPrefix, GpxConstants.PT_AGEOFDGPSDATA, "gps:ageofdgpsdata");
     924        addIntegerIfPresent(wpt, n, gpxPrefix, GpxConstants.PT_DGPSID, "gps:dgpsid");
    919925
    920926        return wpt;
    921927    }
    922928
    923     private static void nodesToGpxData(Collection<Node> nodes, GpxData gpxData, Set<Node> doneNodes) {
     929    private static void nodesToGpxData(Collection<Node> nodes, GpxData gpxData, Set<Node> doneNodes, String gpxPrefix) {
    924930        List<Node> sortedNodes = new ArrayList<>(nodes);
    925931        sortedNodes.removeAll(doneNodes);
     
    929935                continue;
    930936            }
    931             gpxData.waypoints.add(nodeToWayPoint(n));
    932         }
    933     }
    934 
    935     private static void addIntegerIfPresent(WayPoint wpt, OsmPrimitive p, String gpxKey, String osmKey) {
    936         String value = gpxVal(p, gpxKey);
     937            gpxData.waypoints.add(nodeToWayPoint(n, Long.MIN_VALUE, gpxPrefix));
     938        }
     939    }
     940
     941    private static void addIntegerIfPresent(WayPoint wpt, OsmPrimitive p, String gpxPrefix, String gpxKey, String osmKey) {
     942        String value = gpxVal(p, gpxPrefix, gpxKey);
    937943        if (value == null && osmKey != null) {
    938             value = gpxVal(p, osmKey);
     944            value = gpxVal(p, gpxPrefix, osmKey);
    939945        }
    940946        if (value != null) {
     
    952958    }
    953959
    954     private static void addDoubleIfPresent(WayPoint wpt, OsmPrimitive p, String gpxKey, String osmKey) {
    955         String value = gpxVal(p, gpxKey);
     960    private static void addDoubleIfPresent(WayPoint wpt, OsmPrimitive p, String gpxPrefix, String gpxKey, String osmKey) {
     961        String value = gpxVal(p, gpxPrefix, gpxKey);
    956962        if (value == null && osmKey != null) {
    957             value = gpxVal(p, osmKey);
     963            value = gpxVal(p, gpxPrefix, osmKey);
    958964        }
    959965        if (value != null) {
     
    970976    }
    971977
    972     private static void addStringIfPresent(WayPoint wpt, OsmPrimitive p, String gpxKey, String osmKey, String osmKey2) {
    973         String value = gpxVal(p, gpxKey);
     978    private static void addStringIfPresent(WayPoint wpt, OsmPrimitive p, String gpxPrefix, String gpxKey, String osmKey, String osmKey2) {
     979        String value = gpxVal(p, gpxPrefix, gpxKey);
    974980        if (value == null && osmKey != null) {
    975             value = gpxVal(p, osmKey);
     981            value = gpxVal(p, gpxPrefix, osmKey);
    976982        }
    977983        if (value == null && osmKey2 != null) {
    978             value = gpxVal(p, osmKey2);
     984            value = gpxVal(p, gpxPrefix, osmKey2);
    979985        }
    980986        // Sanity checks
  • trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java

    r18065 r18078  
    4949import org.openstreetmap.josm.actions.ExpertToggleAction.ExpertModeChangeListener;
    5050import org.openstreetmap.josm.data.gpx.GpxData;
     51import org.openstreetmap.josm.data.gpx.GpxData.GpxDataChangeEvent;
     52import org.openstreetmap.josm.data.gpx.GpxData.GpxDataChangeListener;
     53import org.openstreetmap.josm.data.gpx.GpxDataContainer;
    5154import org.openstreetmap.josm.data.gpx.GpxImageCorrelation;
    5255import org.openstreetmap.josm.data.gpx.GpxImageCorrelationSettings;
     
    5760import org.openstreetmap.josm.gui.ExtendedDialog;
    5861import org.openstreetmap.josm.gui.MainApplication;
    59 import org.openstreetmap.josm.gui.layer.GpxLayer;
     62import org.openstreetmap.josm.gui.layer.AbstractModifiableLayer;
    6063import org.openstreetmap.josm.gui.layer.Layer;
    6164import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent;
     
    8689
    8790    private final transient GeoImageLayer yLayer;
     91    private transient CorrelationSupportLayer supportLayer;
    8892    private transient GpxTimezone timezone;
    8993    private transient GpxTimeOffset delta;
     
    153157                    yLayer.updateBufferAndRepaint();
    154158                }
     159                removeSupportLayer();
    155160                break;
    156161            case AGAIN:
     
    186191                yLayer.applyTmp();
    187192                yLayer.updateBufferAndRepaint();
     193                removeSupportLayer();
    188194
    189195                break;
     
    191197                throw new IllegalStateException(Integer.toString(result));
    192198            }
     199        }
     200    }
     201
     202    private void removeSupportLayer() {
     203        if (supportLayer != null) {
     204            MainApplication.getLayerManager().removeLayer(supportLayer);
     205            supportLayer = null;
    193206        }
    194207    }
     
    230243    private JPanel outerPanel;
    231244    private JosmComboBox<GpxDataWrapper> cbGpx;
     245    private JButton buttonSupport;
    232246    private JosmTextField tfTimezone;
    233247    private JosmTextField tfOffset;
     
    269283    }
    270284
     285    private class UseSupportLayerActionListener implements ActionListener {
     286
     287        @Override
     288        public void actionPerformed(ActionEvent e) {
     289            supportLayer = new CorrelationSupportLayer(yLayer.getFauxGpxData());
     290            supportLayer.getGpxData().addChangeListener(statusBarUpdaterWithRepaint);
     291            MainApplication.getLayerManager().addLayer(supportLayer);
     292        }
     293    }
     294
    271295    private class AdvancedSettingsActionListener implements ActionListener {
    272296
     
    331355        public void layerAdded(LayerAddEvent e) {
    332356            Layer layer = e.getAddedLayer();
    333             if (layer instanceof GpxLayer) {
    334                 GpxLayer gpx = (GpxLayer) layer;
    335                 File file = gpx.data.storageFile;
     357            if (layer instanceof GpxDataContainer) {
     358                GpxData gpx = ((GpxDataContainer) layer).getGpxData();
     359                File file = gpx.storageFile;
    336360                removeDuplicates(file);
    337                 GpxDataWrapper gdw = new GpxDataWrapper(gpx.getName(), gpx.data, file);
    338                 gpx.addPropertyChangeListener(new GpxLayerRenamedListener(gdw));
     361                GpxDataWrapper gdw = new GpxDataWrapper(layer.getName(), gpx, file);
     362                layer.addPropertyChangeListener(new GpxLayerRenamedListener(gdw));
    339363                gpxModel.addElement(gdw);
    340                 forEachLayer(CorrelateGpxWithImages::repaintCombobox);
     364                forEachLayer(correlateAction -> {
     365                    correlateAction.repaintCombobox();
     366                    if (layer.equals(correlateAction.supportLayer)) {
     367                        correlateAction.buttonSupport.setEnabled(false);
     368                    }
     369                });
    341370            }
    342371        }
     
    344373        @Override
    345374        public void layerRemoving(LayerRemoveEvent e) {
    346             // Not used
     375            Layer layer = e.getRemovedLayer();
     376            if (layer instanceof GpxDataContainer) {
     377                GpxData removedGpxData = ((GpxDataContainer) layer).getGpxData();
     378                for (int i = gpxModel.getSize() - 1; i >= 0; i--) {
     379                    if (gpxModel.getElementAt(i).data.equals(removedGpxData)) {
     380                        gpxModel.removeElementAt(i);
     381                        forEachLayer(correlateAction -> {
     382                            correlateAction.repaintCombobox();
     383                            if (layer.equals(correlateAction.supportLayer)) {
     384                                correlateAction.supportLayer.getGpxData()
     385                                    .removeChangeListener(correlateAction.statusBarUpdaterWithRepaint);
     386                                correlateAction.supportLayer = null;
     387                                correlateAction.buttonSupport.setEnabled(true);
     388                            }
     389                        });
     390                        break;
     391                    }
     392                }
     393            }
    347394        }
    348395
     
    374421        gpxModel = new DefaultComboBoxModel<>();
    375422        GpxDataWrapper defaultItem = null;
    376         for (GpxLayer cur : MainApplication.getLayerManager().getLayersOfType(GpxLayer.class)) {
    377             GpxDataWrapper gdw = new GpxDataWrapper(cur.getName(), cur.data, cur.data.storageFile);
    378             cur.addPropertyChangeListener(new GpxLayerRenamedListener(gdw));
    379             gpxModel.addElement(gdw);
    380             if (cur == yLayer.gpxLayer || defaultItem == null) {
    381                 defaultItem = gdw;
     423        for (AbstractModifiableLayer cur : MainApplication.getLayerManager().getLayersOfType(AbstractModifiableLayer.class)) {
     424            if (cur instanceof GpxDataContainer) {
     425                GpxData data = ((GpxDataContainer) cur).getGpxData();
     426                GpxDataWrapper gdw = new GpxDataWrapper(cur.getName(), data, data.storageFile);
     427                cur.addPropertyChangeListener(new GpxLayerRenamedListener(gdw));
     428                gpxModel.addElement(gdw);
     429                if (data.equals(yLayer.gpxData) || defaultItem == null) {
     430                    defaultItem = gdw;
     431                }
    382432            }
    383433        }
     
    433483        buttonOpen.addActionListener(new LoadGpxDataActionListener());
    434484        panelCb.add(buttonOpen);
     485
     486        buttonSupport = new JButton(tr("Use support layer"));
     487        buttonSupport.addActionListener(new UseSupportLayerActionListener());
     488        panelCb.add(buttonSupport);
    435489
    436490        JPanel panelTf = new JPanel(new GridBagLayout());
     
    584638        cbTaggedImg.addItemListener(statusBarUpdaterWithRepaint);
    585639        pDirectionPosition.addChangeListenerOnComponents(statusBarUpdaterWithRepaint);
     640        pDirectionPosition.addItemListenerOnComponents(statusBarUpdaterWithRepaint);
    586641
    587642        statusBarUpdater.matchAndUpdateStatusBar();
     
    612667    @Override
    613668    public void expertChanged(boolean isExpert) {
     669        if (buttonSupport != null) {
     670            buttonSupport.setVisible(isExpert);
     671        }
    614672        if (sepDirectionPosition != null) {
    615673            sepDirectionPosition.setVisible(isExpert);
     
    640698    private final transient StatusBarUpdater statusBarUpdaterWithRepaint = new StatusBarUpdater(true);
    641699
    642     private class StatusBarUpdater implements DocumentListener, ItemListener, ChangeListener, ActionListener {
     700    private class StatusBarUpdater implements DocumentListener, ItemListener, ChangeListener, ActionListener, GpxDataChangeListener {
    643701        private final boolean doRepaint;
    644702
     
    674732        @Override
    675733        public void actionPerformed(ActionEvent e) {
     734            matchAndUpdateStatusBar();
     735        }
     736
     737        @Override
     738        public void gpxDataChanged(GpxDataChangeEvent e) {
    676739            matchAndUpdateStatusBar();
    677740        }
     
    897960        }
    898961
     962        closeDialog();
     963
    899964        outerPanel = null;
    900965        tfTimezone = null;
     
    906971        sepDirectionPosition = null;
    907972        pDirectionPosition = null;
    908 
    909         closeDialog();
    910973    }
    911974}
  • trunk/src/org/openstreetmap/josm/gui/layer/geoimage/EditImagesSequenceAction.java

    r18065 r18078  
    55
    66import java.awt.event.ActionEvent;
     7import java.awt.event.ItemEvent;
     8import java.awt.event.ItemListener;
    79import java.awt.event.KeyEvent;
    810import java.util.List;
     
    4042        this.pDirectionPosition = ImageDirectionPositionPanel.forImageSequence();
    4143
     44        Updater updater = new Updater();
    4245        pDirectionPosition.addFocusListenerOnComponent(new RepaintTheMapListener(yLayer));
    43         pDirectionPosition.addChangeListenerOnComponents(new Updater());
     46        pDirectionPosition.addChangeListenerOnComponents(updater);
     47        pDirectionPosition.addItemListenerOnComponents(updater);
    4448    }
    4549
     
    5862    }
    5963
    60     class Updater implements ChangeListener {
     64    class Updater implements ChangeListener, ItemListener {
    6165
    6266        @Override
    6367        public void stateChanged(ChangeEvent e) {
     68            matchAndUpdate();
     69        }
     70
     71        @Override
     72        public void itemStateChanged(ItemEvent e) {
    6473            matchAndUpdate();
    6574        }
  • trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java

    r18068 r18078  
    6868/**
    6969 * Layer displaying geotagged pictures.
     70 * @since 99
    7071 */
    7172public class GeoImageLayer extends AbstractModifiableLayer implements
     
    7778
    7879    private final ImageData data;
    79     GpxLayer gpxLayer;
     80    GpxData gpxData;
    8081    GpxLayer gpxFauxLayer;
    8182    GpxData gpxFauxData;
     
    153154     */
    154155    public GeoImageLayer(final List<ImageEntry> data, GpxLayer gpxLayer, final String name, boolean useThumbs) {
     156        this(data, gpxLayer != null ? gpxLayer.data : null, name, useThumbs);
     157    }
     158
     159    /**
     160     * Constructs a new {@code GeoImageLayer}.
     161     * @param data The list of images to display
     162     * @param gpxData The associated GPX data
     163     * @param name Layer name
     164     * @param useThumbs Thumbnail display flag
     165     * @since 18078
     166     */
     167    public GeoImageLayer(final List<ImageEntry> data, GpxData gpxData, final String name, boolean useThumbs) {
    155168        super(name != null ? name : tr("Geotagged Images"));
    156169        this.data = new ImageData(data);
    157         this.gpxLayer = gpxLayer;
     170        this.gpxData = gpxData;
    158171        this.useThumbs = useThumbs;
    159172        this.data.addImageDataUpdateListener(this);
     
    793806
    794807    /**
    795      * Returns the associated GPX layer.
    796      * @return The associated GPX layer
     808     * Returns the associated GPX data if any.
     809     * @return The associated GPX data or {@code null}
     810     * @since 18078
     811     */
     812    public GpxData getGpxData() {
     813        return gpxData;
     814    }
     815
     816    /**
     817     * Returns the associated GPX layer if any.
     818     * @return The associated GPX layer or {@code null}
    797819     */
    798820    public GpxLayer getGpxLayer() {
    799         return gpxLayer;
     821        return gpxData != null ? MainApplication.getLayerManager().getLayersOfType(GpxLayer.class)
     822                .stream().filter(l -> gpxData.equals(l.getGpxData()))
     823                .findFirst().orElseThrow(() -> new IllegalStateException()) : null;
    800824    }
    801825
     
    817841     */
    818842    public synchronized GpxLayer getFauxGpxLayer() {
    819         if (gpxLayer != null) return getGpxLayer();
     843        GpxLayer gpxLayer = getGpxLayer();
     844        if (gpxLayer != null) return gpxLayer;
    820845        if (gpxFauxLayer == null) {
    821846            gpxFauxLayer = new GpxLayer(getFauxGpxData());
     
    830855     */
    831856    public synchronized GpxData getFauxGpxData() {
    832         if (gpxLayer != null) return getGpxLayer().data;
     857        GpxLayer gpxLayer = getGpxLayer();
     858        if (gpxLayer != null) return gpxLayer.data;
    833859        if (gpxFauxData == null) {
    834860            gpxFauxData = new GpxData();
  • trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageDirectionPositionPanel.java

    r18061 r18078  
    66import java.awt.GridBagLayout;
    77import java.awt.event.FocusListener;
     8import java.awt.event.ItemListener;
    89
    910import javax.swing.JCheckBox;
     
    103104
    104105    /**
    105      * Adds a change listener on all checkboxes and spinners of this panel.
     106     * Adds a change listener on all checkboxes of this panel.
     107     * @param listener change listener to add
     108     * @since 18078
     109     */
     110    public void addItemListenerOnComponents(ItemListener listener) {
     111        cChangeImageDirection.addItemListener(listener);
     112    }
     113
     114    /**
     115     * Adds a change listener on all spinners of this panel.
    106116     * @param listener change listener to add
    107117     */
    108118    public void addChangeListenerOnComponents(ChangeListener listener) {
    109         cChangeImageDirection.addChangeListener(listener);
    110119        sOffsetDegrees.addChangeListener(listener);
    111120        sX.addChangeListener(listener);
  • trunk/src/org/openstreetmap/josm/gui/layer/gpx/ConvertFromGpxLayerAction.java

    r17749 r18078  
    2121
    2222import org.openstreetmap.josm.data.gpx.GpxConstants;
     23import org.openstreetmap.josm.data.gpx.GpxData;
    2324import org.openstreetmap.josm.data.gpx.GpxExtension;
    2425import org.openstreetmap.josm.data.gpx.GpxExtensionCollection;
     
    5556    @Override
    5657    public DataSet convert() {
     58        return convert(layer.data, Config.getPref().get(GPX_SETTING, "ask"), GpxConstants.GPX_PREFIX);
     59    }
     60
     61    /**
     62     * Converts the given {@link GpxData} to a {@link DataSet}
     63     * @param data GPX data to convert
     64     * @param convertTags "list", "ask" or "no"
     65     * @param gpxPrefix GPX prefix for tags
     66     * @return the converted dataset
     67     * @since 18078
     68     */
     69    public static DataSet convert(GpxData data, String convertTags, String gpxPrefix) {
    5770        final DataSet ds = new DataSet();
    58         ds.setGPXNamespaces(layer.data.getNamespaces());
     71        ds.setGPXNamespaces(data.getNamespaces());
    5972
    6073        List<String> keys = new ArrayList<>(); // note that items in this list don't have the GPX_PREFIX
    61         String convertTags = Config.getPref().get(GPX_SETTING, "ask");
    6274        boolean check = "list".equals(convertTags) || "ask".equals(convertTags);
    6375        boolean none = "no".equals(convertTags); // no need to convert tags when no dialog will be shown anyways
    6476
    65         for (IGpxTrack trk : layer.data.getTracks()) {
     77        for (IGpxTrack trk : data.getTracks()) {
    6678            for (IGpxTrackSegment segment : trk.getSegments()) {
    6779                List<Node> nodes = new ArrayList<>();
    6880                for (WayPoint p : segment.getWayPoints()) {
    6981                    Node n = new Node(p.getCoor());
    70                     addAttributes(p.getAttributes(), n, keys, check, none);
     82                    addAttributes(p.getAttributes(), n, keys, check, none, gpxPrefix);
    7183                    if (!none) {
    72                         addExtensions(p.getExtensions(), n, false, keys, check);
     84                        addExtensions(p.getExtensions(), n, false, keys, check, gpxPrefix);
    7385                    }
    7486                    ds.addPrimitive(n);
     
    7789                Way w = new Way();
    7890                w.setNodes(nodes);
    79                 addAttributes(trk.getAttributes(), w, keys, check, none);
    80                 addAttributes(segment.getAttributes(), w, keys, check, none);
     91                addAttributes(trk.getAttributes(), w, keys, check, none, gpxPrefix);
     92                addAttributes(segment.getAttributes(), w, keys, check, none, gpxPrefix);
    8193                if (!none) {
    82                     addExtensions(trk.getExtensions(), w, false, keys, check);
    83                     addExtensions(segment.getExtensions(), w, true, keys, check);
     94                    addExtensions(trk.getExtensions(), w, false, keys, check, gpxPrefix);
     95                    addExtensions(segment.getExtensions(), w, true, keys, check, gpxPrefix);
    8496                }
    8597                ds.addPrimitive(w);
     
    106118                if ("no".equals(res.sel)) {
    107119                    // User just chose not to convert any tags, but that was unknown before the initial conversion
    108                     return filterDataSet(ds, null);
     120                    return filterDataSet(ds, null, gpxPrefix);
    109121                } else if ("all".equals(res.sel)) {
    110122                    return ds;
     
    112124            }
    113125            if (!listPos.containsAll(keys)) {
    114                 return filterDataSet(ds, listPos);
     126                return filterDataSet(ds, listPos, gpxPrefix);
    115127            }
    116128        }
     
    118130    }
    119131
    120     private static void addAttributes(Map<String, Object> attr, OsmPrimitive p, List<String> keys, boolean check, boolean none) {
     132    private static void addAttributes(
     133            Map<String, Object> attr, OsmPrimitive p, List<String> keys, boolean check, boolean none, String gpxPrefix) {
    121134        for (Entry<String, Object> entry : attr.entrySet()) {
    122135            String key = entry.getKey();
     
    127140            if (!none && (obj instanceof String || obj instanceof Number)) {
    128141                // only convert when required
    129                 p.put(GpxConstants.GPX_PREFIX + key, obj.toString());
     142                p.put(gpxPrefix + key, obj.toString());
    130143            } else if (obj instanceof Instant && GpxConstants.PT_TIME.equals(key)) {
    131144                // timestamps should always be converted
    132145                Instant date = (Instant) obj;
    133146                if (!none) { //... but the tag will only be set when required
    134                     p.put(GpxConstants.GPX_PREFIX + key, String.valueOf(date));
     147                    p.put(gpxPrefix + key, String.valueOf(date));
    135148                }
    136149                p.setInstant(date);
     
    139152    }
    140153
    141     private static void addExtensions(GpxExtensionCollection exts, OsmPrimitive p, boolean seg, List<String> keys, boolean check) {
     154    private static void addExtensions(
     155            GpxExtensionCollection exts, OsmPrimitive p, boolean seg, List<String> keys, boolean check, String gpxPrefix) {
    142156        for (GpxExtension ext : exts) {
    143157            String value = ext.getValue();
     
    151165                String segpre = seg ? "segment:" : "";
    152166                String key = ext.getFlatKey();
    153                 String fullkey = GpxConstants.GPX_PREFIX + extpre + pre + ":" + segpre + key;
     167                String fullkey = gpxPrefix + extpre + pre + ":" + segpre + key;
    154168                if (GpxConstants.EXTENSION_ABBREVIATIONS.containsKey(fullkey)) {
    155169                    fullkey = GpxConstants.EXTENSION_ABBREVIATIONS.get(fullkey);
     
    160174                p.put(fullkey, value);
    161175            }
    162             addExtensions(ext.getExtensions(), p, seg, keys, check);
     176            addExtensions(ext.getExtensions(), p, seg, keys, check, gpxPrefix);
    163177        }
    164178    }
     
    168182     * @param ds The {@link DataSet}
    169183     * @param listPos A {@code List<String>} containing the tags (without prefix) to be kept, can be {@code null} if all tags are to be removed
     184     * @param gpxPrefix The GPX prefix
    170185     * @return The {@link DataSet}
    171      * @since 14103
     186     * @since 18078
    172187     */
    173     public DataSet filterDataSet(DataSet ds, List<String> listPos) {
     188    public static DataSet filterDataSet(DataSet ds, List<String> listPos, String gpxPrefix) {
    174189        for (OsmPrimitive p : ds.getPrimitives(p -> p instanceof Node || p instanceof Way)) {
    175190            p.visitKeys((primitive, key, value) -> {
    176191                String listkey;
    177                 if (listPos != null && key.startsWith(GpxConstants.GPX_PREFIX)) {
    178                     listkey = key.substring(GpxConstants.GPX_PREFIX.length());
     192                if (listPos != null && key.startsWith(gpxPrefix)) {
     193                    listkey = key.substring(gpxPrefix.length());
    179194                } else {
    180195                    listkey = key;
Note: See TracChangeset for help on using the changeset viewer.