Changeset 23191 in osm for applications/editors/josm/plugins/livegps/src
- Timestamp:
- 2010-09-15T18:56:19+02:00 (15 years ago)
- Location:
- applications/editors/josm/plugins/livegps/src
- Files:
-
- 12 edited
-
livegps/AppendableGpxTrackSegment.java (modified) (1 diff)
-
livegps/ILiveGpsSuppressor.java (modified) (1 diff)
-
livegps/LiveGpsAcquirer.java (modified) (1 diff)
-
livegps/LiveGpsLayer.java (modified) (1 diff)
-
livegps/LiveGpsPlugin.java (modified) (1 diff)
-
livegps/LiveGpsSuppressor.java (modified) (1 diff)
-
livegps/SingleSegmentGpxTrack.java (modified) (1 diff)
-
org/json/JSONArray.java (modified) (5 diffs)
-
org/json/JSONException.java (modified) (1 diff)
-
org/json/JSONObject.java (modified) (15 diffs)
-
org/json/JSONString.java (modified) (1 diff)
-
org/json/JSONTokener.java (modified) (8 diffs)
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 private WayPoint[] wayPoints = new WayPoint[16];17 private int size;18 private Bounds bounds;19 private double length;16 private WayPoint[] wayPoints = new WayPoint[16]; 17 private int size; 18 private Bounds bounds; 19 private double length; 20 20 21 public Bounds getBounds() {22 return bounds;23 }21 public Bounds getBounds() { 22 return bounds; 23 } 24 24 25 public Collection<WayPoint> getWayPoints() {26 return new CopyList<WayPoint>(wayPoints, size);27 }25 public Collection<WayPoint> getWayPoints() { 26 return new CopyList<WayPoint>(wayPoints, size); 27 } 28 28 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 }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 if (size > 0) {37 Double distance = wayPoints[size - 1].getCoor().greatCircleDistance(p.getCoor());38 if (!distance.isNaN() && !distance.isInfinite()) {39 length += distance;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 if (bounds == null) {44 bounds = new Bounds(p.getCoor());45 } else {46 bounds.extend(p.getCoor());47 }43 if (bounds == null) { 44 bounds = new Bounds(p.getCoor()); 45 } else { 46 bounds.extend(p.getCoor()); 47 } 48 48 49 wayPoints[size] = p;50 size++;51 }49 wayPoints[size] = p; 50 size++; 51 } 52 52 53 public double length() {54 return length;55 }53 public double length() { 54 return length; 55 } 56 56 57 @Override58 public int getUpdateCount() {59 return size;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 * 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();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 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 listener53 */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 listener63 */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 a90 * {@link LiveGpsData} object as values.91 * This event is only sent, when the suppressor permits it. This92 * 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 no132 // fix, so gpsd does not send positions133 line = gpsdReader.readLine();134 // </FIXXME>135 if (line == null)136 break;137 138 if (JSONProtocol == true)139 gpsData = ParseJSON(line);140 else141 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 layer167 }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 } else227 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 interested328 }329 }330 331 return null;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 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");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 * The suppressor is queried, if the GUI shall be re-drawn.39 */40 private ILiveGpsSuppressor suppressor;37 /** 38 * The suppressor is queried, if the GUI shall be re-drawn. 39 */ 40 private ILiveGpsSuppressor suppressor; 41 41 42 public LiveGpsLayer(GpxData data) {43 super(data, LAYER_NAME);44 trackSegment = new AppendableGpxTrackSegment();42 public LiveGpsLayer(GpxData data) { 43 super(data, LAYER_NAME); 44 trackSegment = new AppendableGpxTrackSegment(); 45 45 46 Map<String, Object> attr = new HashMap<String, Object>();47 attr.put("desc", "josm live gps");46 Map<String, Object> attr = new HashMap<String, Object>(); 47 attr.put("desc", "josm live gps"); 48 48 49 GpxTrack trackBeingWritten = new SingleSegmentGpxTrack(trackSegment, attr);50 data.tracks.add(trackBeingWritten);51 }49 GpxTrack trackBeingWritten = new SingleSegmentGpxTrack(trackSegment, attr); 50 data.tracks.add(trackBeingWritten); 51 } 52 52 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 position58 // maybe show a "paused" cursor or some such59 return;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 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 }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 // Main.map.repaint();71 }70 // Main.map.repaint(); 71 } 72 72 73 public void center() {74 if (lastPoint != null)75 Main.map.mapView.zoomTo(lastPoint.getCoor());76 }73 public void center() { 74 if (lastPoint != null) 75 Main.map.mapView.zoomTo(lastPoint.getCoor()); 76 } 77 77 78 // void setStatus(String status)79 // {80 // this.status = status;81 // Main.map.repaint();82 // System.out.println("LiveGps status: " + status);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 void setSpeed(float metresPerSecond) {86 speed = metresPerSecond;87 // Main.map.repaint();88 }85 void setSpeed(float metresPerSecond) { 86 speed = metresPerSecond; 87 // Main.map.repaint(); 88 } 89 89 90 void setCourse(float degrees) {91 course = degrees;92 // Main.map.repaint();93 }90 void setCourse(float degrees) { 91 course = degrees; 92 // Main.map.repaint(); 93 } 94 94 95 public void setAutoCenter(boolean ac) {96 autocenter = ac;97 }95 public void setAutoCenter(boolean ac) { 96 autocenter = ac; 97 } 98 98 99 @Override100 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);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 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 }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 // 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);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 // if(status != null) {126 // g.setColor(Color.WHITE);127 // g.drawString("gpsd: " + status, 5, mv.getBounds().height - 15);128 // // lower left corner129 // }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 /* (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 }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 * @param suppressor the suppressor to set158 */159 public void setSuppressor(ILiveGpsSuppressor suppressor) {160 this.suppressor = suppressor;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 * @return the suppressor165 */166 public ILiveGpsSuppressor getSuppressor() {167 return suppressor;168 }163 /** 164 * @return the suppressor 165 */ 166 public ILiveGpsSuppressor getSuppressor() { 167 return suppressor; 168 } 169 169 170 /**171 * Check, if a redraw is currently allowed.172 *173 * @return true, if a redraw is permitted, false, if a re-draw174 * 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 }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 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 was146 // not called from the menu147 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 tracking164 * @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 suppressor172 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 suppressor181 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 acquirer203 // 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 @Override249 public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {250 if (newFrame != null) {251 // add dialog252 newFrame.addToggleDialog(lgpsdialog = new LiveGpsDialog(newFrame));253 // connect listeners with acquirer:254 addPropertyChangeListener(lgpsdialog);255 }256 }257 258 /**259 * @return the lgpsmenu260 */261 public JMenu getLgpsMenu() {262 return this.lgpsmenu;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 * Default sleep time is 5 seconds.22 */23 private static final int DEFAULT_SLEEP_TIME = 5;20 /** 21 * Default sleep time is 5 seconds. 22 */ 23 private static final int DEFAULT_SLEEP_TIME = 5; 24 24 25 /**26 * The currently used sleepTime.27 */28 private int sleepTime = DEFAULT_SLEEP_TIME;25 /** 26 * The currently used sleepTime. 27 */ 28 private int sleepTime = DEFAULT_SLEEP_TIME; 29 29 30 /**31 * The flag allowUpdate is enabled once during the sleepTime.32 */33 private boolean allowUpdate = false;30 /** 31 * The flag allowUpdate is enabled once during the sleepTime. 32 */ 33 private boolean allowUpdate = false; 34 34 35 /**36 * Controls if this thread is still in used.37 */38 private boolean shutdownFlag = false;35 /** 36 * Controls if this thread is still in used. 37 */ 38 private boolean shutdownFlag = false; 39 39 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();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 shutdownFlag = false;48 // stop the thread, when explicitely shut down or when disabled by49 // config setting50 while (!shutdownFlag && isEnabled()) {51 setAllowUpdate(true);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 try {54 Thread.sleep(getSleepTime());55 } catch (InterruptedException e) {56 // TODO I never knew, how to handle this??? Probably just carry57 // on58 }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 * 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);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 // convert seconds into milliseconds internally.76 this.sleepTime = sleepSeconds * 1000;77 }75 // convert seconds into milliseconds internally. 76 this.sleepTime = sleepSeconds * 1000; 77 } 78 78 79 /**80 * Set the allowUpdate flag. May only privately accessible!81 * @param allowUpdate the allowUpdate to set82 */83 private synchronized void setAllowUpdate(boolean allowUpdate) {84 this.allowUpdate = allowUpdate;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 * 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() {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 // if disabled, always permit a re-draw.98 if (!isEnabled()) {99 return true;100 } else {97 // if disabled, always permit a re-draw. 98 if (!isEnabled()) { 99 return true; 100 } else { 101 101 102 if (allowUpdate) {103 allowUpdate = false;104 return true;105 } else {106 return false;107 }108 }109 }102 if (allowUpdate) { 103 allowUpdate = false; 104 return true; 105 } else { 106 return false; 107 } 108 } 109 } 110 110 111 /**112 * A value below 1 disables this feature.113 * This ensures that a small value does not run this thread114 * in a tight loop.115 * 116 * @return true, if suppressing is enabled117 */118 private boolean isEnabled() {119 return this.sleepTime > 0;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 * Shut this thread down.124 */125 public void shutdown() {126 shutdownFlag = true;127 }122 /** 123 * Shut this thread down. 124 */ 125 public void shutdown() { 126 shutdownFlag = true; 127 } 128 128 129 /**130 * @return the defaultSleepTime131 */132 private int getSleepTime() {133 return this.sleepTime;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 private final Map<String, Object> attributes;14 private final GpxTrackSegment trackSegment;13 private final Map<String, Object> attributes; 14 private final GpxTrackSegment trackSegment; 15 15 16 public SingleSegmentGpxTrack(GpxTrackSegment trackSegment, Map<String, Object> attributes) {17 this.attributes = Collections.unmodifiableMap(attributes);18 this.trackSegment = trackSegment;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 public Map<String, Object> getAttributes() {23 return attributes;24 }22 public Map<String, Object> getAttributes() { 23 return attributes; 24 } 25 25 26 public Bounds getBounds() {27 return trackSegment.getBounds();28 }26 public Bounds getBounds() { 27 return trackSegment.getBounds(); 28 } 29 29 30 public Collection<GpxTrackSegment> getSegments() {31 return Collections.singleton(trackSegment);32 }30 public Collection<GpxTrackSegment> getSegments() { 31 return Collections.singleton(trackSegment); 32 } 33 33 34 public double length() {35 return trackSegment.length();36 }34 public double length() { 35 return trackSegment.length(); 36 } 37 37 38 @Override39 public int getUpdateCount() {40 return trackSegment.getUpdateCount();41 }38 @Override 39 public int getUpdateCount() { 40 return trackSegment.getUpdateCount(); 41 } 42 42 43 43 } -
applications/editors/josm/plugins/livegps/src/org/json/JSONArray.java
r21622 r23191 74 74 * <li>Values can be separated by <code>;</code> <small>(semicolon)</small> as 75 75 * well as by <code>,</code> <small>(comma)</small>.</li> 76 * <li>Numbers may have the 76 * <li>Numbers may have the 77 77 * <code>0x-</code> <small>(hex)</small> prefix.</li> 78 78 * </ul> … … 164 164 */ 165 165 public JSONArray(Collection collection) { 166 this.myArrayList = new ArrayList();167 if (collection != null) {168 Iterator iter = collection.iterator();169 while (iter.hasNext()) {170 Object o = iter.next();171 this.myArrayList.add(JSONObject.wrap(o)); 172 }173 }174 } 175 176 166 this.myArrayList = new ArrayList(); 167 if (collection != null) { 168 Iterator iter = collection.iterator(); 169 while (iter.hasNext()) { 170 Object o = iter.next(); 171 this.myArrayList.add(JSONObject.wrap(o)); 172 } 173 } 174 } 175 176 177 177 /** 178 178 * Construct a JSONArray from an array … … 192 192 } 193 193 194 194 195 195 /** 196 196 * Get the object value associated with an index. … … 765 765 return this; 766 766 } 767 768 767 768 769 769 /** 770 770 * Remove an index and close the hole. … … 774 774 */ 775 775 public Object remove(int index) { 776 Object o = opt(index);776 Object o = opt(index); 777 777 this.myArrayList.remove(index); 778 778 return o; -
applications/editors/josm/plugins/livegps/src/org/json/JSONException.java
r21622 r23191 8 8 public class JSONException extends Exception { 9 9 /** 10 *11 */12 private static final long serialVersionUID = 0;13 private Throwable cause;10 * 11 */ 12 private static final long serialVersionUID = 0; 13 private Throwable cause; 14 14 15 15 /** -
applications/editors/josm/plugins/livegps/src/org/json/JSONObject.java
r21622 r23191 155 155 * @param jo A JSONObject. 156 156 * @param names An array of strings. 157 * @throws JSONException 157 * @throws JSONException 158 158 * @exception JSONException If a value is a non-finite number or if a name is duplicated. 159 159 */ … … 161 161 this(); 162 162 for (int i = 0; i < names.length; i += 1) { 163 try {164 putOnce(names[i], jo.opt(names[i]));165 } catch (Exception ignore) {166 }163 try { 164 putOnce(names[i], jo.opt(names[i])); 165 } catch (Exception ignore) { 166 } 167 167 } 168 168 } … … 235 235 * @param map A map object that can be used to initialize the contents of 236 236 * the JSONObject. 237 * @throws JSONException 237 * @throws JSONException 238 238 */ 239 239 public JSONObject(Map map) { … … 455 455 456 456 /** 457 * Get the int value associated with a key. 457 * Get the int value associated with a key. 458 458 * 459 459 * @param key A key string. … … 512 512 513 513 /** 514 * Get the long value associated with a key. 514 * Get the long value associated with a key. 515 515 * 516 516 * @param key A key string. … … 596 596 return this.map.containsKey(key); 597 597 } 598 599 598 599 600 600 /** 601 601 * Increment a property of a JSONObject. If there is no such property, … … 608 608 */ 609 609 public JSONObject increment(String key) throws JSONException { 610 Object value = opt(key);611 if (value == null) {612 put(key, 1);613 } else {614 if (value instanceof Integer) {615 put(key, ((Integer)value).intValue() + 1);616 } else if (value instanceof Long) {617 put(key, ((Long)value).longValue() + 1);618 } else if (value instanceof Double) {619 put(key, ((Double)value).doubleValue() + 1);620 } else if (value instanceof Float) {621 put(key, ((Float)value).floatValue() + 1);622 } else {623 throw new JSONException("Unable to increment [" + key + "].");624 }625 }626 return this;610 Object value = opt(key); 611 if (value == null) { 612 put(key, 1); 613 } else { 614 if (value instanceof Integer) { 615 put(key, ((Integer)value).intValue() + 1); 616 } else if (value instanceof Long) { 617 put(key, ((Long)value).longValue() + 1); 618 } else if (value instanceof Double) { 619 put(key, ((Double)value).doubleValue() + 1); 620 } else if (value instanceof Float) { 621 put(key, ((Float)value).floatValue() + 1); 622 } else { 623 throw new JSONException("Unable to increment [" + key + "]."); 624 } 625 } 626 return this; 627 627 } 628 628 … … 903 903 Class klass = bean.getClass(); 904 904 905 // If klass is a System class then set includeSuperClass to false. 905 // If klass is a System class then set includeSuperClass to false. 906 906 907 907 boolean includeSuperClass = klass.getClassLoader() != null; … … 916 916 String key = ""; 917 917 if (name.startsWith("get")) { 918 if (name.equals("getClass") ||919 name.equals("getDeclaringClass")) {920 key = "";921 } else {922 key = name.substring(3);923 }918 if (name.equals("getClass") || 919 name.equals("getDeclaringClass")) { 920 key = ""; 921 } else { 922 key = name.substring(3); 923 } 924 924 } else if (name.startsWith("is")) { 925 925 key = name.substring(2); … … 1199 1199 1200 1200 /* 1201 * If it might be a number, try converting it. 1202 * We support the non-standard 0x- convention. 1201 * If it might be a number, try converting it. 1202 * We support the non-standard 0x- convention. 1203 1203 * If a number cannot be produced, then the value will just 1204 1204 * be a string. Note that the 0x-, plus, and implied string … … 1217 1217 } 1218 1218 try { 1219 if (s.indexOf('.') > -1 || 1220 s.indexOf('e') > -1 || s.indexOf('E') > -1) {1219 if (s.indexOf('.') > -1 || 1220 s.indexOf('e') > -1 || s.indexOf('E') > -1) { 1221 1221 return Double.valueOf(s); 1222 1222 } else { … … 1495 1495 1496 1496 /** 1497 * Wrap an object, if necessary. If the object is null, return the NULL 1498 * object. If it is an array or collection, wrap it in a JSONArray. If 1499 * it is a map, wrap it in a JSONObject. If it is a standard property 1500 * (Double, String, et al) then it is already wrapped. Otherwise, if it 1501 * comes from one of the java packages, turn it into a string. And if 1497 * Wrap an object, if necessary. If the object is null, return the NULL 1498 * object. If it is an array or collection, wrap it in a JSONArray. If 1499 * it is a map, wrap it in a JSONObject. If it is a standard property 1500 * (Double, String, et al) then it is already wrapped. Otherwise, if it 1501 * comes from one of the java packages, turn it into a string. And if 1502 1502 * it doesn't, try to wrap it in a JSONObject. If the wrapping fails, 1503 1503 * then null is returned. … … 1511 1511 return NULL; 1512 1512 } 1513 if (object instanceof JSONObject || object instanceof JSONArray || 1514 NULL.equals(object) || object instanceof JSONString ||1515 object instanceof Byte || object instanceof Character ||1513 if (object instanceof JSONObject || object instanceof JSONArray || 1514 NULL.equals(object) || object instanceof JSONString || 1515 object instanceof Byte || object instanceof Character || 1516 1516 object instanceof Short || object instanceof Integer || 1517 object instanceof Long || object instanceof Boolean || 1517 object instanceof Long || object instanceof Boolean || 1518 1518 object instanceof Float || object instanceof Double || 1519 1519 object instanceof String) { 1520 1520 return object; 1521 1521 } 1522 1522 1523 1523 if (object instanceof Collection) { 1524 1524 return new JSONArray((Collection)object); … … 1533 1533 String objectPackageName = ( objectPackage != null ? objectPackage.getName() : "" ); 1534 1534 if (objectPackageName.startsWith("java.") || 1535 objectPackageName.startsWith("javax.") ||1536 object.getClass().getClassLoader() == null) {1535 objectPackageName.startsWith("javax.") || 1536 object.getClass().getClassLoader() == null) { 1537 1537 return object.toString(); 1538 1538 } … … 1543 1543 } 1544 1544 1545 1545 1546 1546 /** 1547 1547 * Write the contents of the JSONObject as JSON text to a writer. -
applications/editors/josm/plugins/livegps/src/org/json/JSONString.java
r21622 r23191 9 9 */ 10 10 public interface JSONString { 11 /**12 * The <code>toJSONString</code> method allows a class to produce its own JSON13 * serialization.14 *15 * @return A strictly syntactically correct JSON text.16 */17 public String toJSONString();11 /** 12 * The <code>toJSONString</code> method allows a class to produce its own JSON 13 * serialization. 14 * 15 * @return A strictly syntactically correct JSON text. 16 */ 17 public String toJSONString(); 18 18 } -
applications/editors/josm/plugins/livegps/src/org/json/JSONTokener.java
r21622 r23191 39 39 public class JSONTokener { 40 40 41 private int character;42 private boolean eof;43 private int index;44 private int line;45 private char previous;46 private Reader reader;41 private int character; 42 private boolean eof; 43 private int index; 44 private int line; 45 private char previous; 46 private Reader reader; 47 47 private boolean usePrevious; 48 48 … … 54 54 */ 55 55 public JSONTokener(Reader reader) { 56 this.reader = reader.markSupported() ? 57 reader : new BufferedReader(reader);56 this.reader = reader.markSupported() ? 57 reader : new BufferedReader(reader); 58 58 this.eof = false; 59 59 this.usePrevious = false; … … 109 109 return -1; 110 110 } 111 111 112 112 public boolean end() { 113 return eof && !usePrevious;113 return eof && !usePrevious; 114 114 } 115 115 … … 124 124 if (end()) { 125 125 return false; 126 } 126 } 127 127 back(); 128 128 return true; … … 138 138 int c; 139 139 if (this.usePrevious) { 140 this.usePrevious = false;140 this.usePrevious = false; 141 141 c = this.previous; 142 142 } else { 143 try {144 c = this.reader.read();145 } catch (IOException exception) {146 throw new JSONException(exception);147 }148 149 if (c <= 0) { // End of stream150 this.eof = true;151 c = 0;152 }153 } 154 this.index += 1;155 if (this.previous == '\r') {156 this.line += 1;157 this.character = c == '\n' ? 0 : 1;158 } else if (c == '\n') {159 this.line += 1;160 this.character = 0;161 } else {162 this.character += 1;163 }164 this.previous = (char) c;143 try { 144 c = this.reader.read(); 145 } catch (IOException exception) { 146 throw new JSONException(exception); 147 } 148 149 if (c <= 0) { // End of stream 150 this.eof = true; 151 c = 0; 152 } 153 } 154 this.index += 1; 155 if (this.previous == '\r') { 156 this.line += 1; 157 this.character = c == '\n' ? 0 : 1; 158 } else if (c == '\n') { 159 this.line += 1; 160 this.character = 0; 161 } else { 162 this.character += 1; 163 } 164 this.previous = (char) c; 165 165 return this.previous; 166 166 } … … 204 204 buffer[pos] = next(); 205 205 if (end()) { 206 throw syntaxError("Substring bounds error"); 206 throw syntaxError("Substring bounds error"); 207 207 } 208 208 pos += 1; … … 273 273 case '\\': 274 274 case '/': 275 sb.append(c);276 break;275 sb.append(c); 276 break; 277 277 default: 278 278 throw syntaxError("Illegal escape."); … … 412 412 return c; 413 413 } 414 414 415 415 416 416 /**
Note:
See TracChangeset
for help on using the changeset viewer.
