Ignore:
Timestamp:
2010-06-09T15:21:27+02:00 (14 years ago)
Author:
stoecker
Message:

fixes by Gleb Smirnoff

File:
1 edited

Legend:

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

    r20431 r21622  
    22
    33import static org.openstreetmap.josm.tools.I18n.tr;
     4
     5import java.lang.Float;
    46
    57import java.beans.PropertyChangeEvent;
     
    1618import org.openstreetmap.josm.data.coor.LatLon;
    1719
     20import org.json.JSONObject;
     21import org.json.JSONException;
     22
    1823public class LiveGpsAcquirer implements Runnable {
    19         Socket gpsdSocket;
    20         BufferedReader gpsdReader;
    21         boolean connected = false;
    22         String gpsdHost;
    23         int gpsdPort;
    24         boolean shutdownFlag = false;
     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
    2533        private final List<PropertyChangeListener> propertyChangeListener = new ArrayList<PropertyChangeListener>();
    2634        private PropertyChangeEvent lastStatusEvent;
     
    112120                shutdownFlag = false;
    113121                while (!shutdownFlag) {
    114                         double lat = 0;
    115                         double lon = 0;
    116                         float speed = 0;
    117                         float course = 0;
    118                         boolean haveFix = false;
    119122
    120123                        try {
    121                                 if (!connected) {
    122                                         System.out.println("LiveGps tries to connect to gpsd");
    123                                         fireGpsStatusChangeEvent(
    124                                                         LiveGpsStatus.GpsStatus.CONNECTING,
    125                                                         tr("Connecting"));
    126                                         InetAddress[] addrs = InetAddress.getAllByName(gpsdHost);
    127                                         for (int i = 0; i < addrs.length && gpsdSocket == null; i++) {
    128                                                 try {
    129                                                         gpsdSocket = new Socket(addrs[i], gpsdPort);
    130                                                         break;
    131                                                 } catch (Exception e) {
    132                                                         System.out
    133                                                                         .println("LiveGps: Could not open connection to gpsd: "
    134                                                                                         + e);
    135                                                         gpsdSocket = null;
    136                                                 }
    137                                         }
    138 
    139                                         if (gpsdSocket != null) {
    140                                                 gpsdReader = new BufferedReader(new InputStreamReader(
    141                                                                 gpsdSocket.getInputStream()));
    142                                                 gpsdSocket.getOutputStream().write(
    143                                                                 new byte[] { 'w', 13, 10 });
    144                                                 fireGpsStatusChangeEvent(
    145                                                                 LiveGpsStatus.GpsStatus.CONNECTING,
    146                                                                 tr("Connecting"));
    147                                                 connected = true;
    148                                                 System.out.println("LiveGps: Connected to gpsd");
    149                                         }
    150                                 }
     124                                if (!connected)
     125                                        connect();
    151126
    152127                                if (connected) {
     128                                        String line;
     129
    153130                                        // <FIXXME date="23.06.2007" author="cdaller">
    154131                                        // TODO this read is blocking if gps is connected but has no
    155132                                        // fix, so gpsd does not send positions
    156                                         String line = gpsdReader.readLine();
     133                                        line = gpsdReader.readLine();
    157134                                        // </FIXXME>
    158135                                        if (line == null)
    159136                                                break;
    160                                         String words[] = line.split(",");
    161 
    162                                         if ((words.length == 0) || (!words[0].equals("GPSD"))) {
    163                                                 // unexpected response.
     137
     138                                        if (JSONProtocol == true)
     139                                                gpsData = ParseJSON(line);
     140                                        else
     141                                                gpsData = ParseOld(line);
     142
     143                                        if (gpsData == null)
    164144                                                continue;
    165                                         }
    166 
    167                                         for (int i = 1; i < words.length; i++) {
    168 
    169                                                 if ((words[i].length() < 2)
    170                                                                 || (words[i].charAt(1) != '=')) {
    171                                                         // unexpected response.
    172                                                         continue;
    173                                                 }
    174 
    175                                                 char what = words[i].charAt(0);
    176                                                 String value = words[i].substring(2);
    177                                                 oldGpsData = gpsData;
    178                                                 gpsData = new LiveGpsData();
    179                                                 switch (what) {
    180                                                 case 'O':
    181                                                         // full report, tab delimited.
    182                                                         String[] status = value.split("\\s+");
    183                                                         if (status.length >= 5) {
    184                                                                 lat = Double.parseDouble(status[3]);
    185                                                                 lon = Double.parseDouble(status[4]);
    186                                                                 try {
    187                                                                         speed = Float.parseFloat(status[9]);
    188                                                                         course = Float.parseFloat(status[8]);
    189                                                                         // view.setSpeed(speed);
    190                                                                         // view.setCourse(course);
    191                                                                 } catch (NumberFormatException nex) {
    192                                                                 }
    193                                                                 haveFix = true;
    194                                                         }
    195                                                         break;
    196                                                 case 'P':
    197                                                         // position report, tab delimited.
    198                                                         String[] pos = value.split("\\s+");
    199                                                         if (pos.length >= 2) {
    200                                                                 lat = Double.parseDouble(pos[0]);
    201                                                                 lon = Double.parseDouble(pos[1]);
    202                                                                 speed = Float.NaN;
    203                                                                 course = Float.NaN;
    204                                                                 haveFix = true;
    205                                                         }
    206                                                         break;
    207                                                 default:
    208                                                         // not interested
    209                                                 }
    210                                                 fireGpsStatusChangeEvent(
    211                                                                 LiveGpsStatus.GpsStatus.CONNECTED,
    212                                                                 tr("Connected"));
    213                                                 gpsData.setFix(haveFix);
    214                                                 if (haveFix) {
    215                                                         // view.setCurrentPosition(lat, lon);
    216                                                         gpsData.setLatLon(new LatLon(lat, lon));
    217                                                         gpsData.setSpeed(speed);
    218                                                         gpsData.setCourse(course);
    219                                                         fireGpsDataChangeEvent(oldGpsData, gpsData);
    220                                                 }
    221                                         }
     145
     146                                        fireGpsDataChangeEvent(oldGpsData, gpsData);
     147                                        oldGpsData = gpsData;
    222148                                } else {
    223                                         // not connected:
    224                                         fireGpsStatusChangeEvent(
    225                                                         LiveGpsStatus.GpsStatus.DISCONNECTED,
    226                                                         tr("Not connected"));
     149                                        fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.DISCONNECTED, tr("Not connected"));
    227150                                        try {
    228151                                                Thread.sleep(1000);
    229                                         } catch (InterruptedException ignore) {
    230                                         }
    231                                         ;
     152                                        } catch (InterruptedException ignore) {}
    232153                                }
    233154                        } catch (IOException iox) {
     
    242163                                try {
    243164                                        Thread.sleep(1000);
    244                                 } catch (InterruptedException ignore) {
    245                                 }
    246                                 ;
     165                                } catch (InterruptedException ignore) {} ;
    247166                                // send warning to layer
    248 
    249167                        }
    250168                }
     
    258176                                System.out.println("LiveGps: Disconnected from gpsd");
    259177                        } catch (Exception e) {
    260                                 System.out
    261                                                 .println("LiveGps: Unable to close socket; reconnection may not be possible");
     178                                System.out.println("LiveGps: Unable to close socket; reconnection may not be possible");
    262179                        }
    263180                }
     
    268185        }
    269186
     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        }
    270333}
Note: See TracChangeset for help on using the changeset viewer.