diff --git a/controller/Mission.js b/controller/Mission.js index ffb8a7b..69e9b23 100644 --- a/controller/Mission.js +++ b/controller/Mission.js @@ -2,6 +2,7 @@ const util = require("../util/common"); let dataBase = require("../util/dmDB"); const moment = require('moment-timezone'); var { PlanePoint, entityHJ, entityEvent, simuStatus } = require("../util/variable"); +let entityMgr = require("./entityMgr"); //加载航空兵数据 exports.loadHKBData = (req, res, next) => { @@ -37,28 +38,30 @@ exports.loadHKBData = (req, res, next) => { obj["体系摧毁文本信息"] = "体系摧毁时间为:" + moment(result[10]).format('HH:mm:ss'); obj["体系摧毁文本颜色"] = "255,0,0,255"; - var hj = await getHjFromDb(obj, bdid, "航迹", 1000, 1, "飞机"); + let uid = entityMgr.createEntity("飞机", obj); + + var hj = await getHjFromDb(obj, bdid, "航迹", 1000, 1, "飞机", uid); if (!hj) { - hj = await getHjFromDb(obj, bdid, "航迹", 1000, 0, "飞机"); + hj = await getHjFromDb(obj, bdid, "航迹", 1000, 0, "飞机", uid); } //存入空空攻击事件map - var kksjlist = await getKkwqsyList(bdid, "有效", qcdh, zy, req.query.RQ, req.query.RWBS); + var kksjlist = await getKkwqsyList(bdid, "有效", qcdh, zy, req.query.RQ, req.query.RWBS, uid); //存入空地攻击事件map - var kdsjlist = await getKdwqsyList(bdid, "有效", req.query.RQ); + var kdsjlist = await getKdwqsyList(bdid, "有效", req.query.RQ, uid); //红外弹事件 - var hwdList = await getGrqkList(bdid, "红外弹", qcdh, req.query.RQ); + var hwdList = await getGrqkList(bdid, "红外弹", qcdh, req.query.RQ, uid); //箔条弹事件 - var hwdList = await getGrqkList(bdid, "箔条弹", qcdh, req.query.RQ); + var hwdList = await getGrqkList(bdid, "箔条弹", qcdh, req.query.RQ, uid); //有源干扰事件 - var yyList = await getGrqkList(bdid, "有源干扰", qcdh, req.query.RQ); + var yyList = await getGrqkList(bdid, "有源干扰", qcdh, req.query.RQ, uid); //机载雷达事件 - var ldList = await getGrqkList(bdid, "机载雷达", qcdh, req.query.RQ); + var ldList = await getGrqkList(bdid, "机载雷达", qcdh, req.query.RQ, uid); array.push(obj); @@ -70,7 +73,7 @@ exports.loadHKBData = (req, res, next) => { } //加载飞机航迹 -getHjFromDb = async (obj, bdid, sjlx, sjjd, zsj, zblb) => { +getHjFromDb = async (obj, bdid, sjlx, sjjd, zsj, zblb, uid) => { var params = ["nr"]; var whereSql = "jcid = '" + bdid + "' and sjlx = '" + sjlx + "' and sjjd = " + sjjd + " and zsj = " + zsj; var data = await dataBase.queryTable("kzdk.rw_fj_sj", params, whereSql); @@ -115,14 +118,17 @@ getHjFromDb = async (obj, bdid, sjlx, sjjd, zsj, zblb) => { } points.set(PlanePoint.get('iRelTime'), pt); + + let t = PlanePoint.get('iRelTime'); + entityMgr.insertAnimaPath(uid, t, pt); } - const sortMap = new Map([...points].sort((a, b) => a[0] - b[0])); + //const sortMap = new Map([...points].sort((a, b) => a[0] - b[0])); - if (sortMap.size > 0) { + if (points.size > 0) { var startSimu = simuStatus["开始时间"]; var endSimu = simuStatus["结束时间"]; - const keysArray = [...sortMap.keys()]; + const keysArray = [...points.keys()]; var start = keysArray[0]; var end = keysArray[keysArray.length - 1]; if (startSimu < 0.0) { @@ -139,14 +145,14 @@ getHjFromDb = async (obj, bdid, sjlx, sjjd, zsj, zblb) => { simuStatus["结束时间"] = endSimu; } - entityHJ.set(bdid, sortMap); + //entityHJ.set(bdid, sortMap); return points; } } //空空攻击事件 -getKkwqsyList = async (bdid, qrxg, qcdh, zy, rq, rwbs) => { +getKkwqsyList = async (bdid, qrxg, qcdh, zy, rq, rwbs, uid) => { //查询空空武器攻击事件 var params = ["dx", "fsbh", "GJ_JL", "GJ_FW", "gj_sk", "GJTS", "DMZYSK", "ZD_JSSK", "gjxg_qrmb", "MZYXX", "FS_JH"]; var whereSql = "sjlx = '空空' and gjxg_qrxg = '" + qrxg + "' and bdid = '" + bdid + "'"; @@ -289,26 +295,29 @@ getKkwqsyList = async (bdid, qrxg, qcdh, zy, rq, rwbs) => { //传入Gis的事件 array.push(sjmap); - let eventMap = entityEvent.get(bdid); - if (!eventMap) { - eventMap = new Map(); - } + // let eventMap = entityEvent.get(bdid); + // if (!eventMap) { + // eventMap = new Map(); + // } { let event = {}; event["事件"] = "空空攻击事件"; event["类型"] = "开始"; event["参数"] = csmap; - eventMap.set(startms, event); + //eventMap.set(startms, event); + entityMgr.insertUserEvent(uid, startms, event); } { let event = {}; event["事件"] = "空空攻击事件"; event["类型"] = "结束"; event["参数"] = csmap; - eventMap.set(endms, event); + //eventMap.set(endms, event); + + entityMgr.insertUserEvent(uid, endms, event); } - entityEvent.set(bdid, eventMap); + //entityEvent.set(bdid, eventMap); result = await data.getRow(); } @@ -369,13 +378,13 @@ getKkddFromDb = async (bdid, gjcx) => { points.set(PlanePoint.get('iRelTime'), pt); } - const sortMap = new Map([...points].sort((a, b) => a[0] - b[0])); - return sortMap; + //const sortMap = new Map([...points].sort((a, b) => a[0] - b[0])); + return points; } } //空地攻击事件 -getKdwqsyList = async (bdid, qrxg, rq) => { +getKdwqsyList = async (bdid, qrxg, rq, uid) => { //查询空地武器攻击事件 var params = ["gj_sk", "DMZYSK", "gjxg_qrmb", "dx", "fsbh"]; var whereSql = "sjlx = '空地' and gjxg_qrxg = '" + qrxg + "' and bdid = '" + bdid + "'"; @@ -411,26 +420,27 @@ getKdwqsyList = async (bdid, qrxg, rq) => { //传入Gis的事件 array.push(sjmap); - let eventMap = entityEvent.get(bdid); - if (!eventMap) { - eventMap = new Map(); - } + // let eventMap = entityEvent.get(bdid); + // if (!eventMap) { + // eventMap = new Map(); + // } { let event = {}; event["事件"] = "空地攻击事件"; event["类型"] = "开始"; event["参数"] = csmap; - eventMap.set(startms, event); - + //eventMap.set(startms, event); + entityMgr.insertUserEvent(uid, startms, event); } { let event = {}; event["事件"] = "空地攻击事件"; event["类型"] = "结束"; event["参数"] = csmap; - eventMap.set(endms, event); + // eventMap.set(endms, event); + entityMgr.insertUserEvent(uid, endms, event); } - entityEvent.set(bdid, eventMap); + //entityEvent.set(bdid, eventMap); result = await data.getRow(); } @@ -439,7 +449,7 @@ getKdwqsyList = async (bdid, qrxg, rq) => { } //干扰事件 -getGrqkList = async (bdid, grlx, qcdh, rq) => { +getGrqkList = async (bdid, grlx, qcdh, rq, uid) => { var params = []; var whereSql = "grlx = '" + grlx + "' and bdid = '" + bdid + "'"; var data = await dataBase.queryTable("kzdk.rw_fxjc_grqk", params, whereSql); @@ -477,10 +487,10 @@ getGrqkList = async (bdid, grlx, qcdh, rq) => { map["参数"] = csMap; array.push(map); - let eventMap = entityEvent.get(bdid); - if (!eventMap) { - eventMap = new Map(); - } + // let eventMap = entityEvent.get(bdid); + // if (!eventMap) { + // eventMap = new Map(); + // } var eventType; if (grlx == "红外弹") { eventType = "红外弹干扰事件"; @@ -496,17 +506,18 @@ getGrqkList = async (bdid, grlx, qcdh, rq) => { event["事件"] = eventType; event["类型"] = "开始"; event["参数"] = csMap; - eventMap.set(grSec, event); - + //eventMap.set(grSec, event); + entityMgr.insertUserEvent(uid, grSec, event); } { let event = {}; event["事件"] = eventType; event["类型"] = "结束"; event["参数"] = csMap; - eventMap.set(grjsSec, event); + //eventMap.set(grjsSec, event); + entityMgr.insertUserEvent(uid, grjsSec, event); } - entityEvent.set(bdid, eventMap); + //entityEvent.set(bdid, eventMap); result = await data.getRow(); } @@ -548,15 +559,17 @@ exports.loadDDData = (req, res, next) => { obj["体系摧毁文本颜色"] = "255,0,0,255"; //obj["参数"] = "255,0,0,255"; + let uid = entityMgr.createEntity("地导阵地", obj); + if (dylb == "舰艇") { - var hj = await getHjFromDb(obj, bdid, "航迹", 100, 1, "地导阵地"); + var hj = await getHjFromDb(obj, bdid, "航迹", 100, 1, "地导阵地", uid); if (!hj) { - hj = await getHjFromDb(obj, bdid, "航迹", 100, 0, "地导阵地"); + hj = await getHjFromDb(obj, bdid, "航迹", 100, 0, "地导阵地", uid); } } //当前地导阵地所有地空攻击事件 - var dksjlist = await getDkwqsyList(bdid, zy, dwjc, req.query.RQ); + var dksjlist = await getDkwqsyList(bdid, zy, dwjc, req.query.RQ, uid); array.push(obj); @@ -569,7 +582,7 @@ exports.loadDDData = (req, res, next) => { //查询地空武器攻击事件 //地导武器发射 -getDkwqsyList = async (bdid, zy, dwjc, rq) => { +getDkwqsyList = async (bdid, zy, dwjc, rq, uid) => { var params = ["gjcx", "gjd", "qrxg_mbxh", "qrxg_qrmb", "sk", "qrxg_ywx", "ddbh"]; var whereSql = "jd = '发射' and bdid = '" + bdid + "'"; var data = await dataBase.queryTable("kzdk.rw_dd_wqgj", params, whereSql); @@ -621,6 +634,21 @@ getDkwqsyList = async (bdid, zy, dwjc, rq) => { //传入Gis的事件 array.push(sjmap); + + { + let event = {}; + event["事件"] = "地空攻击事件"; + event["类型"] = "开始"; + event["参数"] = csmap; + entityMgr.insertUserEvent(uid, startms, event); + } + { + let event = {}; + event["事件"] = "地空攻击事件"; + event["类型"] = "结束"; + event["参数"] = csmap; + entityMgr.insertUserEvent(uid, endms, event); + } } } @@ -686,8 +714,8 @@ getDkddFromDb = async (bdid, gjcx, ddbh) => { points.set(PlanePoint.get('iRelTime'), pt); } - const sortMap = new Map([...points].sort((a, b) => a[0] - b[0])); - return sortMap; + //const sortMap = new Map([...points].sort((a, b) => a[0] - b[0])); + return points; } } @@ -736,6 +764,8 @@ exports.loadDJMBData = (req, res, next) => { obj["装备类别"] = "打击目标"; //obj["参数"] = "255,0,0,255"; + let uid = entityMgr.createEntity("打击目标", obj); + array.push(obj); result = await data.getRow(); @@ -770,6 +800,8 @@ exports.loadJDMBData = (req, res, next) => { obj["装备类别"] = "机动目标"; //obj["参数"] = "255,0,0,255"; + let uid = entityMgr.createEntity("机动目标", obj); + array.push(obj); result = await data.getRow(); diff --git a/controller/aircraft.js b/controller/aircraft.js new file mode 100644 index 0000000..85fc8bb --- /dev/null +++ b/controller/aircraft.js @@ -0,0 +1,112 @@ +let Entity = require("./entity"); +let entityMgr = require("./entityMgr"); + +class Aircraft extends Entity { + constructor(base) { + super(base); + } + + init() { + this.insertAttackKKEvent(); + this.insertStopAttackKKEvent(); + + this.insertAttackKDEvent(); + this.insertStopAttackKDEvent(); + + this.insertInfraRedBombEvent(); + this.insertStopInfraRedBombEvent(); + } + + insertAttackKKEvent() { + let event = {}; + event["事件"] = "空空攻击事件"; + event["类型"] = "开始"; + super.bindUserEventFun(event, this.slotBeginAttack); + } + + insertStopAttackKKEvent() { + let event = {}; + event["事件"] = "空空攻击事件"; + event["类型"] = "结束"; + super.bindUserEventFun(event, this.slotStopAttack); + } + + insertAttackKDEvent() { + let event = {}; + event["事件"] = "空地攻击事件"; + event["类型"] = "开始"; + super.bindUserEventFun(event, this.slotBeginAttack); + } + + insertStopAttackKDEvent() { + let event = {}; + event["事件"] = "空地攻击事件"; + event["类型"] = "结束"; + super.bindUserEventFun(event, this.slotStopAttack); + } + + insertInfraRedBombEvent() { + let event = {}; + event["事件"] = "红外弹干扰事件"; + event["类型"] = "开始"; + super.bindUserEventFun(event, this.slotInfraRedBomb); + } + + insertStopInfraRedBombEvent() { + let event = {}; + event["事件"] = "红外弹干扰事件"; + event["类型"] = "结束"; + super.bindUserEventFun(event, this.slotStopInfraRedBomb); + } + + slotBeginAttack(para) { + var hj = para["航迹"]; + if (hj) { + let uid = entityMgr.createEntity("空空弹", para); + for (const [key, value] of hj) { + let t = key; + let pt = value; + entityMgr.insertAnimaPath(uid, t, pt); + } + + var zdjs = para["制导结束时刻"]; + if (zdjs) { + { + let eventJH = {}; + eventJH["事件"] = "导弹截获事件"; + eventJH["类型"] = "开始"; + eventJH["参数"] = para["攻击目标"]; + entityMgr.insertUserEvent(uid, zdjs, eventJH); + } + { + var endMs = para["结束时刻"]; + let eventJH = {}; + eventJH["事件"] = "导弹截获事件"; + eventJH["类型"] = "结束"; + eventJH["参数"] = para["攻击目标"]; + entityMgr.insertUserEvent(uid, endMs, eventJH); + } + } + } + } + + slotStopAttack(para) { + var hj = para["航迹"]; + if (hj) { + let xh = para["型号"]; + let bh = para["编号"]; + let uid = entityMgr.getEntityUID(xh, bh); + if (uid) { + entityMgr.releaseEntity(uid); + } + } + } + + slotInfraRedBomb(para) { + } + + slotStopInfraRedBomb(para) { + } +} + +module.exports = Aircraft; \ No newline at end of file diff --git a/controller/entity.js b/controller/entity.js new file mode 100644 index 0000000..98d0035 --- /dev/null +++ b/controller/entity.js @@ -0,0 +1,177 @@ +const { v1: uuidv1, v3: uuidv3, v4: uuidv4, v5: uuidv5 } = require('uuid'); +const util = require("../util/common"); + +class Entity { + constructor(base) { + this.uid = uuidv4(); + this.base = base; + + this.animaPath = new Map(); + this.userEvent = new Map(); + this.eventFunc = new Map(); + } + + getUID() { + return this.uid; + } + + getBase() { + return this.base; + } + + init() { + + } + + insertAnimaPath(t, point) { + this.animaPath.set(t, point); + } + + sortAnimaPath() { + const sortMap = new Map([...this.animaPath].sort((a, b) => a[0] - b[0])); + this.animaPath = sortMap; + } + + clearAnimaPath() { + this.animaPath.clear(); + } + + updateAnimaPath(t) { + if (this.animaPath.size > 0) { + const keysArray = [...this.animaPath.keys()]; + var indexKey = util.lower_bound(keysArray, t); + if (indexKey < keysArray.length) { + let point = {}; + var second = keysArray[indexKey]; + if (indexKey == 0) { + if (second <= t) { + point = this.animaPath.get(second); + } + } + else { + var first = keysArray[indexKey - 1]; + var delta_time = second - first; + if (delta_time == 0.0) { + point = this.animaPath.get(first); + } + else { + var pointfirst = this.animaPath.get(first); + var pointsecond = this.animaPath.get(second); + + point["空速"] = util.interpolate( + (t - first) / delta_time, + pointfirst["空速"], + pointsecond["空速"]); + + point["升降率"] = util.interpolate( + (t - first) / delta_time, + pointfirst["升降率"], + pointsecond["升降率"]); + + point["过载"] = util.interpolate( + (t - first) / delta_time, + pointfirst["过载"], + pointsecond["过载"]); + + point["马赫数"] = util.interpolate( + (t - first) / delta_time, + pointfirst["马赫数"], + pointsecond["马赫数"]); + + point["经度"] = util.interpolate( + (t - first) / delta_time, + pointfirst["经度"], + pointsecond["经度"]); + + point["纬度"] = util.interpolate( + (t - first) / delta_time, + pointfirst["纬度"], + pointsecond["纬度"]); + + point["海拔"] = util.interpolate( + (t - first) / delta_time, + pointfirst["海拔"], + pointsecond["海拔"]); + + point["航向角"] = util.interpolate( + (t - first) / delta_time, + pointfirst["航向角"], + pointsecond["航向角"]); + + point["俯仰角"] = util.interpolate( + (t - first) / delta_time, + pointfirst["俯仰角"], + pointsecond["俯仰角"]); + + point["倾斜角"] = util.interpolate( + (t - first) / delta_time, + pointfirst["倾斜角"], + pointsecond["倾斜角"]); + } + } + return point; + } + } + } + + insertUserEvent(t, event) { + event["执行"] = 0; + this.userEvent.set(t, event); + } + + clearUserEvent() { + this.userEvent.clear(); + } + + removeUserEvent(t) { + this.userEvent.delete(t); + } + + removeUserEvent(eventname, eventtype) { + for (const [key, value] of this.userEvent) { + let time = key; + let name = value["事件"]; + let type = value["类型"]; + if (name == eventname && type == eventtype) { + this.userEvent.delete(time); + } + } + } + + bindUserEventFun(event, callback) { + let name = event["事件"]; + let type = event["类型"]; + let strKey = name + ";" + type; + this.eventFunc.set(strKey, callback); + } + + updateUserEvent(t) { + if (this.userEvent.size > 0) { + const tArray = [...this.userEvent.keys()]; + var indexT = util.lower_bound(tArray, t); + if (indexT < tArray.length) { + var second = tArray[indexT]; + if (second <= t) { + let event = this.userEvent.get(second); + if (event["执行"] == 0) { + event["执行"] = 1; + //this.userEvent.set(second, event); + + let name = event["事件"]; + let type = event["类型"]; + let para = event["参数"]; + + let callback = this.eventFunc.get(name + ";" + type); + if (callback) { + callback(para); + } + + return event; + } + } + } + } + } +} + +module.exports = Entity; \ No newline at end of file diff --git a/controller/entityMgr.js b/controller/entityMgr.js new file mode 100644 index 0000000..31403d0 --- /dev/null +++ b/controller/entityMgr.js @@ -0,0 +1,85 @@ +let Entity = require("./entity"); +let Aircraft = require("./aircraft"); +let Missile = require("./missile"); + +class EntityMgr { + constructor() { + this.entityMap = new Map(); + } + + createEntity(sclass, base) { + var entity; + if (sclass == "飞机") { + entity = new Aircraft(base); + } else if (sclass == "空空弹") { + entity = new Missile(base); + } else { + entity = new Entity(base); + } + + let uid = entity.getUID(); + entity.init(); + this.entityMap.set(uid, entity); + return uid; + } + + releaseEntity(uid) { + this.entityMap.delete(uid); + } + + getEntity(uid) { + return this.entityMap.get(uid); + } + + getEntityUID(xh, bh) { + for (const [key, value] of this.entityMap) { + let uid = key; + let entity = value; + let base = entity.getBase(); + if (base) { + if (base["型号"] == xh && base["编号"] == bh) { + return uid; + } + } + } + } + + insertAnimaPath(uid, time, point) { + let entity = this.entityMap.get(uid); + if (entity) { + entity.insertAnimaPath(time, point); + } + } + + insertUserEvent(uid, t, event) { + let entity = this.entityMap.get(uid); + if (entity) { + entity.insertUserEvent(t, event); + } + } + + updateEntity(time, data) { + if (this.entityMap.size > 0) { + var arrayHJ = []; + var arrayEvent = []; + for (const [key, value] of this.entityMap) { + let entity = value; + let base = entity.getBase(); + let point = entity.updateAnimaPath(time); + if (point.hasOwnProperty('经度')) { + point["BDID"] = base["BDID"]; + arrayHJ.push(point); + } + let event = entity.updateUserEvent(time); + if (event) { + event["BDID"] = base["BDID"]; + arrayEvent.push(event); + } + } + data["航迹列表"] = arrayHJ; + data["事件列表"] = arrayEvent; + } + } +} + +module.exports = new EntityMgr(); \ No newline at end of file diff --git a/controller/missile.js b/controller/missile.js new file mode 100644 index 0000000..57541e9 --- /dev/null +++ b/controller/missile.js @@ -0,0 +1,10 @@ +let Entity = require("./entity"); + +class Missile extends Entity { + constructor(base) { + super(base); + } + +} + +module.exports = Missile; \ No newline at end of file diff --git a/controller/socket.js b/controller/socket.js index 721ccaa..e0103eb 100644 --- a/controller/socket.js +++ b/controller/socket.js @@ -1,6 +1,7 @@ const WebSocket = require('ws'); const util = require("../util/common"); var { entityHJ, entityEvent, simuStatus } = require("../util/variable"); +let entityMgr = require("./entityMgr"); const deltaT = 1000; @@ -19,8 +20,10 @@ const createServer = () => { var currTime = simuStatus["当前时间"]; let data = {}; - updateEntityHJ(currTime, data); - updateEntityEvent(currTime, data); + entityMgr.updateEntity(currTime, data); + + // updateEntityHJ(currTime, data); + // updateEntityEvent(currTime, data); const message = { time: currTime, diff --git a/package-lock.json b/package-lock.json index 37adf99..bd0b1a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "moment-timezone": "^0.5.47", "morgan": "~1.9.1", "struct": "^0.0.12", + "uuid": "^11.1.0", "ws": "^8.18.1" } }, @@ -1162,6 +1163,18 @@ "node": ">= 0.4.0" } }, + "node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", diff --git a/package.json b/package.json index cee4800..418eae6 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "moment-timezone": "^0.5.47", "morgan": "~1.9.1", "struct": "^0.0.12", + "uuid": "^11.1.0", "ws": "^8.18.1" } }