我正在寻找一种从设备GPS获取GPRMC信息的方法。
它有可能以任何方式吗?
答案 0 :(得分:2)
没有公共API可以从设备的GPS芯片中检索GPRMC。 您最接近的是根据Location API为您提供的GPRMC语句。
以下代码在Swift中从CLLocation构建GPRMC和GPGGA语句。它基于this question和NMEA 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的属性: