Ignore:
Timestamp:
2013-01-28T14:06:52+01:00 (13 years ago)
Author:
bastiK
Message:

add session support for marker layers (see #4029)

The data is exported to a separate GPX file that contains one waypoint for each marker.
This is not very elegant, because most of the time, all the info is already contained in the original GPX File.
However, when dealing with audio markers, they can be synchronized, or additional markers are added
at certain playback positions. This info must be retained.
Another complication is, that two or more MarkerLayers can be merged to one.

All these problems are avoided by explicitly exporting the markers to a separate file (as done in this commit).

Location:
trunk/src/org/openstreetmap/josm/gui/layer/markerlayer
Files:
6 edited

Legend:

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

    r4282 r5684  
    44import java.awt.event.ActionEvent;
    55import java.net.URL;
     6import java.util.Collections;
    67
    78import org.openstreetmap.josm.Main;
    89import org.openstreetmap.josm.data.coor.LatLon;
     10import org.openstreetmap.josm.data.gpx.GpxConstants;
     11import org.openstreetmap.josm.data.gpx.GpxLink;
     12import org.openstreetmap.josm.data.gpx.WayPoint;
    913import org.openstreetmap.josm.tools.AudioPlayer;
    1014import org.openstreetmap.josm.tools.template_engine.TemplateEngineDataProvider;
     
    7781        return TemplateEntryProperty.forAudioMarker(parentLayer.getName());
    7882    }
     83
     84    @Override
     85    public WayPoint convertToWayPoint() {
     86        WayPoint wpt = super.convertToWayPoint();
     87        GpxLink link = new GpxLink(audioUrl.toString());
     88        link.type = "audio";
     89        wpt.attr.put(GpxConstants.META_LINKS, Collections.singleton(link));
     90        wpt.addExtension("offset", Double.toString(offset));
     91        wpt.addExtension("sync-offset", Double.toString(syncOffset));
     92        return wpt;
     93    }
    7994}
  • trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/ImageMarker.java

    r4282 r5684  
    88import java.awt.event.ActionListener;
    99import java.net.URL;
     10import java.util.Collections;
    1011
    1112import javax.swing.Icon;
     
    2122import org.openstreetmap.josm.Main;
    2223import org.openstreetmap.josm.data.coor.LatLon;
     24import org.openstreetmap.josm.data.gpx.GpxConstants;
     25import org.openstreetmap.josm.data.gpx.GpxLink;
     26import org.openstreetmap.josm.data.gpx.WayPoint;
    2327import org.openstreetmap.josm.tools.ImageProvider;
    2428
     
    8387    }
    8488
     89    @Override
     90    public WayPoint convertToWayPoint() {
     91        WayPoint wpt = super.convertToWayPoint();
     92        GpxLink link = new GpxLink(imageUrl.toString());
     93        link.type = "image";
     94        wpt.attr.put(GpxConstants.META_LINKS, Collections.singleton(link));
     95        return wpt;
     96    }
     97
    8598}
  • trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/Marker.java

    r5681 r5684  
    88import java.net.MalformedURLException;
    99import java.net.URL;
     10import java.text.DateFormat;
     11import java.text.SimpleDateFormat;
    1012import java.util.ArrayList;
    1113import java.util.Collection;
     14import java.util.Date;
    1215import java.util.HashMap;
    1316import java.util.LinkedList;
    1417import java.util.List;
    1518import java.util.Map;
     19import java.util.TimeZone;
    1620
    1721import javax.swing.Icon;
     
    2327import org.openstreetmap.josm.data.coor.EastNorth;
    2428import org.openstreetmap.josm.data.coor.LatLon;
     29import org.openstreetmap.josm.data.gpx.Extensions;
    2530import org.openstreetmap.josm.data.gpx.GpxConstants;
    2631import org.openstreetmap.josm.data.gpx.GpxLink;
     
    181186        Marker.markerProducers.add(new MarkerProducers() {
    182187            @SuppressWarnings("unchecked")
     188            @Override
    183189            public Marker createMarker(WayPoint wpt, File relativePath, MarkerLayer parentLayer, double time, double offset) {
    184190                String uri = null;
     
    217223                }
    218224                else if (url.toString().endsWith(".wav")) {
    219                     return new AudioMarker(wpt.getCoor(), wpt, url, parentLayer, time, offset);
     225                    AudioMarker audioMarker = new AudioMarker(wpt.getCoor(), wpt, url, parentLayer, time, offset);
     226                    Extensions exts = (Extensions) wpt.get(GpxConstants.META_EXTENSIONS);
     227                    if (exts != null && exts.containsKey("offset")) {
     228                        try {
     229                            double syncOffset = Double.parseDouble(exts.get("sync-offset"));
     230                            audioMarker.syncOffset = syncOffset;
     231                        } catch (NumberFormatException nfe) {}
     232                    }
     233                    return audioMarker;
    220234                } else if (url.toString().endsWith(".png") || url.toString().endsWith(".jpg") || url.toString().endsWith(".jpeg") || url.toString().endsWith(".gif")) {
    221235                    return new ImageMarker(wpt.getCoor(), url, parentLayer, time, offset);
     
    234248     * @param relativePath An path to use for constructing relative URLs or
    235249     *        <code>null</code> for no relative URLs
     250     * @param parentLayer the <code>MarkerLayer</code> that will contain the created <code>Marker</code>
     251     * @param time time of the marker in seconds since epoch
    236252     * @param offset double in seconds as the time offset of this marker from
    237253     *        the GPX file from which it was derived (if any).
     
    247263    }
    248264
     265    private static final DateFormat timeFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
     266    static {
     267         TimeZone tz = TimeZone.getTimeZone("UTC");
     268         timeFormatter.setTimeZone(tz);
     269    }
     270
    249271    public static final String MARKER_OFFSET = "waypointOffset";
    250272    public static final String MARKER_FORMATTED_OFFSET = "formattedWaypointOffset";
     
    254276    public static final String LABEL_PATTERN_DESC = "{desc}";
    255277
    256 
    257278    private final TemplateEngineDataProvider dataProvider;
    258279    private final String text;
     
    260281    public final Icon symbol;
    261282    public final MarkerLayer parentLayer;
    262     public double time; /* absolute time of marker since epoch */
     283    public double time; /* absolute time of marker in seconds since epoch */
    263284    public double offset; /* time offset in seconds from the gpx point from which it was derived,
    264285                             may be adjusted later to sync with other data, so not final */
     
    296317    }
    297318
     319    /**
     320     * Convert Marker to WayPoint so it can be exported to a GPX file.
     321     *
     322     * Override in subclasses to add all necessary attributes.
     323     *
     324     * @return the corresponding WayPoint with all relevant attributes
     325     */
     326    public WayPoint convertToWayPoint() {
     327        WayPoint wpt = new WayPoint(getCoor());
     328        wpt.put("time", timeFormatter.format(new Date(Math.round(time * 1000))));
     329        if (text != null) {
     330            wpt.addExtension("text", text);
     331        } else if (dataProvider != null) {
     332            for (String key : dataProvider.getTemplateKeys()) {
     333                Object value = dataProvider.getTemplateValue(key, false);
     334                if (value != null && GpxConstants.WPT_KEYS.contains(key)) {
     335                    wpt.put(key, value);
     336                }
     337            }
     338        }
     339        return wpt;
     340    }
     341
    298342    public final void setCoor(LatLon coor) {
    299343        if(this.coor == null) {
     
    343387     * @param mv map view
    344388     * @param mousePressed true if the left mouse button is pressed
     389     * @param showTextOrIcon true if text and icon shall be drawn
    345390     */
    346391    public void paint(Graphics g, MapView mv, boolean mousePressed, boolean showTextOrIcon) {
     
    398443    }
    399444
    400     private String formatOffset () {
     445    private String formatOffset() {
    401446        int wholeSeconds = (int)(offset + 0.5);
    402447        if (wholeSeconds < 60)
  • trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java

    r5681 r5684  
    3232import org.openstreetmap.josm.data.Bounds;
    3333import org.openstreetmap.josm.data.coor.LatLon;
     34import org.openstreetmap.josm.data.gpx.Extensions;
    3435import org.openstreetmap.josm.data.gpx.GpxConstants;
    3536import org.openstreetmap.josm.data.gpx.GpxData;
     
    108109                }
    109110            }
    110             Marker m = Marker.createMarker(wpt, indata.storageFile, this, time, time - firstTime);
     111            Double offset = null;
     112            // If we have an explicit offset, take it.
     113            // Otherwise, for a group of markers with the same Link-URI (e.g. an
     114            // audio file) calculate the offset relative to the first marker of
     115            // that group. This way the user can jump to the corresponding
     116            // playback positions in a long audio track.
     117            Extensions exts = (Extensions) wpt.get(GpxConstants.META_EXTENSIONS);
     118            if (exts != null && exts.containsKey("offset")) {
     119                try {
     120                    offset = Double.parseDouble(exts.get("offset"));
     121                } catch (NumberFormatException nfe) {}
     122            }
     123            if (offset == null) {
     124                offset = time - firstTime;
     125            }
     126            Marker m = Marker.createMarker(wpt, indata.storageFile, this, time, offset);
    111127            if (m != null) {
    112128                data.add(m);
  • trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerProducers.java

    r1169 r5684  
    2424     * @return A Marker object, or <code>null</code>.
    2525     */
    26     public Marker createMarker(WayPoint wp, File relativePath, MarkerLayer parentLayer, double time, double offset);
     26    Marker createMarker(WayPoint wp, File relativePath, MarkerLayer parentLayer, double time, double offset);
    2727}
  • trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/WebMarker.java

    r4282 r5684  
    66import java.awt.event.ActionEvent;
    77import java.net.URL;
     8import java.util.Collections;
    89
    910import javax.swing.JOptionPane;
     
    1112import org.openstreetmap.josm.Main;
    1213import org.openstreetmap.josm.data.coor.LatLon;
     14import org.openstreetmap.josm.data.gpx.GpxConstants;
     15import org.openstreetmap.josm.data.gpx.GpxLink;
     16import org.openstreetmap.josm.data.gpx.WayPoint;
    1317import org.openstreetmap.josm.tools.OpenBrowser;
    1418
     
    3842        }
    3943    }
     44
     45    @Override
     46    public WayPoint convertToWayPoint() {
     47        WayPoint wpt = super.convertToWayPoint();
     48        GpxLink link = new GpxLink(webUrl.toString());
     49        link.type = "web";
     50        wpt.attr.put(GpxConstants.META_LINKS, Collections.singleton(link));
     51        return wpt;
     52    }
    4053}
Note: See TracChangeset for help on using the changeset viewer.