Changeset 553 in josm


Ignore:
Timestamp:
2008-02-21T19:53:16+01:00 (12 years ago)
Author:
david
Message:

(a) add preference dialog, (b) add audio tracing

Location:
trunk
Files:
3 added
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/OpenAction.java

    r529 r553  
    8989                        }
    9090                        r.data.storageFile = file;
    91                         Main.main.addLayer(new GpxLayer(r.data, fn));
    92             MarkerLayer ml = new MarkerLayer(r.data, tr("Markers from {0}", fn), file);
     91                        GpxLayer gpxLayer = new GpxLayer(r.data, fn);
     92                        Main.main.addLayer(gpxLayer);
     93            MarkerLayer ml = new MarkerLayer(r.data, tr("Markers from {0}", fn), file, gpxLayer);
    9394            if (ml.data.size() > 0) {
    9495                Main.main.addLayer(ml);
  • trunk/src/org/openstreetmap/josm/data/coor/EastNorth.java

    r477 r553  
    2727        }
    2828       
     29        public EastNorth interpolate(EastNorth en2, double proportion) {
     30                return new EastNorth(this.x + proportion * (en2.x - this.x),this.y + proportion * (en2.y - this.y));
     31        }
     32       
    2933        @Override public String toString() {
    3034                return "EastNorth[e="+x+", n="+y+"]";
  • trunk/src/org/openstreetmap/josm/data/gpx/WayPoint.java

    r552 r553  
    1616        public final LatLon latlon;
    1717        public final EastNorth eastNorth;
     18        public double time;
    1819
    1920        public WayPoint(LatLon ll) {
    2021                latlon = ll;
    21                 eastNorth = Main.proj.latlon2eastNorth(ll); 
     22                eastNorth = Main.proj.latlon2eastNorth(ll);
    2223        }
    2324
     
    3132         * @return seconds
    3233         */
    33         public double time () {
     34        public void setTime () {
    3435                if (! attr.containsKey("time"))
    35                         return 0.0;
     36                        time = 0.0;
    3637                SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); // ignore timezone
    3738                Date d = f.parse(attr.get("time").toString(), new ParsePosition(0));
    3839                if (d == null /* failed to parse */)
    39                         return 0.0;
    40                 return d.getTime() / 1000.0; /* ms => seconds */
     40                        time = 0.0;
     41                time = d.getTime() / 1000.0; /* ms => seconds */
    4142        }
    4243
  • trunk/src/org/openstreetmap/josm/gui/MapView.java

    r527 r553  
    1010import java.awt.event.ComponentEvent;
    1111import java.awt.event.KeyEvent;
     12import java.awt.event.ActionListener;
     13import java.awt.event.ActionEvent;
    1214import java.util.ArrayList;
    1315import java.util.Collection;
     
    7274         */
    7375        private Layer activeLayer;
     76       
    7477        /**
    7578         * The listener of the active layer changes.
  • trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java

    r552 r553  
    6969public class GpxLayer extends Layer {
    7070        public GpxData data;
    71 
     71        private final GpxLayer me;
     72       
    7273        public GpxLayer(GpxData d) {
    7374                super((String) d.attr.get("name"));
    74                 data = d;               
     75                data = d;
     76                me = this;
    7577        }
    7678
     
    149151                                                                namedTrackPoints.waypoints.add(point);
    150152
    151                     MarkerLayer ml = new MarkerLayer(namedTrackPoints, tr("Named Trackpoints from {0}", name), associatedFile);
     153                    MarkerLayer ml = new MarkerLayer(namedTrackPoints, tr("Named Trackpoints from {0}", name), associatedFile, me);
    152154                    if (ml.data.size() > 0) {
    153155                        Main.main.addLayer(ml);
     
    499501            WayPoint prevPoint = null;
    500502
    501             MarkerLayer ml = new MarkerLayer(new GpxData(), tr("Sampled audio markers from {0}", name), associatedFile);
     503            MarkerLayer ml = new MarkerLayer(new GpxData(), tr("Sampled audio markers from {0}", name), associatedFile, me);
    502504           
    503505                for (GpxTrack track : data.tracks) {
    504506                        for (Collection<WayPoint> seg : track.trackSegs) {
    505507                                for (WayPoint point : seg) {
    506                                         double time = point.time();
     508                                        double time = point.time;
    507509                                        if (firstTime < 0.0)
    508510                                                firstTime = time;
     
    521523                                                else
    522524                                                        markerName = String.format("%d:%02d:%02d", wholeSeconds / 3600, (wholeSeconds % 3600)/60, wholeSeconds % 60);
    523                                                 AudioMarker am = AudioMarker.create(point.latlon, markerName, uri, offset);
     525                                                AudioMarker am = AudioMarker.create(point.latlon, markerName, uri, ml, time, offset);
    524526                                                ml.data.add(am);
    525527                                                prevPoint = point;
  • trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/AudioMarker.java

    r547 r553  
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
     6import java.awt.Graphics;
     7import java.awt.Point;
     8import java.awt.Rectangle;
    69import java.awt.event.ActionEvent;
     10import java.awt.event.ActionListener;
    711import java.io.IOException;
    812import java.net.URL;
    913
    10 import javax.sound.sampled.AudioFormat;
    11 import javax.sound.sampled.AudioInputStream;
    12 import javax.sound.sampled.AudioSystem;
    13 import javax.sound.sampled.DataLine;
    14 import javax.sound.sampled.SourceDataLine;
     14import javax.swing.Icon;
    1515import javax.swing.JOptionPane;
     16import javax.swing.Timer;
    1617
    1718import org.openstreetmap.josm.Main;
    1819import org.openstreetmap.josm.data.coor.LatLon;
    1920import org.openstreetmap.josm.tools.AudioPlayer;
     21import org.openstreetmap.josm.data.gpx.WayPoint;
     22import org.openstreetmap.josm.data.coor.EastNorth;
     23import org.openstreetmap.josm.gui.MapView;
     24
     25import org.openstreetmap.josm.tools.ImageProvider;
    2026
    2127/**
     
    2733public class AudioMarker extends ButtonMarker {
    2834
    29         private URL audioUrl;
    30         private double syncOffset;
     35        private URL audioUrl;   
    3136        private static AudioMarker recentlyPlayedMarker = null;
    32 
     37        public  double syncOffset;
     38       
    3339        /**
    3440         * Verifies the parameter whether a new AudioMarker can be created and return
    3541         * one or return <code>null</code>.
    3642         */
    37         public static AudioMarker create(LatLon ll, String text, String url, double offset) {
     43        public static AudioMarker create(LatLon ll, String text, String url, MarkerLayer parentLayer, double time, double offset) {
    3844                try {
    39                         return new AudioMarker(ll, text, new URL(url), offset);
     45                        return new AudioMarker(ll, text, new URL(url), parentLayer, time, offset);
    4046                } catch (Exception ex) {
    4147                        return null;
     
    4349        }
    4450
    45         private AudioMarker(LatLon ll, String text, URL audioUrl, double offset) {
    46                 super(ll, text, "speech.png", offset);
     51        private AudioMarker(LatLon ll, String text, URL audioUrl, MarkerLayer parentLayer, double time, double offset) {
     52                super(ll, text, "speech.png", parentLayer, time, offset);
    4753                this.audioUrl = audioUrl;
    4854                this.syncOffset = 0.0;
     
    6066                return audioUrl;
    6167        }
    62        
     68               
    6369        /**
    6470         * Starts playing the audio associated with the marker: used in response to pressing
     
    6874        public void play() {
    6975                try {
     76                        // first enable tracing the audio along the track
     77                        if (Main.pref.getBoolean("marker.traceaudio") && parentLayer != null) {
     78                                parentLayer.traceAudio();
     79                        }
     80
    7081                        AudioPlayer.play(audioUrl, offset + syncOffset);
    7182                        recentlyPlayedMarker = this;
     
    7485                }
    7586        }
    76        
     87
    7788        public void adjustOffset(double adjustment) {
    7889                syncOffset = adjustment; // added to offset may turn out negative, but that's ok
  • trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/ButtonMarker.java

    r552 r553  
    2525
    2626        private Rectangle buttonRectangle;
     27        protected Graphics graphicsContext = null;
    2728       
    28         public ButtonMarker(LatLon ll, String buttonImage, double offset) {
    29                 super(ll, null, buttonImage, offset);
     29        public ButtonMarker(LatLon ll, String buttonImage, MarkerLayer parentLayer, double time, double offset) {
     30                super(ll, null, buttonImage, parentLayer, time, offset);
    3031                buttonRectangle = new Rectangle(0, 0, symbol.getIconWidth(), symbol.getIconHeight());
    3132        }
    3233       
    33         public ButtonMarker(LatLon ll, String text, String buttonImage, double offset) {
    34                 super(ll, text, buttonImage, offset);
     34        public ButtonMarker(LatLon ll, String text, String buttonImage, MarkerLayer parentLayer, double time, double offset) {
     35                super(ll, text, buttonImage, parentLayer, time, offset);
    3536                buttonRectangle = new Rectangle(0, 0, symbol.getIconWidth(), symbol.getIconHeight());
    3637        }
     
    4344       
    4445        @Override public void paint(Graphics g, MapView mv, boolean mousePressed, String show) {
     46                graphicsContext = g;
    4547                Point screen = mv.getPoint(eastNorth);
    4648                buttonRectangle.setLocation(screen.x+4, screen.y+2);
  • trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/ImageMarker.java

    r547 r553  
    2222import org.openstreetmap.josm.data.coor.LatLon;
    2323import org.openstreetmap.josm.tools.ImageProvider;
     24import org.openstreetmap.josm.gui.layer.Layer;
    2425
    2526/**
     
    3435        public URL imageUrl;
    3536
    36         public static ImageMarker create(LatLon ll, String url, double offset) {
     37        public static ImageMarker create(LatLon ll, String url, MarkerLayer parentLayer, double time, double offset) {
    3738                try {
    38                         return new ImageMarker(ll, new URL(url), offset);
     39                        return new ImageMarker(ll, new URL(url), parentLayer, time, offset);
    3940                } catch (Exception ex) {
    4041                        return null;
     
    4243        }
    4344
    44         private ImageMarker(LatLon ll, URL imageUrl, double offset) {
    45                 super(ll, "photo.png", offset);
     45        private ImageMarker(LatLon ll, URL imageUrl, MarkerLayer parentLayer, double time, double offset) {
     46                super(ll, "photo.png", parentLayer, time, offset);
    4647                this.imageUrl = imageUrl;
    4748        }
  • trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/Marker.java

    r547 r553  
    2222import org.openstreetmap.josm.data.gpx.WayPoint;
    2323import org.openstreetmap.josm.gui.MapView;
     24import org.openstreetmap.josm.gui.layer.Layer;
    2425import org.openstreetmap.josm.tools.ImageProvider;
    2526
     
    6465        public final String text;
    6566        public final Icon symbol;
     67        public final MarkerLayer parentLayer;
     68        public double time; /* avbsolute time of marker since epocj */
    6669        public double offset; /* time offset in seconds from the gpx point from which it was derived,
    6770                                                         may be adjusted later to sync with other data, so not final */
     
    7881                Marker.markerProducers.add(new MarkerProducers() {
    7982                        public Marker createMarker(WayPoint wpt, File relativePath) {
    80                                 return createMarker(wpt, relativePath, 0.0);
     83                                return createMarker(wpt, relativePath, null, 0.0, 0.0);
    8184                        }
    8285                       
    83                         public Marker createMarker(WayPoint wpt, File relativePath, double offset) {
     86                        public Marker createMarker(WayPoint wpt, File relativePath, MarkerLayer parentLayer, double time, double offset) {
    8487                                String uri = null;
    8588                                // cheapest way to check whether "link" object exists and is a non-empty
     
    104107               
    105108                if (uri == null)
    106                     return new Marker(wpt.latlon, name_desc, wpt.getString("symbol"), offset);
     109                    return new Marker(wpt.latlon, name_desc, wpt.getString("symbol"), parentLayer, time, offset);
    107110                else if (uri.endsWith(".wav"))
    108                     return AudioMarker.create(wpt.latlon, name_desc, uri, offset);
     111                    return AudioMarker.create(wpt.latlon, name_desc, uri, parentLayer, time, offset);
    109112                else if (uri.endsWith(".png") || uri.endsWith(".jpg") || uri.endsWith(".jpeg") || uri.endsWith(".gif"))
    110                                         return ImageMarker.create(wpt.latlon, uri, offset);
     113                                        return ImageMarker.create(wpt.latlon, uri, parentLayer, time, offset);
    111114                                else
    112                                         return WebMarker.create(wpt.latlon, uri, offset);
     115                                        return WebMarker.create(wpt.latlon, uri, parentLayer, time, offset);
    113116                        }
    114117
     
    124127        }
    125128
    126         public Marker(LatLon ll, String text, String iconName, double offset) {
     129        public Marker(LatLon ll, String text, String iconName, MarkerLayer parentLayer, double time, double offset) {
    127130                eastNorth = Main.proj.latlon2eastNorth(ll);
    128131                this.text = text;
    129132                this.offset = offset;
     133                this.time = time;
    130134                Icon symbol = ImageProvider.getIfAvailable("markers",iconName);
    131135                if (symbol == null)
     
    134138                        symbol = ImageProvider.getIfAvailable("nodes",iconName);
    135139                this.symbol = symbol;
     140                this.parentLayer = parentLayer;
    136141        }
    137142
     
    187192         * @return a new Marker object
    188193         */
    189         public static Marker createMarker(WayPoint wpt, File relativePath, double offset) {
     194        public static Marker createMarker(WayPoint wpt, File relativePath, MarkerLayer parentLayer, double time, double offset) {
    190195                for (MarkerProducers maker : Marker.markerProducers) {
    191                         Marker marker = maker.createMarker(wpt, relativePath, offset);
     196                        Marker marker = maker.createMarker(wpt, relativePath, parentLayer, time, offset);
    192197                        if (marker != null)
    193198                                return marker;
     
    207212       
    208213        public AudioMarker audioMarkerFromMarker(String uri) {
    209                 AudioMarker audioMarker = AudioMarker.create(Main.proj.eastNorth2latlon(this.eastNorth), this.text, uri, this.offset);
     214                AudioMarker audioMarker = AudioMarker.create(Main.proj.eastNorth2latlon(this.eastNorth), this.text, uri, this.parentLayer, this.time, this.offset);
    210215                return audioMarker;
    211216        }
  • trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java

    r552 r553  
    99import java.awt.Graphics;
    1010import java.awt.Point;
     11import java.awt.Rectangle;
    1112import java.awt.event.ActionEvent;
    1213import java.awt.event.ActionListener;
     
    2627import javax.swing.JSeparator;
    2728import javax.swing.SwingUtilities;
     29import javax.swing.Timer;
    2830import javax.swing.filechooser.FileFilter;
    2931
    3032import org.openstreetmap.josm.Main;
    3133import org.openstreetmap.josm.actions.RenameLayerAction;
     34import org.openstreetmap.josm.command.Command;
     35import org.openstreetmap.josm.data.coor.EastNorth;
    3236import org.openstreetmap.josm.data.gpx.GpxData;
     37import org.openstreetmap.josm.data.gpx.GpxTrack;
    3338import org.openstreetmap.josm.data.gpx.WayPoint;
    3439import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
     
    3742import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
    3843import org.openstreetmap.josm.gui.layer.Layer;
     44import org.openstreetmap.josm.gui.layer.GpxLayer;
    3945import org.openstreetmap.josm.gui.layer.markerlayer.AudioMarker;
    4046import org.openstreetmap.josm.tools.ColorHelper;
     
    6066        public final Collection<Marker> data;
    6167        private boolean mousePressed = false;
    62        
    63         public MarkerLayer(GpxData indata, String name, File associatedFile) {
     68        public GpxLayer fromLayer = null;
     69        private Rectangle audioTracer = null;
     70        private Icon audioTracerIcon = null;
     71        private EastNorth audioTracerPosition = null;
     72        private static Timer timer = null;
     73        private static double audioAnimationInterval = 0.0; // seconds
     74        private static double previousTime = -1.0;
     75
     76        public MarkerLayer(GpxData indata, String name, File associatedFile, GpxLayer fromLayer) {
    6477               
    6578                super(name);
    6679                this.associatedFile = associatedFile;
    6780                this.data = new ArrayList<Marker>();
     81                this.fromLayer = fromLayer;
    6882                double firstTime = -1.0;
    6983
    7084                for (WayPoint wpt : indata.waypoints) {
    7185                        /* calculate time differences in waypoints */
    72                         double time = wpt.time();
     86                        double time = wpt.time;
    7387                        if (firstTime < 0)
    7488                                firstTime = time;
    75             Marker m = Marker.createMarker(wpt, indata.storageFile, time - firstTime);
     89            Marker m = Marker.createMarker(wpt, indata.storageFile, this, time, time - firstTime);
    7690            if (m != null)
    7791                data.add(m);
     
    147161                        }
    148162                }
     163
     164                if (audioTracer != null) {
     165                        Point screen = Main.map.mapView.getPoint(audioTracerPosition);
     166                        audioTracer.setLocation(screen.x, screen.y);
     167                        audioTracerIcon.paintIcon(Main.map.mapView, g, screen.x, screen.y);
     168                }
     169        }
     170
     171        protected void traceAudio() {
     172                if (timer == null) {
     173                        audioAnimationInterval = Double.parseDouble(Main.pref.get("marker.audioanimationinterval", "1")); //milliseconds
     174                        timer = new Timer((int)(audioAnimationInterval * 1000.0), new ActionListener() {
     175                                public void actionPerformed(ActionEvent e) {
     176                                        timerAction();
     177                                }
     178                        });
     179                        timer.start();
     180                }
     181        }
     182       
     183        /**
     184         * callback for AudioPlayer when position changes
     185         * @param position seconds into the audio stream
     186         */
     187        public void timerAction() {
     188                AudioMarker recentlyPlayedMarker = AudioMarker.recentlyPlayedMarker();
     189                if (recentlyPlayedMarker == null)
     190                        return;
     191                double audioTime = recentlyPlayedMarker.time +
     192                        AudioPlayer.position() -
     193                        recentlyPlayedMarker.offset -
     194                        recentlyPlayedMarker.syncOffset;
     195                if (Math.abs(audioTime- previousTime) < audioAnimationInterval)
     196                        return;
     197                if (fromLayer == null)
     198                        return;
     199                /* find the pair of track points for this position (adjusted by the syncOffset)
     200                 * and interpolate between them
     201                 */
     202                WayPoint w1 = null;
     203                WayPoint w2 = null;
     204
     205                for (GpxTrack track : fromLayer.data.tracks) {
     206                        for (Collection<WayPoint> trackseg : track.trackSegs) {
     207                                for (Iterator<WayPoint> it = trackseg.iterator(); it.hasNext();) {
     208                                        WayPoint w = it.next();
     209                                        if (audioTime < w.time) {
     210                                                w2 = w;
     211                                                break;
     212                                        }
     213                                        w1 = w;
     214                                }
     215                                if (w2 != null) break;
     216                        }
     217                        if (w2 != null) break;
     218                }
     219               
     220                if (w1 == null)
     221                        return;
     222                audioTracerPosition = w2 == null ?
     223                        w1.eastNorth :
     224                        w1.eastNorth.interpolate(w2.eastNorth,
     225                                        (audioTime - w1.time)/(w2.time - w1.time));
     226               
     227                if (audioTracer == null) {
     228                        audioTracerIcon = ImageProvider.getIfAvailable("markers",Main.pref.get("marker.audiotracericon", "audio-tracer"));
     229                        audioTracer = new Rectangle(0, 0, audioTracerIcon.getIconWidth(), audioTracerIcon.getIconHeight());                     
     230                }
     231                previousTime = audioTime;
     232                Main.map.mapView.repaint();
    149233        }
    150234
  • trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerProducers.java

    r547 r553  
    77import org.openstreetmap.josm.data.coor.LatLon;
    88import org.openstreetmap.josm.data.gpx.WayPoint;
     9import org.openstreetmap.josm.gui.layer.Layer;
    910
    1011/**
     
    2728         * @return A Marker object, or <code>null</code>.
    2829         */
    29         public Marker createMarker(WayPoint wp, File relativePath, double offset);
     30        public Marker createMarker(WayPoint wp, File relativePath, MarkerLayer parentLayer, double time, double offset);
    3031}
  • trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/WebMarker.java

    r547 r553  
    1212import org.openstreetmap.josm.data.coor.LatLon;
    1313import org.openstreetmap.josm.tools.OpenBrowser;
     14import org.openstreetmap.josm.gui.layer.Layer;
    1415
    1516/**
     
    2324        public URL webUrl;
    2425
    25         public static WebMarker create (LatLon ll, String url, double offset) {
     26        public static WebMarker create (LatLon ll, String url, MarkerLayer parentLayer, double time, double offset) {
    2627                try {
    27                         return new WebMarker(ll, new URL(url), offset);
     28                        return new WebMarker(ll, new URL(url), parentLayer, time, offset);
    2829                } catch (Exception ex) {
    2930                        return null;
     
    3132        }
    3233
    33         private WebMarker(LatLon ll, URL webUrl, double offset) {
    34                 super(ll, "web.png", offset);
     34        private WebMarker(LatLon ll, URL webUrl, MarkerLayer parentLayer, double time, double offset) {
     35                super(ll, "web.png", parentLayer, time, offset);
    3536                this.webUrl = webUrl;
    3637        }
  • trunk/src/org/openstreetmap/josm/gui/preferences/PreferenceDialog.java

    r486 r553  
    4040        public final JPanel connection = createPreferenceTab("connection", I18n.tr("Connection Settings"), I18n.tr("Connection Settings for the OSM server."));
    4141        public final JPanel map = createPreferenceTab("map", I18n.tr("Map Settings"), I18n.tr("Settings for the map projection and data interpretation."));
    42 
     42        public final JPanel audio = createPreferenceTab("audio", I18n.tr("Audio Settings"), I18n.tr("Settings for the audio player and audio markers."));
     43       
    4344        /**
    4445         * Construct a JPanel for the preference settings. Layout is GridBagLayout
     
    109110                settings.add(new PluginPreference());
    110111                settings.add(Main.toolbar);
    111 
     112                settings.add(new AudioPreference());
     113               
    112114                for (PluginProxy plugin : Main.plugins) {
    113115                        PreferenceSetting p = plugin.getPreferenceSetting();
  • trunk/src/org/openstreetmap/josm/io/GpxReader.java

    r547 r553  
    234234                                } else if (qName.equals("rtept")) {
    235235                                        currentState = states.pop();
     236                                        currentWayPoint.setTime();
    236237                                        currentRoute.routePoints.add(currentWayPoint);
    237238                                } else if (qName.equals("trkpt")) {
    238239                                        currentState = states.pop();
     240                                        currentWayPoint.setTime();
    239241                                        currentTrackSeg.add(currentWayPoint);
    240242                                        if (Main.pref.getBoolean("marker.namedtrackpoints") &&
     
    246248                                } else if (qName.equals("wpt")) {
    247249                                        currentState = states.pop();
     250                                        currentWayPoint.setTime();
    248251                                        currentData.waypoints.add(currentWayPoint);
    249252                                }
  • trunk/src/org/openstreetmap/josm/tools/AudioPlayer.java

    r549 r553  
    3535        private double position; // seconds
    3636        private double bytesPerSecond;
    37        
     37
    3838        /**
    3939         * Passes information from the control thread to the playing thread
Note: See TracChangeset for help on using the changeset viewer.