Ignore:
Timestamp:
2009-12-09T22:16:15+01:00 (15 years ago)
Author:
casualwalker
Message:

Changed behaviour:
Suppressing frequent updates will now fire every update event (thus, each received trackpoint is still drawn).
It only suppressed the re-draw.

Technical changes:
Moved responsibility for the Suppressor from the LiveGpsAqcuirer towards the LiveGpsPlugin; it is queried by the LiveGpsLayer, when refreshing the UI.

Location:
applications/editors/josm/plugins/livegps/src/livegps
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/livegps/src/livegps/LiveGpsAcquirer.java

    r18941 r19011  
    1717
    1818public class LiveGpsAcquirer implements Runnable {
    19     Socket gpsdSocket;
    20     BufferedReader gpsdReader;
    21     boolean connected = false;
    22     String gpsdHost = Main.pref.get("livegps.gpsd.host", "localhost");
    23     int gpsdPort = Main.pref.getInteger("livegps.gpsd.port", 2947);
    24     boolean shutdownFlag = false;
    25     private final List<PropertyChangeListener> propertyChangeListener = new ArrayList<PropertyChangeListener>();
    26     private PropertyChangeEvent lastStatusEvent;
    27     private PropertyChangeEvent lastDataEvent;
    28 
    29     /**
    30      * The LiveGpsSuppressor is queried, if an event shall be suppressed.
    31      */
    32     private LiveGpsSuppressor suppressor = null;
    33 
    34     /**
    35      * separate thread, where the LiveGpsSuppressor executes.
    36      */
    37     private Thread suppressorThread = null;
    38 
    39     /**
    40      * Adds a property change listener to the acquirer.
    41      * @param listener the new listener
    42      */
    43     public void addPropertyChangeListener(PropertyChangeListener listener) {
    44         if (!propertyChangeListener.contains(listener)) {
    45             propertyChangeListener.add(listener);
    46         }
    47     }
    48 
    49     /**
    50      * Remove a property change listener from the acquirer.
    51      * @param listener the new listener
    52      */
    53     public void removePropertyChangeListener(PropertyChangeListener listener) {
    54         if (propertyChangeListener.contains(listener)) {
    55             propertyChangeListener.remove(listener);
    56         }
    57     }
    58 
    59     /**
    60      * Fire a gps status change event. Fires events with key "gpsstatus" and a {@link LiveGpsStatus}
    61      * object as value.
    62      * The status event may be sent any time.
    63      * @param status the status.
    64      * @param statusMessage the status message.
    65      */
    66     public void fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus status,
    67             String statusMessage) {
    68         PropertyChangeEvent event = new PropertyChangeEvent(this, "gpsstatus",
    69                 null, new LiveGpsStatus(status, statusMessage));
    70 
    71         if (!event.equals(lastStatusEvent)) {
    72             firePropertyChangeEvent(event);
    73             lastStatusEvent = event;
    74         }
    75     }
    76 
    77     /**
    78      * Fire a gps data change event to all listeners. Fires events with key "gpsdata" and a
    79      * {@link LiveGpsData} object as values.
    80      * This event is only sent, when the suppressor permits it. This
    81      * event will cause the UI to re-draw itself, which has some performance penalty,
    82      * @param oldData the old gps data.
    83      * @param newData the new gps data.
    84      */
    85     public void fireGpsDataChangeEvent(LiveGpsData oldData, LiveGpsData newData) {
    86         PropertyChangeEvent event = new PropertyChangeEvent(this, "gpsdata",
    87                 oldData, newData);
    88 
    89         if (!event.equals(lastDataEvent) && checkSuppress()) {
    90             firePropertyChangeEvent(event);
    91             lastDataEvent = event;
    92         }
    93     }
    94 
    95     /**
    96      * Fires the given event to all listeners.
    97      * @param event the event to fire.
    98      */
    99     protected void firePropertyChangeEvent(PropertyChangeEvent event) {
    100         for (PropertyChangeListener listener : propertyChangeListener) {
    101             listener.propertyChange(event);
    102         }
    103     }
    104 
    105     public void run() {
    106         LiveGpsData oldGpsData = null;
    107         LiveGpsData gpsData = null;
    108 
    109         initSuppressor();
    110 
    111         shutdownFlag = false;
    112         while (!shutdownFlag) {
    113             double lat = 0;
    114             double lon = 0;
    115             float speed = 0;
    116             float course = 0;
    117             boolean haveFix = false;
    118 
    119             try {
    120                 if (!connected) {
    121                     System.out.println("LiveGps tries to connect to gpsd");
    122                     fireGpsStatusChangeEvent(
    123                             LiveGpsStatus.GpsStatus.CONNECTING,
    124                             tr("Connecting"));
    125                     InetAddress[] addrs = InetAddress.getAllByName(gpsdHost);
    126                     for (int i = 0; i < addrs.length && gpsdSocket == null; i++) {
    127                         try {
    128                             gpsdSocket = new Socket(addrs[i], gpsdPort);
    129                             break;
    130                         } catch (Exception e) {
    131                             System.out
    132                             .println("LiveGps: Could not open connection to gpsd: "
    133                                     + e);
    134                             gpsdSocket = null;
    135                         }
    136                     }
    137 
    138                     if (gpsdSocket != null) {
    139                         gpsdReader = new BufferedReader(new InputStreamReader(
    140                                 gpsdSocket.getInputStream()));
    141                         gpsdSocket.getOutputStream().write(
    142                                 new byte[] { 'w', 13, 10 });
    143                         fireGpsStatusChangeEvent(
    144                                 LiveGpsStatus.GpsStatus.CONNECTING,
    145                                 tr("Connecting"));
    146                         connected = true;
    147                         System.out.println("LiveGps: Connected to gpsd");
    148                     }
    149                 }
    150 
    151                 if (connected) {
    152                     // <FIXXME date="23.06.2007" author="cdaller">
    153                     // TODO this read is blocking if gps is connected but has no
    154                     // fix, so gpsd does not send positions
    155                     String line = gpsdReader.readLine();
    156                     // </FIXXME>
    157                     if (line == null)
    158                         break;
    159                     String words[] = line.split(",");
    160 
    161                     if ((words.length == 0) || (!words[0].equals("GPSD"))) {
    162                         // unexpected response.
    163                         continue;
    164                     }
    165 
    166                     for (int i = 1; i < words.length; i++) {
    167 
    168                         if ((words[i].length() < 2)
    169                                 || (words[i].charAt(1) != '=')) {
    170                             // unexpected response.
    171                             continue;
    172                         }
    173 
    174                         char what = words[i].charAt(0);
    175                         String value = words[i].substring(2);
    176                         oldGpsData = gpsData;
    177                         gpsData = new LiveGpsData();
    178                         switch (what) {
    179                         case 'O':
    180                             // full report, tab delimited.
    181                             String[] status = value.split("\\s+");
    182                             if (status.length >= 5) {
    183                                 lat = Double.parseDouble(status[3]);
    184                                 lon = Double.parseDouble(status[4]);
    185                                 try {
    186                                     speed = Float.parseFloat(status[9]);
    187                                     course = Float.parseFloat(status[8]);
    188                                     // view.setSpeed(speed);
    189                                     // view.setCourse(course);
    190                                 } catch (NumberFormatException nex) {
    191                                 }
    192                                 haveFix = true;
    193                             }
    194                             break;
    195                         case 'P':
    196                             // position report, tab delimited.
    197                             String[] pos = value.split("\\s+");
    198                             if (pos.length >= 2) {
    199                                 lat = Double.parseDouble(pos[0]);
    200                                 lon = Double.parseDouble(pos[1]);
    201                                 speed = Float.NaN;
    202                                 course = Float.NaN;
    203                                 haveFix = true;
    204                             }
    205                         default:
    206                             // not interested
    207                         }
    208                         fireGpsStatusChangeEvent(
    209                                 LiveGpsStatus.GpsStatus.CONNECTED,
    210                                 tr("Connected"));
    211                         gpsData.setFix(haveFix);
    212                         if (haveFix) {
    213                             // view.setCurrentPosition(lat, lon);
    214                             gpsData.setLatLon(new LatLon(lat, lon));
    215                             gpsData.setSpeed(speed);
    216                             gpsData.setCourse(course);
    217                             fireGpsDataChangeEvent(oldGpsData, gpsData);
    218                         }
    219                     }
    220                 } else {
    221                     // not connected:
    222                     fireGpsStatusChangeEvent(
    223                             LiveGpsStatus.GpsStatus.DISCONNECTED,
    224                             tr("Not connected"));
    225                     try {
    226                         Thread.sleep(1000);
    227                     } catch (InterruptedException ignore) {
    228                     }
    229                     ;
    230                 }
    231             } catch (IOException iox) {
    232                 connected = false;
    233                 if (gpsData != null) {
    234                     gpsData.setFix(false);
    235                     fireGpsDataChangeEvent(oldGpsData, gpsData);
    236                 }
    237                 fireGpsStatusChangeEvent(
    238                         LiveGpsStatus.GpsStatus.CONNECTION_FAILED,
    239                         tr("Connection Failed"));
    240                 try {
    241                     Thread.sleep(1000);
    242                 } catch (InterruptedException ignore) {
    243                 }
    244                 ;
    245                 // send warning to layer
    246 
    247             }
    248         }
    249 
    250         fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.DISCONNECTED,
    251                 tr("Not connected"));
    252         if (gpsdSocket != null) {
    253             try {
    254                 gpsdSocket.close();
    255                 gpsdSocket = null;
    256                 System.out.println("LiveGps: Disconnected from gpsd");
    257             } catch (Exception e) {
    258                 System.out
    259                 .println("LiveGps: Unable to close socket; reconnection may not be possible");
    260             }
    261         }
    262     }
    263 
    264     /**
    265      * Initialize the suppressor and start its thread.
    266      */
    267     private void initSuppressor() {
    268         suppressor = new LiveGpsSuppressor();
    269         suppressorThread = new Thread(suppressor);
    270         suppressorThread.start();
    271     }
    272 
    273     public void shutdown() {
    274         // shut down the suppressor thread, too.
    275         suppressor.shutdown();
    276         this.suppressor = null;
    277         shutdownFlag = true;
    278     }
    279 
    280     /**
    281      * Check, if an event may be sent now.
    282      * @return true, if an event may be sent.
    283      */
    284     private boolean checkSuppress() {
    285         if (suppressor != null) {
    286             if (suppressor.isAllowUpdate()) {
    287                 return true;
    288             } else {
    289                 return false;
    290             }
    291         } else {
    292             return true;
    293         }
    294     }
     19        Socket gpsdSocket;
     20        BufferedReader gpsdReader;
     21        boolean connected = false;
     22        String gpsdHost = Main.pref.get("livegps.gpsd.host", "localhost");
     23        int gpsdPort = Main.pref.getInteger("livegps.gpsd.port", 2947);
     24        boolean shutdownFlag = false;
     25        private final List<PropertyChangeListener> propertyChangeListener = new ArrayList<PropertyChangeListener>();
     26        private PropertyChangeEvent lastStatusEvent;
     27        private PropertyChangeEvent lastDataEvent;
     28
     29        /**
     30         * Adds a property change listener to the acquirer.
     31         * @param listener the new listener
     32         */
     33        public void addPropertyChangeListener(PropertyChangeListener listener) {
     34                if (!propertyChangeListener.contains(listener)) {
     35                        propertyChangeListener.add(listener);
     36                }
     37        }
     38
     39        /**
     40         * Remove a property change listener from the acquirer.
     41         * @param listener the new listener
     42         */
     43        public void removePropertyChangeListener(PropertyChangeListener listener) {
     44                if (propertyChangeListener.contains(listener)) {
     45                        propertyChangeListener.remove(listener);
     46                }
     47        }
     48
     49        /**
     50         * Fire a gps status change event. Fires events with key "gpsstatus" and a {@link LiveGpsStatus}
     51         * object as value.
     52         * The status event may be sent any time.
     53         * @param status the status.
     54         * @param statusMessage the status message.
     55         */
     56        public void fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus status,
     57                        String statusMessage) {
     58                PropertyChangeEvent event = new PropertyChangeEvent(this, "gpsstatus",
     59                                null, new LiveGpsStatus(status, statusMessage));
     60
     61                if (!event.equals(lastStatusEvent)) {
     62                        firePropertyChangeEvent(event);
     63                        lastStatusEvent = event;
     64                }
     65        }
     66
     67        /**
     68         * Fire a gps data change event to all listeners. Fires events with key "gpsdata" and a
     69         * {@link LiveGpsData} object as values.
     70         * This event is only sent, when the suppressor permits it. This
     71         * event will cause the UI to re-draw itself, which has some performance penalty,
     72         * @param oldData the old gps data.
     73         * @param newData the new gps data.
     74         */
     75        public void fireGpsDataChangeEvent(LiveGpsData oldData, LiveGpsData newData) {
     76                PropertyChangeEvent event = new PropertyChangeEvent(this, "gpsdata",
     77                                oldData, newData);
     78
     79                if (!event.equals(lastDataEvent)) {
     80                        firePropertyChangeEvent(event);
     81                        lastDataEvent = event;
     82                }
     83        }
     84
     85        /**
     86         * Fires the given event to all listeners.
     87         * @param event the event to fire.
     88         */
     89        protected void firePropertyChangeEvent(PropertyChangeEvent event) {
     90                for (PropertyChangeListener listener : propertyChangeListener) {
     91                        listener.propertyChange(event);
     92                }
     93        }
     94
     95        public void run() {
     96                LiveGpsData oldGpsData = null;
     97                LiveGpsData gpsData = null;
     98
     99                shutdownFlag = false;
     100                while (!shutdownFlag) {
     101                        double lat = 0;
     102                        double lon = 0;
     103                        float speed = 0;
     104                        float course = 0;
     105                        boolean haveFix = false;
     106
     107                        try {
     108                                if (!connected) {
     109                                        System.out.println("LiveGps tries to connect to gpsd");
     110                                        fireGpsStatusChangeEvent(
     111                                                        LiveGpsStatus.GpsStatus.CONNECTING,
     112                                                        tr("Connecting"));
     113                                        InetAddress[] addrs = InetAddress.getAllByName(gpsdHost);
     114                                        for (int i = 0; i < addrs.length && gpsdSocket == null; i++) {
     115                                                try {
     116                                                        gpsdSocket = new Socket(addrs[i], gpsdPort);
     117                                                        break;
     118                                                } catch (Exception e) {
     119                                                        System.out
     120                                                                        .println("LiveGps: Could not open connection to gpsd: "
     121                                                                                        + e);
     122                                                        gpsdSocket = null;
     123                                                }
     124                                        }
     125
     126                                        if (gpsdSocket != null) {
     127                                                gpsdReader = new BufferedReader(new InputStreamReader(
     128                                                                gpsdSocket.getInputStream()));
     129                                                gpsdSocket.getOutputStream().write(
     130                                                                new byte[] { 'w', 13, 10 });
     131                                                fireGpsStatusChangeEvent(
     132                                                                LiveGpsStatus.GpsStatus.CONNECTING,
     133                                                                tr("Connecting"));
     134                                                connected = true;
     135                                                System.out.println("LiveGps: Connected to gpsd");
     136                                        }
     137                                }
     138
     139                                if (connected) {
     140                                        // <FIXXME date="23.06.2007" author="cdaller">
     141                                        // TODO this read is blocking if gps is connected but has no
     142                                        // fix, so gpsd does not send positions
     143                                        String line = gpsdReader.readLine();
     144                                        // </FIXXME>
     145                                        if (line == null)
     146                                                break;
     147                                        String words[] = line.split(",");
     148
     149                                        if ((words.length == 0) || (!words[0].equals("GPSD"))) {
     150                                                // unexpected response.
     151                                                continue;
     152                                        }
     153
     154                                        for (int i = 1; i < words.length; i++) {
     155
     156                                                if ((words[i].length() < 2)
     157                                                                || (words[i].charAt(1) != '=')) {
     158                                                        // unexpected response.
     159                                                        continue;
     160                                                }
     161
     162                                                char what = words[i].charAt(0);
     163                                                String value = words[i].substring(2);
     164                                                oldGpsData = gpsData;
     165                                                gpsData = new LiveGpsData();
     166                                                switch (what) {
     167                                                case 'O':
     168                                                        // full report, tab delimited.
     169                                                        String[] status = value.split("\\s+");
     170                                                        if (status.length >= 5) {
     171                                                                lat = Double.parseDouble(status[3]);
     172                                                                lon = Double.parseDouble(status[4]);
     173                                                                try {
     174                                                                        speed = Float.parseFloat(status[9]);
     175                                                                        course = Float.parseFloat(status[8]);
     176                                                                        // view.setSpeed(speed);
     177                                                                        // view.setCourse(course);
     178                                                                } catch (NumberFormatException nex) {
     179                                                                }
     180                                                                haveFix = true;
     181                                                        }
     182                                                        break;
     183                                                case 'P':
     184                                                        // position report, tab delimited.
     185                                                        String[] pos = value.split("\\s+");
     186                                                        if (pos.length >= 2) {
     187                                                                lat = Double.parseDouble(pos[0]);
     188                                                                lon = Double.parseDouble(pos[1]);
     189                                                                speed = Float.NaN;
     190                                                                course = Float.NaN;
     191                                                                haveFix = true;
     192                                                        }
     193                                                default:
     194                                                        // not interested
     195                                                }
     196                                                fireGpsStatusChangeEvent(
     197                                                                LiveGpsStatus.GpsStatus.CONNECTED,
     198                                                                tr("Connected"));
     199                                                gpsData.setFix(haveFix);
     200                                                if (haveFix) {
     201                                                        // view.setCurrentPosition(lat, lon);
     202                                                        gpsData.setLatLon(new LatLon(lat, lon));
     203                                                        gpsData.setSpeed(speed);
     204                                                        gpsData.setCourse(course);
     205                                                        fireGpsDataChangeEvent(oldGpsData, gpsData);
     206                                                }
     207                                        }
     208                                } else {
     209                                        // not connected:
     210                                        fireGpsStatusChangeEvent(
     211                                                        LiveGpsStatus.GpsStatus.DISCONNECTED,
     212                                                        tr("Not connected"));
     213                                        try {
     214                                                Thread.sleep(1000);
     215                                        } catch (InterruptedException ignore) {
     216                                        }
     217                                        ;
     218                                }
     219                        } catch (IOException iox) {
     220                                connected = false;
     221                                if (gpsData != null) {
     222                                        gpsData.setFix(false);
     223                                        fireGpsDataChangeEvent(oldGpsData, gpsData);
     224                                }
     225                                fireGpsStatusChangeEvent(
     226                                                LiveGpsStatus.GpsStatus.CONNECTION_FAILED,
     227                                                tr("Connection Failed"));
     228                                try {
     229                                        Thread.sleep(1000);
     230                                } catch (InterruptedException ignore) {
     231                                }
     232                                ;
     233                                // send warning to layer
     234
     235                        }
     236                }
     237
     238                fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.DISCONNECTED,
     239                                tr("Not connected"));
     240                if (gpsdSocket != null) {
     241                        try {
     242                                gpsdSocket.close();
     243                                gpsdSocket = null;
     244                                System.out.println("LiveGps: Disconnected from gpsd");
     245                        } catch (Exception e) {
     246                                System.out
     247                                                .println("LiveGps: Unable to close socket; reconnection may not be possible");
     248                        }
     249                }
     250        }
     251
     252        public void shutdown() {
     253                shutdownFlag = true;
     254        }
     255
    295256}
  • applications/editors/josm/plugins/livegps/src/livegps/LiveGpsLayer.java

    r18597 r19011  
    2323
    2424public class LiveGpsLayer extends GpxLayer implements PropertyChangeListener {
    25     public static final String LAYER_NAME = tr("LiveGPS layer");
    26     public static final String KEY_LIVEGPS_COLOR ="color.livegps.position";
    27     LatLon lastPos;
    28     WayPoint lastPoint;
    29     GpxTrack trackBeingWritten;
    30     Collection<WayPoint> trackSegment;
    31     float speed;
    32     float course;
    33     String status;
    34     //JLabel lbl;
    35     boolean autocenter;
    36     private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
     25        public static final String LAYER_NAME = tr("LiveGPS layer");
     26        public static final String KEY_LIVEGPS_COLOR = "color.livegps.position";
     27        LatLon lastPos;
     28        WayPoint lastPoint;
     29        GpxTrack trackBeingWritten;
     30        Collection<WayPoint> trackSegment;
     31        float speed;
     32        float course;
     33        String status;
     34        // JLabel lbl;
     35        boolean autocenter;
     36        private SimpleDateFormat dateFormat = new SimpleDateFormat(
     37                        "yyyy-MM-dd'T'HH:mm:ss.SSS");
    3738
    38     public LiveGpsLayer(GpxData data)
    39     {
    40         super (data, LAYER_NAME);
    41         trackBeingWritten = new GpxTrack();
    42         trackBeingWritten.attr.put("desc", "josm live gps");
    43         trackSegment = new ArrayList<WayPoint>();
    44         trackBeingWritten.trackSegs.add(trackSegment);
    45         data.tracks.add(trackBeingWritten);
    46     }
     39        /**
     40         * The suppressor is queried, if the GUI shall be re-drawn.
     41         */
     42        private ILiveGpsSuppressor suppressor;
    4743
    48     void setCurrentPosition(double lat, double lon)
    49     {
    50         //System.out.println("adding pos " + lat + "," + lon);
    51         LatLon thisPos = new LatLon(lat, lon);
    52         if ((lastPos != null) && (thisPos.equalsEpsilon(lastPos))) {
    53             // no change in position
    54             // maybe show a "paused" cursor or some such
    55             return;
    56         }
     44        public LiveGpsLayer(GpxData data) {
     45                super(data, LAYER_NAME);
     46                trackBeingWritten = new GpxTrack();
     47                trackBeingWritten.attr.put("desc", "josm live gps");
     48                trackSegment = new ArrayList<WayPoint>();
     49                trackBeingWritten.trackSegs.add(trackSegment);
     50                data.tracks.add(trackBeingWritten);
     51        }
    5752
    58         lastPos = thisPos;
    59         lastPoint = new WayPoint(thisPos);
    60         lastPoint.attr.put("time", dateFormat.format(new Date()));
    61         // synchronize when adding data, as otherwise the autosave action
    62         // needs concurrent access and this results in an exception!
    63         synchronized (LiveGpsLock.class) {
    64             trackSegment.add(lastPoint);
    65         }
    66         if (autocenter) {
    67             center();
    68         }
     53        void setCurrentPosition(double lat, double lon) {
     54                // System.out.println("adding pos " + lat + "," + lon);
     55                LatLon thisPos = new LatLon(lat, lon);
     56                if ((lastPos != null) && (thisPos.equalsEpsilon(lastPos))) {
     57                        // no change in position
     58                        // maybe show a "paused" cursor or some such
     59                        return;
     60                }
    6961
    70         //Main.map.repaint();
    71     }
     62                lastPos = thisPos;
     63                lastPoint = new WayPoint(thisPos);
     64                lastPoint.attr.put("time", dateFormat.format(new Date()));
     65                // synchronize when adding data, as otherwise the autosave action
     66                // needs concurrent access and this results in an exception!
     67                synchronized (LiveGpsLock.class) {
     68                        trackSegment.add(lastPoint);
     69                }
     70                if (autocenter && allowRedraw()) {
     71                        center();
     72                }
    7273
    73     public void center()
    74     {
    75         if (lastPoint != null)
    76             Main.map.mapView.zoomTo(lastPoint.getCoor());
    77     }
     74                // Main.map.repaint();
     75        }
    7876
    79 //  void setStatus(String status)
    80 //  {
    81 //      this.status = status;
    82 //      Main.map.repaint();
    83 //        System.out.println("LiveGps status: " + status);
    84 //  }
     77        public void center() {
     78                if (lastPoint != null)
     79                        Main.map.mapView.zoomTo(lastPoint.getCoor());
     80        }
    8581
    86     void setSpeed(float metresPerSecond)
    87     {
    88         speed = metresPerSecond;
    89         //Main.map.repaint();
    90     }
     82        // void setStatus(String status)
     83        // {
     84        // this.status = status;
     85        // Main.map.repaint();
     86        // System.out.println("LiveGps status: " + status);
     87        // }
    9188
    92     void setCourse(float degrees)
    93     {
    94         course = degrees;
    95         //Main.map.repaint();
    96     }
     89        void setSpeed(float metresPerSecond) {
     90                speed = metresPerSecond;
     91                // Main.map.repaint();
     92        }
    9793
    98     public void setAutoCenter(boolean ac)
    99     {
    100         autocenter = ac;
    101     }
     94        void setCourse(float degrees) {
     95                course = degrees;
     96                // Main.map.repaint();
     97        }
    10298
    103     @Override public void paint(Graphics2D g, MapView mv, Bounds bounds)
    104     {
    105         //System.out.println("in paint");
    106         synchronized (LiveGpsLock.class) {
    107             //System.out.println("in synced paint");
    108             super.paint(g, mv, bounds);
    109 //          int statusHeight = 50;
    110 //          Rectangle mvs = mv.getBounds();
    111 //          mvs.y = mvs.y + mvs.height - statusHeight;
    112 //          mvs.height = statusHeight;
    113 //          g.setColor(new Color(1.0f, 1.0f, 1.0f, 0.8f));
    114 //          g.fillRect(mvs.x, mvs.y, mvs.width, mvs.height);
     99        public void setAutoCenter(boolean ac) {
     100                autocenter = ac;
     101        }
    115102
    116             if (lastPoint != null)
    117             {
    118                 Point screen = mv.getPoint(lastPoint.getCoor());
    119                 g.setColor(Main.pref.getColor(KEY_LIVEGPS_COLOR, Color.RED));
    120                 g.drawOval(screen.x-10, screen.y-10,20,20);
    121                 g.drawOval(screen.x-9, screen.y-9,18,18);
    122             }
     103        @Override
     104        public void paint(Graphics2D g, MapView mv, Bounds bounds) {
     105                // System.out.println("in paint");
     106                synchronized (LiveGpsLock.class) {
     107                        // System.out.println("in synced paint");
     108                        super.paint(g, mv, bounds);
     109                        // int statusHeight = 50;
     110                        // Rectangle mvs = mv.getBounds();
     111                        // mvs.y = mvs.y + mvs.height - statusHeight;
     112                        // mvs.height = statusHeight;
     113                        // g.setColor(new Color(1.0f, 1.0f, 1.0f, 0.8f));
     114                        // g.fillRect(mvs.x, mvs.y, mvs.width, mvs.height);
    123115
    124 //          lbl.setText("gpsd: "+status+" Speed: " + speed + " Course: "+course);
    125 //          lbl.setBounds(0, 0, mvs.width-10, mvs.height-10);
    126 //          Graphics sub = g.create(mvs.x+5, mvs.y+5, mvs.width-10, mvs.height-10);
    127 //          lbl.paint(sub);
     116                        if (lastPoint != null) {
     117                                Point screen = mv.getPoint(lastPoint.getCoor());
     118                                g.setColor(Main.pref.getColor(KEY_LIVEGPS_COLOR, Color.RED));
     119                                g.drawOval(screen.x - 10, screen.y - 10, 20, 20);
     120                                g.drawOval(screen.x - 9, screen.y - 9, 18, 18);
     121                        }
    128122
    129 //          if(status != null) {
    130 //          g.setColor(Color.WHITE);
    131 //          g.drawString("gpsd: " + status, 5, mv.getBounds().height - 15); // lower left corner
    132 //          }
    133         }
    134     }
     123                        // lbl.setText("gpsd: "+status+" Speed: " + speed +
     124                        // " Course: "+course);
     125                        // lbl.setBounds(0, 0, mvs.width-10, mvs.height-10);
     126                        // Graphics sub = g.create(mvs.x+5, mvs.y+5, mvs.width-10,
     127                        // mvs.height-10);
     128                        // lbl.paint(sub);
    135129
    136     /* (non-Javadoc)
    137      * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
    138      */
    139     public void propertyChange(PropertyChangeEvent evt) {
    140         if(!isVisible()) {
    141             return;
    142         }
    143         if("gpsdata".equals(evt.getPropertyName())) {
    144             LiveGpsData data = (LiveGpsData) evt.getNewValue();
    145             if(data.isFix()) {
    146                 setCurrentPosition(data.getLatitude(), data.getLongitude());
    147                 if(!Float.isNaN(data.getSpeed())) {
    148                     setSpeed(data.getSpeed());
    149                 }
    150                 if(!Float.isNaN(data.getCourse())) {
    151                     setCourse(data.getCourse());
    152                 }
    153                 Main.map.repaint();
    154             }
    155         }
    156     }
     130                        // if(status != null) {
     131                        // g.setColor(Color.WHITE);
     132                        // g.drawString("gpsd: " + status, 5, mv.getBounds().height - 15);
     133                        // // lower left corner
     134                        // }
     135                }
     136        }
     137
     138        /* (non-Javadoc)
     139         * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
     140         */
     141        public void propertyChange(PropertyChangeEvent evt) {
     142                if (!isVisible()) {
     143                        return;
     144                }
     145                if ("gpsdata".equals(evt.getPropertyName())) {
     146                        LiveGpsData data = (LiveGpsData) evt.getNewValue();
     147                        if (data.isFix()) {
     148                                setCurrentPosition(data.getLatitude(), data.getLongitude());
     149                                if (!Float.isNaN(data.getSpeed())) {
     150                                        setSpeed(data.getSpeed());
     151                                }
     152                                if (!Float.isNaN(data.getCourse())) {
     153                                        setCourse(data.getCourse());
     154                                }
     155                                if (!autocenter && allowRedraw()) {
     156                                        Main.map.repaint();
     157                                }
     158                        }
     159                }
     160        }
     161
     162        /**
     163         * @param suppressor the suppressor to set
     164         */
     165        public void setSuppressor(ILiveGpsSuppressor suppressor) {
     166                this.suppressor = suppressor;
     167        }
     168
     169        /**
     170         * @return the suppressor
     171         */
     172        public ILiveGpsSuppressor getSuppressor() {
     173                return suppressor;
     174        }
     175
     176        /**
     177         * Check, if a redraw is currently allowed.
     178         *
     179         * @return true, if a redraw is permitted, false, if a re-draw
     180         * should be suppressed.
     181         */
     182        private boolean allowRedraw() {
     183                if (this.suppressor != null) {
     184                        return this.suppressor.isAllowUpdate();
     185                } else {
     186                        return true;
     187                }
     188        }
    157189}
  • applications/editors/josm/plugins/livegps/src/livegps/LiveGpsPlugin.java

    r18941 r19011  
    2525import org.openstreetmap.josm.tools.Shortcut;
    2626
    27 public class LiveGpsPlugin extends Plugin implements LayerChangeListener
    28 {
    29     private LiveGpsAcquirer acquirer = null;
    30     private Thread acquirerThread = null;
    31     private JMenu lgpsmenu;
    32     private JCheckBoxMenuItem lgpscapture;
    33     private JMenuItem lgpscenter;
    34     private JCheckBoxMenuItem lgpsautocenter;
    35     private LiveGpsDialog lgpsdialog;
    36     List<PropertyChangeListener>listenerQueue;
    37 
    38     private GpxData data = new GpxData();
    39     private LiveGpsLayer lgpslayer = null;
    40 
    41     public class CaptureAction extends JosmAction {
    42         public CaptureAction() {
    43             super(tr("Capture GPS Track"), "capturemenu", tr("Connect to gpsd server and show current position in LiveGPS layer."),
    44                 Shortcut.registerShortcut("menu:livegps:capture", tr("Menu: {0}", tr("Capture GPS Track")),
    45                 KeyEvent.VK_R, Shortcut.GROUP_MENU), true);
    46         }
    47 
    48         public void actionPerformed(ActionEvent e) {
    49             enableTracking(lgpscapture.isSelected());
    50         }
    51     }
    52 
    53     public class CenterAction extends JosmAction {
    54         public CenterAction() {
    55             super(tr("Center Once"), "centermenu", tr("Center the LiveGPS layer to current position."),
    56             Shortcut.registerShortcut("edit:centergps", tr("Edit: {0}", tr("Center Once")),
    57             KeyEvent.VK_HOME, Shortcut.GROUP_EDIT), true);
    58         }
    59 
    60         public void actionPerformed(ActionEvent e) {
    61             if(lgpslayer != null) {
    62                 lgpslayer.center();
    63             }
    64         }
    65     }
    66 
    67     public class AutoCenterAction extends JosmAction {
    68         public AutoCenterAction() {
    69             super(tr("Auto-Center"), "autocentermenu", tr("Continuously center the LiveGPS layer to current position."),
    70             Shortcut.registerShortcut("menu:livegps:autocenter", tr("Menu: {0}", tr("Capture GPS Track")),
    71             KeyEvent.VK_HOME, Shortcut.GROUP_MENU), true);
    72         }
    73 
    74         public void actionPerformed(ActionEvent e) {
    75             if(lgpslayer != null) {
    76                 setAutoCenter(lgpsautocenter.isSelected());
    77             }
    78         }
    79     }
    80 
    81     public void activeLayerChange(Layer oldLayer, Layer newLayer) {
    82     }
    83 
    84     public void layerAdded(Layer newLayer) {
    85     }
    86 
    87     public void layerRemoved(Layer oldLayer) {
    88         if(oldLayer == lgpslayer)
    89         {
    90             enableTracking(false);
    91             lgpscapture.setSelected(false);
    92             removePropertyChangeListener(lgpslayer);
    93             Layer.listeners.remove(this);
    94             lgpslayer = null;
    95         }
    96     }
    97 
    98     public LiveGpsPlugin()
    99     {
    100         MainMenu menu = Main.main.menu;
    101         lgpsmenu = menu.addMenu(marktr("LiveGPS"), KeyEvent.VK_G, menu.defaultMenuPos, ht("/Plugin/LiveGPS"));
    102 
    103         JosmAction captureAction = new CaptureAction();
    104         lgpscapture = new JCheckBoxMenuItem(captureAction);
    105         lgpsmenu.add(lgpscapture);
    106         lgpscapture.setAccelerator(captureAction.getShortcut().getKeyStroke());
    107 
    108         JosmAction centerAction = new CenterAction();
    109         JMenuItem centerMenu = new JMenuItem(centerAction);
    110         lgpsmenu.add(centerMenu);
    111         centerMenu.setAccelerator(centerAction.getShortcut().getKeyStroke());
    112 
    113         JosmAction autoCenterAction = new AutoCenterAction();
    114         lgpsautocenter = new JCheckBoxMenuItem(autoCenterAction);
    115         lgpsmenu.add(lgpsautocenter);
    116         lgpsautocenter.setAccelerator(autoCenterAction.getShortcut().getKeyStroke());
    117     }
    118 
    119     /**
    120      * Set to <code>true</code> if the current position should always be in the center of the map.
    121      * @param autoCenter if <code>true</code> the map is always centered.
    122      */
    123     public void setAutoCenter(boolean autoCenter) {
    124         lgpsautocenter.setSelected(autoCenter); // just in case this method was not called from the menu
    125         if(lgpslayer != null) {
    126             lgpslayer.setAutoCenter(autoCenter);
    127             if (autoCenter) lgpslayer.center();
    128         }
    129     }
    130 
    131     /**
    132      * Returns <code>true</code> if autocenter is selected.
    133      * @return <code>true</code> if autocenter is selected.
    134      */
    135     public boolean isAutoCenter() {
    136         return lgpsautocenter.isSelected();
    137     }
    138 
    139     /**
    140      * Enable or disable gps tracking
    141      * @param enable if <code>true</code> tracking is started.
    142      */
    143     public void enableTracking(boolean enable) {
    144         if ((acquirer != null) && (!enable))
    145         {
    146             acquirer.shutdown();
    147             acquirerThread = null;
    148         }
    149         else if(enable)
    150         {
    151             if (acquirer == null) {
    152                 acquirer = new LiveGpsAcquirer();
    153                 if (lgpslayer == null) {
    154                     lgpslayer = new LiveGpsLayer(data);
    155                     Main.main.addLayer(lgpslayer);
    156                     Layer.listeners.add(this);
    157                     lgpslayer.setAutoCenter(isAutoCenter());
    158                 }
    159                 // connect layer with acquirer:
    160                 addPropertyChangeListener(lgpslayer);
    161                 // add all listeners that were added before the acquirer existed:
    162                 if(listenerQueue != null) {
    163                     for(PropertyChangeListener listener : listenerQueue) {
    164                         addPropertyChangeListener(listener);
    165                     }
    166                     listenerQueue.clear();
    167                 }
    168             }
    169             if(acquirerThread == null) {
    170                 acquirerThread = new Thread(acquirer);
    171                 acquirerThread.start();
    172             }
    173         }
    174     }
    175 
    176     /**
    177      * Add a listener for gps events.
    178      * @param listener the listener.
    179      */
    180     public void addPropertyChangeListener(PropertyChangeListener listener) {
    181         if(acquirer != null) {
    182             acquirer.addPropertyChangeListener(listener);
    183         } else {
    184             if(listenerQueue == null) {
    185                 listenerQueue = new ArrayList<PropertyChangeListener>();
    186             }
    187             listenerQueue.add(listener);
    188         }
    189     }
    190 
    191     /**
    192      * Remove a listener for gps events.
    193      * @param listener the listener.
    194      */
    195     public void removePropertyChangeListener(PropertyChangeListener listener) {
    196         if(acquirer != null)
    197             acquirer.removePropertyChangeListener(listener);
    198         else if(listenerQueue != null && listenerQueue.contains(listener))
    199             listenerQueue.remove(listener);
    200     }
    201 
    202     /* (non-Javadoc)
    203      * @see org.openstreetmap.josm.plugins.Plugin#mapFrameInitialized(org.openstreetmap.josm.gui.MapFrame, org.openstreetmap.josm.gui.MapFrame)
    204      */
    205     @Override
    206     public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
    207         if(newFrame != null) {
    208             // add dialog
    209             newFrame.addToggleDialog(lgpsdialog = new LiveGpsDialog(newFrame));
    210             // connect listeners with acquirer:
    211             addPropertyChangeListener(lgpsdialog);
    212         }
    213     }
    214 
    215     /**
    216      * @return the lgpsmenu
    217      */
    218     public JMenu getLgpsMenu() {
    219         return this.lgpsmenu;
    220     }
     27public class LiveGpsPlugin extends Plugin implements LayerChangeListener {
     28        private LiveGpsAcquirer acquirer = null;
     29        private Thread acquirerThread = null;
     30        private JMenu lgpsmenu;
     31        private JCheckBoxMenuItem lgpscapture;
     32        private JMenuItem lgpscenter;
     33        private JCheckBoxMenuItem lgpsautocenter;
     34        private LiveGpsDialog lgpsdialog;
     35        List<PropertyChangeListener> listenerQueue;
     36
     37        private GpxData data = new GpxData();
     38        private LiveGpsLayer lgpslayer = null;
     39
     40        /**
     41         * The LiveGpsSuppressor is queried, if an event shall be suppressed.
     42         */
     43        private LiveGpsSuppressor suppressor;
     44
     45        /**
     46         * separate thread, where the LiveGpsSuppressor executes.
     47         */
     48        private Thread suppressorThread;
     49
     50        public class CaptureAction extends JosmAction {
     51                public CaptureAction() {
     52                        super(
     53                                        tr("Capture GPS Track"),
     54                                        "capturemenu",
     55                                        tr("Connect to gpsd server and show current position in LiveGPS layer."),
     56                                        Shortcut.registerShortcut("menu:livegps:capture", tr(
     57                                                        "Menu: {0}", tr("Capture GPS Track")),
     58                                                        KeyEvent.VK_R, Shortcut.GROUP_MENU), true);
     59                }
     60
     61                public void actionPerformed(ActionEvent e) {
     62                        enableTracking(lgpscapture.isSelected());
     63                }
     64        }
     65
     66        public class CenterAction extends JosmAction {
     67                public CenterAction() {
     68                        super(tr("Center Once"), "centermenu",
     69                                        tr("Center the LiveGPS layer to current position."),
     70                                        Shortcut.registerShortcut("edit:centergps", tr("Edit: {0}",
     71                                                        tr("Center Once")), KeyEvent.VK_HOME,
     72                                                        Shortcut.GROUP_EDIT), true);
     73                }
     74
     75                public void actionPerformed(ActionEvent e) {
     76                        if (lgpslayer != null) {
     77                                lgpslayer.center();
     78                        }
     79                }
     80        }
     81
     82        public class AutoCenterAction extends JosmAction {
     83                public AutoCenterAction() {
     84                        super(
     85                                        tr("Auto-Center"),
     86                                        "autocentermenu",
     87                                        tr("Continuously center the LiveGPS layer to current position."),
     88                                        Shortcut.registerShortcut("menu:livegps:autocenter", tr(
     89                                                        "Menu: {0}", tr("Capture GPS Track")),
     90                                                        KeyEvent.VK_HOME, Shortcut.GROUP_MENU), true);
     91                }
     92
     93                public void actionPerformed(ActionEvent e) {
     94                        if (lgpslayer != null) {
     95                                setAutoCenter(lgpsautocenter.isSelected());
     96                        }
     97                }
     98        }
     99
     100        public void activeLayerChange(Layer oldLayer, Layer newLayer) {
     101        }
     102
     103        public void layerAdded(Layer newLayer) {
     104        }
     105
     106        public void layerRemoved(Layer oldLayer) {
     107                if (oldLayer == lgpslayer) {
     108                        enableTracking(false);
     109                        lgpscapture.setSelected(false);
     110                        removePropertyChangeListener(lgpslayer);
     111                        Layer.listeners.remove(this);
     112                        lgpslayer = null;
     113                }
     114        }
     115
     116        public LiveGpsPlugin() {
     117                MainMenu menu = Main.main.menu;
     118                lgpsmenu = menu.addMenu(marktr("LiveGPS"), KeyEvent.VK_G,
     119                                menu.defaultMenuPos, ht("/Plugin/LiveGPS"));
     120
     121                JosmAction captureAction = new CaptureAction();
     122                lgpscapture = new JCheckBoxMenuItem(captureAction);
     123                lgpsmenu.add(lgpscapture);
     124                lgpscapture.setAccelerator(captureAction.getShortcut().getKeyStroke());
     125
     126                JosmAction centerAction = new CenterAction();
     127                JMenuItem centerMenu = new JMenuItem(centerAction);
     128                lgpsmenu.add(centerMenu);
     129                centerMenu.setAccelerator(centerAction.getShortcut().getKeyStroke());
     130
     131                JosmAction autoCenterAction = new AutoCenterAction();
     132                lgpsautocenter = new JCheckBoxMenuItem(autoCenterAction);
     133                lgpsmenu.add(lgpsautocenter);
     134                lgpsautocenter.setAccelerator(autoCenterAction.getShortcut()
     135                                .getKeyStroke());
     136        }
     137
     138        /**
     139         * Set to <code>true</code> if the current position should always be in the center of the map.
     140         * @param autoCenter if <code>true</code> the map is always centered.
     141         */
     142        public void setAutoCenter(boolean autoCenter) {
     143                lgpsautocenter.setSelected(autoCenter); // just in case this method was
     144                // not called from the menu
     145                if (lgpslayer != null) {
     146                        lgpslayer.setAutoCenter(autoCenter);
     147                        if (autoCenter)
     148                                lgpslayer.center();
     149                }
     150        }
     151
     152        /**
     153         * Returns <code>true</code> if autocenter is selected.
     154         * @return <code>true</code> if autocenter is selected.
     155         */
     156        public boolean isAutoCenter() {
     157                return lgpsautocenter.isSelected();
     158        }
     159
     160        /**
     161         * Enable or disable gps tracking
     162         * @param enable if <code>true</code> tracking is started.
     163         */
     164        public void enableTracking(boolean enable) {
     165                if ((acquirer != null) && (!enable)) {
     166                        acquirer.shutdown();
     167                        acquirerThread = null;
     168
     169                        // also stop the suppressor
     170                        if (suppressor != null) {
     171                                suppressor.shutdown();
     172                                suppressorThread = null;
     173                                if (lgpslayer != null) {
     174                                        lgpslayer.setSuppressor(null);
     175                                }
     176                        }
     177                } else if (enable) {
     178                        // also start the suppressor
     179                        if (suppressor == null) {
     180                                suppressor = new LiveGpsSuppressor();
     181                        }
     182                        if (suppressorThread == null) {
     183                                suppressorThread = new Thread(suppressor);
     184                                suppressorThread.start();
     185                        }
     186
     187                        if (acquirer == null) {
     188                                acquirer = new LiveGpsAcquirer();
     189                                if (lgpslayer == null) {
     190                                        lgpslayer = new LiveGpsLayer(data);
     191                                        Main.main.addLayer(lgpslayer);
     192                                        Layer.listeners.add(this);
     193                                        lgpslayer.setAutoCenter(isAutoCenter());
     194                                }
     195                                // connect layer with acquirer:
     196                                addPropertyChangeListener(lgpslayer);
     197
     198                                // connect layer with suppressor:
     199                                lgpslayer.setSuppressor(suppressor);
     200                                // add all listeners that were added before the acquirer
     201                                // existed:
     202                                if (listenerQueue != null) {
     203                                        for (PropertyChangeListener listener : listenerQueue) {
     204                                                addPropertyChangeListener(listener);
     205                                        }
     206                                        listenerQueue.clear();
     207                                }
     208                        }
     209                        if (acquirerThread == null) {
     210                                acquirerThread = new Thread(acquirer);
     211                                acquirerThread.start();
     212                        }
     213
     214                }
     215        }
     216
     217        /**
     218         * Add a listener for gps events.
     219         * @param listener the listener.
     220         */
     221        public void addPropertyChangeListener(PropertyChangeListener listener) {
     222                if (acquirer != null) {
     223                        acquirer.addPropertyChangeListener(listener);
     224                } else {
     225                        if (listenerQueue == null) {
     226                                listenerQueue = new ArrayList<PropertyChangeListener>();
     227                        }
     228                        listenerQueue.add(listener);
     229                }
     230        }
     231
     232        /**
     233         * Remove a listener for gps events.
     234         * @param listener the listener.
     235         */
     236        public void removePropertyChangeListener(PropertyChangeListener listener) {
     237                if (acquirer != null)
     238                        acquirer.removePropertyChangeListener(listener);
     239                else if (listenerQueue != null && listenerQueue.contains(listener))
     240                        listenerQueue.remove(listener);
     241        }
     242
     243        /* (non-Javadoc)
     244         * @see org.openstreetmap.josm.plugins.Plugin#mapFrameInitialized(org.openstreetmap.josm.gui.MapFrame, org.openstreetmap.josm.gui.MapFrame)
     245         */
     246        @Override
     247        public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
     248                if (newFrame != null) {
     249                        // add dialog
     250                        newFrame.addToggleDialog(lgpsdialog = new LiveGpsDialog(newFrame));
     251                        // connect listeners with acquirer:
     252                        addPropertyChangeListener(lgpsdialog);
     253                }
     254        }
     255
     256        /**
     257         * @return the lgpsmenu
     258         */
     259        public JMenu getLgpsMenu() {
     260                return this.lgpsmenu;
     261        }
     262
    221263}
  • applications/editors/josm/plugins/livegps/src/livegps/LiveGpsSuppressor.java

    r19001 r19011  
    1616 *
    1717 */
    18 public class LiveGpsSuppressor implements Runnable {
     18public class LiveGpsSuppressor implements Runnable, ILiveGpsSuppressor {
    1919
    2020        /**
     
    3636         * Controls if this thread is still in used.
    3737         */
    38         boolean shutdownFlag = false;
     38        private boolean shutdownFlag = false;
    3939
    4040        /**
     
    9191         *
    9292         * @return true, if an update is currently allowed; false, if the update shall be suppressed.
     93         * @see livegps.ILiveGpsSuppressor#isAllowUpdate()
    9394         */
    9495        public synchronized boolean isAllowUpdate() {
Note: See TracChangeset for help on using the changeset viewer.