我有一个websocket,它以2Hz的速率返回GPS NMEA句子流。每个响应通常包含六个句子,包括两个GSV卫星可见性句子和一个GGA定位句子。每个GSV语句包含1-4个卫星的仰角,方位角和信噪比信息,这些是我最初感兴趣的句子。我想创建一个包含Satellite[]
数组的可观察流目前可见的GNSS卫星的仰角和方位角细节。
以下打字稿代码片段每个GSV
句子产生一个数组,但我想要的是每个响应的数组,可能包括几个GSV语句。我已经研究过使用concat,combine,merge和它们的变体但是没有成功。
最终我还想将GGA定位信息提取到另一个流中。
道歉,如果对此有一个简单的答案,我对RXJS来说相对较新,所以我找到了自己的方式。
// The information available for each satellite.
export interface Satellite {
id: string;
elevation: number;
azimuth: number;
noise: number;
}
// The code to process the web socket data.
this.satellites$ = <Subject<Satellite[]>> this.wss
.connect('ws://localhost:8887')
.mergeMap((response) => { return response.data.split(/\r?\n/); }) // Split the multi line response into individual lines.
.filter((line) => line !== '') // Filter out blank lines.
.mergeMap((sentence) => { return this.nmeaPacket(sentence); }) // Parse the line into an NMEA sentence.
.filter((packet) => { return packet.sentenceId === 'GSV'; }) // Filter out everything except GSV sentences.
.map((gsvPacket: nmea.GSVPacket): Satellite[] => {
// Extract the satellite info from this sentence.
let satellites: Satellite[] = [];
for (let satellite of gsvPacket.satellites) {
if (satellite.prnNumber > 1) {
satellites.push({
id: this.satelliteId(satellite.prnNumber),
azimuth: satellite.azimuthTrue,
elevation: satellite.elevationDegrees,
noise: satellite.SNRdB})
}
}
return satellites;
}); // Re-combine the array here or back where the initial line split is done??
// Use nmea-simple to parse a line from the response into an NMEA sentence.
private nmeaPacket(sentence: any): Observable<nmea.Packet> {
return Observable.of(nmea.parseNmeaSentence(sentence));
}
&#13;
下面是一张大理石图,其中包含示例输入数据,显示了我希望如何处理这些数据。希望这可以更清楚地了解我想要实现的目标。
答案 0 :(得分:0)
我认为您的问题会受益于输入和所需输出的示例,因为我不确定数组实际意味着什么重组。
此外,我不确定您的代码是否会产生评论中列出的行为。例如response.data.split(/\r?\n/)
返回一个数组,但只有当.filter((line) => line !== '')
是一个字符串并且该字符串为空时,true
才会返回line
。
最后,如果你能澄清为什么satellites$
是一个主题而不是一个Observable
和nmeaPacket
会返回一个与nmea.Packet
相反的可观察对象,那将会有所帮助。
话虽如此,让我建议一些调整,看看是否有帮助:
this.satellites$ = this.wss
.connect('ws://localhost:8887')
.map((response) => response.data.split(/\r?\n/).filter((line) => line !== '') // <- can you provide an example of the input here
.map((sentence) => this.nmeaPacket(sentence))
.filter((packet) => packet.sentenceId === 'GSV')
.map((packet) => {
let satellites: Satellite[] = [];
packet.satellites.forEach((satellite) => {
if (satellite.prnNumber > 1) {
satellites.push({
id: this.satelliteId(satellite.prnNumber),
azimuth: satellite.azimuthTrue,
elevation: satellite.elevationDegrees,
noise: satellite.SNRdB})
}
}
return satellites;
})
}) // <- can you provide an example of the desired output here
private nmeaPacket(sentence: any): nmea.Packet {
return nmea.parseNmeaSentence(sentence);
}
答案 1 :(得分:0)
要重新组合最后的行,您可以用map
替换最后的reduce
:
Rx.Observable.of(1,2,3).reduce((acc, value) => [...acc, value], []).subscribe(console.log)
(...但我不确定Observables是否是正确的工具,你确定你不想只将每个响应映射到其他形状吗?在这种情况下一个简单的具有同步过滤器/映射操作的.map
就足够了。)
答案 2 :(得分:0)
我怀疑这是最有效或最优雅的解决方案,但它确实实现了我的目标。有几个地方我不得不在卫星信息阵列上进行迭代,我在这些地方尝试过flatMap / mergeMap但是没有取得多大成功。
password
&#13;