source: osm/applications/editors/josm/plugins/livegps/src/LiveGpsAcquirer.java@ 14003

Last change on this file since 14003 was 13497, checked in by skela, 16 years ago

applications/editors/josm: Set svn:eol-style native on all *.java files
in plugins. Normalize the eol-style in
plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/StringEnumConfigurer.java.

  • Property svn:eol-style set to native
File size: 9.5 KB
Line 
1package livegps;
2
3import static org.openstreetmap.josm.tools.I18n.tr;
4import java.beans.PropertyChangeEvent;
5import java.beans.PropertyChangeListener;
6import java.io.BufferedReader;
7import java.io.FileInputStream;
8import java.io.FileNotFoundException;
9import java.io.IOException;
10import java.io.InputStreamReader;
11import java.net.InetAddress;
12import java.net.Socket;
13import java.util.ArrayList;
14import java.util.List;
15import java.util.Properties;
16
17import org.openstreetmap.josm.data.coor.LatLon;
18
19public class LiveGpsAcquirer implements Runnable {
20 Socket gpsdSocket;
21 BufferedReader gpsdReader;
22 boolean connected = false;
23 String gpsdHost = "localhost";
24 int gpsdPort = 2947;
25 String configFile = "liveGPS.conf";
26 boolean shutdownFlag = false;
27 private List<PropertyChangeListener> propertyChangeListener = new ArrayList<PropertyChangeListener>();
28 private PropertyChangeEvent lastStatusEvent;
29 private PropertyChangeEvent lastDataEvent;
30
31 public LiveGpsAcquirer(String pluginDir) {
32
33 Properties liveGPSconfig = new Properties();
34
35 FileInputStream fis = null;
36
37 try {
38 fis = new FileInputStream(pluginDir + configFile);
39 } catch (FileNotFoundException e) {
40 System.err.println("No liveGPS.conf found, using defaults");
41 }
42
43 if(fis != null)
44 {
45 try {
46 liveGPSconfig.load(fis);
47 this.gpsdHost = liveGPSconfig.getProperty("host");
48 this.gpsdPort = Integer.parseInt(liveGPSconfig.getProperty("port"));
49
50 } catch (IOException e) {
51 System.err.println("Error while loading liveGPS.conf, using defaults");
52 }
53
54 if(this.gpsdHost == null || this.gpsdPort == 0)
55 {
56 System.err.println("Error in liveGPS.conf, using defaults");
57 this.gpsdHost = "localhost";
58 this.gpsdPort = 2947;
59 }
60 }
61
62 }
63
64 /**
65 * Adds a property change listener to the acquirer.
66 * @param listener the new listener
67 */
68 public void addPropertyChangeListener(PropertyChangeListener listener) {
69 if(!propertyChangeListener.contains(listener)) {
70 propertyChangeListener.add(listener);
71 }
72 }
73
74 /**
75 * Fire a gps status change event. Fires events with key "gpsstatus" and a {@link LiveGpsStatus}
76 * object as value.
77 * @param status the status.
78 * @param statusMessage the status message.
79 */
80 public void fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus status, String statusMessage) {
81 PropertyChangeEvent event = new PropertyChangeEvent(this, "gpsstatus", null, new LiveGpsStatus(status, statusMessage));
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 * @param oldData the old gps data.
92 * @param newData the new gps data.
93 */
94 public void fireGpsDataChangeEvent(LiveGpsData oldData, LiveGpsData newData) {
95 PropertyChangeEvent event = new PropertyChangeEvent(this, "gpsdata", oldData, newData);
96 if(!event.equals(lastDataEvent)) {
97 firePropertyChangeEvent(event);
98 lastDataEvent = event;
99 }
100 }
101
102 /**
103 * Fires the given event to all listeners.
104 * @param event the event to fire.
105 */
106 protected void firePropertyChangeEvent(PropertyChangeEvent event) {
107 for (PropertyChangeListener listener : propertyChangeListener) {
108 listener.propertyChange(event);
109 }
110 }
111
112 public void run() {
113 LiveGpsData oldGpsData = null;
114 LiveGpsData gpsData = null;
115 shutdownFlag = false;
116 while(!shutdownFlag) {
117 double lat = 0;
118 double lon = 0;
119 float speed = 0;
120 float course = 0;
121 boolean haveFix = false;
122
123 try
124 {
125 if (!connected)
126 {
127 System.out.println("LiveGps tries to connect to gpsd");
128 fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.CONNECTING, tr("Connecting"));
129 InetAddress[] addrs = InetAddress.getAllByName(gpsdHost);
130 for (int i=0; i < addrs.length && gpsdSocket == null; i++) {
131 try {
132 gpsdSocket = new Socket(addrs[i], gpsdPort);
133 break;
134 } catch (Exception e) {
135 System.out.println("LiveGps: Could not open connection to gpsd: " + e);
136 gpsdSocket = null;
137 }
138 }
139
140 if (gpsdSocket != null)
141 {
142 gpsdReader = new BufferedReader(new InputStreamReader(gpsdSocket.getInputStream()));
143 gpsdSocket.getOutputStream().write(new byte[] { 'w', 13, 10 });
144 fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.CONNECTING, tr("Connecting"));
145 connected = true;
146 System.out.println("LiveGps: Connected to gpsd");
147 }
148 }
149
150
151 if(connected) {
152 // <FIXXME date="23.06.2007" author="cdaller">
153 // TODO this read is blocking if gps is connected but has no fix, so gpsd does not send positions
154 String line = gpsdReader.readLine();
155 // </FIXXME>
156 if (line == null) break;
157 String words[] = line.split(",");
158
159 if ((words.length == 0) || (!words[0].equals("GPSD"))) {
160 // unexpected response.
161 continue;
162 }
163
164 for (int i = 1; i < words.length; i++) {
165
166 if ((words[i].length() < 2) || (words[i].charAt(1) != '=')) {
167 // unexpected response.
168 continue;
169 }
170
171 char what = words[i].charAt(0);
172 String value = words[i].substring(2);
173 oldGpsData = gpsData;
174 gpsData = new LiveGpsData();
175 switch(what) {
176 case 'O':
177 // full report, tab delimited.
178 String[] status = value.split("\\s+");
179 if (status.length >= 5) {
180 lat = Double.parseDouble(status[3]);
181 lon = Double.parseDouble(status[4]);
182 try {
183 speed = Float.parseFloat(status[9]);
184 course = Float.parseFloat(status[8]);
185 //view.setSpeed(speed);
186 //view.setCourse(course);
187 } catch (NumberFormatException nex) {}
188 haveFix = true;
189 }
190 break;
191 case 'P':
192 // position report, tab delimited.
193 String[] pos = value.split("\\s+");
194 if (pos.length >= 2) {
195 lat = Double.parseDouble(pos[0]);
196 lon = Double.parseDouble(pos[1]);
197 speed = Float.NaN;
198 course = Float.NaN;
199 haveFix = true;
200 }
201 default:
202 // not interested
203 }
204 fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.CONNECTED, tr("Connected"));
205 gpsData.setFix(haveFix);
206 if (haveFix) {
207 //view.setCurrentPosition(lat, lon);
208 gpsData.setLatLon(new LatLon(lat, lon));
209 gpsData.setSpeed(speed);
210 gpsData.setCourse(course);
211 fireGpsDataChangeEvent(oldGpsData, gpsData);
212 }
213 }
214 } else {
215 // not connected:
216 fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.DISCONNECTED, tr("Not connected"));
217 try { Thread.sleep(1000); } catch (InterruptedException ignore) {};
218 }
219 } catch(IOException iox) {
220 connected = false;
221 if(gpsData != null) {
222 gpsData.setFix(false);
223 fireGpsDataChangeEvent(oldGpsData, gpsData);
224 }
225 fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.CONNECTION_FAILED, tr("Connection Failed"));
226 try { Thread.sleep(1000); } catch (InterruptedException ignore) {};
227 // send warning to layer
228
229 }
230 }
231
232 fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.DISCONNECTED, tr("Not connected"));
233 if (gpsdSocket != null) {
234 try {
235 gpsdSocket.close();
236 gpsdSocket = null;
237 System.out.println("LiveGps: Disconnected from gpsd");
238 }
239 catch (Exception e) {
240 System.out.println("LiveGps: Unable to close socket; reconnection may not be possible");
241 };
242 }
243 }
244
245 public void shutdown()
246 {
247 shutdownFlag = true;
248 }
249}
Note: See TracBrowser for help on using the repository browser.