gps.js
function(str, gsv) {

      if (gsv.length % 4 % 3 === 0) {
        throw new Error('Invalid GSV length: ' + str);
      }

      /*
       $GPGSV,1,1,13,02,02,213,,03,-3,000,,11,00,121,,14,13,172,05*67
       
       1    = Total number of messages of this type in this cycle
       2    = Message number
       3    = Total number of SVs in view
       repeat [
       4    = SV PRN number
       5    = Elevation in degrees, 90 maximum
       6    = Azimuth, degrees from true north, 000 to 359
       7    = SNR (signal to noise ratio), 00-99 dB (null when not tracking, higher is better)
       ]
       N+1   = signalID NMEA 4.10
       N+2   = Checksum
       */

      var sats = [];

      for (var i = 4; i < gsv.length - 3; i += 4) {

        var prn = parseNumber(gsv[i]);
        var snr = parseNumber(gsv[i + 3]);
        /*
         Plot satellites in Radar chart with north on top
         by linear map elevation from 0° to 90° into r to 0
         
         centerX + cos(azimuth - 90) * (1 - elevation / 90) * radius
         centerY + sin(azimuth - 90) * (1 - elevation / 90) * radius
         */
        sats.push({
          'prn': prn,
          'elevation': parseNumber(gsv[i + 1]),
          'azimuth': parseNumber(gsv[i + 2]),
          'snr': snr,
          'status': prn !== null ? (snr !== null ? 'tracking' : 'in view') : null
        });
      }

      return {
        'msgNumber': parseNumber(gsv[2]),
        'msgsTotal': parseNumber(gsv[1]),
        //'satsInView'  : parseNumber(gsv[3]), // Can be obtained by satellites.length
        'satellites': sats,
        'signalId': gsv.length % 4 === 2 ? parseNumber(gsv[gsv.length - 2]) : null // NMEA 4.10 addition
      };
    }
function(str, gsv) {

      if (gsv.length % 4 % 3 === 0) {
        throw new Error('Invalid GSV length: ' + str);
      }

      /*
       $GPGSV,1,1,13,02,02,213,,03,-3,000,,11,00,121,,14,13,172,05*67
       
       1    = Total number of messages of this type in this cycle
       2    = Message number
       3    = Total number of SVs in view
       repeat [
       4    = SV PRN number
       5    = Elevation in degrees, 90 maximum
       6    = Azimuth, degrees from true north, 000 to 359
       7    = SNR (signal to noise ratio), 00-99 dB (null when not tracking, higher is better)
       ]
       N+1   = signalID NMEA 4.10
       N+2   = Checksum
       */

      var sats = [];

      for (var i = 4; i < gsv.length - 3; i += 4) {

        var prn = parseNumber(gsv[i]);
        var snr = parseNumber(gsv[i + 3]);
        /*
         Plot satellites in Radar chart with north on top
         by linear map elevation from 0° to 90° into r to 0
         
         centerX + cos(azimuth - 90) * (1 - elevation / 90) * radius
         centerY + sin(azimuth - 90) * (1 - elevation / 90) * radius
         */
        sats.push({
          'prn': prn,
          'elevation': parseNumber(gsv[i + 1]),
          'azimuth': parseNumber(gsv[i + 2]),
          'snr': snr,
          'status': prn !== null ? (snr !== null ? 'tracking' : 'in view') : null
        });
      }

      return {
        'msgNumber': parseNumber(gsv[2]),
        'msgsTotal': parseNumber(gsv[1]),
        //'satsInView'  : parseNumber(gsv[3]), // Can be obtained by satellites.length
        'satellites': sats,
        'signalId': gsv.length % 4 === 2 ? parseNumber(gsv[gsv.length - 2]) : null // NMEA 4.10 addition
      };
    }
satellites in view