Changeset 23191 in osm for applications/editors/josm/plugins/livegps/src/livegps
- Timestamp:
- 2010-09-15T18:56:19+02:00 (14 years ago)
- Location:
- applications/editors/josm/plugins/livegps/src/livegps
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/livegps/src/livegps/AppendableGpxTrackSegment.java
r20431 r23191 14 14 public class AppendableGpxTrackSegment implements GpxTrackSegment { 15 15 16 17 18 19 16 private WayPoint[] wayPoints = new WayPoint[16]; 17 private int size; 18 private Bounds bounds; 19 private double length; 20 20 21 22 23 21 public Bounds getBounds() { 22 return bounds; 23 } 24 24 25 26 27 25 public Collection<WayPoint> getWayPoints() { 26 return new CopyList<WayPoint>(wayPoints, size); 27 } 28 28 29 30 31 32 33 34 29 public void addWaypoint(WayPoint p) { 30 if (wayPoints.length == size) { 31 WayPoint[] newWaypoints = new WayPoint[wayPoints.length * 2]; 32 System.arraycopy(wayPoints, 0, newWaypoints, 0, wayPoints.length); 33 wayPoints = newWaypoints; 34 } 35 35 36 37 38 39 40 41 36 if (size > 0) { 37 Double distance = wayPoints[size - 1].getCoor().greatCircleDistance(p.getCoor()); 38 if (!distance.isNaN() && !distance.isInfinite()) { 39 length += distance; 40 } 41 } 42 42 43 44 45 46 47 43 if (bounds == null) { 44 bounds = new Bounds(p.getCoor()); 45 } else { 46 bounds.extend(p.getCoor()); 47 } 48 48 49 50 51 49 wayPoints[size] = p; 50 size++; 51 } 52 52 53 54 55 53 public double length() { 54 return length; 55 } 56 56 57 58 59 60 57 @Override 58 public int getUpdateCount() { 59 return size; 60 } 61 61 62 62 } -
applications/editors/josm/plugins/livegps/src/livegps/ILiveGpsSuppressor.java
r19011 r23191 3 3 /** 4 4 * Interface for class LiveGpsSuppressor, only has a query if currently an update is allowed. 5 * 6 * @author casualwalker 5 * 6 * @author casualwalker 7 7 * 8 8 */ 9 9 public interface ILiveGpsSuppressor { 10 10 11 12 13 14 15 16 17 18 11 /** 12 * Query, if an update is currently allowed. 13 * When it is allowed, it will disable the allowUpdate flag as a side effect. 14 * (this means, one thread got to issue an update event) 15 * 16 * @return true, if an update is currently allowed; false, if the update shall be suppressed. 17 */ 18 boolean isAllowUpdate(); 19 19 20 20 } -
applications/editors/josm/plugins/livegps/src/livegps/LiveGpsAcquirer.java
r21622 r23191 22 22 23 23 public class LiveGpsAcquirer implements Runnable { 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 try { 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 24 private String gpsdHost; 25 private int gpsdPort; 26 27 private Socket gpsdSocket; 28 private BufferedReader gpsdReader; 29 private boolean connected = false; 30 private boolean shutdownFlag = false; 31 private boolean JSONProtocol = true; 32 33 private final List<PropertyChangeListener> propertyChangeListener = new ArrayList<PropertyChangeListener>(); 34 private PropertyChangeEvent lastStatusEvent; 35 private PropertyChangeEvent lastDataEvent; 36 37 /** 38 * Constructor, initializes the configurable settings. 39 */ 40 public LiveGpsAcquirer() { 41 super(); 42 43 gpsdHost = Main.pref.get("livegps.gpsd.host", "localhost"); 44 gpsdPort = Main.pref.getInteger("livegps.gpsd.port", 2947); 45 // put the settings back in to the preferences, makes keys appear. 46 Main.pref.put("livegps.gpsd.host", gpsdHost); 47 Main.pref.putInteger("livegps.gpsd.port", gpsdPort); 48 } 49 50 /** 51 * Adds a property change listener to the acquirer. 52 * @param listener the new listener 53 */ 54 public void addPropertyChangeListener(PropertyChangeListener listener) { 55 if (!propertyChangeListener.contains(listener)) { 56 propertyChangeListener.add(listener); 57 } 58 } 59 60 /** 61 * Remove a property change listener from the acquirer. 62 * @param listener the new listener 63 */ 64 public void removePropertyChangeListener(PropertyChangeListener listener) { 65 if (propertyChangeListener.contains(listener)) { 66 propertyChangeListener.remove(listener); 67 } 68 } 69 70 /** 71 * Fire a gps status change event. Fires events with key "gpsstatus" and a {@link LiveGpsStatus} 72 * object as value. 73 * The status event may be sent any time. 74 * @param status the status. 75 * @param statusMessage the status message. 76 */ 77 public void fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus status, 78 String statusMessage) { 79 PropertyChangeEvent event = new PropertyChangeEvent(this, "gpsstatus", 80 null, new LiveGpsStatus(status, statusMessage)); 81 82 if (!event.equals(lastStatusEvent)) { 83 firePropertyChangeEvent(event); 84 lastStatusEvent = event; 85 } 86 } 87 88 /** 89 * Fire a gps data change event to all listeners. Fires events with key "gpsdata" and a 90 * {@link LiveGpsData} object as values. 91 * This event is only sent, when the suppressor permits it. This 92 * event will cause the UI to re-draw itself, which has some performance penalty, 93 * @param oldData the old gps data. 94 * @param newData the new gps data. 95 */ 96 public void fireGpsDataChangeEvent(LiveGpsData oldData, LiveGpsData newData) { 97 PropertyChangeEvent event = new PropertyChangeEvent(this, "gpsdata", 98 oldData, newData); 99 100 if (!event.equals(lastDataEvent)) { 101 firePropertyChangeEvent(event); 102 lastDataEvent = event; 103 } 104 } 105 106 /** 107 * Fires the given event to all listeners. 108 * @param event the event to fire. 109 */ 110 protected void firePropertyChangeEvent(PropertyChangeEvent event) { 111 for (PropertyChangeListener listener : propertyChangeListener) { 112 listener.propertyChange(event); 113 } 114 } 115 116 public void run() { 117 LiveGpsData oldGpsData = null; 118 LiveGpsData gpsData = null; 119 120 shutdownFlag = false; 121 while (!shutdownFlag) { 122 123 try { 124 if (!connected) 125 connect(); 126 127 if (connected) { 128 String line; 129 130 // <FIXXME date="23.06.2007" author="cdaller"> 131 // TODO this read is blocking if gps is connected but has no 132 // fix, so gpsd does not send positions 133 line = gpsdReader.readLine(); 134 // </FIXXME> 135 if (line == null) 136 break; 137 138 if (JSONProtocol == true) 139 gpsData = ParseJSON(line); 140 else 141 gpsData = ParseOld(line); 142 143 if (gpsData == null) 144 continue; 145 146 fireGpsDataChangeEvent(oldGpsData, gpsData); 147 oldGpsData = gpsData; 148 } else { 149 fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.DISCONNECTED, tr("Not connected")); 150 try { 151 Thread.sleep(1000); 152 } catch (InterruptedException ignore) {} 153 } 154 } catch (IOException iox) { 155 connected = false; 156 if (gpsData != null) { 157 gpsData.setFix(false); 158 fireGpsDataChangeEvent(oldGpsData, gpsData); 159 } 160 fireGpsStatusChangeEvent( 161 LiveGpsStatus.GpsStatus.CONNECTION_FAILED, 162 tr("Connection Failed")); 163 try { 164 Thread.sleep(1000); 165 } catch (InterruptedException ignore) {} ; 166 // send warning to layer 167 } 168 } 169 170 fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.DISCONNECTED, 171 tr("Not connected")); 172 if (gpsdSocket != null) { 173 try { 174 gpsdSocket.close(); 175 gpsdSocket = null; 176 System.out.println("LiveGps: Disconnected from gpsd"); 177 } catch (Exception e) { 178 System.out.println("LiveGps: Unable to close socket; reconnection may not be possible"); 179 } 180 } 181 } 182 183 public void shutdown() { 184 shutdownFlag = true; 185 } 186 187 private void connect() throws IOException { 188 JSONObject greeting; 189 String line, type, release; 190 191 System.out.println("LiveGps: trying to connect to gpsd at " + gpsdHost + ":" + gpsdPort); 192 fireGpsStatusChangeEvent( LiveGpsStatus.GpsStatus.CONNECTING, tr("Connecting")); 193 194 InetAddress[] addrs = InetAddress.getAllByName(gpsdHost); 195 for (int i = 0; i < addrs.length && gpsdSocket == null; i++) { 196 try { 197 gpsdSocket = new Socket(addrs[i], gpsdPort); 198 break; 199 } catch (Exception e) { 200 System.out.println("LiveGps: Could not open connection to gpsd: " + e); 201 gpsdSocket = null; 202 } 203 } 204 205 if (gpsdSocket == null) 206 return; 207 208 fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.CONNECTING, tr("Connecting")); 209 210 /* 211 * First emit the "w" symbol. The older version will activate, the newer one will ignore it. 212 */ 213 gpsdSocket.getOutputStream().write(new byte[] { 'w', 13, 10 }); 214 215 gpsdReader = new BufferedReader(new InputStreamReader(gpsdSocket.getInputStream())); 216 line = gpsdReader.readLine(); 217 if (line == null) 218 return; 219 220 try { 221 greeting = new JSONObject(line); 222 type = greeting.getString("class"); 223 if (type.equals("VERSION")) { 224 release = greeting.getString("release"); 225 System.out.println("LiveGps: Connected to gpsd " + release); 226 } else 227 System.out.println("LiveGps: Unexpected JSON in gpsd greeting: " + line); 228 } catch (JSONException jex) { 229 if (line.startsWith("GPSD,")) { 230 connected = true; 231 JSONProtocol = false; 232 System.out.println("LiveGps: Connected to old gpsd protocol version."); 233 fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.CONNECTED, tr("Connected")); 234 } 235 } 236 237 if (JSONProtocol == true) { 238 JSONObject Watch = new JSONObject(); 239 try { 240 Watch.put("enable", true); 241 Watch.put("json", true); 242 } catch (JSONException je) {}; 243 244 String Request = "?WATCH=" + Watch.toString() + ";\n"; 245 gpsdSocket.getOutputStream().write(Request.getBytes()); 246 247 connected = true; 248 fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.CONNECTED, tr("Connected")); 249 } 250 } 251 252 private LiveGpsData ParseJSON(String line) { 253 JSONObject report; 254 String type; 255 double lat = 0; 256 double lon = 0; 257 float speed = 0; 258 float course = 0; 259 260 try { 261 report = new JSONObject(line); 262 type = report.getString("class"); 263 } catch (JSONException jex) { 264 System.out.println("LiveGps: line read from gpsd is not a JSON object:" + line); 265 return null; 266 } 267 if (!type.equals("TPV")) 268 return null; 269 270 try { 271 lat = report.getDouble("lat"); 272 lon = report.getDouble("lon"); 273 speed = (new Float(report.getDouble("speed"))).floatValue(); 274 course = (new Float(report.getDouble("track"))).floatValue(); 275 276 return new LiveGpsData(lat, lon, course, speed, true); 277 } catch (JSONException je) {} 278 279 return null; 280 } 281 282 private LiveGpsData ParseOld(String line) { 283 String words[]; 284 double lat = 0; 285 double lon = 0; 286 float speed = 0; 287 float course = 0; 288 289 words = line.split(","); 290 if ((words.length == 0) || (!words[0].equals("GPSD"))) 291 return null; 292 293 for (int i = 1; i < words.length; i++) { 294 if ((words[i].length() < 2) || (words[i].charAt(1) != '=')) { 295 // unexpected response. 296 continue; 297 } 298 299 char what = words[i].charAt(0); 300 String value = words[i].substring(2); 301 switch (what) { 302 case 'O': 303 // full report, tab delimited. 304 String[] status = value.split("\\s+"); 305 if (status.length >= 5) { 306 lat = Double.parseDouble(status[3]); 307 lon = Double.parseDouble(status[4]); 308 try { 309 speed = Float.parseFloat(status[9]); 310 course = Float.parseFloat(status[8]); 311 } catch (NumberFormatException nex) {} 312 return new LiveGpsData(lat, lon, course, speed, true); 313 } 314 break; 315 case 'P': 316 // position report, tab delimited. 317 String[] pos = value.split("\\s+"); 318 if (pos.length >= 2) { 319 lat = Double.parseDouble(pos[0]); 320 lon = Double.parseDouble(pos[1]); 321 speed = Float.NaN; 322 course = Float.NaN; 323 return new LiveGpsData(lat, lon, course, speed, true); 324 } 325 break; 326 default: 327 // not interested 328 } 329 } 330 331 return null; 332 } 333 333 } -
applications/editors/josm/plugins/livegps/src/livegps/LiveGpsLayer.java
r20431 r23191 23 23 24 24 public class LiveGpsLayer extends GpxLayer implements PropertyChangeListener { 25 26 27 28 29 30 31 32 33 34 35 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 private final AppendableGpxTrackSegment trackSegment; 30 float speed; 31 float course; 32 // JLabel lbl; 33 boolean autocenter; 34 private SimpleDateFormat dateFormat = new SimpleDateFormat( 35 "yyyy-MM-dd'T'HH:mm:ss.SSS"); 36 36 37 38 39 40 37 /** 38 * The suppressor is queried, if the GUI shall be re-drawn. 39 */ 40 private ILiveGpsSuppressor suppressor; 41 41 42 43 44 42 public LiveGpsLayer(GpxData data) { 43 super(data, LAYER_NAME); 44 trackSegment = new AppendableGpxTrackSegment(); 45 45 46 47 46 Map<String, Object> attr = new HashMap<String, Object>(); 47 attr.put("desc", "josm live gps"); 48 48 49 50 51 49 GpxTrack trackBeingWritten = new SingleSegmentGpxTrack(trackSegment, attr); 50 data.tracks.add(trackBeingWritten); 51 } 52 52 53 54 55 56 57 58 59 60 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 } 61 61 62 63 64 65 66 67 68 62 lastPos = thisPos; 63 lastPoint = new WayPoint(thisPos); 64 lastPoint.attr.put("time", dateFormat.format(new Date())); 65 trackSegment.addWaypoint(lastPoint); 66 if (autocenter && allowRedraw()) { 67 center(); 68 } 69 69 70 71 70 // Main.map.repaint(); 71 } 72 72 73 74 75 76 73 public void center() { 74 if (lastPoint != null) 75 Main.map.mapView.zoomTo(lastPoint.getCoor()); 76 } 77 77 78 79 80 81 82 83 78 // void setStatus(String status) 79 // { 80 // this.status = status; 81 // Main.map.repaint(); 82 // System.out.println("LiveGps status: " + status); 83 // } 84 84 85 86 87 88 85 void setSpeed(float metresPerSecond) { 86 speed = metresPerSecond; 87 // Main.map.repaint(); 88 } 89 89 90 91 92 93 90 void setCourse(float degrees) { 91 course = degrees; 92 // Main.map.repaint(); 93 } 94 94 95 96 97 95 public void setAutoCenter(boolean ac) { 96 autocenter = ac; 97 } 98 98 99 100 101 102 103 104 105 106 107 108 109 99 @Override 100 public void paint(Graphics2D g, MapView mv, Bounds bounds) { 101 // System.out.println("in paint"); 102 // System.out.println("in synced paint"); 103 super.paint(g, mv, bounds); 104 // int statusHeight = 50; 105 // Rectangle mvs = mv.getBounds(); 106 // mvs.y = mvs.y + mvs.height - statusHeight; 107 // mvs.height = statusHeight; 108 // g.setColor(new Color(1.0f, 1.0f, 1.0f, 0.8f)); 109 // g.fillRect(mvs.x, mvs.y, mvs.width, mvs.height); 110 110 111 112 113 114 115 116 111 if (lastPoint != null) { 112 Point screen = mv.getPoint(lastPoint.getCoor()); 113 g.setColor(Main.pref.getColor(KEY_LIVEGPS_COLOR, Color.RED)); 114 g.drawOval(screen.x - 10, screen.y - 10, 20, 20); 115 g.drawOval(screen.x - 9, screen.y - 9, 18, 18); 116 } 117 117 118 119 120 121 122 123 118 // lbl.setText("gpsd: "+status+" Speed: " + speed + 119 // " Course: "+course); 120 // lbl.setBounds(0, 0, mvs.width-10, mvs.height-10); 121 // Graphics sub = g.create(mvs.x+5, mvs.y+5, mvs.width-10, 122 // mvs.height-10); 123 // lbl.paint(sub); 124 124 125 126 127 128 129 130 125 // if(status != null) { 126 // g.setColor(Color.WHITE); 127 // g.drawString("gpsd: " + status, 5, mv.getBounds().height - 15); 128 // // lower left corner 129 // } 130 } 131 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 132 /* (non-Javadoc) 133 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent) 134 */ 135 public void propertyChange(PropertyChangeEvent evt) { 136 if (!isVisible()) { 137 return; 138 } 139 if ("gpsdata".equals(evt.getPropertyName())) { 140 LiveGpsData data = (LiveGpsData) evt.getNewValue(); 141 if (data.isFix()) { 142 setCurrentPosition(data.getLatitude(), data.getLongitude()); 143 if (!Float.isNaN(data.getSpeed())) { 144 setSpeed(data.getSpeed()); 145 } 146 if (!Float.isNaN(data.getCourse())) { 147 setCourse(data.getCourse()); 148 } 149 if (!autocenter && allowRedraw()) { 150 Main.map.repaint(); 151 } 152 } 153 } 154 } 155 155 156 157 158 159 160 161 156 /** 157 * @param suppressor the suppressor to set 158 */ 159 public void setSuppressor(ILiveGpsSuppressor suppressor) { 160 this.suppressor = suppressor; 161 } 162 162 163 164 165 166 167 168 163 /** 164 * @return the suppressor 165 */ 166 public ILiveGpsSuppressor getSuppressor() { 167 return suppressor; 168 } 169 169 170 171 172 173 174 175 176 177 178 179 180 181 182 170 /** 171 * Check, if a redraw is currently allowed. 172 * 173 * @return true, if a redraw is permitted, false, if a re-draw 174 * should be suppressed. 175 */ 176 private boolean allowRedraw() { 177 if (this.suppressor != null) { 178 return this.suppressor.isAllowUpdate(); 179 } else { 180 return true; 181 } 182 } 183 183 } -
applications/editors/josm/plugins/livegps/src/livegps/LiveGpsPlugin.java
r20431 r23191 28 28 29 29 public class LiveGpsPlugin extends Plugin implements LayerChangeListener { 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 30 private LiveGpsAcquirer acquirer = null; 31 private Thread acquirerThread = null; 32 private JMenu lgpsmenu; 33 private JCheckBoxMenuItem lgpscapture; 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 /** 42 * The LiveGpsSuppressor is queried, if an event shall be suppressed. 43 */ 44 private LiveGpsSuppressor suppressor; 45 46 /** 47 * separate thread, where the LiveGpsSuppressor executes. 48 */ 49 private Thread suppressorThread; 50 51 public class CaptureAction extends JosmAction { 52 public CaptureAction() { 53 super( 54 tr("Capture GPS Track"), 55 "capturemenu", 56 tr("Connect to gpsd server and show current position in LiveGPS layer."), 57 Shortcut.registerShortcut("menu:livegps:capture", tr( 58 "Menu: {0}", tr("Capture GPS Track")), 59 KeyEvent.VK_R, Shortcut.GROUP_MENU), true); 60 } 61 62 public void actionPerformed(ActionEvent e) { 63 enableTracking(lgpscapture.isSelected()); 64 } 65 } 66 67 public class CenterAction extends JosmAction { 68 public CenterAction() { 69 super(tr("Center Once"), "centermenu", 70 tr("Center the LiveGPS layer to current position."), 71 Shortcut.registerShortcut("edit:centergps", tr("Edit: {0}", 72 tr("Center Once")), KeyEvent.VK_HOME, 73 Shortcut.GROUP_EDIT), true); 74 } 75 76 public void actionPerformed(ActionEvent e) { 77 if (lgpslayer != null) { 78 lgpslayer.center(); 79 } 80 } 81 } 82 83 public class AutoCenterAction extends JosmAction { 84 public AutoCenterAction() { 85 super( 86 tr("Auto-Center"), 87 "autocentermenu", 88 tr("Continuously center the LiveGPS layer to current position."), 89 Shortcut.registerShortcut("menu:livegps:autocenter", tr( 90 "Menu: {0}", tr("Capture GPS Track")), 91 KeyEvent.VK_HOME, Shortcut.GROUP_MENU), true); 92 } 93 94 public void actionPerformed(ActionEvent e) { 95 if (lgpslayer != null) { 96 setAutoCenter(lgpsautocenter.isSelected()); 97 } 98 } 99 } 100 101 public void activeLayerChange(Layer oldLayer, Layer newLayer) { 102 } 103 104 public void layerAdded(Layer newLayer) { 105 } 106 107 public void layerRemoved(Layer oldLayer) { 108 if (oldLayer == lgpslayer) { 109 enableTracking(false); 110 lgpscapture.setSelected(false); 111 removePropertyChangeListener(lgpslayer); 112 MapView.removeLayerChangeListener(this); 113 lgpslayer = null; 114 } 115 } 116 117 public LiveGpsPlugin(PluginInformation info) { 118 super(info); 119 MainMenu menu = Main.main.menu; 120 lgpsmenu = menu.addMenu(marktr("LiveGPS"), KeyEvent.VK_G, 121 menu.defaultMenuPos, ht("/Plugin/LiveGPS")); 122 123 JosmAction captureAction = new CaptureAction(); 124 lgpscapture = new JCheckBoxMenuItem(captureAction); 125 lgpsmenu.add(lgpscapture); 126 lgpscapture.setAccelerator(captureAction.getShortcut().getKeyStroke()); 127 128 JosmAction centerAction = new CenterAction(); 129 JMenuItem centerMenu = new JMenuItem(centerAction); 130 lgpsmenu.add(centerMenu); 131 centerMenu.setAccelerator(centerAction.getShortcut().getKeyStroke()); 132 133 JosmAction autoCenterAction = new AutoCenterAction(); 134 lgpsautocenter = new JCheckBoxMenuItem(autoCenterAction); 135 lgpsmenu.add(lgpsautocenter); 136 lgpsautocenter.setAccelerator(autoCenterAction.getShortcut() 137 .getKeyStroke()); 138 } 139 140 /** 141 * Set to <code>true</code> if the current position should always be in the center of the map. 142 * @param autoCenter if <code>true</code> the map is always centered. 143 */ 144 public void setAutoCenter(boolean autoCenter) { 145 lgpsautocenter.setSelected(autoCenter); // just in case this method was 146 // not called from the menu 147 if (lgpslayer != null) { 148 lgpslayer.setAutoCenter(autoCenter); 149 if (autoCenter) 150 lgpslayer.center(); 151 } 152 } 153 154 /** 155 * Returns <code>true</code> if autocenter is selected. 156 * @return <code>true</code> if autocenter is selected. 157 */ 158 public boolean isAutoCenter() { 159 return lgpsautocenter.isSelected(); 160 } 161 162 /** 163 * Enable or disable gps tracking 164 * @param enable if <code>true</code> tracking is started. 165 */ 166 public void enableTracking(boolean enable) { 167 if ((acquirer != null) && (!enable)) { 168 acquirer.shutdown(); 169 acquirerThread = null; 170 171 // also stop the suppressor 172 if (suppressor != null) { 173 suppressor.shutdown(); 174 suppressorThread = null; 175 if (lgpslayer != null) { 176 lgpslayer.setSuppressor(null); 177 } 178 } 179 } else if (enable) { 180 // also start the suppressor 181 if (suppressor == null) { 182 suppressor = new LiveGpsSuppressor(); 183 } 184 if (suppressorThread == null) { 185 suppressorThread = new Thread(suppressor); 186 suppressorThread.start(); 187 } 188 189 if (acquirer == null) { 190 acquirer = new LiveGpsAcquirer(); 191 if (lgpslayer == null) { 192 lgpslayer = new LiveGpsLayer(data); 193 Main.main.addLayer(lgpslayer); 194 MapView.addLayerChangeListener(this); 195 lgpslayer.setAutoCenter(isAutoCenter()); 196 } 197 // connect layer with acquirer: 198 addPropertyChangeListener(lgpslayer); 199 200 // connect layer with suppressor: 201 lgpslayer.setSuppressor(suppressor); 202 // add all listeners that were added before the acquirer 203 // existed: 204 if (listenerQueue != null) { 205 for (PropertyChangeListener listener : listenerQueue) { 206 addPropertyChangeListener(listener); 207 } 208 listenerQueue.clear(); 209 } 210 } 211 if (acquirerThread == null) { 212 acquirerThread = new Thread(acquirer); 213 acquirerThread.start(); 214 } 215 216 } 217 } 218 219 /** 220 * Add a listener for gps events. 221 * @param listener the listener. 222 */ 223 public void addPropertyChangeListener(PropertyChangeListener listener) { 224 if (acquirer != null) { 225 acquirer.addPropertyChangeListener(listener); 226 } else { 227 if (listenerQueue == null) { 228 listenerQueue = new ArrayList<PropertyChangeListener>(); 229 } 230 listenerQueue.add(listener); 231 } 232 } 233 234 /** 235 * Remove a listener for gps events. 236 * @param listener the listener. 237 */ 238 public void removePropertyChangeListener(PropertyChangeListener listener) { 239 if (acquirer != null) 240 acquirer.removePropertyChangeListener(listener); 241 else if (listenerQueue != null && listenerQueue.contains(listener)) 242 listenerQueue.remove(listener); 243 } 244 245 /* (non-Javadoc) 246 * @see org.openstreetmap.josm.plugins.Plugin#mapFrameInitialized(org.openstreetmap.josm.gui.MapFrame, org.openstreetmap.josm.gui.MapFrame) 247 */ 248 @Override 249 public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) { 250 if (newFrame != null) { 251 // add dialog 252 newFrame.addToggleDialog(lgpsdialog = new LiveGpsDialog(newFrame)); 253 // connect listeners with acquirer: 254 addPropertyChangeListener(lgpsdialog); 255 } 256 } 257 258 /** 259 * @return the lgpsmenu 260 */ 261 public JMenu getLgpsMenu() { 262 return this.lgpsmenu; 263 } 264 264 265 265 } -
applications/editors/josm/plugins/livegps/src/livegps/LiveGpsSuppressor.java
r19011 r23191 18 18 public class LiveGpsSuppressor implements Runnable, ILiveGpsSuppressor { 19 19 20 21 22 23 20 /** 21 * Default sleep time is 5 seconds. 22 */ 23 private static final int DEFAULT_SLEEP_TIME = 5; 24 24 25 26 27 28 25 /** 26 * The currently used sleepTime. 27 */ 28 private int sleepTime = DEFAULT_SLEEP_TIME; 29 29 30 31 32 33 30 /** 31 * The flag allowUpdate is enabled once during the sleepTime. 32 */ 33 private boolean allowUpdate = false; 34 34 35 36 37 38 35 /** 36 * Controls if this thread is still in used. 37 */ 38 private boolean shutdownFlag = false; 39 39 40 41 42 43 44 45 40 /** 41 * Run thread enables the allowUpdate flag once during its cycle. 42 * @see java.lang.Runnable#run() 43 */ 44 public void run() { 45 initSleepTime(); 46 46 47 48 49 50 51 47 shutdownFlag = false; 48 // stop the thread, when explicitely shut down or when disabled by 49 // config setting 50 while (!shutdownFlag && isEnabled()) { 51 setAllowUpdate(true); 52 52 53 54 55 56 57 58 59 53 try { 54 Thread.sleep(getSleepTime()); 55 } catch (InterruptedException e) { 56 // TODO I never knew, how to handle this??? Probably just carry 57 // on 58 } 59 } 60 60 61 61 } 62 62 63 64 65 66 67 68 69 70 71 72 73 63 /** 64 * Retrieve the sleepTime from the configuration. 65 * If no such configuration key exists, it will be initialized here. 66 */ 67 private void initSleepTime() { 68 // fetch it from the user setting, or use the default value. 69 int sleepSeconds = 0; 70 sleepSeconds = Main.pref.getInteger("livegps.refreshinterval", 71 DEFAULT_SLEEP_TIME); 72 // creates the setting, if none present. 73 Main.pref.putInteger("livegps.refreshinterval", sleepSeconds); 74 74 75 76 77 75 // convert seconds into milliseconds internally. 76 this.sleepTime = sleepSeconds * 1000; 77 } 78 78 79 80 81 82 83 84 85 79 /** 80 * Set the allowUpdate flag. May only privately accessible! 81 * @param allowUpdate the allowUpdate to set 82 */ 83 private synchronized void setAllowUpdate(boolean allowUpdate) { 84 this.allowUpdate = allowUpdate; 85 } 86 86 87 88 89 90 91 92 93 94 95 87 /** 88 * Query, if an update is currently allowed. 89 * When it is allowed, it will disable the allowUpdate flag as a side effect. 90 * (this means, one thread got to issue an update event) 91 * 92 * @return true, if an update is currently allowed; false, if the update shall be suppressed. 93 * @see livegps.ILiveGpsSuppressor#isAllowUpdate() 94 */ 95 public synchronized boolean isAllowUpdate() { 96 96 97 98 99 100 97 // if disabled, always permit a re-draw. 98 if (!isEnabled()) { 99 return true; 100 } else { 101 101 102 103 104 105 106 107 108 109 102 if (allowUpdate) { 103 allowUpdate = false; 104 return true; 105 } else { 106 return false; 107 } 108 } 109 } 110 110 111 112 113 114 115 * 116 117 118 119 120 111 /** 112 * A value below 1 disables this feature. 113 * This ensures that a small value does not run this thread 114 * in a tight loop. 115 * 116 * @return true, if suppressing is enabled 117 */ 118 private boolean isEnabled() { 119 return this.sleepTime > 0; 120 } 121 121 122 123 124 125 126 127 122 /** 123 * Shut this thread down. 124 */ 125 public void shutdown() { 126 shutdownFlag = true; 127 } 128 128 129 130 131 132 133 134 129 /** 130 * @return the defaultSleepTime 131 */ 132 private int getSleepTime() { 133 return this.sleepTime; 134 } 135 135 136 136 } -
applications/editors/josm/plugins/livegps/src/livegps/SingleSegmentGpxTrack.java
r20431 r23191 11 11 public class SingleSegmentGpxTrack implements GpxTrack { 12 12 13 14 13 private final Map<String, Object> attributes; 14 private final GpxTrackSegment trackSegment; 15 15 16 17 18 19 16 public SingleSegmentGpxTrack(GpxTrackSegment trackSegment, Map<String, Object> attributes) { 17 this.attributes = Collections.unmodifiableMap(attributes); 18 this.trackSegment = trackSegment; 19 } 20 20 21 21 22 23 24 22 public Map<String, Object> getAttributes() { 23 return attributes; 24 } 25 25 26 27 28 26 public Bounds getBounds() { 27 return trackSegment.getBounds(); 28 } 29 29 30 31 32 30 public Collection<GpxTrackSegment> getSegments() { 31 return Collections.singleton(trackSegment); 32 } 33 33 34 35 36 34 public double length() { 35 return trackSegment.length(); 36 } 37 37 38 39 40 41 38 @Override 39 public int getUpdateCount() { 40 return trackSegment.getUpdateCount(); 41 } 42 42 43 43 }
Note:
See TracChangeset
for help on using the changeset viewer.