cpnav/lib/pages/pass_track/sevice/file_handle.dart

691 lines
22 KiB
Dart
Raw Normal View History

2024-09-06 09:11:06 +08:00
import 'dart:convert';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:pass_track/binding.dart';
import 'package:pass_track/pass_track.dart';
import 'dart:ffi' as ffi;
import 'package:ffi/ffi.dart';
import 'package:web_socket_channel/io.dart';
import 'package:web_socket_channel/status.dart' as status;
import 'package:pass_track/binding.dart' as Binding;
import '../../../service/base.dart';
import '../model/coord_trans.dart';
import '../model/draw_context.dart';
import '../model/recievemodel.dart';
DrawContext drawCtx = DrawContext();
2024-09-06 15:16:09 +08:00
2024-09-06 09:11:06 +08:00
class FileHandle {
int textureId = -1;
int index = 0;
List deviceList = [];
Map deviceData = {};
String type = "cumulate";
List palette = [];
//所有点的数据
List allPointData = [];
//需要渲染的点的数据
List pointData = [];
double L0 = 102;
late CoordTrans coordTrans;
/* 这个是配合原版ts更改的addpoint*/
// //过滤点
// filterPoint(var point) {
// //传null筛选所有点并把筛选完的点全部返回如果传入一个点返回true或者false
// if (point == null) {
// //页面初始化的时候对所有的点进行筛选
// List newpointData = [];
// if (pointData is List) {
// for (var i = 0; i < (pointData as List).length; i++) {
// if (pointData[i]['bits'] != 0) {
// if (pointData[i]['count'] >= 0 && pointData[i]['count'] <= 50) {
// newpointData.add(pointData[i]);
// } else if (pointData[i]['type'] == 0 || pointData[i]['type'] == 2) {
// newpointData.add(pointData[i]);
// }
// }
// }
// } else {
// //当是个对象的时候websocket时用
// }
// pointData = newpointData;
// return newpointData;
// } else {
// //历史的时候筛点
// if (point.runtimeType == "undefind" ||
// point.obj.runtimeType == "undefined") {
// return false;
// }
// if (point["bits"] != 0) {
// if (point["count"] >= 0 && point["count"] <= 50) {
// return true;
// } else if (point["type"] == 0 || point["type"] == 2) {
// return true;
// } else {
// return false;
// }
// } else {
// return false;
// }
// }
// }
//过滤点null就是全部点有endindex就是回放
filterPoint(var startIndex, var endIndex) {
List newpointData = [];
if (endIndex == null || startIndex == null) {
if (allPointData is List) {
for (var i = 0; i < (allPointData as List).length; i++) {
if (allPointData[i]['bits'] != 0) {
if (allPointData[i]['count'] >= 0 &&
allPointData[i]['count'] <= 50) {
newpointData.add(allPointData[i]);
} else if (allPointData[i]['type'] == 0 ||
allPointData[i]['type'] == 2) {
newpointData.add(allPointData[i]);
}
}
}
} else {
//当是个对象的时候websocket时用
}
pointData = newpointData;
return newpointData;
} else {
if (allPointData is List) {
for (var i = startIndex; i < endIndex; i++) {
if (allPointData[i]['bits'] != 0) {
if (allPointData[i]['count'] >= 0 &&
allPointData[i]['count'] <= 50) {
newpointData.add(allPointData[i]);
} else if (allPointData[i]['type'] == 0 ||
allPointData[i]['type'] == 2) {
newpointData.add(allPointData[i]);
}
}
}
} else {
//当是个对象的时候websocket时用
}
pointData = newpointData;
return newpointData;
}
}
updateObj(pointData) {
final obj = DecodeDataObj.fromBase64(pointData['data']);
pointData['obj'] = obj;
// var check = ffi.sizeOf<Point>() - (512 * 512 - obj.w * obj.h) * 2;
var size_x = ffi.sizeOf<Point>();
// if (check < 0) {
// print('check:$check');
// }
ffi.Pointer<Point> pointer = calloc.allocate<Point>(
ffi.sizeOf<Point>() - (512 * 512 - obj.w * obj.h) * 2 + 1000);
// ffi.Pointer<Point> pointer = calloc
// .allocate<Point>(size_x>>1);
if (pointer == ffi.nullptr) {
return;
}
// pointer.ref.tile.x = obj.x;
// pointer.ref.tile.y = obj.y;
// pointer.ref.tile.w = obj.w;
// pointer.ref.tile.h = obj.h;
// pointer.ref.tile.dx = obj.dx;
// pointer.ref.tile.dy = obj.dy;
// pointer.ref.tile.rad = obj.rad;
pointer.ref.TID = pointData["TID"] as int;
pointer.ref.type = pointData["type"] as int;
pointer.ref.bits = pointData['bits'] == null ? 0 : pointData['bits'] as int;
pointer.ref.typeBits =
pointData['typeBits'] == null ? 0 : pointData['typeBits'] as int;
pointer.ref.TP = (pointData["TP"]) * 1.0;
pointer.ref.speed = pointData["speed"].toDouble();
pointer.ref.count = pointData["count"] as int;
pointer.ref.LAT = pointData["LAT"].toDouble();
pointer.ref.LNG = pointData["LNG"].toDouble();
pointer.ref.ASL = pointData["ASL"].toDouble();
var xyh = coordTrans.d2p(CoordBLH(
B: pointData["LAT"].toDouble(),
L: pointData["LNG"].toDouble(),
H: pointData["ASL"].toDouble()));
pointer.ref.X = xyh.X * 20;
pointer.ref.Y = xyh.Y * 20;
pointer.ref.H = xyh.H;
// print(pointer.ref.X);
// print(pointer.ref.Y);
// print(pointer.ref.H);
pointer.ref.HDG = pointData["HDG"].toDouble();
pointer.ref.UTC = pointData["UTC"] as int;
pointer.ref.layer = pointData["layer"] as int;
// pointer.ref.mile = pointData["mile"] as int;
pointer.ref.status = pointData["status"] as int;
// for (int i = 0; i < obj.w; i++) {
// //对tile处理
// for (int j = 0; j < obj.h; j++) {
// if (i * obj.h + j < obj.data.length) {
// pointer.ref.tile.data[i * obj.h + j] = obj.data[i * obj.h + j];
// }
// }
// }
// passTrackPlugin.passTrack_fullMap_addPoint(pointer);
//calloc.free(pointer);
}
Future<bool> init() async {
return false;
// await initDevice();
// await initPalette();
// coordTrans = CoordTrans(TransOptions(L0: L0));
// List allPointData = filterPoint(null, null);
// var count = 0;
// if (allPointData is List) {
// for (var e in allPointData) {
// count++;
// updateObj(e);
// // if (count > 100000) {
// // break;
// // // ++count
// // }
// }
// } else {
// count++;
// updateObj(allPointData);
// // if (count > 100000) {
// // return true;
// // }
// }
// // passTrackPlugin.passTrack_drawFullScreen(true);
// ffi.Pointer<Binding.Point> pointerNull =
// calloc.allocate<Binding.Point>(ffi.sizeOf<Binding.Point>());
// // passTrackPlugin.playTrack(true, true, false, 0, 115000, ffi.nullptr);
// calloc.free(pointerNull);
// return true;
}
//初始化设备并且根据设备修改point的bits值
2024-09-06 09:52:06 +08:00
// initDevice() async {
// //读取设备数据
// List temp = await GetServices().getDeviceBind();
// //筛出其中的roller和paver
// temp.forEach((element) {
// if (element["type"] == "roller" || element["type"] == "paver") {
// deviceList.add(element);
// }
// });
2024-09-06 09:11:06 +08:00
2024-09-06 09:52:06 +08:00
// for (var i = 0; i < deviceList.length; i++) {
// //对所有设备的bits进行处理
// deviceList[i]["bits"] = 1 << i;
// //再将TID作为键赋值给deviceData
// deviceData[deviceList[i]["tid"]] = deviceList[i];
// }
2024-09-06 09:11:06 +08:00
2024-09-06 09:52:06 +08:00
// await getFile();
// }
2024-09-06 09:11:06 +08:00
//获取txt文件内容
2024-09-06 09:52:06 +08:00
// getFile() async {
// var fileList = await GetServices().getHisFileList();
// for (var i = 0; i < fileList["list"].length; i++) {
// // print(fileList[i]);
// dynamic data = await GetServices().getHisFile(fileList["list"][i]);
// allPointData.addAll(resolveJson(data, passTrackPlugin));
// }
// allPointData.forEach((ele) {
// updateDevices(ele);
// });
// // print(pointData);
// }
2024-09-06 09:11:06 +08:00
//处理文本文件
resolveJson(var res, PassTrack passTrackPlugin) {
if (res is String) {
List<RecieveModel> allPointData = [];
int start = 0;
var allPointLen = 0;
2024-09-06 15:16:09 +08:00
// data 是一个列表
var data = jsonDecode(res)["data"];
for (var item in data) {
// RecieveModel recieveModel = RecieveModel.fromJson(item);
var X = item["X"].toDouble();
var Y = item["Y"].toDouble();
var TID = item["TID"];
var type = int.parse(item["type"]);
var p = passTrackPlugin.wantPoint();
p.ref.X = X;
p.ref.Y = Y;
p.ref.TID = TID;
p.ref.type = type;
2024-09-06 09:11:06 +08:00
}
2024-09-06 15:16:09 +08:00
return data.length;
2024-09-06 09:11:06 +08:00
}
2024-09-06 15:16:09 +08:00
return 0;
// 记录当前数组的长度
// while (true) {
// int end = res.indexOf('\n', start);
// if (end < 0) {
// break;
// }
// String str = res.substring(start, end);
// try {
// if (str[str.length - 1] == ",") {
// str = str.substring(0, str.length - 1);
// }
// var item = jsonDecode(str);
// RecieveModel recieveModel = RecieveModel.fromJson(item);
// if (drawCtx.zeroDX == 0 || drawCtx.zeroDY == 0) {
// //dart重置中心
// drawCtx.setCenter(
// // {"x": recieveModel.x / 20, "y": recieveModel.y / 20});//532863.8,4208668.95
// {"x": 10656637 / 20, "y": 84172941 / 20}); //532863.8,4208668.95
// }
// int x = recieveModel.x;
// int y = recieveModel.y;
// int tid = recieveModel.TID;
// int type = recieveModel.type;
// var p = passTrackPlugin.wantPoint();
// p.ref.X = x.toDouble();
// p.ref.Y = y.toDouble();
// p.ref.TID = tid;
// p.ref.type = type;
// // var data = item['data'];
// // if (data != null) {
// // item['TID'] =
// // item['TID'] is int ? item['TID'] : num.parse(item['TID']);
// // item['type'] =
// // item['type'] is int ? item['type'] : num.parse(item['type']);
// // item['obj'] = DecodeDataObj.fromBase64(item['data']);
// // // this.updateDevice(item);
// // // this.sportsData.push(item);
// allPointData.add(recieveModel);
// // }
// } catch (e) {
// print("----$e\r\n$str");
// }
// allPointLen++;
// start = end + 1;
// }
// return allPointLen;
// } else {
// //只有一条数据的时候
// var item = res;
// var data = item['data'];
// if (data != null) {
// item['obj'] = DecodeDataObj.fromBase64(item['data']);
// item['type'] = num.parse(item['type']);
// item['TID'] = num.parse(item['TID']);
// // this.updateDevice(item);
// // this.sportsData.push(item);
// }
// return 1;
// }
2024-09-06 09:11:06 +08:00
}
//修改点的bits和typeBits
updateDevices(var point) {
var TID = point["TID"];
if (deviceData.containsKey(TID)) {
var device = deviceData[TID];
device["show"] = true;
point["bits"] = device["bits"];
point["typeBits"] = (device["type"] == "paver" ? 2 : 1) < 2
? 1
: device["bits"] | (1 << ((device["type"] == "paver" ? 2 : 1) - 2));
device["point"] = point;
}
//bug
//websocket
// if(isLive ==true&&devicState.timer==null){
// //设置了一个定时器
// }
}
//读取颜色
// initPalette() async {
// var data = await GetServices().getLayeConfig();
// for (var i = 0; i < data.length; i++) {
// if (data[i]['name'] == "times_draw") {
// data[i] = filterAndResolveModel(data[i]);
// }
// data[i] = FormatColor(data[i]);
// if (data[i]['type'] == 'layer' && data[i]["standard"] != null) {
// data[i] = BubbleSort(data[i]);
// }
// }
// palette = data[0]["color"];
// //给调色板赋值
// for (int i = 0; i < palette.length; i++) {
// passTrackPlugin.setPalette(i, changeARGBInt8toInt32(palette[i]));
// }
// // print(palette);
// // print(palette.length);
// //如果是cumulate类型还要对颜色进行扩充
// }
List liveData = [];
bool isLive = false;
var devicState;
num centerTid = 0;
// 是否结束播放
bool end = true;
var sportsData;
num angle = 0;
// 中心设备的编号
var centerDevice = null;
bool isCenter = false;
//是否平移
bool isTranslate = false;
// 正北模式
bool isView = false;
int? startIndex;
int? endIndex;
//websocket
liveView(bool isLive, String wsHost, String proj_code) {
String token = "";
String ws_url = wsHost + "?token=" + token;
final _channel = IOWebSocketChannel.connect(ws_url);
String? message;
//发送消息
_channel.sink.add(jsonEncode(["ProjSubscribe", "cp_road", proj_code]));
_channel.stream.listen((message) {
//检查收到数据
List data = json.decode(message);
if (data[0] == "ProjSubAck") {
//如果响应的数据不正确,重新发送信息
if (proj_code != data[2]) {
_channel.sink
.add(jsonEncode(["ProjSubscribe", "cp_road", proj_code]));
}
//bug,这里应该还有些操作
//绘制设备,绘制数据,
} else if (data[0] == "cp_roadPublish") {
if (proj_code != data[2]) {}
var row = data[3];
row.obj = DecodeDataObj.fromBase64(row.data);
row.TID = num.parse(row.TID);
liveData.add(row);
recivePoint(row);
updateDevices(row);
//有tid以当前设备为中心
if (centerTid != 0 && row.TID == centerTid) {
//bug
//这里申请地址创建一个point传给c++
// passTrackPlugin.passTrack_fullMap_updateCenter(point);
drawCtx.setCenter(row.obj);
}
//如果该点不符合要求直接return
if (!filterPoint(null, null).isNotEmpty) {
return;
}
if (end && isLive) {
var socketInfo;
sportsData.addAll(liveData);
liveData.clear();
if (angle == 0) {
angle = pi / 2 - row.obj.rad;
socketInfo.rotate = (180 / pi) * angle;
socketInfo.TP = row.TP;
socketInfo.speed = row.speed;
socketInfo.LAT = row.LAT;
socketInfo.LNG = row.LNG;
} else if (row.bits == centerDevice) {
angle = pi / 2 - row.obj.rad;
socketInfo.rotate = (180 / pi) * angle;
socketInfo.TP = row.TP;
socketInfo.speed = row.speed;
socketInfo.LAT = row.LAT;
socketInfo.LNG = row.LNG;
if (isCenter) {
backCenter();
}
}
socketInfo.count = row.count;
// this.eventObject['socketing']?.call(this, socketInfo);
}
if (!this.isTranslate) {
//bug 局部重绘
// this.fillAndDrawImageData(false, row);
if (isView || !centerDevice) {
//bug
// centerDevice=
}
}
}
});
}
recivePoint(var point) {
if (drawCtx.zeroDX == 0 || drawCtx.zeroDY == 0) {
//dart重置中心
drawCtx.setCenter(point);
//bug
//c++重置中心
ffi.Pointer<Binding.Point> pointer =
calloc.allocate<Binding.Point>(ffi.sizeOf<Binding.Point>());
// pointer.ref.x
// passTrackPlugin.playTrack(
// true, false, false, 0, -1, pointer);
calloc.free(pointer);
}
//bug
//这里要申请地址然后把point传给c++
// passTrackPlugin.passTrack_fullMap_addPoint(point);
// passTrackPlugin.passTrack_drawFullScreen(true);
//这是c++addpoint后的返回值
bool isSucceed = true;
if (isSucceed) {
isCenter = true;
} else {
isCenter = false;
}
}
//返回中心坐标
backCenter() {
//bug
//应该可以和刷新一样
}
drawSection(int startIndex, int endIndex, bool isCenter) {
if (endIndex > allPointData.length) {
return;
}
if (isCenter) {
filterPoint(startIndex, endIndex);
} else {}
}
// drawSection(int startIndex, int endIndex, bool isCenter) {
// if (startIndex < 0 && endIndex < 0) {
// return;
// }
// //清空屏幕
// //bug
// // this.ctx.clearRect(0, 0, this.width, this.height);
// // this.global.data.fill(0);
// updateDeviceVisible();
// if (isCenter || drawCtx.zeroDX == 0 || drawCtx.zeroDY == 0) {
// if (sportsData[endIndex]["obj"] != null) {
// double ox = sportsData[endIndex]["obj"]["x"];
// double oy = sportsData[endIndex]["obj"]["y"];
// num x = ((ox / drawCtx.scale - drawCtx.screenSize.width / 2) -
// drawCtx.zeroDX)
// .floor()
// .abs();
// num y = ((oy / drawCtx.scale - drawCtx.screenSize.height / 2) -
// drawCtx.zeroDY)
// .floor()
// .abs();
// if (x >= drawCtx.screenSize.width / 2 ||
// y >= drawCtx.screenSize.height / 2) {
// drawCtx.zeroX = ox;
// drawCtx.zeroY = oy;
// drawCtx.setCenter(null);
// }
// }
// }
// reciveAndFilterPoint(startIndex, endIndex);
// //绘制全屏
// // this.fillAndDrawImageData(true);
// //绘制网格
// // this.drawGrid();
// //绘制道路边线
// // this.drawSideLine(this.roadData);
// //获取设备
// // let arr = this.getDeviceData();
// //绘制设备
// // this.drawDevice(arr);
// endIndex = endIndex;
// startIndex = startIndex;
// //监听当前视图状态 播放进度
// // this.viewStatus(false);
// // this.isPlay = false;
// }
// //筛选出需要绘制的设备
// updateDeviceVisible() {
// for (int i = 0; i < deviceList.length; i++) {
// if (deviceList[i] != null) {
// deviceList[i]["show"] = true;
// } else {
// deviceList[i]["show"] = false;
// }
// }
// }
// reciveAndFilterPoint(int startIndex, int endIndex) {
// if (endIndex == -1) {
// endIndex = sportsData.length - 1;
// }
// for (int i = startIndex; i <= endIndex; i++) {
// var isDraw = filterPoint(sportsData[i]);
// if (isDraw) {
// recivePoint(sportsData[i]);
// updateDevices(sportsData[i]);
// // this.allowDLPI = index;
// }
// }
// }
}
//将后端的rgba转换成abgr因为c++那边渲染需要abgr
int changeARGBInt8toInt32(List row) {
int result;
result = (row[3] << 24) | (row[2] << 16) | (row[1] << 8) | row[0];
return result;
}
//根据standard处理color的值
Map filterAndResolveModel(Map item) {
item["standard"] = tranToArray(item["standard"]);
item["color"] = tranToArray(item["color"]);
var standard = item["standard"];
var color = item["color"];
for (var i = 0; i < standard.length; i++) {
var inter = standard[i];
var actColor = color[i];
var interDiff = inter[1] - inter[0];
var colorDiff1 =
((actColor[0][0] - actColor[1][0]) / interDiff).round().abs();
var colorDiff2 =
((actColor[0][1] - actColor[1][1]) / interDiff).round().abs();
var colorDiff3 =
((actColor[0][2] - actColor[1][2]) / interDiff).round().abs();
var arr = [];
for (var j = 1; j < interDiff; j++) {
arr.add([
actColor[0][0] - colorDiff1 * j,
actColor[0][1] - colorDiff2 * j,
actColor[0][2] - colorDiff3 * j,
255
]);
}
actColor.insert(1, arr);
}
var newStandard = [];
for (var i = 0; i < standard.length; i++) {
for (var j = 0; j < standard[i].length; j++) {
newStandard.add(standard[i][j]);
}
}
item["standard"] = newStandard;
var newColor = [];
for (var i = 0; i < color.length; i++) {
for (var j = 0; j < color[i].length; j++) {
for (var k = 0; k < color[i][j].length; k++) {
if (color[i][j][k] is int) {
newColor.add(color[i][j]);
break;
} else {
newColor.add(color[i][j][k]);
}
}
}
}
item["color"] = newColor;
return item;
}
List tranToArray(List arr) {
var newArr = [];
for (var i = 0; i < arr.length; i += 2) {
newArr.add([arr[i], arr[i + 1]]);
}
return newArr;
}
//对于类型是cumulate的颜色扩充到256对于非cumulate的颜色添加一个白色的初始色
Map FormatColor(Map item) {
if (item["type"] == "cumulate") {
List newColor = [];
for (int i = 1; i < item["color"].length; i++) {
newColor.addAll([
item["color"][i],
item["color"][i],
item["color"][i],
item["color"][i]
]);
}
item["color"] = newColor;
var maxColor = item["color"][item["color"].length - 1];
for (var i = item["color"].length; i < 254; i++) {
item["color"].add(maxColor);
}
item["color"].insert(0, [0, 0, 0, 0]);
item["color"].insert(0, [0, 0, 0, 0]);
} else {
item["color"].insert(0, [0, 0, 0, 0]);
}
if (item["sideColor"] != null && item["sideColor"] != 0) {
item["color"][1] = item["sideColor"];
}
return item;
}
//如果类型是layer重新对standard和color排序
Map BubbleSort(Map item) {
for (var i = 0; i < item["standard"].length; i++) {
for (var j = 1; j < item["standard"].length; j++) {
if (item["standard"][i] > item["standard"][j]) {
var num = item["standard"][i];
item["standard"][i] = item["standard"][j];
item["standard"][j] = num;
var color = item["color"][i];
item["color"][i] = item["color"][j];
item["color"][j] = color;
}
}
}
return item;
}