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

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

甚至可能以任何方式?

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

但是,在CLLocationManager提供的CLLocation中可以使用GPRMC消息的数据。

让我们看一下RMC的属性:

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

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

以下代码在Swift中从CLLocation构建GPRMC和GPGGA语句。 它基于这个问题和NMEA规范的句子。 有些数据是硬编码的,因为我们无权访问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) }