cpnav/lib/pages/pass_track/sevice/file_handle.dart
2024-09-06 15:16:09 +08:00

691 lines
22 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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();
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值
// initDevice() async {
// //读取设备数据
// List temp = await GetServices().getDeviceBind();
// //筛出其中的roller和paver
// temp.forEach((element) {
// if (element["type"] == "roller" || element["type"] == "paver") {
// deviceList.add(element);
// }
// });
// for (var i = 0; i < deviceList.length; i++) {
// //对所有设备的bits进行处理
// deviceList[i]["bits"] = 1 << i;
// //再将TID作为键赋值给deviceData
// deviceData[deviceList[i]["tid"]] = deviceList[i];
// }
// await getFile();
// }
//获取txt文件内容
// 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);
// }
//处理文本文件
resolveJson(var res, PassTrack passTrackPlugin) {
if (res is String) {
List<RecieveModel> allPointData = [];
int start = 0;
var allPointLen = 0;
// 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;
}
return data.length;
}
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;
// }
}
//修改点的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;
}