const express = require('express');
const bodyParser = require('body-parser');
const config = require('./config/config');
const Ebag = require('./ebag');
const jpeg = require('jpeg-js');
const base64 = require('base64-js');
const cv = require('opencv');
const fs = require('fs');
const app = express();
let g_ebag = new Ebag();
let g_app = {topic_show_list: ''};
app.use(bodyParser.urlencoded({extended: false, limit: '20mb'}));
app.use('/', express.static('public'));
app.post('/data', function (req, res) {
let bucket = req.body.bucket;
let dir = req.body.dir;
let topicList = req.body.topiclist;
let topicConf = [];
let initTopiclist = [];
if (bucket === '0' || dir === '0') {
res.send({'data': [{'name': 'Please', 'value': [-1, Date.now() - 1, '']},
{'name': 'Please', 'value': [-1, Date.now(), '']}],
'list': ['Please', 'enter', 'cloud', 'information', '.']});
return;
}
if (topicList !== '') {
topicConf = topicList.substr(0, topicList.length - 1).split(',');
}
g_ebag.open_data(bucket, dir, err => {
if (err) {
let result = {'err': -1, 'msg': '读取文件失败,请检查bucket与资源目录地址是否有误'};
res.send(result);
} else {
// 数据 x/y 数据
g_ebag.topic_msg = {};
for (let msg of g_ebag.op_blocks.message) {
let topic = msg.head.topic;
if (!g_ebag.topic_msg[topic]) {
g_ebag.topic_msg[topic] = [];
}
g_ebag.topic_msg[topic].push(msg);
}
g_app.topic_show_list = Object.keys(g_ebag.topic_msg).sort();
// 显示图表
let topic_index = {};
let data = [];
let idx = 0;
// 如果topiclist不为空 计算与g_app.topic_show_list的交集 过滤展示的topic
if (topicConf.length !== 0) {
/**
* 重组选择消息列表 已选择 为checked
*/
g_app.topic_show_list.forEach(function (value, index) {
initTopiclist[index] = {
'name': value,
'checked': (topicConf.indexOf(value) === -1) ? 0 : 1
};
});
g_app.topic_show_list = topicConf.filter(function (val) {
return g_app.topic_show_list.indexOf(val) > -1;
});
} else {
g_app.topic_show_list.forEach(function (value, index) {
initTopiclist[index] = {'name': value, 'checked': 0};
});
}
// 画图参数 及 自定义echarts数据组装
g_app.topic_show_list.forEach(function (topic, index) {
topic_index[topic] = idx++;
for (let msg of g_ebag.topic_msg[topic]) {
let tm = Number(msg.head.time);
data.push({
name: topic,
value: [
topic_index[topic],
tm,
msg.pos
]
});
}
});
// 获取topic信息的data
let topicData = g_ebag.op_blocks.data;
// 返回图片信息
let topicPic = {};
/* bca-disable */
for (let key in topicData) {
// 有图片数据 需要处理图片相应的数据
switch (topicData[key].type) {
case 'baidu.pavaro.CameraDataPb': // BGR -> RGB -> jpeg -> base64
let img = {
data: [],
height: topicData[key].decode_msg.height,
width: topicData[key].decode_msg.width,
};
for (let i = 0, j = 0; i < topicData[key].decode_msg.data.length; i += 3, j += 4)
{
img.data[j + 0] = topicData[key].decode_msg.data[i + 2];
img.data[j + 1] = topicData[key].decode_msg.data[i + 1];
img.data[j + 2] = topicData[key].decode_msg.data[i + 0];
img.data[j + 3] = 0xff;
}
let rawImageData = {
data: img.data,
width: topicData[key].decode_msg.width,
height: topicData[key].decode_msg.height
};
let jpg_data_a = jpeg.encode(rawImageData, 50);
let jpg_data_base_a = base64.fromByteArray(jpg_data_a.data);
topicPic[key] = jpg_data_base_a;
delete topicData[key].decode_msg.data;
break;
case 'baidu.pavaro.CameraCompressDataPb':
let raw = jpeg.decode(topicData[key].decode_msg.data, true);
for (let i = 0; i < raw.data.length; i += 4) {
let t = raw.data[i + 0];
raw.data[i + 0] = raw.data[i + 2];
raw.data[i + 2] = t;
}
let jpg_data_b = jpeg.encode(raw, 50);
let jpg_data_base_b = base64.fromByteArray(jpg_data_b.data);
topicPic[key] = jpg_data_base_b;
delete topicData[key].decode_msg.data;
break;
default:
break;
}
}
let result = {
'err': 0,
'data': data,
'list': g_app.topic_show_list,
'topic': topicData,
'img': topicPic,
'initTopiclist': initTopiclist
};
res.send(result);
}
});
});
app.post('/mark', function (req, res) {
let obstacle = JSON.parse(req.body.perdata);
let freespace = JSON.parse(req.body.freedata);
let imgData = req.body.obdata;
let date = Date.now();
// base64 存储到 文件
let path = './public/sourceimg/' + date + '.jpeg';
// 过滤data:URL
let base64Data = imgData.replace(/^data:image\/\w+;base64,/, '');
let dataBuffer = Buffer.from(base64Data, 'base64');
fs.writeFile(path, dataBuffer, function (err) {
if (err) {
res.send({'code': '-1', 'msg': '图片处理失败!'});
}
// 障碍物标记 - 输出图片
let outputPath = './public/obstaclesimg/' + date + '.jpeg';
// 处理图片
/* bca-disable */
cv.readImage(path, function (err, im) {
// 标记障碍物信息
obstacle.forEach(function (value, index) {
im.rectangle([value.imageX, value.imageY], [value.imageW, value.imageH], [0, 255, 0], 2);
});
// 标记可行驶区域信息
/* bca-disable */
freespace.forEach(function (val, idx) {
im.rectangle([val.x, val.y], [3, 3], [0, 255, 0], 3);
});
im.save(outputPath);
});
res.send({'code': '1', 'output': '/obstaclesimg/' + date + '.jpeg'});
});
});
app.listen(config.port);