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

Last change on this file since 2936 was 2936, checked in by christofd, 18 years ago

Initial import.

File size: 6.8 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.IOException;
8import java.io.InputStreamReader;
9import java.net.InetAddress;
10import java.net.Socket;
11import java.util.ArrayList;
12import java.util.List;
13
14import org.openstreetmap.josm.data.coor.LatLon;
15
16public class LiveGpsAcquirer implements Runnable {
17 Socket gpsdSocket;
18 BufferedReader gpsdReader;
19 boolean connected = false;
20 String gpsdHost = "localhost";
21 int gpsdPort = 2947;
22 boolean shutdownFlag = false;
23 private List<PropertyChangeListener> propertyChangeListener = new ArrayList<PropertyChangeListener>();
24
25 public LiveGpsAcquirer() {
26
27 }
28
29 /**
30 * Adds a property change listener to the acquirer.
31 * @param listener the new listener
32 */
33 public void addPropertyChangeListener(PropertyChangeListener listener) {
34 if(!propertyChangeListener.contains(listener)) {
35 propertyChangeListener.add(listener);
36 }
37 }
38
39 /**
40 * Fire a gps status change event. Fires events with key "gpsstatus" and a {@link LiveGpsStatus}
41 * object as value.
42 * @param status the status.
43 * @param statusMessage the status message.
44 */
45 public void fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus status, String statusMessage) {
46 PropertyChangeEvent event = new PropertyChangeEvent(this, "gpsstatus", null, new LiveGpsStatus(status, statusMessage));
47 firePropertyChangeEvent(event);
48 }
49
50 /**
51 * Fire a gps data change event to all listeners. Fires events with key "gpsdata" and a
52 * {@link LiveGpsData} object as values.
53 * @param oldData the old gps data.
54 * @param newData the new gps data.
55 */
56 public void fireGpsDataChangeEvent(LiveGpsData oldData, LiveGpsData newData) {
57 PropertyChangeEvent event = new PropertyChangeEvent(this, "gpsdata", oldData, newData);
58 firePropertyChangeEvent(event);
59 }
60
61 /**
62 * Fires the given event to all listeners.
63 * @param event the event to fire.
64 */
65 protected void firePropertyChangeEvent(PropertyChangeEvent event) {
66 for (PropertyChangeListener listener : propertyChangeListener) {
67 listener.propertyChange(event);
68 }
69 }
70
71 public void run() {
72 LiveGpsData oldGpsData = null;
73 LiveGpsData gpsData = null;
74 shutdownFlag = false;
75 while(!shutdownFlag) {
76 double lat = 0;
77 double lon = 0;
78 float speed = 0;
79 float course = 0;
80 boolean haveFix = false;
81
82 try
83 {
84 if (!connected)
85 {
86 fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.CONNECTING, tr("Connecting"));
87 InetAddress[] addrs = InetAddress.getAllByName(gpsdHost);
88 for (int i=0; i < addrs.length && gpsdSocket == null; i++) {
89 try {
90 gpsdSocket = new Socket(addrs[i], gpsdPort);
91 break;
92 } catch (Exception e) {
93 gpsdSocket = null;
94 }
95 }
96
97 if (gpsdSocket != null)
98 {
99 gpsdReader = new BufferedReader(new InputStreamReader(gpsdSocket.getInputStream()));
100 gpsdSocket.getOutputStream().write(new byte[] { 'w', 13, 10 });
101 fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.CONNECTED, tr("Connected"));
102 connected = true;
103 }
104 }
105
106
107 if(connected) {
108 String line = gpsdReader.readLine();
109 if (line == null) break;
110 String words[] = line.split(",");
111
112 if ((words.length == 0) || (!words[0].equals("GPSD"))) {
113 // unexpected response.
114 continue;
115 }
116
117 for (int i = 1; i < words.length; i++) {
118
119 if ((words[i].length() < 2) || (words[i].charAt(1) != '=')) {
120 // unexpected response.
121 continue;
122 }
123
124 char what = words[i].charAt(0);
125 String value = words[i].substring(2);
126 oldGpsData = gpsData;
127 gpsData = new LiveGpsData();
128 switch(what) {
129 case 'O':
130 // full report, tab delimited.
131 String[] status = value.split("\\s+");
132 if (status.length >= 5) {
133 lat = Double.parseDouble(status[3]);
134 lon = Double.parseDouble(status[4]);
135 try {
136 speed = Float.parseFloat(status[9]);
137 course = Float.parseFloat(status[8]);
138 //view.setSpeed(speed);
139 //view.setCourse(course);
140 } catch (NumberFormatException nex) {}
141 haveFix = true;
142 }
143 break;
144 case 'P':
145 // position report, tab delimited.
146 String[] pos = value.split("\\s+");
147 if (pos.length >= 2) {
148 lat = Double.parseDouble(pos[0]);
149 lon = Double.parseDouble(pos[1]);
150 speed = Float.NaN;
151 course = Float.NaN;
152 haveFix = true;
153 }
154 default:
155 // not interested
156 }
157 gpsData.setFix(haveFix);
158 if (haveFix) {
159 //view.setCurrentPosition(lat, lon);
160 gpsData.setLatLon(new LatLon(lat, lon));
161 gpsData.setSpeed(speed);
162 gpsData.setCourse(course);
163 fireGpsDataChangeEvent(oldGpsData, gpsData);
164 }
165 }
166 } else {
167 // not connected:
168 try { Thread.sleep(1000); } catch (InterruptedException ignore) {};
169 }
170 } catch(IOException iox) {
171 connected = false;
172 gpsData.setFix(false);
173 fireGpsDataChangeEvent(oldGpsData, gpsData);
174 fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.CONNECTION_FAILED, tr("Connection Failed"));
175 try { Thread.sleep(1000); } catch (InterruptedException ignore) {};
176 // send warning to layer
177
178 }
179 }
180 fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.DISCONNECTED, tr("Disconnected"));
181 if (gpsdSocket != null) try { gpsdSocket.close(); } catch (Exception ignore) {};
182 }
183
184
185
186 public void shutdown()
187 {
188 shutdownFlag = true;
189 }
190}
Note: See TracBrowser for help on using the repository browser.