Ignore:
Timestamp:
2017-12-17T15:37:11+01:00 (8 years ago)
Author:
Don-vip
Message:

fix #15606 - export relation to GPX file or convert to a new GPX layer (patch by cmuelle8, modified)

File:
1 edited

Legend:

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

    r12987 r13210  
    77import java.awt.Dimension;
    88import java.awt.Graphics2D;
     9import java.awt.event.ActionEvent;
    910import java.io.File;
    1011import java.text.DateFormat;
     12import java.util.ArrayList;
    1113import java.util.Arrays;
    1214import java.util.Date;
    13 
     15import java.util.List;
     16
     17import javax.swing.AbstractAction;
    1418import javax.swing.Action;
    1519import javax.swing.Icon;
     
    1721import javax.swing.SwingUtilities;
    1822
     23import org.openstreetmap.josm.actions.ExpertToggleAction;
     24import org.openstreetmap.josm.actions.ExpertToggleAction.ExpertModeChangeListener;
    1925import org.openstreetmap.josm.actions.RenameLayerAction;
    2026import org.openstreetmap.josm.actions.SaveActionBase;
     
    4854 * A layer that displays data from a Gpx file / the OSM gpx downloads.
    4955 */
    50 public class GpxLayer extends Layer {
     56public class GpxLayer extends Layer implements ExpertModeChangeListener {
    5157
    5258    /** GPX data */
    5359    public GpxData data;
    5460    private final boolean isLocalFile;
     61    private boolean isExpertMode;
    5562    /**
    5663     * used by {@link ChooseTrackVisibilityAction} to determine which tracks to show/hide
     
    8491
    8592    /**
    86      * Constructs a new {@code GpxLayer} with a given name, thah can be attached to a local file.
     93     * Constructs a new {@code GpxLayer} with a given name, that can be attached to a local file.
    8794     * @param d GPX data
    8895     * @param name layer name
     
    97104        setName(name);
    98105        isLocalFile = isLocal;
     106        ExpertToggleAction.addExpertModeChangeListener(this, true);
    99107    }
    100108
     
    139147    @Override
    140148    public Object getInfoComponent() {
    141         StringBuilder info = new StringBuilder(48).append("<html>");
     149        StringBuilder info = new StringBuilder(128)
     150                .append("<html><head><style>")
     151                .append("td { padding: 4px 16px; }")
     152                .append("</style></head><body>");
    142153
    143154        if (data.attr.containsKey("name")) {
     
    151162        if (!data.getTracks().isEmpty()) {
    152163            info.append("<table><thead align='center'><tr><td colspan='5'>")
    153                 .append(trn("{0} track", "{0} tracks", data.tracks.size(), data.tracks.size()))
    154                 .append("</td></tr><tr align='center'><td>").append(tr("Name")).append("</td><td>")
    155                 .append(tr("Description")).append("</td><td>").append(tr("Timespan"))
    156                 .append("</td><td>").append(tr("Length")).append("</td><td>").append(tr("URL"))
     164                .append(trn("{0} track, {1} track segments", "{0} tracks, {1} track segments",
     165                        data.getTrackCount(), data.getTrackCount(),
     166                        data.getTrackSegsCount(), data.getTrackSegsCount()))
     167                .append("</td></tr><tr align='center'><td>").append(tr("Name"))
     168                .append("</td><td>").append(tr("Description"))
     169                .append("</td><td>").append(tr("Timespan"))
     170                .append("</td><td>").append(tr("Length"))
     171                .append("</td><td>").append(tr("Number of<br/>Segments"))
     172                .append("</td><td>").append(tr("URL"))
    157173                .append("</td></tr></thead>");
    158174
     
    171187                info.append(SystemOfMeasurement.getSystemOfMeasurement().getDistText(trk.length()));
    172188                info.append("</td><td>");
     189                info.append(trk.getSegments().size());
     190                info.append("</td><td>");
    173191                if (trk.getAttributes().containsKey("url")) {
    174192                    info.append(trk.get("url"));
     
    181199        info.append(tr("Length: {0}", SystemOfMeasurement.getSystemOfMeasurement().getDistText(data.length()))).append("<br>")
    182200            .append(trn("{0} route, ", "{0} routes, ", data.getRoutes().size(), data.getRoutes().size()))
    183             .append(trn("{0} waypoint", "{0} waypoints", data.getWaypoints().size(), data.getWaypoints().size())).append("<br></html>");
     201            .append(trn("{0} waypoint", "{0} waypoints", data.getWaypoints().size(), data.getWaypoints().size()))
     202            .append("<br></body></html>");
    184203
    185204        final JScrollPane sp = new JScrollPane(new HtmlPanel(info.toString()));
     
    196215    @Override
    197216    public Action[] getMenuEntries() {
    198         return new Action[] {
     217        List<Action> entries = new ArrayList<>(Arrays.asList(
    199218                LayerListDialog.getInstance().createShowHideLayerAction(),
    200219                LayerListDialog.getInstance().createDeleteLayerAction(),
     
    213232                SeparatorLayerAction.INSTANCE,
    214233                new ChooseTrackVisibilityAction(this),
    215                 new RenameLayerAction(getAssociatedFile(), this),
    216                 SeparatorLayerAction.INSTANCE,
    217                 new LayerListPopup.InfoAction(this) };
     234                new RenameLayerAction(getAssociatedFile(), this)));
     235
     236        List<Action> expert = Arrays.asList(
     237                new CombineTracksToSegmentedTrackAction(this),
     238                new SplitTrackSegementsToTracksAction(this),
     239                new SplitTracksToLayersAction(this));
     240
     241        if (isExpertMode && expert.stream().anyMatch(t -> t.isEnabled())) {
     242            entries.add(SeparatorLayerAction.INSTANCE);
     243            expert.stream().filter(t -> t.isEnabled()).forEach(t -> entries.add(t));
     244        }
     245
     246        entries.add(SeparatorLayerAction.INSTANCE);
     247        entries.add(new LayerListPopup.InfoAction(this));
     248        return entries.toArray(new Action[0]);
    218249    }
    219250
     
    238269        }
    239270
    240         info.append(trn("{0} track, ", "{0} tracks, ", data.getTracks().size(), data.getTracks().size()))
     271        info.append(trn("{0} track", "{0} tracks", data.getTrackCount(), data.getTrackCount()))
     272            .append(trn(" ({0} segment)", " ({0} segments)", data.getTrackSegsCount(), data.getTrackSegsCount()))
     273            .append(", ")
    241274            .append(trn("{0} route, ", "{0} routes, ", data.getRoutes().size(), data.getRoutes().size()))
    242275            .append(trn("{0} waypoint", "{0} waypoints", data.getWaypoints().size(), data.getWaypoints().size())).append("<br>")
     
    330363        return new GpxDrawHelper(this);
    331364    }
     365
     366    /**
     367     * Action to merge tracks into a single segmented track
     368     *
     369     * @since 13210
     370     */
     371    public static class CombineTracksToSegmentedTrackAction extends AbstractAction {
     372        private final transient GpxLayer layer;
     373
     374        /**
     375         * Create a new CombineTracksToSegmentedTrackAction
     376         * @param layer The layer with the data to work on.
     377         */
     378        public CombineTracksToSegmentedTrackAction(GpxLayer layer) {
     379            // FIXME: icon missing, create a new icon for this action
     380            //new ImageProvider("gpx_tracks_to_segmented_track").getResource().attachImageIcon(this, true);
     381            putValue(SHORT_DESCRIPTION, tr("Collect segments of all tracks and combine in a single track."));
     382            putValue(NAME, tr("Combine tracks of this layer"));
     383            this.layer = layer;
     384        }
     385
     386        @Override
     387        public void actionPerformed(ActionEvent e) {
     388            layer.data.combineTracksToSegmentedTrack();
     389            layer.invalidate();
     390        }
     391
     392        @Override
     393        public boolean isEnabled() {
     394            return layer.data.getTrackCount() > 1;
     395        }
     396    }
     397
     398    /**
     399     * Action to split track segments into a multiple tracks with one segment each
     400     *
     401     * @since 13210
     402     */
     403    public static class SplitTrackSegementsToTracksAction extends AbstractAction {
     404        private final transient GpxLayer layer;
     405
     406        /**
     407         * Create a new SplitTrackSegementsToTracksAction
     408         * @param layer The layer with the data to work on.
     409         */
     410        public SplitTrackSegementsToTracksAction(GpxLayer layer) {
     411            // FIXME: icon missing, create a new icon for this action
     412            //new ImageProvider("gpx_segmented_track_to_tracks").getResource().attachImageIcon(this, true);
     413            putValue(SHORT_DESCRIPTION, tr("Split multiple track segments of one track into multiple tracks."));
     414            putValue(NAME, tr("Split track segments to tracks"));
     415            this.layer = layer;
     416        }
     417
     418        @Override
     419        public void actionPerformed(ActionEvent e) {
     420            layer.data.splitTrackSegmentsToTracks();
     421            layer.invalidate();
     422        }
     423
     424        @Override
     425        public boolean isEnabled() {
     426            return layer.data.getTrackSegsCount() > layer.data.getTrackCount();
     427        }
     428    }
     429
     430    /**
     431     * Action to split tracks of one gpx layer into multiple gpx layers,
     432     * the result is one GPX track per gpx layer.
     433     *
     434     * @since 13210
     435     */
     436    public static class SplitTracksToLayersAction extends AbstractAction {
     437        private final transient GpxLayer layer;
     438
     439        /**
     440         * Create a new SplitTrackSegementsToTracksAction
     441         * @param layer The layer with the data to work on.
     442         */
     443        public SplitTracksToLayersAction(GpxLayer layer) {
     444            // FIXME: icon missing, create a new icon for this action
     445            //new ImageProvider("gpx_split_tracks_to_layers").getResource().attachImageIcon(this, true);
     446            putValue(SHORT_DESCRIPTION, tr("Split the tracks of this layer to one new layer each."));
     447            putValue(NAME, tr("Split tracks to new layers"));
     448            this.layer = layer;
     449        }
     450
     451        @Override
     452        public void actionPerformed(ActionEvent e) {
     453            layer.data.splitTracksToLayers();
     454            // layer is not modified by this action
     455        }
     456
     457        @Override
     458        public boolean isEnabled() {
     459            return layer.data.getTrackCount() > 1;
     460        }
     461    }
     462
     463    @Override
     464    public void expertChanged(boolean isExpert) {
     465        this.isExpertMode = isExpert;
     466    }
    332467}
Note: See TracChangeset for help on using the changeset viewer.