是否可以从设备GPS检索GPRMC?

时间:2014-03-06 14:29:38

标签: ios objective-c gps location

我正在寻找一种从设备GPS获取GPRMC信息的方法。

它有可能以任何方式吗?

2 个答案:

答案 0 :(得分:2)

没有公共API可以从设备的GPS芯片中检索GPRMC。 您最接近的是根据Location API为您提供的GPRMC语句。

以下代码在Swift中从CLLocation构建GPRMC和GPGGA语句。它基于this questionNMEA specification这些句子。有些数据是硬编码的,因为我们无法访问iOS上的数据。

CLLocationManagerDelegate上:

let timestampFormatter = NSDateFormatter()
let nmeaDateFormatter = NSDateFormatter()

init () {
    timestampFormatter.timeZone = NSTimeZone(name: "UTC")
    timestampFormatter.dateFormat = "HHmmss.SSS"

    nmeaDateFormatter.timeZone = NSTimeZone(name: "UTC")
    nmeaDateFormatter.dateFormat = "ddMMyy"
}

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    for location in locations {
        let latitude = convertCLLocationDegreesToNmea(location.coordinate.latitude)
        let longitude = convertCLLocationDegreesToNmea(location.coordinate.longitude)

        // GPGGA
        // http://www.gpsinformation.org/dale/nmea.htm#GGA
        var nmea0183GPGGA = "GPGGA," + timestampFormatter.stringFromDate(location.timestamp)
        nmea0183GPGGA += String(format: ",%08.4f,", arguments: [abs(latitude)])
        nmea0183GPGGA += latitude > 0.0 ? "N" : "S"
        nmea0183GPGGA += String(format: ",%08.4f,", arguments: [abs(longitude)])
        nmea0183GPGGA += longitude > 0.0 ? "E" : "W"
        nmea0183GPGGA += ",1,08,1.0,"
        nmea0183GPGGA += String(format: "%1.1f,M,%1.1f,M,,,", arguments: [location.altitude, location.altitude])
        nmea0183GPGGA += String(format: "*%02lX", arguments: [nmeaSentenceChecksum(nmea0183GPGGA)])
        nmea0183GPGGA = "$" + nmea0183GPGGA

        // GPRMC
        // http://www.gpsinformation.org/dale/nmea.htm#RMC
        var nmea0183GPRMC = "GPRMC," + timestampFormatter.stringFromDate(location.timestamp) + ",A,"
        nmea0183GPRMC += String(format: "%08.4f,", arguments: [abs(latitude)])
        nmea0183GPRMC += latitude > 0.0 ? "N" : "S"
        nmea0183GPRMC += String(format: ",%08.4f,", arguments: [abs(longitude)])
        nmea0183GPRMC += longitude > 0.0 ? "E" : "W"
        nmea0183GPRMC += String(format: ",%04.1f,", arguments: [(location.course > 0.0 ? location.speed * 3600.0 / 1000.0 * 0.54 : 0.0)])
        nmea0183GPRMC += String(format: "%04.1f,", arguments: [(location.course > 0.0 ? location.course : 0.0)])
        nmea0183GPRMC += nmeaDateFormatter.stringFromDate(location.timestamp)
        nmea0183GPRMC += ",,,A"
        nmea0183GPRMC += String(format: "*%02lX", arguments: [nmeaSentenceChecksum(nmea0183GPRMC)])
        nmea0183GPRMC = "$" + nmea0183GPRMC

        // Log
        debugPrint(nmea0183GPGGA)
        debugPrint(nmea0183GPRMC)
    }
}

func convertCLLocationDegreesToNmea(degrees: CLLocationDegrees) -> Double {
    let degreeSign = ((degrees > 0.0) ? 1.0 : ((degrees < 0.0) ? -1.0 : 0));
    let degree = abs(degrees);
    let degreeDecimal = floor(degree);
    let degreeFraction = degree - degreeDecimal;
    let minutes = degreeFraction * 60.0;
    let nmea = degreeSign * (degreeDecimal * 100.0 + minutes);
    return nmea;
}

func nmeaSentenceChecksum(sentence: String) -> CLong {
    var checksum: unichar = 0;
    var stringUInt16 = [UInt16]()
    stringUInt16 += sentence.utf16
    for char in stringUInt16 {
        checksum ^= char
    }
    checksum &= 0x0ff
    return CLong(checksum)
}

答案 1 :(得分:1)

不,这是不可能的。
第一个GPRMC是来自基于文本的NMEA协议的消息,这是一个定义不明确的协议1,每个芯片制造商对它的解释都不同。
在大多数专业设备中,使用芯片制造商提供的二进制协议。 即使Apple在内部使用NMEA Protokoll与芯片进行通信,您也无法访问该消息。

然而,在CLLocationManager提供的CLLocation中可以获得GPRMC消息的数据。

让我们看一下RMC的属性:

  • 时间:不是真的,苹果可以通过当地时间或用户修正偏移来纠正时间 偏移。
  • validFlag:CLLocation中的是
  • 纬度:是
  • 经度:是
  • 速度:是的
  • 当然:是(CLLocation.course)
  • 磁变化:是的,但需要API调用。