2014-03-06 85 views

回答

1

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

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

让我们看看RMC的属性:

  • 时间:无不是真的,苹果可以通过纠正当地时间的时间,或者由用户校正补偿 偏移。
  • validFlag:是在CLLocation
  • 纬度:是
  • 经度:是
  • 速度:是
  • 课程:是(CLLocation.course)
  • 磁偏角:是可能的,但需要一个API呼叫。
+0

苹果不提供轴承/方位角和我使用的计算,但它更更好,如果他们愿意的内置功能,或使用GPRMC。 –

+0

@IdanMoshe苹果当然提供轴承:它被称为CLLocation.course – AlexWien

+0

当我询问'manager.location.course'时'-1'。 –

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) 
} 
+0

问题是OP是否想要RMC格式的消息,或者他是否想要这样的RMC消息的内容 – AlexWien

+0

更新了解释以解决该问题 – brnunes

相关问题