Ticket #675: josm-nmea-support.2.patch

File josm-nmea-support.2.patch, 7.8 KB (added by egore@…, 17 years ago)

Patch that merges the two patches. Should work correct now

  • src/org/openstreetmap/josm/actions/OpenAction.java

     
    1717
    1818import org.openstreetmap.josm.Main;
    1919import org.openstreetmap.josm.data.osm.DataSet;
     20import org.openstreetmap.josm.gui.layer.GpxLayer;
    2021import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    21 import org.openstreetmap.josm.gui.layer.GpxLayer;
    2222import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;
     23import org.openstreetmap.josm.io.GpxReader;
     24import org.openstreetmap.josm.io.NmeaReader;
    2325import org.openstreetmap.josm.io.OsmReader;
    24 import org.openstreetmap.josm.io.GpxReader;
    2526import org.xml.sax.SAXException;
    2627
    2728/**
     
    5556                try {
    5657                        if (asGpxData(file.getName()))
    5758                                openFileAsGpx(file);
     59                        else if (asNmeaData(file.getName()))
     60                                openFileAsNmea(file);
    5861                        else
    5962                                openAsData(file);
    6063                } catch (SAXException x) {
     
    102105                }
    103106    }
    104107
     108        private void openFileAsNmea(File file) throws IOException, FileNotFoundException {
     109                String fn = file.getName();
     110                if (ExtensionFileFilter.filters[ExtensionFileFilter.NMEA].acceptName(fn)) {
     111                        NmeaReader r = new NmeaReader(new FileInputStream(file), file.getAbsoluteFile().getParentFile());
     112                        r.data.storageFile = file;
     113                        GpxLayer gpxLayer = new GpxLayer(r.data, fn);
     114                        Main.main.addLayer(gpxLayer);
     115                        if (Main.pref.getBoolean("marker.makeautomarkers", true)) {
     116                                MarkerLayer ml = new MarkerLayer(r.data, tr("Markers from {0}", fn), file, gpxLayer);
     117                                if (ml.data.size() > 0) {
     118                                        Main.main.addLayer(ml);
     119                                }
     120                        }
    105121
     122                } else {
     123                        throw new IllegalStateException();
     124                }
     125    }
     126
    106127        private boolean asGpxData(String fn) {
    107128                return ExtensionFileFilter.filters[ExtensionFileFilter.GPX].acceptName(fn);
    108129        }
    109130
     131        private boolean asNmeaData(String fn) {
     132                return ExtensionFileFilter.filters[ExtensionFileFilter.NMEA].acceptName(fn);
     133        }
    110134
     135
    111136}
  • src/org/openstreetmap/josm/actions/ExtensionFileFilter.java

     
    2020
    2121        public static final int OSM = 0;
    2222        public static final int GPX = 1;
     23        public static final int NMEA = 2;
    2324       
    2425        public static ExtensionFileFilter[] filters = {
    2526                new ExtensionFileFilter("osm,xml", "osm", tr("OSM Server Files (.osm .xml)")),
    2627                new ExtensionFileFilter("gpx,gpx.gz", "gpx", tr("GPX Files (.gpx .gpx.gz)")),
     28                new ExtensionFileFilter("nmea", "nmea", tr("NMEA-0183 Files (.nmea)")),
    2729        };
    2830
    2931        /**
  • src/org/openstreetmap/josm/io/NmeaReader.java

     
     1//License: GPL. Copyright 2008 by Christoph Brill
     2
     3package org.openstreetmap.josm.io;
     4
     5import java.io.BufferedReader;
     6import java.io.File;
     7import java.io.IOException;
     8import java.io.InputStream;
     9import java.io.InputStreamReader;
     10import java.text.ParseException;
     11import java.text.SimpleDateFormat;
     12import java.util.ArrayList;
     13import java.util.Calendar;
     14import java.util.Collection;
     15import java.util.Date;
     16
     17import org.openstreetmap.josm.data.coor.EastNorth;
     18import org.openstreetmap.josm.data.coor.LatLon;
     19import org.openstreetmap.josm.data.gpx.GpxData;
     20import org.openstreetmap.josm.data.gpx.GpxTrack;
     21import org.openstreetmap.josm.data.gpx.WayPoint;
     22
     23/**
     24 * Read a nmea file. Based on information from
     25 * http://www.kowoma.de/gps/zusatzerklaerungen/NMEA.htm
     26 *
     27 * @author cbrill
     28 */
     29public class NmeaReader {
     30
     31        /** Handler for the different types that NMEA speaks. */
     32        public static enum NMEA_TYPE {
     33
     34                /** RMC = recommended minimum sentence C. */
     35                GPRMC("$GPRMC"),
     36                /** GPS positions. */
     37                GPGGA("$GPGGA"),
     38                /** SA = satellites active. */
     39                GPGSA("$GPGSA");
     40
     41                private final String type;
     42
     43                NMEA_TYPE(String type) {
     44                        this.type = type;
     45                }
     46
     47                public String getType() {
     48                        return this.type;
     49                }
     50
     51                public boolean equals(String type) {
     52                        return this.type.equals(type);
     53                }
     54        }
     55
     56        private static final int TYPE = 0;
     57
     58        // The following only applies to GPRMC
     59        public static enum GPRMC {
     60                TIME(1),
     61                /** Warning from the receiver (A = data ok, V = warning) */
     62                RECEIVER_WARNING(2), WIDTH_NORTH(3), WIDTH_NORTH_NAME(4), LENGTH_EAST(5), LENGTH_EAST_NAME(
     63                        6),
     64                /** Speed in knots */
     65                SPEED(7), COURSE(8), DATE(9),
     66                /** magnetic declination */
     67                MAGNETIC_DECLINATION(10), UNKNOWN(11),
     68                /**
     69                 * Mode (A = autonom; D = differential; E = estimated; N = not valid; S
     70                 * = simulated)
     71                 *
     72                 * @since NMEA 2.3
     73                 */
     74                MODE(12);
     75
     76                public final int position;
     77
     78                GPRMC(int position) {
     79                        this.position = position;
     80                }
     81        }
     82
     83        // The following only applies to GPGGA
     84        public static enum GPGGA {
     85                TIME(1), LATITUDE(2), LATITUDE_NAME(3), LONGITUDE(4), LONGITUDE_NAME(5),
     86                /**
     87                 * Quality (0 = invalid, 1 = GPS, 2 = DGPS, 6 = estimanted (@since NMEA
     88                 * 2.3))
     89                 */
     90                QUALITY(6), SATELLITE_COUNT(7),
     91                /** HDOP (horizontal dilution of precision) */
     92                HDOP(8),
     93                /** height above NN (above geoid) */
     94                HEIGHT(9), HEIGHT_UNTIS(10),
     95                /** height geoid - height ellipsoid (WGS84) */
     96                HEIGHT_2(11), HEIGHT_2_UNTIS(12);
     97
     98                public final int position;
     99
     100                GPGGA(int position) {
     101                        this.position = position;
     102                }
     103        }
     104
     105        // The following only applies to GPGGA
     106        public static enum GPGSA {
     107                AUTOMATIC(1),
     108                /** 1 = not fixed, 2 = 2D fixed, 3 = 3D fixed) */
     109                FIX_TYPE(2),
     110                // PRN numbers for max 12 satellites
     111                PRN_1(3), PRN_2(4), PRN_3(5), PRN_4(6), PRN_5(7), PRN_6(8), PRN_7(9), PRN_8(
     112                        10), PRN_9(11), PRN_10(12), PRN_11(13), PRN_12(14),
     113                /** PDOP (precision) */
     114                PDOP(15),
     115                /** HDOP (horizontal precision) */
     116                HDOP(16),
     117                /** VDOP (vertical precision) */
     118                VDOP(17), ;
     119
     120                public final int position;
     121
     122                GPGSA(int position) {
     123                        this.position = position;
     124                }
     125        }
     126
     127        public GpxData data;
     128
     129        public NmeaReader(InputStream source, File relativeMarkerPath) {
     130                data = new GpxData();
     131                GpxTrack currentTrack = new GpxTrack();
     132                Collection<WayPoint> currentTrackSeg = new ArrayList<WayPoint>();
     133                currentTrack.trackSegs.add(currentTrackSeg);
     134                data.tracks.add(currentTrack);
     135
     136                BufferedReader rd;
     137                String nmeaWithChecksum;
     138
     139                try {
     140                        rd = new BufferedReader(new InputStreamReader(source));
     141                        while ((nmeaWithChecksum = rd.readLine()) != null) {
     142                                String[] nmeaAndChecksum = nmeaWithChecksum.split("\\*");
     143                                String nmea = nmeaAndChecksum[0];
     144                                // XXX: No need for it: String checksum = nmeaAndChecksum[1];
     145                                String[] e = nmea.split(",");
     146                                if (NMEA_TYPE.GPRMC.equals(e[TYPE])) {
     147                                        LatLon latLon = parseLatLon(e);
     148                                        if (latLon == null) {
     149                                                continue;
     150                                        }
     151                                        WayPoint currentWayPoint = new WayPoint(latLon);
     152                                        currentTrackSeg.add(currentWayPoint);
     153                                }
     154                        }
     155                        rd.close();
     156                } catch (final IOException e) {
     157                        System.out.println("Error reading file");
     158                }
     159
     160        }
     161
     162        private LatLon parseLatLon(String[] e) throws NumberFormatException {
     163                String widthNorth = e[GPRMC.WIDTH_NORTH.position];
     164                String lengthEast = e[GPRMC.LENGTH_EAST.position];
     165                if ("".equals(widthNorth) || "".equals(lengthEast)) {
     166                        return null;
     167                }
     168
     169                int latdeg = Integer.parseInt(widthNorth.substring(0, 2));
     170                if ("S".equals(e[GPRMC.WIDTH_NORTH_NAME.position])) {
     171                        latdeg = -latdeg;
     172                }
     173                double latmin = Double.parseDouble(widthNorth.substring(2));
     174
     175                int londeg = Integer.parseInt(lengthEast.substring(0, 3));
     176                if ("W".equals(e[GPRMC.LENGTH_EAST_NAME.position])) {
     177                        londeg = -londeg;
     178                }
     179                double lonmin = Double.parseDouble(lengthEast.substring(3));
     180
     181                return new LatLon(latdeg + latmin / 60, londeg + lonmin / 60);
     182        }
     183}