Exemple #1
0
func DecodeCompressedPositionReport(c string) (geospatial.Point, rune, rune, string, error) {
	// Example:    =/5L!!<*e7OS]S

	var err error
	var matches []string

	p := geospatial.Point{}

	pr := regexp.MustCompile(`[=!]([\\\/])(.{4})(.{4})(.)(..)(.)(.*)$`)

	remains := pr.ReplaceAllString(c, "")

	p.Time = time.Now()

	if matches = pr.FindStringSubmatch(c); len(matches) > 0 {

		if len(matches[7]) > 0 {
			remains = matches[7]
		}

		symTable := rune(matches[1][0])
		symCode := rune(matches[4][0])

		p.Lat, err = DecodeBase91Lat([]byte(matches[2]))
		if err != nil {
			return p, ' ', ' ', remains, fmt.Errorf("Could not decode compressed latitude: %v\n", err)
		}

		p.Lon, err = DecodeBase91Lon([]byte(matches[3]))
		if err != nil {
			return p, ' ', ' ', remains, fmt.Errorf("Could not decode compressed longitude: %v\n", err)
		}

		// A space in this position indicates that the report includes no altitude, speed/course, or radio range.
		if matches[5][0] != ' ' {

			// First we look at the Compression Byte ("T" in the spec) and check for a GGA NMEA source.
			// If the GGA bits are set, we decode an altitude reading.  Otherwise, try to decode a course/
			// speed reading or a radio range reading
			if (byte(matches[6][0])-33)&0x18 == 0x10 {
				// This report has an encoded altitude reading
				p.Altitude, err = DecodeBase91Altitude([]byte(matches[5]))
				if err != nil {
					return p, ' ', ' ', remains, fmt.Errorf("Could not decode compressed altitude: %v\n", err)
				}
			} else if (byte(matches[5][0])-33) >= 0 && (byte(matches[5][0])-33) <= 89 {
				p.Heading, p.Speed, err = DecodeBase91CourseSpeed([]byte(matches[5]))
			} else if matches[5][0] == '{' {
				p.RadioRange = DecodeBase91RadioRange(byte(matches[5][1]))
			}
		}

		return p, symTable, symCode, remains, nil

	}
	return p, ' ', ' ', remains, nil
}