如何在node中解码gtfsprotobufs
how do you decode gtfs protobufs in node
我正在尝试使用https://github.com/dcodeIO/ProtoBuf.js以解析三聚体gtfs数据。
这是我到目前为止的代码,它正确地解析.proto文件并创建生成器,并具有所有预期的属性和方法,当我试图用它解码任何数据时,它会抛出一个错误。
Error: Data must be corrupt: Buffer overrun
proto文件来自https://developers.google.com/transit/gtfs-realtime/gtfs-realtime-proto
var ProtoBuf = require('protobufjs')
, request = require('request')
var transit = ProtoBuf.protoFromFile('gtfs-realtime.proto').build('transit_realtime')
request('http://developer.trimet.org/ws/V1/FeedSpecAlerts/?appID=618F30BB3062F39AF24AED9EC', parse)
function parse(err, res, body) {
try {
console.log(transit.FeedMessage.decode(res.body))
} catch(e) {
console.log(e)
}
}
多亏了Brian Ferris,我能够解析头gtfs_realtime_version: "1"
的第一部分,但解析器在下一个组件(时间戳uint64)上失败了
感谢
在搜索您遇到的同一问题时,我一直在寻找您的问题,希望我能帮助其他人。在互联网上搜索的时间比我应该搜索的时间长得多之后,我想出了一些有效的方法。直到我解码了一个工作提要,我才完全理解数据。
这在很大程度上似乎与数据的读取方式有关。我不是NodeJS的人,所以我不知道为什么,但这取决于如何使用http
而不是request
读取数据进行解码。我无法使用相同的方法来处理request
的数据。
其中一部分是我从https://github.com/dcodeIO/ProtoBuf.js/wiki/How-to-read-binary-data-in-the-browser-or-under-node.js%3F但我还不太了解如何使用protobufjs
,所以我在这里为其他人举一个工作示例。希望能有所帮助。
var ProtoBuf = require('protobufjs');
var http = require("http");
// create a protobuf decoder
var transit = ProtoBuf.protoFromFile('gtfs-realtime.proto').build('transit_realtime');
// your protobuf binary feed URL
var feedUrl = "...";
// HTTP GET the binary feed
http.get(feedUrl, parse);
// process the feed
function parse(res) {
// gather the data chunks into a list
var data = [];
res.on("data", function(chunk) {
data.push(chunk);
});
res.on("end", function() {
// merge the data to one buffer, since it's in a list
data = Buffer.concat(data);
// create a FeedMessage object by decooding the data with the protobuf object
var msg = transit.FeedMessage.decode(data);
// do whatever with the object
console.log(msg);
});
});
来自Developers.Google.com/transit/gtfs-realtime/examples/nodejs-sample上的谷歌开发者页面。谷歌现在提供了一个Node.js npm模块,让事情变得非常简单:
npm install gtfs-realtime-bindings
以下是谷歌的代码片段(Apache 2.0许可证)
var GtfsRealtimeBindings = require('gtfs-realtime-bindings');
var request = require('request');
var requestSettings = {
method: 'GET',
url: 'URL OF YOUR GTFS-REALTIME SOURCE GOES HERE',
encoding: null
};
request(requestSettings, function (error, response, body) {
if (!error && response.statusCode == 200) {
var feed = GtfsRealtimeBindings.transit_realtime.FeedMessage.decode(body);
feed.entity.forEach(function(entity) {
if (entity.trip_update) {
console.log(entity.trip_update);
}
});
}
});
我通过强制request
模块使用null编码,从而确保它返回缓冲区而不是字符串,从而使这一点得以实现(无论如何,使用纽约MTA提要)。像这样:
request({
url: 'http://developer.trimet.org/ws/V1/FeedSpecAlerts/?appID=618F30BB3062F39AF24AED9EC'
encoding: null
}, parse)
然后解析似乎工作正常。
这不能回答您的问题,但您可以使用类似url的文本获取RT提要http://developer.trimet.org/ws/V1/FeedSpecAlerts/appid/618F30BB3062F39AF24AED9EC/text/true
还可以看看节点gtfs模块。
我不是节点专家,但GTFS实时提要的根消息类型是"FeedMessage":
https://developers.google.com/transit/gtfs-realtime/reference
您似乎试图将提要解析为"警报"消息:
console.log(transit.Alert.decode(res.body))
也许可以尝试将Alert更改为FeedMessage,看看会发生什么?
- 在文本区域POST后解码JSON
- Json字符串可以'当字符串末尾有“'时,t解码;
- 有没有一种方法可以在没有文档或jQuery的情况下使用javascript解码html实体
- 从Base64 Ionic编码和解码图像
- 如何在JS中编码URL并在PHP中解码
- 在服务器中编码,并使用escape在javascript中解码
- 如何编码/解码这个专有校验和(Athena 16C PID控制器)
- php中javascript解码中的base64编码
- 在Erlang中解码URIComponent
- AngularJs正在解码HTML字符(不需要)
- 隐藏HTML元素中的JSON编码和解码
- 将Base64音频文件Mp3解码为可播放的Mp3
- 如何使用Java解码由window.btoa编码的base64图像
- 标题不适用于解码URIComponent和空格
- 为什么我不必在 JS 中解码/解析 PHP 生成的 JSON 字符串
- 需要使用Java编码/转义HTML字符串,并在JavaScript中解码HTML字符串
- 解码十六进制编码/混淆的javascript
- JavaScript 正则表达式解码 atob
- 如何在节点中解码 gzip 或 utf-8 响应
- 如何在node中解码gtfsprotobufs